GDI+ & MFC - Resizing problem
-
Hi, I am getting crazy with my problem, and I really hope that someone can help me out. Actually it sounds quite easy: I have a normal simple dialog, and I then draw 2 lines (like the axes of a coordinate system) in that dialog using GDI+. So far so good. When the user resizes my dialog I of course also want to apply the changes in size to my 2 lines. That means that they should always have the same margin to the dialog borders. And that's the problem. When I make the dialog bigger, then the lines don't get "longer" but they stay in the same length as before. But If I make the dialog smaller they also get smaller. Just strange. I do this by overriding the OnSize message handler of MFC and I then just get the client rectangle of the dialog and then draw the lines with this new rectangle applied. I also tested this with just a normal button instead of the GDI+ lines. With a normal button it works as it should, but when using GDI+ it doesn't work and I absolutley don't know why :( Many thanks for that person who can help me... P.S. I didn't know exactly in which forum to post it, because it may be a problem with MFC, but it also may be a problem with GDI+, so I just posted it in here, because I think that here are more readers...
-
Hi, I am getting crazy with my problem, and I really hope that someone can help me out. Actually it sounds quite easy: I have a normal simple dialog, and I then draw 2 lines (like the axes of a coordinate system) in that dialog using GDI+. So far so good. When the user resizes my dialog I of course also want to apply the changes in size to my 2 lines. That means that they should always have the same margin to the dialog borders. And that's the problem. When I make the dialog bigger, then the lines don't get "longer" but they stay in the same length as before. But If I make the dialog smaller they also get smaller. Just strange. I do this by overriding the OnSize message handler of MFC and I then just get the client rectangle of the dialog and then draw the lines with this new rectangle applied. I also tested this with just a normal button instead of the GDI+ lines. With a normal button it works as it should, but when using GDI+ it doesn't work and I absolutley don't know why :( Many thanks for that person who can help me... P.S. I didn't know exactly in which forum to post it, because it may be a problem with MFC, but it also may be a problem with GDI+, so I just posted it in here, because I think that here are more readers...
FreeCastle wrote:
I do this by overriding the OnSize message handler of MFC and I then just get the client rectangle of the dialog and then draw the lines with this new rectangle applied.
By this i understood that you are drawing the lines in OnSize handler..if then its wrong. Draw the lines in OnPaint handler, the framewrok will call the OnPaint handler after the window got resized. So, in OnPaint handler, get the client rect and draw the lines
Do your Duty and Don't expect the Result
Rate this Post, if I helped You -
FreeCastle wrote:
I do this by overriding the OnSize message handler of MFC and I then just get the client rectangle of the dialog and then draw the lines with this new rectangle applied.
By this i understood that you are drawing the lines in OnSize handler..if then its wrong. Draw the lines in OnPaint handler, the framewrok will call the OnPaint handler after the window got resized. So, in OnPaint handler, get the client rect and draw the lines
Do your Duty and Don't expect the Result
Rate this Post, if I helped YouOh okay, I didn't say it right. To be exact, I get the client rectangle in the OnSize message handler, and then compute the new dimensions of the two lines. All I do then in the OnSize()-method is a call to Invalidate() and nothing else. The commands for drawing the two lines are placed in the OnPaint handler. And yes, the dimensions of the two lines are computed correctly for 100% sure. That's strange in addition: The resizing works correctly if I make the dialog smaller, but when I make the dialog bigger then the two lines don't get bigger starting from a certain size.
-
Oh okay, I didn't say it right. To be exact, I get the client rectangle in the OnSize message handler, and then compute the new dimensions of the two lines. All I do then in the OnSize()-method is a call to Invalidate() and nothing else. The commands for drawing the two lines are placed in the OnPaint handler. And yes, the dimensions of the two lines are computed correctly for 100% sure. That's strange in addition: The resizing works correctly if I make the dialog smaller, but when I make the dialog bigger then the two lines don't get bigger starting from a certain size.
FreeCastle wrote:
I get the client rectangle in the OnSize message handler, and then compute the new dimensions of the two lines
No need to get the client rect in the OnSize handler. the cx and cy will give you the width and height of the window.
FreeCastle wrote:
All I do then in the OnSize()-method is a call to Invalidate
No need to call Invalidate in OnSize Handler
FreeCastle wrote:
the dimensions of the two lines are computed correctly for 100% sure
Pls provide some code, to figure out the problem
Do your Duty and Don't expect the Result
Rate this Post, if I helped You -
FreeCastle wrote:
I get the client rectangle in the OnSize message handler, and then compute the new dimensions of the two lines
No need to get the client rect in the OnSize handler. the cx and cy will give you the width and height of the window.
FreeCastle wrote:
All I do then in the OnSize()-method is a call to Invalidate
No need to call Invalidate in OnSize Handler
FreeCastle wrote:
the dimensions of the two lines are computed correctly for 100% sure
Pls provide some code, to figure out the problem
Do your Duty and Don't expect the Result
Rate this Post, if I helped YouYes I know that cx and cy will also work. But I wanted to be completely sure, so I used GetClientRectangle. The result is anyway the same. When I don't call "Invalidate" in the OnSize Handler then my dialog won't clear out the old contents (this will be then first done when I hide and show it again). Here is some example code (all placed in my simple dialog class): I have the following attributes:
Graphics* m_Canvas; //the GDI+ Graphics object to draw some stuff RECT m_rcRect; //holds the actual client rectangle of the window
And the following methods:OnPaint() { drawLines(); CDialog::OnPaint(); } OnSize(UINT nType,int cx, int cy) { CDialog::OnSize(nType,cx,cy); m_rcRect.bottom = cy; m_rcRect.right = cx; Invalidate(); } drawLines() { static bool bFirstCall = true; static Pen pen(Color::Red); if (bFirstCall == true) { m_Canvas = ::new Graphics(m_hWnd); bFirstCall = false; } m_Canvas->DrawLine(&pen,10,10,m_rcRect.right-10-10,10); m_Canvas->DrawLine(&pen,10,10,10,m_rcRect.bottom-10-10); }
-
Yes I know that cx and cy will also work. But I wanted to be completely sure, so I used GetClientRectangle. The result is anyway the same. When I don't call "Invalidate" in the OnSize Handler then my dialog won't clear out the old contents (this will be then first done when I hide and show it again). Here is some example code (all placed in my simple dialog class): I have the following attributes:
Graphics* m_Canvas; //the GDI+ Graphics object to draw some stuff RECT m_rcRect; //holds the actual client rectangle of the window
And the following methods:OnPaint() { drawLines(); CDialog::OnPaint(); } OnSize(UINT nType,int cx, int cy) { CDialog::OnSize(nType,cx,cy); m_rcRect.bottom = cy; m_rcRect.right = cx; Invalidate(); } drawLines() { static bool bFirstCall = true; static Pen pen(Color::Red); if (bFirstCall == true) { m_Canvas = ::new Graphics(m_hWnd); bFirstCall = false; } m_Canvas->DrawLine(&pen,10,10,m_rcRect.right-10-10,10); m_Canvas->DrawLine(&pen,10,10,10,m_rcRect.bottom-10-10); }
Do as below,
OnPaint(..)
{
CPaintDC dc(this);
DrawLines(&dc);
//CDialog::OnPaint(); /* Don't call this */
}OnSize()
{
/* No Need for this */
}DrawLines(CDC* pDC)
{
Graphics g(pDC->m_hDC);
Pen pen(Color::Red);
CRect rc; GetClientRect(rc);
g.DrawLine(&pen, 10, 10, rc.Width() - 20, 10);
g.DrawLine(&pen, 10, 10, 10, rc.Height() - 20);
}
Do your Duty and Don't expect the Result
Rate this Post, if I helped You -
Do as below,
OnPaint(..)
{
CPaintDC dc(this);
DrawLines(&dc);
//CDialog::OnPaint(); /* Don't call this */
}OnSize()
{
/* No Need for this */
}DrawLines(CDC* pDC)
{
Graphics g(pDC->m_hDC);
Pen pen(Color::Red);
CRect rc; GetClientRect(rc);
g.DrawLine(&pen, 10, 10, rc.Width() - 20, 10);
g.DrawLine(&pen, 10, 10, 10, rc.Height() - 20);
}
Do your Duty and Don't expect the Result
Rate this Post, if I helped YouAhhh thank you, that works. But anyway I have to put an Invalidate() into the OnSize handler, because without that I see the changes only after hiding and showing again the dialog. I don't really understand why this has to be done by a HDC, but the main thing is that it works. But there is one question open to me. In my "real" application I also do some transformations on the Graphics object (you know, for e.g. having a real local coordinate system and so on). Actually those transformations have only to be done when the dialog is showed the first time, and each time when the dialog is resized. But with that solution I also would have to make those transformations each time I draw my graphical objects. I don't really know, but I think this slows the performance a little bit down (and performance is important to me in this app). So is there a way to just recreate the Graphics object when the windows is resized (so that I don't have to perform all the time those transformations)? Anyway... thank you a lot!!
-
Ahhh thank you, that works. But anyway I have to put an Invalidate() into the OnSize handler, because without that I see the changes only after hiding and showing again the dialog. I don't really understand why this has to be done by a HDC, but the main thing is that it works. But there is one question open to me. In my "real" application I also do some transformations on the Graphics object (you know, for e.g. having a real local coordinate system and so on). Actually those transformations have only to be done when the dialog is showed the first time, and each time when the dialog is resized. But with that solution I also would have to make those transformations each time I draw my graphical objects. I don't really know, but I think this slows the performance a little bit down (and performance is important to me in this app). So is there a way to just recreate the Graphics object when the windows is resized (so that I don't have to perform all the time those transformations)? Anyway... thank you a lot!!
FreeCastle wrote:
But anyway I have to put an Invalidate() into the OnSize handler, because without that I see the changes only after hiding and showing again the dialog.
That's because only the new part of the window is invalidated (marked for repainting) during a resize. To force the entire window to be repainted when the size changes, invalidating on WM_SIZE is fine.
FreeCastle wrote:
I don't really understand why this has to be done by a HDC
Why what needs to be done with an HDC? If you want to keep a Graphics object (associated with a HDC for the window) around for the life of the window then you may want to consider using CS_OWNDC in the window class. See the RegisterClass API for details (AfxRegisterClass for MFC). Mark
"If you can dodge a wrench, you can dodge a ball."