Windows API Tutorial - Part Two, Page 3
Brilliant we now have our menu and the image we want to put 'on it'.
Now let's add some code to get it all working:
- Add the following code behind your Command Button:
Private Sub Command1_Click()On Error Resume NextDim lngMenu As LongDim lngSubMenu As LongDim lngMenuItemID As LongDim lngRet As LonglngMenu = GetMenu(Form1.hwnd)lngSubMenu = GetSubMenu(lngMenu, 0)lngMenuItemID = GetMenuItemID(lngSubMenu, 2)lngRet = SetMenuItemBitmaps(lngMenu, lngMenuItemID, 0, _Picture1.Picture, Picture1.Picture)End Sub
Do you understand what's happening here?
lngMenu = GetMenu(Form1.hwnd)
This grabs the menu collection 'handle' for the entire form.
lngSubMenu = GetSubMenu(lngMenu, 0)
This function visits the 'menu collection' specified in the handle lngMenu and gets the handle of the first (0) menu. In this case, File.
Top Tip: Unfortunately most API calls expect you to count in this peculiar way starting with 0 as the first item, 1 for the second and so on. Just stick with it. This zero-based counting is something that can apply to other areas of Visual Basic too, such as Arrays.
lngMenuItemID = GetMenuItemID(lngSubMenu, 2)
This function checks out the menu referenced in lngSubMenu (such as File) and returns a handle to the third item on it (that's number 2 getting used to this yet?).
Note: In our case, that third item is 'Exit'. That's right, the 'separator' you added counts as one item.
lngRet = SetMenuItemBitmaps(lngMenu, lngMenuItemID, 0, _Picture1.Picture, Picture1.Picture)
This final call just runs the SetMenuItemBitmaps function and passes the return value back to lngRet typically, a 1 indicates success.
We're passing this call a handle to the menus (lngMenu) and a handle to the individual menu item (lngMenuItemID). The third argument requests any 'flags' in other words, special extra bits of information a little like the MB_OK or MB_ICONEXCLAMATION from last week's message box. However I'm not really bothered about this right now, so just threw in a 0.
The final two arguments asked for the handle to two images hBitmapUnchecked and hBitmapChecked respectively. Here, we simply pass the Picture property of Picture1.
"Hold on to your leather panties here for one little minute!", I hear you cry. "That function asks for a handle after all, the name begins with 'h' and the data type is Long. So why are you passing the Picture property of the PictureBox control?"
Well, not many people know this but the Picture property of the PictureBox control simply returns a handle to the holding picture. Try doing a simple 'MsgBox Picture1.Picture' it should return a number, the picture handle.
So you see, it's fine to pass this property direct to the API.
Interesting stuff, eh? What was that? No? Oh, I s'pose you're right actually. Anyway, enough theory. Let's test our project!
- Press F5 to run your application
- Hit the Command Button
Check out the File menu. Do you see what has happened? Following your calls to the API, the image in your Picture Box control has been added to your menu!
And that's something you simply can't do in Visual Basic - without the API.
Note: If you're interested in adding the full Office look to your applications, you can get the entire lowdown at VB Thunder.