I updated
Shimanov's code to support icons. I don't know if anybody did this already, but I didn't find anything while snooping around. The same rules apply: 12x12 icons, first pixel color transparent. Some parameters are droped, since I use this function to set images, not checkboxes.
Code:
/* p_menu = "MenuName" (e.g., Tray, etc.)
p_item = 1, ...
p_bm_unchecked,
*/
Menu_AssignIcon( p_menu, p_item, p_bm_unchecked)
{
static h_menuDummy
if h_menuDummy=
{
Menu, menuDummy, Add
Menu, menuDummy, DeleteAll
Gui, 99:Menu, menuDummy
Gui, 99:Show, Hide, guiDummy
old_DetectHiddenWindows := A_DetectHiddenWindows
DetectHiddenWindows, on
Process, Exist
h_menuDummy := DllCall( "GetMenu", "uint", WinExist( "guiDummy ahk_class AutoHotkeyGUI ahk_pid " ErrorLevel ) )
if ReportError( ErrorLevel or h_menuDummy = 0, "Menu_AssignBitmap: GetMenu", "h_menuDummy = " h_menuDummy )
return, false
DetectHiddenWindows, %old_DetectHiddenWindows%
Gui, 99:Menu
Gui, 99:Destroy
}
Menu, menuDummy, Add, :%p_menu%
h_menu := DllCall( "GetSubMenu", "uint", h_menuDummy, "int", 0 )
if ReportError( ErrorLevel or h_menu = 0, "Menu_AssignBitmap: GetSubMenu", "h_menu = " h_menu )
return, false
success := DllCall( "RemoveMenu", "uint", h_menuDummy, "uint", 0, "uint", 0x400 )
if ReportError( ErrorLevel or ! success, "Menu_AssignBitmap: RemoveMenu", "success = " success )
return, false
Menu, menuDummy, Delete, :%p_menu%
if ( p_bm_unchecked )
{
hbm_unchecked := DllCall( "LoadImage"
, "uint", 0
, "str", p_bm_unchecked
, "uint", 2 ; IMAGE_ICON
, "int", 0
, "int", 0
, "uint", 0x10 | 0x20 ) ; LR_LOADFROMFILE|LR_LOADTRANSPARENT
if ReportError( ErrorLevel or ! hbm_unchecked, "Menu_AssignBitmap: LoadImage: unchecked", "hbm_unchecked = " hbm_unchecked )
return, false
VarSetCapacity(sICONINFO, 20, 0) ;4 + 2*4+ 2*4 = 20
InsertInteger(1, sICONINFO, 0)
res := DllCall( "GetIconInfo", "Uint", hbm_unchecked, "str", sICONINFO)
if ReportError( ErrorLevel or ! res, "Menu_AssignBitmap: GetIconInfo: ", "res = " res )
return, false
hbm_unchecked := ExtractInteger(sICONINFO, 16, true)
}
success := DllCall( "SetMenuItemBitmaps"
, "uint", h_menu
, "uint", p_item-1
, "uint", 0x400 ; MF_BYPOSITION
, "uint", hbm_unchecked
, "uint", 0 )
if ReportError( ErrorLevel or ! success, "Menu_AssignBitmap: SetMenuItemBitmaps", "success = " success )
return, false
return, true
}
ReportError( p_condition, p_title, p_extra )
{
if p_condition
MsgBox,
( LTrim
[Error] %p_title%
EL = %ErrorLevel%, LE = %A_LastError%
%p_extra%
)
return, p_condition
}
If anybody knows a way for a larger icons (16x16, 32x32) or at least has ideas, please let me know.