Jump to content

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

Menu Icons v2


  • Please log in to reply
138 replies to this topic
Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
ItemClick executes when an item is selected from the example menu. Afaik, every item must have a label, but since the example is only showing off the icons, the label doesn't need to do anything.

Superfraggle
  • Members
  • 1019 posts
  • Last active: Sep 25 2011 01:06 AM
  • Joined: 02 Nov 2004
Hi Lexicos, Great script as always.

I am having some issues with it, probably missed a comment somewhere, but take this example.

; Uncomment this if MI.ahk is not in your function library:
;#include %A_ScriptDir%\MI.ahk

#NoEnv

; Sample menu items.
Menu, M, Add, 16x16 Icon, ItemClick
MI_SetMenuItemIcon("M", 1, "shell32.dll", 4, 16)
Menu,Tray,Add,M,:M
hTM := MI_GetMenuHandle("Tray")
if (A_OSVersion != "WIN_VISTA")
{   ; It is necessary to hook the tray icon for owner-drawing to work.
    ; (Owner-drawing is not used on Windows Vista.)
    OnMessage(0x404, "AHK_NOTIFYICON")
    OnMessage(0x111, "WM_COMMAND") ; To track "pause" status.
    MI_SetMenuStyle(hTM, 0x4000000) ; MNS_CHECKORBMP (optional)
}

SplitPath, A_AhkPath,, SpyPath
SpyPath = %SpyPath%\AU3_Spy.exe

MI_SetMenuItemIcon(hTM, 1, A_AhkPath, 1, 16) ; open
MI_SetMenuItemIcon(hTM, 2, A_WinDir "\hh.exe", 1, 16) ; help
;-
MI_SetMenuItemIcon(hTM, 4, SpyPath,   1, 16) ; spy
; reload - icon needed!
MI_SetMenuItemIcon(hTM, 6, A_AhkPath, 2, 16) ; edit
;-
MI_SetMenuItemIcon(hTM, 8, A_AhkPath, 3, 16) ; suspend
MI_SetMenuItemIcon(hTM, 9, A_AhkPath, 4, 16) ; pause
MI_SetMenuItemBitmap(hTM, 10, 8) ; exit


MI_ShowMenu("M")
return

ItemClick:
Menu, M, Deleteall
Menu, M, Add, 16x16 Icon, ItemClick
MI_SetMenuItemIcon("M", 1, "shell32.dll", 4, 16)
return


AHK_NOTIFYICON(wParam, lParam)
{
    global hTM, M_IsPaused
    if (lParam = 0x205) ; WM_RBUTTONUP
    {
        ; Update "Suspend Script" and "Pause Script" checkmarks.
        DllCall("CheckMenuItem","uint",hTM,"uint",65305,"uint",A_IsSuspended ? 8:0)
        DllCall("CheckMenuItem","uint",hTM,"uint",65306,"uint",M_IsPaused ? 8:0)
        ; Show menu to allow owner-drawing.
        MI_ShowMenu(hTM)
        Tooltip,Bleah
        return 0
    }
}

WM_COMMAND(wParam, lParam, Msg, hwnd)
{
    Critical
    global M_IsPaused
    id := wParam & 0xFFFF
    if id in 65306,65403  ; tray pause, file menu pause
    {
        ; When the script is not paused, WM_COMMAND() is called once for
        ; AutoHotkey --** and once for OwnerDrawnMenuMsgWin **--.
        DetectHiddenWindows, On
        WinGetClass, cl, ahk_id %hwnd%
        if cl != AutoHotkey
            return
       
        ; This will become incorrect if "pause" is used from the script.
        M_IsPaused := ! M_IsPaused
    }
}

After you click the custom menu for the first time and the deleteall is performed the tray menu will no longer open.

This is XP of course otherwise I wouldnt need the mi_showmenu.
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
It appears AutoHotkey recreates the tray menu when you delete M, so hTM is no longer valid. You also need to reset the tray menu icons. Try this:
; Uncomment this if MI.ahk is not in your function library:
;#include %A_ScriptDir%\MI.ahk

#NoEnv

; Sample menu items.
Menu, M, Add, 16x16 Icon, ItemClick
MI_SetMenuItemIcon("M", 1, "shell32.dll", 4, 16)
Menu,Tray,Add,M,:M
gosub SetTrayMenuIcons
if A_OSVersion != WIN_VISTA
{   ; It is necessary to hook the tray icon for owner-drawing to work.
    ; (Owner-drawing is not used on Windows Vista.)
    OnMessage(0x404, "AHK_NOTIFYICON")
    OnMessage(0x111, "WM_COMMAND") ; To track "pause" status.
}

SplitPath, A_AhkPath,, SpyPath
SpyPath = %SpyPath%\AU3_Spy.exe

MI_ShowMenu("M")
return

ItemClick:
Menu, M, Deleteall
Menu, M, Add, 16x16 Icon, ItemClick
MI_SetMenuItemIcon("M", 1, "shell32.dll", 4, 16)

; ALSO SET TRAY MENU ICONS:

SetTrayMenuIcons:
hTM := MI_GetMenuHandle("Tray")
if A_OSVersion != WIN_VISTA
    MI_SetMenuStyle(hTM, 0x4000000) ; MNS_CHECKORBMP (optional)
MI_SetMenuItemIcon(hTM, 1, A_AhkPath, 1, 16) ; open
MI_SetMenuItemIcon(hTM, 2, A_WinDir "\hh.exe", 1, 16) ; help
;-
MI_SetMenuItemIcon(hTM, 4, SpyPath,   1, 16) ; spy
; reload - icon needed!
MI_SetMenuItemIcon(hTM, 6, A_AhkPath, 2, 16) ; edit
;-
MI_SetMenuItemIcon(hTM, 8, A_AhkPath, 3, 16) ; suspend
MI_SetMenuItemIcon(hTM, 9, A_AhkPath, 4, 16) ; pause
MI_SetMenuItemBitmap(hTM, 10, 8) ; exit
return


AHK_NOTIFYICON(wParam, lParam)
{
    global hTM, M_IsPaused
    if (lParam = 0x205) ; WM_RBUTTONUP
    {
        ; Update "Suspend Script" and "Pause Script" checkmarks.
        DllCall("CheckMenuItem","uint",hTM,"uint",65305,"uint",A_IsSuspended ? 8:0)
        DllCall("CheckMenuItem","uint",hTM,"uint",65306,"uint",M_IsPaused ? 8:0)
        ; Show menu to allow owner-drawing.
        MI_ShowMenu(hTM)
        Tooltip,Bleah
        return 0
    }
}

WM_COMMAND(wParam, lParam, Msg, hwnd)
{
    Critical
    global M_IsPaused
    id := wParam & 0xFFFF
    if id in 65306,65403  ; tray pause, file menu pause
    {
        ; When the script is not paused, WM_COMMAND() is called once for
        ; AutoHotkey --** and once for OwnerDrawnMenuMsgWin **--.
        DetectHiddenWindows, On
        WinGetClass, cl, ahk_id %hwnd%
        if cl != AutoHotkey
            return
       
        ; This will become incorrect if "pause" is used from the script.
        M_IsPaused := ! M_IsPaused
    }
}


  • Guests
  • Last active:
  • Joined: --
hi do you know how i can use your menuicons with this kind of menu?



#include %A_ScriptDir%\MI.ahk 

#NoEnv
#SingleInstance force
SendMode Input
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

myMenu1 =
(
D
@EXPLORER.EXE /n, /e, d:\
Notepad
@Notepad
)


; myMenu

~LButton & WheelUp::
CreateMenu("myMenu", myMenu1, "myMenu2")
Menu myMenu, Show
Return
 

myMenu2:
   RunMenuItem(myMenu1, A_ThisMenuItemPos)
Return


; MI_SetMenuItemIcon("myMenu1", 1, "shell32.dll", 4, 16) 
; MI_SetMenuStyle("myMenu1", 0x4000000) 

CreateMenu(_menuName, _menuDef, _menuLabel)
{
   Loop Parse, _menuDef, `n
   {
      If (Mod(A_Index, 2) = 1) ; Odd
      {
         Menu %_menuName%, Add, %A_LoopField%, %_menuLabel%
      }
   }
}

RunMenuItem(_menuDef, _index)
{
   local cmd, toRun, tmp

   Loop Parse, _menuDef, `n
   {
      If (_index * 2 = A_Index)
         {
         StringLeft cmd, A_LoopField, 1
         StringTrimLeft toRun, A_LoopField, 1
         If (cmd = "@")
         {
            Run %toRun%
         }
         Else
         {
            MsgBox 16, RunMenuItem, Invalid command: '%cmd%'! (%A_LoopField%)
         }
         Break
      }
   }
}


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Follow the examples previously posted. It is no different from any other menu...

; MI_SetMenuItemIcon("myMenu1", 1, "shell32.dll", 4, 16)
; MI_SetMenuStyle("myMenu1", 0x4000000)

It appears you've used the wrong name. The menu name you should be using is the name you used with the Menu command:

Menu myMenu, Show

You will need to use MI_ShowMenu if you are not on Windows Vista.

Guest again
  • Guests
  • Last active:
  • Joined: --
thanks

but i cant get it to work. im on xp sp3

I get no errors with this code, but no icons either. Also the menu gets stuck if i try to click it away (outside of the menu). I tried to experiment within the CreateMenu() loop with no luck.

The example above gives me icons but with 20-30 menu/submenu items it gets alot lines of code that way ...


Maybe im lost in translation, is this the way you meant?


#include %A_ScriptDir%\MI.ahk 

#NoEnv
#SingleInstance force
SendMode Input
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

myMenu1 =
(
D
@EXPLORER.EXE /n, /e, d:\
Notepad
@Notepad
)
Return

MI_SetMenuItemIcon([color=red]"myMenu"[/color], 1, "shell32.dll", 4, 16) 
MI_SetMenuStyle([color=red]"myMenu"[/color], 0x4000000) 

; myMenu

~LButton & WheelUp::
CreateMenu("myMenu", myMenu1, "myMenu2")
[color=red]MI_ShowMenu("myMenu")[/color]
Return
 

myMenu2:
   RunMenuItem(myMenu1, A_ThisMenuItemPos)
Return




CreateMenu(_menuName, _menuDef, _menuLabel)
{
   Loop Parse, _menuDef, `n
   {
      If (Mod(A_Index, 2) = 1) ; Odd
      {
         Menu %_menuName%, Add, %A_LoopField%, %_menuLabel%
      }
   }
}

RunMenuItem(_menuDef, _index)
{
   local cmd, toRun, tmp

   Loop Parse, _menuDef, `n
   {
      If (_index * 2 = A_Index)
         {
         StringLeft cmd, A_LoopField, 1
         StringTrimLeft toRun, A_LoopField, 1
         StringReplace toRun, toRun, ***, %Clipboard%, All
         If (cmd = "@")
         {
            Run %toRun%
         }
         Else
         {
            MsgBox 16, RunMenuItem, Invalid command: '%cmd%'! (%A_LoopField%)
         }
         Break
      }
   }
}


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
...



myMenu1 =

(

D

@EXPLORER.EXE /n, /e, d:\

Notepad

@Notepad

)

[color=red]Return[/color] ; "Stop here; don't go any further."



[color=#606060]MI_SetMenuItemIcon("myMenu", 1, "shell32.dll", 4, 16)

MI_SetMenuStyle("myMenu", 0x4000000) [/color]



...
Move Return. You must also create the menu before setting icons...

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008
Sorry for waking a dead thread, but just wanted to add my $0.02 and see if this helps. I added memoization (of menu handles) to your code and was wondering if you might incorporate it into the main program - so that others can use it too.

My question is: will memoizing the values cause problems? I presume not since you suggested a similar technique, but just wanted to make sure.

Here is the "updated" MI_GetMenuHandle method. This way, you don't have to pass the handle, but can just pass the menu name (e.g. "Tray"), and it will (on first access), save the value, and on subsequent calls reuse that value. And, thanks to your excellent encapsulation, this applies to ALL the methods.

Of course you can choose to add this or discard it. If you discard it because there's some problem with it please do tell - I don't want to build code using this method if it's faulty.

Here's the code, pay attention to the lines in red.

MI_GetMenuHandle(menu_name)
{
    static   h_menuDummy

    ;use memoized value (if it exists)
   [color=red] if MI_getMenuHandleCache(menu_name)
        return MI_getMenuHandleCache(menu_name)[/color]
    
    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 ErrorLevel or h_menuDummy=0
            return 0

        DetectHiddenWindows, %old_DetectHiddenWindows%

        Gui, 99:Menu
        Gui, 99:Destroy
    }

    Menu, menuDummy, Add, :%menu_name%
    h_menu := DllCall( "GetSubMenu", "uint", h_menuDummy, "int", 0 )
    DllCall( "RemoveMenu", "uint", h_menuDummy, "uint", 0, "uint", 0x400 )
    Menu, menuDummy, Delete, :%menu_name%
    
    ;memoizes values for later use
    [color=red]MI_setMenuHandleCache(menu_name, h_menu)
    MI_setMenuName(h_menu, menu_name)[/color]
    
    return h_menu
}

And then the getter/setter used

MI_getMenuHandleCache(menu_name)
{
    return MenuIconsMenuHandle[%menu_name%]
}

MI_setMenuHandleCache(menu_name, h_menu)
{
    global

    MenuIconsMenuHandle[%menu_name%] := h_menu
}

MI_getMenuName(h_menu)
{
    return MenuIconsMenuName[%h_menu%]
}

MI_setMenuName(h_menu, menu_name)
{
    global
    
    MenuIconsMenuName[%h_menu%] := menu_name
}

MI_getMenuHandleCache allows you to get the menu handle for the given menu name, and
MI_getMenuName allows you to get the menu name for the given menu handle.
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008
Also, I was reading through the code a bit and think this is a typo.

Old version:
MI_GetMenuHandle(menu_name)
{
    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 ) )
        [color=darkred]If ErrorLevel or h_menuDummy=0
            return 0[/color]

        [color=red]DetectHiddenWindows, %old_DetectHiddenWindows%[/color]

        Gui, 99:Menu
        Gui, 99:Destroy
    }

    Menu, menuDummy, Add, :%menu_name%
    h_menu := DllCall( "GetSubMenu", "uint", h_menuDummy, "int", 0 )
    DllCall( "RemoveMenu", "uint", h_menuDummy, "uint", 0, "uint", 0x400 )
    Menu, menuDummy, Delete, :%menu_name%
        
    return h_menu
}

should be: (moved the restore of the DetectHiddenWindows setting above the return statement)

MI_GetMenuHandle(menu_name)
{
    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 ) )

        [color=red]DetectHiddenWindows, %old_DetectHiddenWindows%[/color]

        [color=darkred]If ErrorLevel or h_menuDummy=0
            return 0[/color]
      
        Gui, 99:Menu
        Gui, 99:Destroy
    }

    Menu, menuDummy, Add, :%menu_name%
    h_menu := DllCall( "GetSubMenu", "uint", h_menuDummy, "int", 0 )
    DllCall( "RemoveMenu", "uint", h_menuDummy, "uint", 0, "uint", 0x400 )
    Menu, menuDummy, Delete, :%menu_name%
        
    return h_menu
}

and you didn't restore the setting for DetectHiddenWindows here, was it intentional?

MI_OwnerDrawnMenuItemWndProc(hwnd, Msg, wParam, lParam)
{
    static WM_DRAWITEM = 0x002B, WM_MEASUREITEM = 0x002C, WM_COMMAND = 0x111
    static ScriptHwnd
    Critical 500

    if (Msg = WM_MEASUREITEM && wParam = 0)
    {   ; MSDN: wParam - If the value is zero, the message was sent by a menu.
        h_icon := NumGet(lParam+20)
        if !h_icon
            return false
        
        ; Measure icon and put results into lParam.
        VarSetCapacity(buf,24)
        if DllCall("GetIconInfo","uint",h_icon,"uint",&buf)
        {
            hbmColor := NumGet(buf,16)
            hbmMask  := NumGet(buf,12)
            x := DllCall("GetObject","uint",hbmColor,"int",24,"uint",&buf)
            DllCall("DeleteObject","uint",hbmColor)
            DllCall("DeleteObject","uint",hbmMask)
            if !x
                return false
            NumPut(NumGet(buf,4,"int")+2, lParam+12) ; width
            NumPut(NumGet(buf,8,"int")  , lParam+16) ; height
            return true
        }
        return false
    }
    else if (Msg = WM_DRAWITEM && wParam = 0)
    {
        hdcDest := NumGet(lParam+24)
        x       := NumGet(lParam+28)
        y       := NumGet(lParam+32)
        h_icon  := NumGet(lParam+44)
        if !(h_icon && hdcDest)
            return false

        return DllCall("DrawIconEx","uint",hdcDest,"int",x,"int",y,"uint",h_icon
                        ,"uint",0,"uint",0,"uint",0,"uint",0,"uint",3)
    }
    else if (Msg = WM_COMMAND && !(wParam>>16)) ; (clicked a menu item)
    {
        [color=red]DetectHiddenWindows, On[/color]
        if !ScriptHwnd {
            Process, Exist
            ScriptHwnd := WinExist("ahk_class AutoHotkey ahk_pid " ErrorLevel)
        }
        if (hwnd != ScriptHwnd) {
            ; Forward this message to the AutoHotkey main window.
            PostMessage, Msg, wParam, lParam,, ahk_id %ScriptHwnd%
            return ErrorLevel
        }
    }
    if A_EventInfo  ; Let the "super-class" window procedure handle all other messages.
        return DllCall("CallWindowProc","uint",A_EventInfo,"uint",hwnd,"uint",Msg,"uint",wParam,"uint",lParam)
    else            ; Let the default window procedure handle all other messages.
        return DllCall("DefWindowProc","uint",hwnd,"uint",Msg,"uint",wParam,"uint",lParam)
}

I just want to say that I never know if correcting another's code comes off as offensive. If you took offense, sorry, that wasn't my intent.
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

should be: (moved the restore of the DetectHiddenWindows setting above the return statement)

Right.

and you didn't restore the setting for DetectHiddenWindows here, was it intentional?

Yes - MI_OwnerDrawnMenuItemWndProc executes on a new thread, so A_DetectHiddenWindows is saved and restored automatically.

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008
In response to my first post, is there a problem with caching the menu handles as I did?
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Sorry, I didn't see that post.

There is a problem, but only if the menu is deleted and recreated - i.e. because the handle changes. Is there any particular reason you think the menu handles need to be cached?

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008
Well, right now I'm writing a "complex" (maybe inclusive is a better word) menu wrapper, which I will post when complete, and I want the ability to incorporate my functions with yours. Right now, there are many people that use your code and they may have all their menus set up around the handle of a menu. So, to ease transition and to incorporate the functionality of these tools, I would like some way to link the handle numbers currently used with the menu name (which is what I use to wrap the menus).

The other reason is that I presume that many people, myself being one, don't want to have to keep track of another variable to store the handle of the menu when using your suite. Instead, I would much rather call the functions using the menu name (versus the handle) and have the code cache for me.

Another benefit is that anyone else that has any menu wrappers they want to add to your suite (and mine when ready) will then be able to have an easy link (since both the menu names and handles will be easily linked).

In my menu wrapper I will account for the fact that deleting a menu will change the handles. Will it change just the menu handle for the deleted menu or for all menus?

I am just tired of having to keep track of all the values that I use for my menus - the menu handle, the item names, the displayed item names (which may differ if for example the item contains ampersands as literals), a pointer to the menu data (so to allow easy moving of menu items in the menu without having to move the menu data that goes with it), the menu label, the menu size (both the displayed menu size, and the number of items already added to the "menu storage"), and others that are program dependant - which is why I'm creating a menu wrapper. Then, I thought that I could combine it with the functonality of your menu icons program - and to do this (and account for all the code that uses menu handles and not menu names), I need all my functions that use menu names to allow the handle to be used instead (which then checks the cache for the menu name).

So, in "short", it's because I think AHK needs "good" wrapper methods so that menu creation is easier (like we have many GUI wrappers to make GUI creation easier).

The code should be up in a few days (working out some of the small details), so you don't have to decide now, and instead can see my menu wrapper and see if you want to.

I believe that the code recommendations are backward compatable and thus all the code already running will be fine - I just thought that a little upgrade would help to incorporate your suite with mine (and any others that do/will use menu names to store menu data)

Also, to clear up any confusion I may have created, when I say "incorporate" I don't mean they need to be combined, just that by adding these functions they can "work well" with each other (and other menu suites that are/will be developed through the life of AHK).
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

The other reason is that I presume that many people, myself being one, don't want to have to keep track of another variable to store the handle of the menu when using your suite.

You can simply use the menu name, hence the parameter name "MenuNameOrHandle". [Edit] There probably isn't much performance benefit to caching the menu handle in a dynamic variable.

Will it change just the menu handle for the deleted menu or for all menus?

Technically the menu handle does not change - one menu is deleted, and another is created with the same name.

So, in "short", it's because I think AHK needs "good" wrapper methods so that menu creation is easier

Perhaps a built-in method to retrieve the menu handle is worth considering.

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008
So, just to clarify, there is "no" (or little) performance loss by using the menu name (versus the menu handle) in your functions? My confusion comes because inside your TestMenu.ahk file you say the following, "Refer to a menu by handle for efficiency."

Technically the menu handle does not change - one menu is deleted, and another is created with the same name.

I'm not sure what you mean here. Does this mean that the other menu handles remain the same?

Perhaps a built-in method to retrieve the menu handle is worth considering.

This is a very good idea - do you have a reference so I can figure out how to do that? :D
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.