Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Graphic menu items


  • Please log in to reply
8 replies to this topic
corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Here's a test script and function for setting an image for a menu item (requested by and credit for providing info goes to AGU :) ). If anyone knows of a way to use an icon instead of a bitmap and/or if anyone has any comments/suggestions please let me know...

*Updated* (already... :lol: )
- added option to use a different bitmap when an item is unchecked
- added additional comments and a bit more error checking
- menu item in test script toggles bitmap on/off

DetectHiddenWindows, On 
Gui, Add, Picture, w-1 h64, %A_ScriptDir%\sample.bmp
Gui, Add, Button, x0 y80 h30 w64 gBr1, Browse...

; Create a sample menu
Menu, file1, Add, Sample Item, MyMenuItem
Menu, file1, Add, ; Separator
Menu, file1, Add, E&xit, BBye
Menu, FileMenu, add, &File, :file1 
Gui, Menu, FileMenu
Menu, file1, ToggleCheck, Sample Item

; Create the window but do not make visible 
Gui, Show, +Hide, Menu Bitmaps 

; Wait for the window to be created 
WinWait, Menu Bitmaps 

; Get the handle to the window 
WinHandle := WinExist("Menu Bitmaps")

; Add image to menu item
SetMenuItemIcon(WinHandle, A_ScriptDir "\sample.bmp", "0", "0") 

; Show the window 
Gui, Show, w200, Menu Bitmaps 
Return 



SetMenuItemIcon(WindowHWND, ImgPath, ItemNumber=0, SubMenuNum=0, UnChkImg="")
{
  ; WindowHWND = Window handle
  ; ImgPath = Path to a bitmap to use for a checked item
  ; ItemNumber = Menu Item number in SubMenu (starting at 0 from the top down)
  ; SubMenuNum = SubMenu number (starting at 0)
  ; ChkImg = Optional Bitmap image to use when an item is not checked (default - none)
 
  ; Set Constants
  MF_BYPOSITION := 1024
  NULL= 
  LR_LOADFROMFILE := 16
  IMAGE_BITMAP := 0

  ; Check if the image file exists
  IfNotExist, %ImgPath%
    Return, Error - Image does not exist 

  ; Get the Handle to our window's main menu
  MenuHWND := DllCall("GetMenu", "Uint", WindowHWND, "Uint")
  If !MenuHWND
    Return, Error - Window does not have a menu

  ; Get the handle to the submenu using the menu handle
   SubMenuHWND := DllCall("GetSubMenu", "Uint", MenuHWND, "Int", SubMenuNum, "Uint")
  If !SubMenuHWND
    Return, Error - SubMenu not found
 
  ; Load the image from the file and retrieve the image handle 
  IcoHwnd := DllCall("LoadImage", "UInt", NULL, "Str", ImgPath, "UInt", IMAGE_BITMAP, "Int", "12", "Int", "12", "UInt", LR_LOADFROMFILE, "UInt") 

  If UnChkImg
  {
    ; Load the image from the file and retrieve the image handle 
    IcoHwndB := DllCall("LoadImage", "UInt", NULL, "Str", UnChkImg, "UInt", IMAGE_BITMAP, "Int", "12", "Int", "12", "UInt", LR_LOADFROMFILE, "UInt")
  }
  Else
  {
    IcoHWNDB := 
  } 

  ; Assign the image to the menu item (last 2 params - image while unchecked, while checked)
  DllCall("SetMenuItemBitmaps", "UInt", SubMenuHWND, "Int", ItemNumber, "UInt", MF_BYPOSITION, "UInt", IcoHwndB, "UInt", IcoHwnd)

  ; Return the handle to the image 
  retImg := IcoHwnd "|" IcoHwndB 
  Return, %retImg%
}

Br1:
sel1=
FileSelectFile, sel1, 3,, Select Bitmap, *.bmp
If sel1
{
  SetMenuItemIcon(WinHandle, sel1, "0", "0")
  GuiControl,, Static1, *w64 %sel1%
} 
Return

MyMenuItem: 
Menu, file1, ToggleCheck, Sample Item
return 

BBye:
GuiClose: 
ExitApp 
Return 


Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Adding icons next to menu items has been requested quite often, so thanks for sharing this solution. It will also help me add the feature when the time comes.

I know there are a lot of pending things I've promised but haven't delivered yet (cmdret, picture buttons, multi-column menus, etc.). The OnMesssage/WinLIRC thing was something of a tangent, but it seemed justified given how central it is to the hotkey mission of AutoHotkey.

Thanks for posting this solution.

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004

Adding icons next to menu items has been requested quite often, so thanks for sharing this solution. It will also help me add the feature when the time comes.

YW :) . This method doesn't quite have the effect I was hoping for since the bitmaps are really small but it is a bit more exciting than a plain checkmark and shows a bit of an image...

I know there are a lot of pending things I've promised but haven't delivered yet (cmdret, picture buttons, multi-column menus, etc.). The OnMesssage/WinLIRC thing was something of a tangent, but it seemed justified given how central it is to the hotkey mission of AutoHotkey.

Thanks for posting this solution.

As much as I would like to see a few of these features added to AHK, I think part of the fun of using AHK for me comes from trying to create various add-ons to extend functionality ;) :D . Also, I'm not in a hurry. I'm sure you didn't start working on AHK with the goal of rushing through it. Enjoy ;) .

AGU
  • Guests
  • Last active:
  • Joined: --
Yeah, Chris there is no need to hurry.

Graphic Buttons for example can be wonderfully accomplished by corrupts script. And the "requested" icons in menus was some kind of experiment to me.

I played around at one of corrupts mentioned API sites and discovered this SetMenuItemBitmap thing. So I proposed it to the "evil masterplan" ;) cause I was curious about how this can be accomplished with AHK and DLL Call. I have to mention here that DllCall and all this API thing is all greek to me.

Concerning Icons in menus I did a little search in Google Groups. Maybe you'll find s.th helpful:
http://groups.google...n in Menu&hl=de
e.g. this thread
http://groups.google... ... 350e3d0678

I've read s.th about "UserDrawn Menus", "transparent bitmaps", "monochrome bitmaps", "VisualBasic", ... Man I'm confused and understand only half of it.

Decarlo110
  • Members
  • 303 posts
  • Last active: Feb 12 2006 02:15 AM
  • Joined: 15 Dec 2004

I know there are a lot of pending things I've promised but haven't delivered yet (cmdret, picture buttons, multi-column menus, etc.). The OnMesssage/WinLIRC thing was something of a tangent, but it seemed justified given how central it is to the hotkey mission of AutoHotkey.

Tangential only in timing relative to other to-do items. OnMessage is absolutely essential for advanced inter-script capabilities. Plus also, i can now update my version of Window Spy to become like Winspector Spy, so thanks for it.

Thanks, corrupt, for presenting this graphical menu-item script. I'll probably make use of it when coding optional integration of my proposed (future) hotkey interface with the Ahk system tray menu.
1) The Open Source Definition http://www.opensourc...ition_plain.php

2) Intuitive. Logical. Versatile. Adaptable. <>

twhyman
  • Members
  • 348 posts
  • Last active: Sep 17 2014 01:55 AM
  • Joined: 07 Dec 2005
thanks for the script, but i dont seem to manage to create to create more
menu items with icon... :?

i know it somthing to do with this line in order to attach the icon:
SetMenuItemIcon(WinHandle, A_ScriptDir "\sample.bmp", "0", "0")

and i tried to to changed the zeros to 1 and nothing happens...

please help
Thanks
Twhyman

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004

and i tried to to changed the zeros to 1 and nothing happens...


The zeros indicate that the image should be displayed on the first menu item in the first submenu. The values for these numbers will depend on your menu. If this doesn't help, could you please give a bit more information on your menu, image and/or provide a sample script? Thanks :) .

SetMenuItemIcon(WindowHWND, ImgPath, ItemNumber=0, SubMenuNum=0, UnChkImg="")
{
; WindowHWND = Window handle
; ImgPath = Path to a bitmap to use for a checked item
; ItemNumber = Menu Item number in SubMenu (starting at 0 from the top down)
; SubMenuNum = SubMenu number (starting at 0)
; ChkImg = Optional Bitmap image to use when an item is not checked (default - none)



twhyman
  • Members
  • 348 posts
  • Last active: Sep 17 2014 01:55 AM
  • Joined: 07 Dec 2005
here is your script with an added menu item and an image named sample1.bmp:
DetectHiddenWindows, On 
Gui, Add, Picture, w-1 h64, %A_ScriptDir%\sample.bmp 
Gui, Add, Button, x0 y80 h30 w64 gBr1, Browse... 

; Create a sample menu 
Menu, file1, Add, Sample Item, MyMenuItem
Menu, file1, Add, test Item , testItem ; i added another menu
Menu, file1, Add, ; Separator 
Menu, file1, Add, E&xit, BBye 
Menu, FileMenu, add, &File, :file1 
Gui, Menu, FileMenu 
Menu, file1, ToggleCheck, Sample Item 

; Create the window but do not make visible 
Gui, Show, +Hide, Menu Bitmaps 

; Wait for the window to be created 
WinWait, Menu Bitmaps 

; Get the handle to the window 
WinHandle := WinExist("Menu Bitmaps") 

; Add image to menu item 
SetMenuItemIcon(WinHandle, A_ScriptDir "\sample.bmp", "0", "0")
; i the line below too
SetMenuItemIcon(WinHandle, A_ScriptDir "\sample1.bmp", "1", "0")
; Show the window 
Gui, Show, w200, Menu Bitmaps 
Return 



SetMenuItemIcon(WindowHWND, ImgPath, ItemNumber=0, SubMenuNum=0, UnChkImg="") 
{ 
  ; WindowHWND = Window handle 
  ; ImgPath = Path to a bitmap to use for a checked item 
  ; ItemNumber = Menu Item number in SubMenu (starting at 0 from the top down) 
  ; SubMenuNum = SubMenu number (starting at 0) 
  ; ChkImg = Optional Bitmap image to use when an item is not checked (default - none) 
  
  ; Set Constants 
  MF_BYPOSITION := 1024 
  NULL= 
  LR_LOADFROMFILE := 16 
  IMAGE_BITMAP := 0 

  ; Check if the image file exists 
  IfNotExist, %ImgPath% 
    Return, Error - Image does not exist 

  ; Get the Handle to our window's main menu 
  MenuHWND := DllCall("GetMenu", "Uint", WindowHWND, "Uint") 
  If !MenuHWND 
    Return, Error - Window does not have a menu 

  ; Get the handle to the submenu using the menu handle 
   SubMenuHWND := DllCall("GetSubMenu", "Uint", MenuHWND, "Int", SubMenuNum, "Uint") 
  If !SubMenuHWND 
    Return, Error - SubMenu not found 
  
  ; Load the image from the file and retrieve the image handle 
  IcoHwnd := DllCall("LoadImage", "UInt", NULL, "Str", ImgPath, "UInt", IMAGE_BITMAP, "Int", "12", "Int", "12", "UInt", LR_LOADFROMFILE, "UInt") 

  If UnChkImg 
  { 
    ; Load the image from the file and retrieve the image handle 
    IcoHwndB := DllCall("LoadImage", "UInt", NULL, "Str", UnChkImg, "UInt", IMAGE_BITMAP, "Int", "12", "Int", "12", "UInt", LR_LOADFROMFILE, "UInt") 
  } 
  Else 
  { 
    IcoHWNDB := 
  } 

  ; Assign the image to the menu item (last 2 params - image while unchecked, while checked) 
  DllCall("SetMenuItemBitmaps", "UInt", SubMenuHWND, "Int", ItemNumber, "UInt", MF_BYPOSITION, "UInt", IcoHwndB, "UInt", IcoHwnd) 

  ; Return the handle to the image 
  retImg := IcoHwnd "|" IcoHwndB 
  Return, %retImg% 
} 

Br1: 
sel1= 
FileSelectFile, sel1, 3,, Select Bitmap, *.bmp 
If sel1 
{ 
  SetMenuItemIcon(WinHandle, sel1, "0", "0") 
  GuiControl,, Static1, *w64 %sel1% 
} 
Return 

MyMenuItem: 
Menu, file1, ToggleCheck, Sample Item 
return 

testItem: 
;Menu, file1, ToggleCheck, Sample Item 
return 

BBye: 
GuiClose: 
ExitApp 
Return 

i tried changing the other 0 to 1 and nothing happend

thanks for the help
Twhyman

lingoist
  • Members
  • 122 posts
  • Last active: Jan 28 2014 03:50 PM
  • Joined: 05 Oct 2004
Is is possible to add an icon to a tab after it is created?

Thanks,
Lingoist