Solved

window resize and updating size of dc's

Posted on 2004-04-14
11
602 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
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 
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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
repeatEnd java challenge 42 85
scoreUp challenge 14 64
Sed question 2 103
Remove Password Protection from pdf (with password) using an command line executable 5 63
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
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.
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

830 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