Windows programming

Moderators: None (Apply to moderate this forum)
Number of threads: 3711
Number of posts: 9173

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Windows Resource Cleanup... Posted by Sephiroth on 13 Feb 2004 at 12:42 AM
OK, my OGG-player is skinning properly (except for the main one, but I know why). Now, when I start the app, it preloads all the button bitmap images into an array of HBITMAPs. When I exit, whether due to an error or regular, I have a function to clean up the memory used by those images. I want to verify that I'm doing this properly. I check to make sure each HBITMAP isn't NULL in case I load half of the images, then one doesn't, so it calls the clean function to free JUST those that got allocated.
void FreeSkin()
  {
  for(char Loop = 0; Loop < 20; Loop++)
    if(BtnImages[Loop] != NULL)
      DeleteObject(BtnImages[Loop]);
  }

Would those images being selected into the button DCs be a problem? I Set them as the buttons in the function below. I only mess with them in this function, nowhere else.
void DrawButtons(WPARAM ID, LPARAM ItemStruct)
  {
  HDC MemoryDC;
  HBITMAP OldImage;
  LPDRAWITEMSTRUCT Item;

  Item = (LPDRAWITEMSTRUCT)ItemStruct;
  if(Item->CtlType != ODT_BUTTON)
    return;

  MemoryDC = CreateCompatibleDC(Item->hDC);
  switch(ID)
    {
    case IDW_OPEN:
      if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[0]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      else
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[1]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      break;

    case IDW_PLAY:
      if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[2]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      else
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[3]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      break;
    
    case IDW_PAUSE:
      if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[4]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      else
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[5]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      break;

    case IDW_LAST:
      if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[6]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      else
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[7]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      break;

    case IDW_RW:
      if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[8]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      else
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[9]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      break;

    case IDW_STOP:
      if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[10]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      else
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[11]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      break;

    case IDW_FF:
      if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[12]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      else
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[13]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      break;

    case IDW_NEXT:
      if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[14]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      else
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[15]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      break;

    case IDW_CONFIG:
      if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[16]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      else
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[17]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      break;

    case IDW_EXIT:
      if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[18]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      else
        {
        OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[19]);
        StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
        }
      break;
    }

  SelectObject(MemoryDC, OldImage);
  DeleteObject(OldImage);
  DeleteDC(MemoryDC);
  }

So is my cleanup function good to go for a release?
-Sephiroth
Report
Re: Windows Resource Cleanup... Posted by AsmGuru62 on 13 Feb 2004 at 7:06 AM
: OK, my OGG-player is skinning properly (except for the main one, but I know why). Now, when I start the app, it preloads all the button bitmap images into an array of HBITMAPs. When I exit, whether due to an error or regular, I have a function to clean up the memory used by those images. I want to verify that I'm doing this properly. I check to make sure each HBITMAP isn't NULL in case I load half of the images, then one doesn't, so it calls the clean function to free JUST those that got allocated.
:
: void FreeSkin()
:   {
:   for(char Loop = 0; Loop < 20; Loop++)
:     if(BtnImages[Loop] != NULL)
:       DeleteObject(BtnImages[Loop]);
:   }
: 

: Would those images being selected into the button DCs be a problem? I Set them as the buttons in the function below. I only mess with them in this function, nowhere else.
:
: void DrawButtons(WPARAM ID, LPARAM ItemStruct)
:   {
:   HDC MemoryDC;
:   HBITMAP OldImage;
:   LPDRAWITEMSTRUCT Item;
: 
:   Item = (LPDRAWITEMSTRUCT)ItemStruct;
:   if(Item->CtlType != ODT_BUTTON)
:     return;
: 
:   MemoryDC = CreateCompatibleDC(Item->hDC);
:   switch(ID)
:     {
:     case IDW_OPEN:
:       if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[0]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       else
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[1]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       break;
: 
:     case IDW_PLAY:
:       if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[2]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       else
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[3]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       break;
:     
:     case IDW_PAUSE:
:       if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[4]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       else
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[5]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       break;
: 
:     case IDW_LAST:
:       if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[6]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       else
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[7]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       break;
: 
:     case IDW_RW:
:       if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[8]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       else
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[9]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       break;
: 
:     case IDW_STOP:
:       if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[10]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       else
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[11]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       break;
: 
:     case IDW_FF:
:       if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[12]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       else
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[13]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       break;
: 
:     case IDW_NEXT:
:       if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[14]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       else
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[15]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       break;
: 
:     case IDW_CONFIG:
:       if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[16]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       else
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[17]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       break;
: 
:     case IDW_EXIT:
:       if(SendMessage(Item->hwndItem, BM_GETSTATE, 0, 0) & BST_PUSHED)
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[18]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       else
:         {
:         OldImage = (HBITMAP)SelectObject(MemoryDC, BtnImages[19]);
:         StretchBlt(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, MemoryDC, 0, 0, 32, 32, SRCCOPY);
:         }
:       break;
:     }
: 
:   SelectObject(MemoryDC, OldImage);
:   DeleteObject(OldImage);
:   DeleteDC(MemoryDC);
:   }
: 

: So is my cleanup function good to go for a release?
: -Sephiroth
:
I once made an interesting research: MSDN clearly states that HBITMAP being deleted by DeleteObject() MUST be deselected out of HDC. But when perform the DeleteObject() call on a still selected HBITMAP I got TRUE back from it, meaning that it was a sucess. I did not run this research on every Windows out there, but I think that any programmer should follow MSDN if he/she codes for Windows. So, my advice - before using DeleteObject() - deselect the images from HDC.
Report
Re: Windows Resource Cleanup... Posted by Sephiroth on 13 Feb 2004 at 12:11 PM
: I once made an interesting research: MSDN clearly states that HBITMAP being deleted by DeleteObject() MUST be deselected out of HDC. But when perform the DeleteObject() call on a still selected HBITMAP I got TRUE back from it, meaning that it was a sucess. I did not run this research on every Windows out there, but I think that any programmer should follow MSDN if he/she codes for Windows. So, my advice - before using DeleteObject() - deselect the images from HDC.
:

So even though I didn't use 'SelectObject' to directly place the image into the button DC, selecting it into a memory DC and then stretching it onto the button DC still counts? If that's the case, how do I tell if the image is currently selected into a specific DC? I mean I could just code it to remove the image from the right DC, but what if the 'LoadSkin()' function returned false and it is exiting before it selected the image into the DC?

-Sephiroth

Report
Re: Windows Resource Cleanup... Posted by AsmGuru62 on 14 Feb 2004 at 12:43 PM
This message was edited by AsmGuru62 at 2004-2-14 12:43:39

: : I once made an interesting research: MSDN clearly states that HBITMAP being deleted by DeleteObject() MUST be deselected out of HDC. But when perform the DeleteObject() call on a still selected HBITMAP I got TRUE back from it, meaning that it was a sucess. I did not run this research on every Windows out there, but I think that any programmer should follow MSDN if he/she codes for Windows. So, my advice - before using DeleteObject() - deselect the images from HDC.
: :
:
: So even though I didn't use 'SelectObject' to directly place the image into the button DC, selecting it into a memory DC and then stretching it onto the button DC still counts? If that's the case, how do I tell if the image is currently selected into a specific DC? I mean I could just code it to remove the image from the right DC, but what if the 'LoadSkin()' function returned false and it is exiting before it selected the image into the DC?
:
: -Sephiroth
:
:
If you are painting your buttons - your sequence of events goes like this:
void DrawButton ()
{
  mem DC = create compatible DC;
  select HBITMAP into mem DC
      (this ^^^ pushes out the default HBITMAP for the mem DC)
  stretch on a button DC (...or whatever you need...)
  select the default HBITMAP back into mem DC
      (this ^^^ pushes out YOUR HBITMAP - currently selected)
  delete mem DC
}

To make program run faster - you can keep the compatible DCs for each button with already selected HBITMAPs for these buttons, so your drawing function will look like this:
void DrawButton ()
{
  stretch from a mem DC (you keep it) on a button DC
}




Report
Re: Windows Resource Cleanup... Posted by pingpong on 14 Feb 2004 at 4:13 PM
: So is my cleanup function good to go for a release?

Ship it.



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.