Sign in to follow this  
derek7

questoin about frequently create

Recommended Posts

it is from petzold programming windows. I think line marked with "B" should put "A" , every time refresh window,CreateCompatibleDC and SelectObject will be call, is it necessary?
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static HBITMAP hBitmap ;
     static int     cxClient, cyClient, cxSource, cySource ;
     BITMAP         bitmap ;
     HDC            hdc, hdcMem ;
     HINSTANCE      hInstance ;
     int            x, y ;
     PAINTSTRUCT    ps ;
/*  A
     
*/ 
     switch (message)
     {
     case WM_CREATE:
          hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;

          hBitmap = LoadBitmap (hInstance, TEXT ("Bricks")) ;

          GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;

          cxSource = bitmap.bmWidth ;
          cySource = bitmap.bmHeight ;

          return 0 ;

     case WM_SIZE:
          cxClient = LOWORD (lParam) ;
          cyClient = HIWORD (lParam) ;
          return 0 ;

     case WM_PAINT:
          hdc = BeginPaint (hwnd, &ps) ;

/* B
          hdcMem = CreateCompatibleDC (hdc) ;
          SelectObject (hdcMem, hBitmap) ;
*/
          for (y = 0 ; y < cyClient ; y += cySource)
          for (x = 0 ; x < cxClient ; x += cxSource)
          {
               BitBlt (hdc, x, y, cxSource, cySource, hdcMem, 0, 0, SRCCOPY) ;
          }

          DeleteDC (hdcMem) ;
          EndPaint (hwnd, &ps) ;
          return 0 ;

     case WM_DESTROY:
          DeleteObject (hBitmap) ;
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

Share this post


Link to post
Share on other sites
Usually, it's better to create the resources you need at application startup (Or in WM_CREATE), and free them at shutdown (WM_DESTROY). That would be far better for performance. You shouldn't create and destroy a DC every time you call WM_PAINT. Putting the code at point A would be even worse, since then it'd be called for every window message, not just WM_PAINT.
Also, you have a resource leak there, you never save the return value of SelectObject(), and never put it back into the DC. This is what you should do:

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HBITMAP hBitmap, hBmpOld ;
static int cxClient, cyClient, cxSource, cySource;
static HDC hdcMem;
BITMAP bitmap ;
HDC hdc;
HINSTANCE hInstance ;
int x, y ;
PAINTSTRUCT ps ;
/* A

*/

switch (message)
{
case WM_CREATE:
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;

hBitmap = LoadBitmap (hInstance, TEXT ("Bricks")) ;
GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;
cxSource = bitmap.bmWidth ;
cySource = bitmap.bmHeight ;

hdc = GetDC(hwnd);
hdcMem = CreateCompatibleDC(hdc) ;
ReleaseDC(hwnd,hdc);
hBmpOld = SelectObject (hdcMem, hBitmap) ;

return 0 ;

case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;

case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;

for (y = 0 ; y < cyClient ; y += cySource)
for (x = 0 ; x < cxClient ; x += cxSource)
{
BitBlt (hdc, x, y, cxSource, cySource, hdcMem, 0, 0, SRCCOPY) ;
}

EndPaint (hwnd, &ps) ;
return 0 ;

case WM_DESTROY:
SelectObject(hdcMem,hBmpOld);
DeleteDC(hdcMem);
DeleteObject (hBitmap) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}


Or something like that. That code is untested.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this