• Advertisement
Sign in to follow this  

questoin about frequently create

This topic is 4331 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement
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
Sign in to follow this  

  • Advertisement