Right-clicking an AHK menu item

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Right-clicking an AHK menu item

26 Mar 2015, 21:15

Having displayed an AHK menu with fly-outs, is there a reasonably easy way of detecting a right-click on a menu item and determining which menu and which item were selected?

(I'm aware of how to do this for a left click.)
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
garry
Posts: 3795
Joined: 22 Dec 2013, 12:50

Re: Right-clicking an AHK menu item

27 Mar 2015, 03:30

just an idea with button, rightclick ( or click )

Code: Select all

#NoEnv
sc=ContextMenuButton_Test
Gui,2:-border
Gui,2: Color, ControlColor, Black
Gui,2: Font,s9   ,Lucida console


Menu,2: Menu1, Add
Menu,2: Menu1, Add, AHK-Basic , MC1
Menu,2: Menu1, Add, AHK-L     , MC2
Menu,2: Menu1, Add

Menu,2: Menu2, Add, Notepad, Notepad1
Menu,2: Menu2, Add
Menu,2: Menu2, Add, Calc   , Calc1

Menu,2: Menu3, Add, Exit

Gui,2: Add, Button, x0   y0 w90  h18  vMb1 gAa1,AHK
Gui,2: Add, Button, x90  y0 w90  h18  vMb2 gAa2,Calculator
Gui,2: Add, Button, x180 y0 w70  h18  vMb3 gAa3,Exit

Gui,2: Show, x100 y10 h170 w330 ,%sc%
Return
;--------------------------------

2GuiClose:
ExitApp
esc::exitapp

2GuiContextMenu:
 {
 MouseGetPos,,,,Control1
 If (A_GuiControl = "Mb1")
   Menu,2: Menu1, Show
 If (A_GuiControl = "Mb2")
   Menu,2: Menu2, Show
 If (A_GuiControl = "Mb3")
   Menu,2: Menu3, Show
 }
return
;---------------------------
mc1:
run,http://www.autohotkey.com/board/
return

mc2:
run,http://ahkscript.org/boards/
return
;---------------------------
notepad1:
run,notepad
return

calc1:
run,calc
return

exit:
exitapp
;---------------------------
aa1:
msgbox,You used Button Test-1
return

aa2:
msgbox,You used Button Test-2
return

aa3:
exitapp
;=============== end script ===================

Last edited by garry on 28 Mar 2015, 03:53, edited 1 time in total.
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: Right-clicking an AHK menu item

27 Mar 2015, 21:24

Thanks for the code. I'll check it out.
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: Right-clicking an AHK menu item

28 Mar 2015, 18:33

Thanks for the reply, but I'm wanting to detect a right-click on a free-standing menu originally activated by a hot key. Again, the menu may have flyouts. I need to be able to detect the menu plus the menu item.
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
MJs
Posts: 454
Joined: 23 Sep 2014, 03:29

Re: Right-clicking an AHK menu item

28 Mar 2015, 22:23

Code: Select all

Menu, Tray, add
Menu, NewMenu, add, New Sub 1, MenuHandler
Menu, NewMenu, add, New Sub 2, MenuHandler
Menu, Tray, Add, &New Menu, :NewMenu
hMenu:=MI_GetMenuHandle("Tray")
return

Esc::
ExitApp
return

CapsLock::
Menu_Show( hMenu, A_ScriptHwnd,,, TPM_RIGHTBUTTON := 0x0002) ;The user can select menu items with both the left and right mouse buttons.
return

MenuHandler:
MsgBox, Detecting the menu plus the menu item`nMenu: %A_ThisMenu%`nMenu Item: %A_ThisMenuItem%
return

Menu_Show( hMenu, hWnd=0, mX="", mY="", Flags=0x1 ) {
 ; http://ahkscript.org/boards/viewtopic.php?p=7088#p7088
 ; Flags: TPM_RECURSE := 0x1, TPM_RETURNCMD := 0x100, TPM_NONOTIFY := 0x80
 VarSetCapacity( POINT, 8, 0 ), DllCall( "GetCursorPos", UInt,&Point )
 mX := ( mX <> "" ) ? mX : NumGet( Point,0 )
 mY := ( mY <> "" ) ? mY : NumGet( Point,4 )
Return DllCall( "TrackPopupMenu", UInt,hMenu, UInt,Flags ; TrackPopupMenu()  goo.gl/CosNig
               , Int,mX, Int,mY, UInt,0, UInt,hWnd ? hWnd : WinActive("A"), UInt,0 )
}

;________________Lexikos (www.autohotkey.com/board/topic/20253-menu-icons-v2/) in Menu Icons MI.ahk
; Gets a menu handle from a menu name.
; Adapted from Shimanov's Menu_AssignBitmap()
;   http://www.autohotkey.com/forum/topic7526.html
MI_GetMenuHandle(menu_name){
    static   h_menuDummy
    ; v2.2: Check for !h_menuDummy instead of h_menuDummy="" in case init failed last time.
    If !h_menuDummy
    {
        Menu, menuDummy, Add
        Menu, menuDummy, DeleteAll

        Gui, 99:Menu, menuDummy
        ; v2.2: Use LastFound method instead of window title. [Thanks animeaime.]
        Gui, 99:+LastFound

        h_menuDummy := DllCall("GetMenu", "uint", WinExist())

        Gui, 99:Menu
        Gui, 99:Destroy
        
        ; v2.2: Return only after cleaning up. [Thanks animeaime.]
        if !h_menuDummy
            return 0
    }

    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
}
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: Right-clicking an AHK menu item

29 Mar 2015, 17:01

Wow! Tricky... Can I distinguish between right and left clicks?
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
MJs
Posts: 454
Joined: 23 Sep 2014, 03:29

Re: Right-clicking an AHK menu item

30 Mar 2015, 03:09

you're going to have to be trickier
see here:http://ahkscript.org/boards/viewtopic.php?t=971
and take a look at the message:
WM_MENURBUTTONUP
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: Right-clicking an AHK menu item

30 Mar 2015, 21:00

Ok...
I've had a look at the items you referenced, but I'm no wiser as to how to get this to work. (I'm a relative beginner regarding AHK and Windows programming.) Any further ideas?
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
MJs
Posts: 454
Joined: 23 Sep 2014, 03:29

Re: Right-clicking an AHK menu item

01 Apr 2015, 06:08

Code: Select all

Menu, ContextMenu, add,  Menu1, MenuHandler
Menu, ContextMenu, add,  Menu2, MenuHandler
Menu, NewMenu, add, New Sub 1, MenuHandler
Menu, NewMenu, add, New Sub 2, MenuHandler
Menu, ContextMenu, Add, &New Menu, :NewMenu
hMenu:=MI_GetMenuHandle("ContextMenu")
OnMessage(0x0122 , "WM_MENURBUTTONUP"), OnMessage( 0x211, "WM_ENTERMENULOOP" )
RButton_Click:=false
return

CapsLock::
Menu_Show( hMenu, A_ScriptHwnd) ;The user can select menu items with both the left and right mouse buttons.
return

MenuHandler:

MsgBox, % "Detecting the menu plus the menu item`n"
		  . "Menu: " A_ThisMenu "`n"
		  . "Menu Item: " A_ThisMenuItem "`n"
		  . "Button: " (RButton_Click ? "Right" : "Left")
RButton_Click:=false ; always do this, so that you can differentiate between normal or right click
return
WM_MENURBUTTONUP(wparam, lparam){
	Global RButton_Click
MouseGetPos,,, w
ControlSend,, {enter}, ahk_id %w%
RButton_Click:=true
return
}
WM_ENTERMENULOOP(){ ; Notifies an application's main window procedure that a menu modal loop has been entered.
					; by returning true, the AHK doesn't halt processing Messages, timers, hotkeys... (the default behavior)
return, true
}
Menu_Show( hMenu, hWnd=0, mX="", mY="", Flags=0x1 ) {
 ; http://ahkscript.org/boards/viewtopic.php?p=7088#p7088
 ; Flags: TPM_RECURSE := 0x1, TPM_RETURNCMD := 0x100, TPM_NONOTIFY := 0x80
 VarSetCapacity( POINT, 8, 0 ), DllCall( "GetCursorPos", UInt,&Point )
 mX := ( mX <> "" ) ? mX : NumGet( Point,0 )
 mY := ( mY <> "" ) ? mY : NumGet( Point,4 )
Return DllCall( "TrackPopupMenu", UInt,hMenu, UInt,Flags ; TrackPopupMenu()  goo.gl/CosNig
               , Int,mX, Int,mY, UInt,0, UInt,hWnd ? hWnd : WinActive("A"), UInt,0 )
}


;________________Lexikos (www.autohotkey.com/board/topic/20253-menu-icons-v2/) in Menu Icons MI.ahk
; Gets a menu handle from a menu name.
; Adapted from Shimanov's Menu_AssignBitmap()
;   http://www.autohotkey.com/forum/topic7526.html
MI_GetMenuHandle(menu_name){
    static   h_menuDummy
    ; v2.2: Check for !h_menuDummy instead of h_menuDummy="" in case init failed last time.
    If !h_menuDummy
    {
        Menu, menuDummy, Add
        Menu, menuDummy, DeleteAll

        Gui, 99:Menu, menuDummy
        ; v2.2: Use LastFound method instead of window title. [Thanks animeaime.]
        Gui, 99:+LastFound

        h_menuDummy := DllCall("GetMenu", "uint", WinExist())

        Gui, 99:Menu
        Gui, 99:Destroy
       
        ; v2.2: Return only after cleaning up. [Thanks animeaime.]
        if !h_menuDummy
            return 0
    }

    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
}
Esc::
ExitApp
return
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: Right-clicking an AHK menu item

01 Apr 2015, 19:11

Looking good!

Thanks for all your help with this, MJs (and Garry).

(I'm surprised that the ability to detect a right-click on a free-standing menu item is not built in to the AHK language. It seems a fairly basic requirement.)
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: Right-clicking an AHK menu item

01 Apr 2015, 21:43

I've been giving your AHK code a good work out and found a couple of problems:-

If the script is started by double clicking in a file explorer window (then caps lock is pressed to show the menu), if the first click on a menu item is a right-click it is sometimes not actioned. (When the script is started using the enter key it seems ok.)

When the menu is displayed (without clicking any items), pressing Esc or clicking away from the menu usually doesn't remove the menu, unlike normal menus. (I changed the Esc hot key in your script to something else so I could test this.) There needs to be the usual way of dismissing the menu if no action is needed. (I also noticed that this problem doesn't occur if the menu is not responding to a right-click as per the first problem.)

Sorry to be reporting problems - I do appreciate all your hard work!
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
MJs
Posts: 454
Joined: 23 Sep 2014, 03:29

Re: Right-clicking an AHK menu item

02 Apr 2015, 05:45

If the script is started by double clicking in a file explorer window (then caps lock is pressed to show the menu), if the first click on a menu item is a right-click it is sometimes not actioned. (When the script is started using the enter key it seems ok.)
didn't notice, don't know.
those are known problems, remember tricky and trickier, well you need to get even more so, the problem is that normally AHK halt processing messages when a popup menu is shown, in other word if you show a menu, no timer, no hotkeys, no nothing.
for the ESC key issue, well it's not, it's just when you're testing, get a key to exit, any key.
There needs to be the usual way
need to get trickier and then some.
you may be better off using two scripts, one showing the menu, and one controlling it using hotkey to get the usual everything
take a look at this, and do some search.
http://www.autohotkey.com/board/topic/9 ... s-problem/
http://www.autohotkey.com/board/topic/9 ... s-problem/
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: Right-clicking an AHK menu item

02 Apr 2015, 17:21

I see that another side effect of this approach is that the menu items are not selectable by keyboard.

Thanks again for all your efforts.
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
lexikos
Posts: 9690
Joined: 30 Sep 2013, 04:07
Contact:

Re: Right-clicking an AHK menu item

19 Sep 2015, 20:16

It's a bit late, but:

If you want to navigate menu items with the keyboard, just add this above the call to Menu_Show():

Code: Select all

DetectHiddenWindows On
WinActivate ahk_id %A_ScriptHwnd%
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: Right-clicking an AHK menu item

05 Dec 2015, 17:19

Even later....(I was away on holiday when you replied)

Thanks Lexikos. Your suggestion solves two of my problems.
Now Esc and clicking away removes the menu, and I can select items using the keyboard.

However this problem still remains:
If the script is started by double clicking in a file explorer window (then caps lock is pressed to show the menu), if the first click on a menu item is a right-click it is sometimes not actioned. (When the script is started using the enter key it seems ok.)
Any ideas?
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: Right-clicking an AHK menu item

25 Jan 2017, 20:47

Awakening an old post.

I'm using the following method to provide right-clicking on menus. This is similar to earlier code in this thread, but updated to use later AHK enhancements.

The Lexikos enhancement:

Code: Select all

DetectHiddenWindows On
WinActivate ahk_id %A_ScriptHwnd%
allows the menu items to be selected by keyboard, and also allows the menu to be dismissed by Esc - all very good.

However, if the script is reloaded via the tray reload option, the next time the menu hotkey capslock is used, the AHK 'Open' window appears, along with the menu. This even happens if the script is compiled. If I comment out the above statements this problem doesn't occur, but then I lose menu keyboard navigation ability.

Is this a bug?

Here is the full demo code:

Code: Select all

#NoEnv                            ; For performance & future compatibility
#Warn                             ; For catching common errors
SendMode Input                    ; For superior speed and reliability
SetWorkingDir %A_ScriptDir%       ; Ensures a consistent starting directory
; ===========================  Initial Settings  ===============================
Menu, ContextMenu, add,  Menu&1, MenuHandler
Menu, ContextMenu, add,  Menu&2, MenuHandler
Menu, NewMenu, add, New Sub 1, MenuHandler
Menu, NewMenu, add, New Sub 2, MenuHandler
Menu, ContextMenu, Add, &New Menu, :NewMenu
OnMessage(0x0122,"WM_MENURBUTTONUP"), OnMessage(0x211,"WM_ENTERMENULOOP"), rbc=0
return

CapsLock::
rbc:=0, Menu_Show(MenuGetHandle("ContextMenu"), A_ScriptHwnd) ; Can select menu
return                            ;   with both the left and right mouse buttons.

MenuHandler:
MsgBox,% "Menu:`t" A_ThisMenu "`n"
      .  "Item:`t" A_ThisMenuItem "`n"
      .  "Button:`t" (rbc ? "Right" : "Left")
return

WM_MENURBUTTONUP(wparam, lparam)
{ local w
  MouseGetPos,,, w
  ControlSend,, {enter}, ahk_id %w%
  rbc:=1
}
WM_ENTERMENULOOP() ; Notifies an application's main window procedure that a
{ return true ; menu modal loop has been entered. By returning true, AHK
} ; doesn't halt processing Messages, timers, hotkeys... (the default behavior)

Menu_Show(hMenu, hWnd=0, mX="", mY="", Flags=0x1) ; goo.gl/fRwDwG
{ local p, a=VarSetCapacity(p,8,0), b=DllCall("GetCursorPos", UInt,&p)
  DetectHiddenWindows On
  WinActivate ahk_id %hWnd%
  Return DllCall("TrackPopupMenu",UInt,hMenu,UInt,Flags, Int,mX=""?NumGet(p,0):mX
  , Int,mY=""?NumGet(p,4):mY, UInt,0, UInt,hWnd?hWnd:WinActive("A"), UInt,0)
} ; goo.gl/CosNig; Flags: TPM_RECURSE=0x1, TPM_RETURNCMD=0x100, TPM_NONOTIFY=0x80

F4::ExitApp
F5::Reload
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
Contact:

Re: Right-clicking an AHK menu item

26 Jan 2017, 15:00

TAC109 wrote:However, if the script is reloaded via the tray reload option, the next time the menu hotkey capslock is used, the AHK 'Open' window appears, along with the menu. This even happens if the script is compiled. If I comment out the above statements this problem doesn't occur, but then I lose menu keyboard navigation ability.
It appears to happen when AutoHotkey minimises the main window in some cases.

The only bad workaround I have is forcing the window to show and then hiding it, but that causes the main window to flash when the script is reloaded, which is eurgh.
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: Right-clicking an AHK menu item

26 Jan 2017, 17:37

Thanks for your reply.

I have found a circumvention.
I wrote my own 'reload' tray entry so that I WinActivate a different window immediately prior to the reload command. Then the new instance of the script no longer has this problem! :crazy:
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
Contact:

Re: Right-clicking an AHK menu item

26 Jan 2017, 17:44

Glad you found a solution. Doing the following in the "initial settings" part appears to work too, but is definitely hacky compared to your solution:

Code: Select all

if (InStr(DllCall("GetCommandLine", "Str"), " /restart")) {
	parent := DllCall("GetParent", "Ptr", A_ScriptHwnd, "Ptr") ; actually NULL 'cause there is no parent initially, but we'll roll with it
	DllCall("SetParent", "Ptr", A_ScriptHwnd, "Ptr", -3) ; set to a message-only window which may introduce problems
	DllCall("ShowWindow", "Ptr", A_ScriptHwnd, "Int", 1) ; SW_SHOWNORMAL - apparently needed to remove WS_MINIMIZE...
	DllCall("ShowWindow", "Ptr", A_ScriptHwnd, "Int", 0) ; SW_HIDE
	DllCall("SetParent", "Ptr", A_ScriptHwnd, "Ptr", parent)
}
I didn't try it, but you might be able to use OnExit to detect a reload and WinActivate another window there so you can continue to use the standard reload menu option

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 356 guests