Solved

window resize and updating size of dc's

Posted on 2004-04-14
11
601 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
Comprehensive Backup Solutions for Microsoft

Acronis protects the complete Microsoft technology stack: Windows Server, Windows PC, laptop and Surface data; Microsoft business applications; Microsoft Hyper-V; Azure VMs; Microsoft Windows Server 2016; Microsoft Exchange 2016 and SQL Server 2016.

 
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

Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Windows Drag & Drop Location 2 100
Execute multiple curl cmds with sleep and send output to file 10 97
matchUp  challenge 9 110
Use of condition with 'serial' in ansible 2 62
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
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.
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

803 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