Jump to content
Sign in to follow this  

Icons in Menus

Recommended Posts


I'm working on a program that doesn't have a main window; it just pops up a menu.

My program populates this menu based on an .ini file, and that part works. My problem is I need an icon next to each item to show which program runs each file. There will only be 3-5 different icons for about 10-50 different files.

I can extract the icons from the .exe easily, but try as I may, I simply cannot get them to appear in the menu. I've tried so many ideas that I'm just confusing myself.

...Let me know what you need to see and I'll provide it.

Edited by borderLine

Share this post

Link to post
Share on other sites

You should be able to use code from this example from the forums

; Menu - add icons to menu items

#include <GUIConstantsEx.au3>
#include <GUIMenu.au3>
#include <Constants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Opt('MustDeclareVars', 1)

Global $hMenu, $hForm, $hFile = 1000, $idNew, $idExit

$hForm = GUICreate('Menu', 400, 300)

$hFile = _GUICtrlMenu_CreateMenu()
_GUICtrlMenu_InsertMenuItem($hFile, 0, ' &Favorites', $idNew)
_GUICtrlMenu_InsertMenuItem($hFile, 1, '', 0)
_GUICtrlMenu_InsertMenuItem($hFile, 2, ' E&xit', $idExit)
$hMenu = _GUICtrlMenu_CreateMenu()
_GUICtrlMenu_InsertMenuItem($hMenu, 0, '&File', 0, $hFile)
_GUICtrlMenu_SetMenu($hForm, $hMenu)
_GUICtrlMenu_SetItemBmp($hFile, 0, _CreateBitmapFromIcon(_WinAPI_GetSysColor($COLOR_MENU), @SystemDir & '\shell32.dll', 43, 16, 16))
_GUICtrlMenu_SetItemBmp($hFile, 2, _CreateBitmapFromIcon(_WinAPI_GetSysColor($COLOR_MENU), @SystemDir & '\shell32.dll', 27, 16, 16))



Func _CreateBitmapFromIcon($iBackground, $sIcon, $iIndex, $iWidth, $iHeight)
    Local $hDC, $hBackDC, $hBackSv, $hIcon, $hBitmap
    $hDC = _WinAPI_GetDC(0)
    $hBackDC = _WinAPI_CreateCompatibleDC($hDC)
    $hBitmap = _WinAPI_CreateSolidBitmap(0, $iBackground, $iWidth, $iHeight)
    $hBackSv = _WinAPI_SelectObject($hBackDC, $hBitmap)
    $hIcon = _WinAPI_PrivateExtractIcon($sIcon, $iIndex, $iWidth, $iHeight)
    If Not @error Then
        _WinAPI_DrawIconEx($hBackDC, 0, 0, $hIcon, 0, 0, 0, 0, $DI_NORMAL)
    _WinAPI_SelectObject($hBackDC, $hBackSv)
    _WinAPI_ReleaseDC(0, $hDC)
    Return $hBitmap
EndFunc ;==>_CreateBitmapFromIcon

Func _WinAPI_PrivateExtractIcon($sIcon, $iIndex, $iWidth, $iHeight)
    Local $hIcon, $tIcon = DllStructCreate('hwnd'), $tID = DllStructCreate('hwnd')
    Local $Ret = DllCall('user32.dll', 'int', 'PrivateExtractIcons', 'str', $sIcon, 'int', $iIndex, 'int', $iWidth, 'int', $iHeight, 'ptr', DllStructGetPtr($tIcon), 'ptr', DllStructGetPtr($tID), 'int', 1, 'int', 0)
    If (@error) Or ($Ret[0] = 0) Then
        Return SetError(1, 0, 0)
    $hIcon = DllStructGetData($tIcon, 1)
    If ($hIcon = Ptr(0)) Or (Not IsPtr($hIcon)) Then
        Return SetError(1, 0, 0)
    Return $hIcon
EndFunc ;==>_WinAPI_PrivateExtractIcon

Share this post

Link to post
Share on other sites


I incorporated this info that you gave me into my script, and it looks like this dude had to go through a lot of work making his own DLL calls even though AutoIT functions supposedly exist. But it looks like crap. I'm thinking that this is just something that can't be done with AutoIT, and I'm giving up on this project.

Edit: Looking back at this, I think I need to be more careful about how I word my messages. I didn't intend to imply that the code was crap, just that there may be a deficiency in what AutoIt is capable of.

But upon further reflection; since we're able to make DLL calls, AutoIt can basically do anything Windows can do. I just need to learn more to make use of the full power granted to me. Since I originally posted this, I've discovered that the include files contain functions that aren't shown in the help file. (It's the exhaustive help file that makes AutoIt the easiest of all Windows programming languages I've yet seen.) And I've finally learned how to access DLLs myself by looking at those include files. I'm still giving up on this project because it was intended for a quick-fix for a script I had written earlier for my nephews in PowerPro, but the replacement for that program is showing so much progress that I don't feel the need for a quick fix.


Edited by borderLine

Share this post

Link to post
Share on other sites

I know I'm a little late to this party, but I just wanted to point out that, for me at least, the _CreateBitmapFromIcon function gets the background colour for icons wrong. It actually has the red and blue channels swapped, so you'd need to do something like this:

$iBackground = BitAND(BitShift($iBackground, -16) + BitAND($iBackground, 0xFF00) + BitShift($iBackground, 16), 0xFFFFFF)

Before it gets used in the _WinAPI_CreateSolidBitmap function on line 34.

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