AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to detect and close a context menu?

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
Stefaan
Guest





PostPosted: Sun Dec 02, 2007 5:46 pm    Post subject: How to detect and close a context menu? Reply with quote

I'm trying to make a hotkey that sends ctrl v to paste, when I press the left and right mouse buttons together. Now I have:

Code:
~LButton & RButton::Send ^v
~RButton & LButton::Send ^v

This works great, except if I press the right button first. Then a context menu is shown on releasing this button. I want to close this menu in my script, but I don't know how to detect the menu. Just sending an escape key wouldn't work, because if no menu is shown, this key could trigger an wrong action, like closing the window.

Another possibility would be to send an {alt} key to the window. This also closes a context menu. But this has the same problem: if no menu is shown, the alt will activate the main menu of the window which will prevent typing in the editor.

So I need to find out if a menu is shown before closing it, to prevent side effects if there isn't a menu. Or I need a solution to close the menu that has no side effects when there is no menu.

Can someone help me further?

Thanks
Back to top
ahklerner



Joined: 26 Jun 2006
Posts: 1205
Location: USA

PostPosted: Sun Dec 02, 2007 5:52 pm    Post subject: Reply with quote

use a rbutton::return map in your script too..not tested.
_________________
Back to top
View user's profile Send private message
Stefaan
Guest





PostPosted: Sun Dec 02, 2007 7:28 pm    Post subject: Reply with quote

No, that doesn't work. I first thought it would block the right mouse button but in fact it doesn't do anything.
However, It's not my intention to block the right mouse button. I just want to close the context menu from the script.
Back to top
HuBa



Joined: 24 Feb 2007
Posts: 172
Location: Budapest, Hungary

PostPosted: Sun Dec 02, 2007 7:47 pm    Post subject: Reply with quote

Code:
KeyWait RButton  ; Wait for releasing Right button to show menu
Send {Esc}  ; This closes the context menu
Send ^v  ; Paste
Back to top
View user's profile Send private message Visit poster's website
Stefaan
Guest





PostPosted: Mon Dec 03, 2007 3:32 pm    Post subject: Reply with quote

Thanks for your answer, but it's not quite what I'm looking for.

First should be checked if there actually is a menu shown before sending an escape. Else the escape can have unwanted side effects. For instance, if the hotkey is used in a dialog window and no context menu is shown after releasing the right button, the escape would cancel the dialog.
Back to top
HuBa



Joined: 24 Feb 2007
Posts: 172
Location: Budapest, Hungary

PostPosted: Mon Dec 03, 2007 3:38 pm    Post subject: Reply with quote

Stefaan wrote:
Thanks for your answer, but it's not quite what I'm looking for.

First should be checked if there actually is a menu shown before sending an escape. Else the escape can have unwanted side effects. For instance, if the hotkey is used in a dialog window and no context menu is shown after releasing the right button, the escape would cancel the dialog.

You can build an ahk group of windows and check for it with IfWinActive
Back to top
View user's profile Send private message Visit poster's website
Stefaan
Guest





PostPosted: Mon Dec 03, 2007 4:13 pm    Post subject: Reply with quote

It depends on where I'm clicking in a window if I get a context menu or not. So I can't know before if a context menu will be shown in a given window. Generally, clicking in an edit will show a menu, but clicking next to an edit will not. In the last case the clipboard will be pasted in the active edit, without showing a menu. So I really need to detect if there's a context menu or not.
Back to top
HuBa



Joined: 24 Feb 2007
Posts: 172
Location: Budapest, Hungary

PostPosted: Mon Dec 03, 2007 4:30 pm    Post subject: Reply with quote

Stefaan wrote:
It depends on where I'm clicking in a window if I get a context menu or not. So I can't know before if a context menu will be shown in a given window. Generally, clicking in an edit will show a menu, but clicking next to an edit will not. In the last case the clipboard will be pasted in the active edit, without showing a menu. So I really need to detect if there's a context menu or not.

If focused control's name contains "edit" then context menu will be shown.
Just 2 lines of code.
Back to top
View user's profile Send private message Visit poster's website
svi



Joined: 09 Oct 2006
Posts: 124
Location: Finland

PostPosted: Mon Dec 03, 2007 5:25 pm    Post subject: Re: How to detect and close a context menu? Reply with quote

Stefaan wrote:
... I don't know how to detect the menu. ... So I need to find out if a menu is shown before closing it ...

Use PixelGetColor to test if a menu is shown. The menu color is (probably EDIT: confirmed) in HKEY_CURRENT_USER\Control Panel\Colors\Menu (decimal values).

If I understood you correctly, you want the action to work for the active window no matter where the cursor is.
So using ControlGetFocus wouldn't work (to detect if the control under mouse contains "Edit"), but MouseGetPos, [OutputVarX, OutputVarY, OutputVarWin, OutputVarControl ...] would.
Clicking on title bar also shows a menu. So also caption should be detected (using WM_NCHITTEST), and at least Taskbar.
So PixelGetColor is perhaps simpliest, unless someone shows a smart way ...

EDIT:
PixelGetColor is not useful because the menu background is by default white (I forgot Embarassed ), same as window background. Using menu border color (HKEY_CURRENT_USER\Control Panel\Colors\ButtonShadow) even with menu color isn't still reliable enough.
_________________
Pekka Vartto


Last edited by svi on Wed Dec 05, 2007 9:19 pm; edited 2 times in total
Back to top
View user's profile Send private message
Stefaan
Guest





PostPosted: Mon Dec 03, 2007 9:28 pm    Post subject: Reply with quote

I have found a solution. The windows api function GetGUIThreadInfo can be used to get information about a window and its thread. If no window is specified, the foreground window is used. The GuiThreadInfo struct contains a variable flags. In this flag bit 4 is set if the thread is showing a menu. Using this information I created the following function:

Code:
closeContextMenu()
{
   GuiThreadInfoSize = 48
   VarSetCapacity(GuiThreadInfo, 48)
   NumPut(GuiThreadInfoSize, GuiThreadInfo, 0)
   if not DllCall("GetGUIThreadInfo", uint, 0, str, GuiThreadInfo)
   {
      MsgBox GetGUIThreadInfo() indicated a failure.
      return
   }
   ; GuiThreadInfo contains a DWORD flags at byte 4
   ; Bit 4 of this flag is set if the thread is in menu mode. GUI_INMENUMODE = 0x4
   if (NumGet(GuiThreadInfo, 4) & 0x4)
      send {escape}
}

And I'm using it like this:

Code:
~LButton & RButton::
   #MaxThreadsPerHotkey 3
   Send ^v
   return
~RButton & LButton::
   #MaxThreadsPerHotkey 3
   Send ^v
   if waiting
      return
   waiting = 1
   KeyWait, RButton
   waiting = 0
   Sleep, 50
   closeContextMenu()
   return
Back to top
svi



Joined: 09 Oct 2006
Posts: 124
Location: Finland

PostPosted: Wed Dec 05, 2007 9:10 pm    Post subject: Reply with quote

You showed a smart way, Stefaan, but I'll show a simple way: just send Ctrl + Alt. I think it has no side effects (unless you've defined the combination to trigger an action).
You may have to define the Control key to be the right one:
Code:
Send {RCtrl DOWN}{Alt DOWN}{Alt UP}{RCtrl UP}


I should have found this solution earlier, because I've used AltGr to close a menu after accidental press of Apps key (they are handily next to each other) - and AltGr is almost like Ctrl + Alt - , but I didn't first remember it was AltGr.
_________________
Pekka Vartto
Back to top
View user's profile Send private message
HuBa



Joined: 24 Feb 2007
Posts: 172
Location: Budapest, Hungary

PostPosted: Wed Dec 05, 2007 9:15 pm    Post subject: Reply with quote

Code:
Send {RCtrl DOWN}{Alt DOWN}{Alt UP}{RCtrl UP}

Nice trick, I like it!
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group