IonicWind Software

Creative Basic => GUI Programs => Topic started by: aurelCB on August 06, 2009, 01:54:09 PM

Title: Menu item bitmaps
Post by: aurelCB on August 06, 2009, 01:54:09 PM
Hi..
Title: Re: Menu item bitmaps
Post by: ZeroDog on August 06, 2009, 06:57:54 PM
Thanks for the conversion  :)
Title: Re: Menu item bitmaps
Post by: REDEBOLT on August 06, 2009, 07:59:51 PM
Zlatko,

Where may I find the New1.bmp, Open3.bmp and Save2.bmp files?
Title: Re: Menu item bitmaps
Post by: ZeroDog on August 07, 2009, 01:04:39 AM
Something like this:
'Set menu bitmaps in CB 13x13 in 256 colors,by Aurel

def hID:int
def hbmp[4]:int
def hMenu:int
def hSubmenu:int
CONST MF_BITMAP = 0x4
DECLARE "user32",GetMenu(hwnd AS INT),INT
DECLARE "user32",GetSubMenu(hMenu AS INT,nPos AS INT),INT
DECLARE "user32",GetMenuItemID(hMenu AS INT,nPos AS INT),INT
DECLARE "user32",GetMenuItemCount(hMenu AS INT),INT
DECLARE "user32",SetMenuItemBitmaps(hMenu AS INT,nPosition AS INT,wFlags AS INT,hBitmapUnchecked AS INT,hBitmapChecked AS INT),INT

Def win:window
Window win,0,0,400,300,@minbox,0,"Bitmaps on Menu Items",main

'create menu
Menu win,"T,File,0,0","I, New,0,1","I, Open,0,2","I, Save,0,4","I, Exit,0,3"
InsertMenu win,1,"T,Options,0,0","I, Font,0,5"

AddPic2Menu()
AddPic2Menu2()

Waituntil win=0
'delete the memory used by the images
for x=0 to 3
if (hbmp[x]) then deleteimage hbmp[x],@IMGBITMAP
next x
End

Sub main
Select @class
case @idclosewindow : closewindow win
case @idcreate : centerwindow win
Endselect
Return

Sub AddPic2Menu

'First get the menuhandle of your app
hMenu = GetMenu(win.hwnd)
'Then get the handle of the first submenu
hSubmenu = GetSubMenu(hMenu,0)       

'Add bitmap to "New" item
hID = GetMenuItemID(hSubmenu,0) : 'Get the menu Id of the first entry
hbmp[0] = LOADIMAGE (GETSTARTPATH+"New1.bmp",@IMGBITMAP)
SetMenuItemBitmaps(hMenu,hID,MF_BITMAP,hbmp[0],hbmp[0])

'Add bitmap to "Open" item
hID = GetMenuItemID(hSubmenu,1)   
hbmp[1] = LOADIMAGE (GETSTARTPATH+"Open3.bmp",@IMGBITMAP)
SetMenuItemBitmaps(hMenu,hID,MF_BITMAP,hbmp[1],hbmp[1])

'Add bitmap to "Save" item
hID = GetMenuItemID(hSubmenu,2)   
hbmp[2] = LOADIMAGE (GETSTARTPATH+"Save2.bmp",@IMGBITMAP)
SetMenuItemBitmaps(hMenu,hID,MF_BITMAP,hbmp[2],hbmp[2])   


Return


Sub AddPic2Menu2
'Get the handle of the second submenu
hSubmenu = GetSubMenu(hMenu,1)       

'Add bitmap to "Font" item
hID = GetMenuItemID(hSubmenu,0) : 'Get the menu Id of the first entry
hbmp[3] = LOADIMAGE (GETSTARTPATH+"Font4.bmp",@IMGBITMAP)
SetMenuItemBitmaps(hMenu,hID,MF_BITMAP,hbmp[3],hbmp[3])

Return


Also, make sure that whenever you use LOADIMAGE, that you also use the DELETEIMAGE to free up the memory used by LOADIMAGE.
Title: Re: Menu item bitmaps
Post by: aurelCB on August 07, 2009, 02:07:43 AM
Thanks Zero ;)
Title: Re: Menu item bitmaps
Post by: ZeroDog on August 07, 2009, 11:39:21 AM
You're going to run into memory problems with this example.  You are using bbmp as the variable to hold the handle of the bitmap that  is loaded with LOADIMAGE.  but... then you're using the same variable with the rest of the LOADIMAGE calls you make.   So when you use the DELETEIMAGE on hbmp, you are only freeing up the memory used on the LAST call to LOADIMAGE, since hbmp can only hold the handle to one memory location at a time.  Each call to LOADIMAGE must have a matching DELETEIMAGE, which is why when I altered your code, I changed the hbmp to an array, then deleted each array element individually when the program is closed.
:) 
Title: Re: Menu item bitmaps
Post by: Ionic Wind Support Team on August 07, 2009, 01:59:30 PM
Aurel,
ZD is correct.  You MUST delete any images you load.  As specified in the users guide. What you are allocating is GDI resources when you use LOADIMAGE, or a COM object if you are loading a .jpg, and those resources must be returned to the system.

Paul.
Title: Re: Menu item bitmaps
Post by: aurelCB on August 07, 2009, 02:56:57 PM
Paul...
I did what Zero recomend me, see:
For x = 0 TO 6
DeleteImage hbmp[x],@IMGBITMAP
mem = mem + hbmp[x]
Next x


I hope that this loop really delete image memory .
By the way this small bitmaps uses only 8kB of mem - this is alllmost nothing.
OK you are right i know that is proper way deleteimage and i do this.

But still I'm not sure is it memory realy clean. ::)
Title: Re: Menu item bitmaps
Post by: Ionic Wind Support Team on August 07, 2009, 03:51:30 PM
Aurel...we don't make this stuff up LOL  ::).  LOADIMAGE, when used with a bitmap calls the API function LoadImageA.  And when you call DELETEIMAGE it calls the API function DestroyObject. 

If you don't want to take Creative BASIC's authors word for it, then perhaps Microsoft can convince you:

http://msdn.microsoft.com/en-us/library/ms648045(VS.85).aspx

Scroll down to the "Remarks" section.

Regards,
Paul Turley
Ionic Wind Software
Title: Re: Menu item bitmaps
Post by: aurelCB on August 07, 2009, 04:03:03 PM
Paul...
Everything is OK, i dont wanna bothering you or anyone here.
Yes you and Zero say right .
Just for info from msdn:
QuoteThe system automatically deletes these resources when the process that created them terminates; however, calling the appropriate function saves memory and decreases the size of the process's working set.
Title: Re: Menu item bitmaps
Post by: Ionic Wind Support Team on August 07, 2009, 05:10:20 PM
Aurel,
Yes I know the resources are forced to be freed on NT kernels when the process terminates.  But you shouldn't be depending on the OS to do it for you.  And that only applies if you are using bitmaps, icons or cursors.  If you are using scalable image type, and you forget to free it,  then the memory is lost until you reboot.

You have to get into good programming practices, the images might only be 8K, but what happens when you write a program that loads thousands of them without ever freeing them?  You have to consider every possible user of what you are writing.
Title: Re: Menu item bitmaps
Post by: ZeroDog on August 07, 2009, 05:19:00 PM
mem = mem + hbmp[x]

This isnt going to work.  when you use LOADIMAGE, it returns a pointer to a memory location which, in your example, is being stored in hbmp.  The variable itself does not hold the image, but only holds a pointer to the memory in which the image is stored.  The value of hbmp is going to be some seemingly random number, so adding those numbers together will only result in a new random number. It would be like adding together house numbers in an attempt to calculate how many people live in a certain area.   

hbmp does not contain the image, it contains an address to where the image is stored.  If you use the same variable for more than one image, you will loose the address of the previous images, making it impossible to free from memory later. 

hbmp=LOADIMAGE( ...   <-  hbmp now has the address of where the image is stored in memory.
hbmp=LOADIMAGE( ...   <-  hbmp now has a new address of where the new image is stored in memory

So what you're doing is over writing the old address with the new address.  Both images are still stored im memory, but you no longer have an address to use with DELETEIMAGE for the first image you loaded. 

I'm not sure offhand how you can calculate how much memory is being used by the images.  Perhaps somehow using LEN() on the hbmp.  Not really sure about that.  It might just tell you how much memory is benig used by the variable holding the pointer to the image, and not how much memory is being used by the image.