Solved

window resize and updating size of dc's

Posted on 2004-04-14
11
604 Views
Last Modified: 2013-11-20
Hi,

I have a sprite animation that stores the background of the window it uses and want to know how to check for the window being resized?  I have tried onSizing but it only gets called at the end of the program.  I would like code to be called when the user drags the window to a new size or uses the maximise or restore buttons.

In the CFrameWnd subclass constructor I use this code to create a memory dc for the entire window:

  paintBuffer.CreateCompatibleDC(GetDC());
  GetClientRect(clientRect);
  paintBmp.CreateCompatibleBitmap(GetDC(), clientRect.Width(), clientRect.Height());
  paintBuffer.SelectObject( &paintBmp );

clientRect is a CRect and paintBuffer is a  CDC object, paintBmp is a CBitmap.  They are private members of the window class.

I blit things to paintBuffer as needed and then blit that to the window in the OnPaint event.  When the window gets resized how do I update the above variables to handle the new size?  Do I need to delete and recreate them?  If so how exactly?

My sprites depend on paintBuffer being correct due to saving and restoring the background, I will post more about that if I need to.

Thanks in advance for any help.


0
Comment
Question by:jasoncpp
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 3
11 Comments
 
LVL 4

Expert Comment

by:caner_elci
ID: 10824997
You need to add a message handle for WM_SIZE of your window.. then in WM_SIZE handler, you can call Invalidate() of your window.. that will repaint the window calling WM_PAINT (OnPaint)
0
 

Author Comment

by:jasoncpp
ID: 10826215
Sorry, that doesn't answer my question.  I need to recreate the memory dc of the window using paintBuffer etc on a resize event, not just refresh the window.
0
 
LVL 4

Expert Comment

by:caner_elci
ID: 10827413
Okay, you cannot resize a DC.. only you can resize the bitmap associated (selected) with it.. That means, you need to create a new bitmap, bitblit your old bitmap on it, or redraw whole bitmap, using your DC..

Do you need a sample code after this?
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 48

Accepted Solution

by:
AlexFM earned 500 total points
ID: 10830554
In WM_SIZE message hanller write:

paintBuffer.DeleteDC();
paintBmp.DeleteObject();

In OnPaint write:

if ( ! paintBuffer.m_hDC )
{
  paintBuffer.CreateCompatibleDC(GetDC());
  GetClientRect(clientRect);
  paintBmp.CreateCompatibleBitmap(GetDC(), clientRect.Width(), clientRect.Height());
  paintBuffer.SelectObject( &paintBmp );
}

// continue drawing here

WM_SIZE message handler releases graphic object. As result of this, next time OnPaint is called it creates them with new client rectangle size.
0
 

Author Comment

by:jasoncpp
ID: 10831229
Sorry for the delay in replying, unavoidable:

AlexFM: I have tried doing what you say but it leads to a crash.  I stepped through the code and before the window is shown, it goes to OnSize and deletes the paintBuffer and paintBmp.  An assert fails here:

int CDC::SetBkMode(int nBkMode)
{
  ASSERT(m_hDC != NULL);
  int nRetVal = 0;
   ....

This is where I delete, it does not appear it gets to onpaint before crashing:

afx_msg void MyWindow::OnSize(UINT nType, int cx, int cy) {
  CFrameWnd::OnSize(nType, cx, cy);
  paintBuffer.DeleteDC();
  paintBmp.DeleteObject();
}

I will have it go at doing what caner_elci said and see what happens.
0
 
LVL 4

Expert Comment

by:caner_elci
ID: 10831247
make this changes in AlexFM's code:

if( ::IsWindow( GetSafeHwnd() ) )
{

paintBuffer.DeleteDC();
paintBmp.DeleteObject();

In OnPaint write:

if ( ! paintBuffer.m_hDC )
{
  paintBuffer.CreateCompatibleDC(GetDC());
  GetClientRect(clientRect);
  paintBmp.CreateCompatibleBitmap(GetDC(), clientRect.Width(), clientRect.Height());
  paintBuffer.SelectObject( &paintBmp );
}

}
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 10831318
if ( paintBuffer.m_hDC )
    paintBuffer.DeleteDC();

if ( paintBmp.m_hObject )
    paintBmp.DeleteObject();
0
 

Author Comment

by:jasoncpp
ID: 10831371
I tried both things and it crashed, I got this in a debugger after AlexFM's code:

int CDC::SetPolyFillMode(int nPolyFillMode)
{
  ASSERT(m_hDC != NULL);
  ...

It failed on that assert having evaluated the if statements to true when size was called.

Any more ideas appreciated.

Thanks.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 10831410
Please show your OnSize function and debugger stack when assertion is raised.
0
 

Author Comment

by:jasoncpp
ID: 10831496
I tried the below.  The call stack info is from .Net debugger as it is installed on my system but I am using VC++ 6.  Not sure how to get the debugger back to the version 6 one, but if it matters let me know and I'll try and change it.

afx_msg void MyWindow::OnSize(UINT nType, int cx, int cy) {
  CFrameWnd::OnSize(nType, cx, cy);

  if ( paintBuffer.m_hDC )
    paintBuffer.DeleteDC();

  if ( paintBmp.m_hObject )
    paintBmp.DeleteObject();
}

Call stack:

MFC42D.DLL!CDC::SetBkMode(int nBkMode=1)  Line 315 + 0x1c      C++
HP Program.exe!ScoreText::writeScores(CDC * memDC=0x00324588, int line=0)  Line 20 + 0xa      C++
HP Program.exe!MyWindow::OnPaint()  Line 407      C++
MFC42D.DLL!CWnd::OnWndMsg(unsigned int message=15, unsigned int wParam=0, long lParam=0, long * pResult=0x0012fc44)  Line 1825      C++
MFC42D.DLL!CWnd::WindowProc(unsigned int message=15, unsigned int wParam=0, long lParam=0)  Line 1585 + 0x1e      C++
MFC42D.DLL!AfxCallWndProc(CWnd * pWnd=0x00324358, HWND__ * hWnd=0x003304e4, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 215 + 0x1a      C++
MFC42D.DLL!AfxWndProc(HWND__ * hWnd=0x003304e4, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 368      C++
MFC42D.DLL!AfxWndProcBase(HWND__ * hWnd=0x003304e4, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 220 + 0x15      C++
user32.dll!77d43a50()       
user32.dll!77d43b1f()       
user32.dll!77d444f5()       
user32.dll!77d44525()       
ntdll.dll!77f75da3()       
user32.dll!77d45ba2()       
user32.dll!77d45b93()       
MFC42D.DLL!CWnd::UpdateWindow()  Line 118 + 0x3f      C++
HP Program.exe!HP::InitInstance()  Line 464      C++
MFC42D.DLL!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x0014240e, int nCmdShow=1)  Line 39 + 0xb      C++
HP Program.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x0014240e, int nCmdShow=1)  Line 30      C++
HP Program.exe!WinMainCRTStartup()  Line 330 + 0x36      C
       kernel32.dll!77e814c7()       
0
 

Author Comment

by:jasoncpp
ID: 10831640
Oops, sorry guys, looks like I have been silly.  I managed to use the paintBuffer prior to checking in onPaint for this:

if ( ! paintBuffer.m_hDC ) {

I have now solved the problem using AlexFM's code.

Thanks again for your help.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…

696 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question