Solved

window resize and updating size of dc's

Posted on 2004-04-14
11
600 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
  • 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
 
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
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.
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…

863 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

Need Help in Real-Time?

Connect with top rated Experts

28 Experts available now in Live!

Get 1:1 Help Now