Jump to content

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

Menu focus problem


  • Please log in to reply
16 replies to this topic
VanDiZ
  • Members
  • 21 posts
  • Last active: Mar 20 2013 07:40 PM
  • Joined: 25 Aug 2011

Hello everyone, I was working on a Right Click activated menu for a Non-AutoHotKey application, the code is working fine accept that it [the menu] defocuses the application window.

 

I know it is the by-design [maybe] behavior of AutoHotKey menus but it is a problem for me because I need the application window to stay focused when the menu pops-up.

So I am here with a hope to find a workaround to the problem [at-least for me].

 

Can anyone help me please...

 



Jackie Sztuk _Blackholyman
  • Spam Officer
  • 3757 posts
  • Last active: Apr 03 2016 08:47 PM
  • Joined: 28 Feb 2012

trie the steps in this link.

http://www.autohotke...y-3-step-guide/

 

please post code so we can se the things that have been done and maybe what can be done.

 

hope it helps


Helping%20you%20learn%20autohotkey.jpg?d

[AHK] Version. 1.1+ [CLOUD] DropBox ; Copy [WEBSITE] Blog ; About

VanDiZ
  • Members
  • 21 posts
  • Last active: Mar 20 2013 07:40 PM
  • Joined: 25 Aug 2011

Thank you vary much Blackholyman for your quick reply.

As far as I understand the problem I am asking for is not specific to my code, it's a  general problem.

If I am not wrong the "problem" occurs because the menu is actually of the main AHK window, so when we use any hoykey [in my case RClick] to show a menu on any other apps window, it focuses the main AHK window and thus the app window of the "other app" is becomes deactivated. [Please correct me if I am wrong]

 

If you want a code then we can work on the sample code bellow -
 

Loop, 6
{
    Menu, MyMenu, Add, MenuItem%A_Index%, MH_MenuItem%A_Index%
}

~MButton::
    If (A_PriorHotKey = A_ThisHotKey and A_TimeSincePriorHotkey < DllCall("GetDoubleClickTime")) {
        Menu, MyMenu, Show
    }
return

MH_MenuItem1:
MH_MenuItem2:
MH_MenuItem3:
MH_MenuItem4:
MH_MenuItem5:
MH_MenuItem6:
return

 

The above script dose nothing accept popping up a 6 item menu. As you can see, if you dubble-middle-click on a window [e.g. notepad window] the menu pops-up but the window becomes deactivated. Is that because of the mismatch between the window thread and the menu thread ???  [Please correct me If I am wrong anywhere]


Please point me to a workaround to the problem.

[I am using the AHK_L v1.1.09.00 on Windows 7 Ultimate 32Bit Acer Aspire 4736 Laptop]



Person93
  • Members
  • 443 posts
  • Last active: Feb 11 2014 12:07 AM
  • Joined: 26 Jan 2012

Would it help if the first thing that every menu item did was to activate the app window or do you actually need it to be active the entire time?



VanDiZ
  • Members
  • 21 posts
  • Last active: Mar 20 2013 07:40 PM
  • Joined: 25 Aug 2011

Would it help if the first thing that every menu item did was to activate the app window or do you actually need it to be active the entire time?

 

Thank you vary much Person93 for your reply.


When I Dubble-Middle-Click on a application window, I want that application window to stay active when the menu is being popping-up.



Person93
  • Members
  • 443 posts
  • Last active: Feb 11 2014 12:07 AM
  • Joined: 26 Jan 2012

Is there any particular reason?

 

If there is, there might be another way to accomplish what you are looking to do.



VanDiZ
  • Members
  • 21 posts
  • Last active: Mar 20 2013 07:40 PM
  • Joined: 25 Aug 2011

Thank you vary much Person93 for your reply.

 

There is some reasons:

#1> It's a bit annoying.

#2> My app users complains about it [including me to myself].

 

If there is, there might be another way to accomplish what you are looking to do.

 

What I was wanting to do with that program is done. Everything is working fine what I intended to work but accept the annoying problem.

 

Now, I want that annoying problem to be solved. Can I have any help ???



Person93
  • Members
  • 443 posts
  • Last active: Feb 11 2014 12:07 AM
  • Joined: 26 Jan 2012

From what you are saying, it seems to be an aesthetic issue, perhaps you can look into WinSet commands and the like that make a window appear to be active even though it isn't.



VanDiZ
  • Members
  • 21 posts
  • Last active: Mar 20 2013 07:40 PM
  • Joined: 25 Aug 2011

Yeah, it's a aesthetic issue but vary important to me,

 

AHK scripts are paused when a menu is shown so you cannot run any command or so after it pops-up, If I run another script to make the window active then the script's main window will become deactivated so the menu will disappear so it will not work.

 

So at this point what can we do ???? Any idea ???

 

 

 

[Sorry for my bad English]



faqbot
  • Members
  • 997 posts
  • Last active:
  • Joined: 10 Apr 2012
You could try to ditch the menu and use a Gui which can always be ontop but not active (see the NA option in Gui Show) a simple menu is easy to fake using a gui.

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

The following shows a menu without activating the script's window:

 

Menu m, Add, Item 1, n
Menu m, Add, Item 2, n
Menu m, Add, Item 3, n
h := MI_GetMenuHandle("m")
CoordMode Mouse
MouseGetPos x, y
DllCall("TrackPopupMenu", "ptr", h, "uint", 0, "int", x, "int", y
                        , "int", 0, "ptr", A_ScriptHwnd, "ptr", 0)
Sleep 1 ; Let menu command be processed.
ExitApp
n:
MsgBox % A_ThisMenuItem
return

This requires AutoHotkey v1.1 and MI_GetMenuHandle from MI.ahk.

 

There are three problems:

  • Clicking a menu item will still temporarily deactivate the active window.
  • The menu does not automatically disappear if you click elsewhere.
  • You cannot use the keyboard to select an item or cancel the menu, as it does not have keyboard focus.


VanDiZ
  • Members
  • 21 posts
  • Last active: Mar 20 2013 07:40 PM
  • Joined: 25 Aug 2011

Thank you vary much faqbot and Lexikos for your reply.


@faqbot, Your Idea is good but big work for a little task, and also have a flaw, when you click in that Gui-Menu, it will become active, to solve this you have to block mouse inputs to it and now you have another problem of clicking on a menu item, yes it can be solved also but vary messy. Another thing, menu item boxes should be highlighted when mouse hovers on it, so we need another bit of coding for that. 

 

I would like to use it as a last way.

 

@Lexikos, I learned a lot from your posts in past, and thank you vary much for the AHK_L.

 

I tried the "TrackPopupMenu" technique you showed but had some problems as you mentioned.

 

This technique can be usable [but not satisfactory et. al] if at-least it disappear when I click outside the menu, so, because, script is become paused after the menu appears, we can run another script before showing the menu to check when I click outside it and then delete it. With that idea I setup a test script to check it but had no luck.

 

 

;The test script
+F1::
    SendMessage, 0x1E1, 0, 0,, ahk_class #32768
    hMenu := ErrorLevel
    rtrn := DllCall("DestroyMenu", "Ptr", hMenu)
    ToolTip, hMenu="%hMenu%"`nrtrn="%rtrn%", 100, 100
return

 

Nothing happens when I press Shift+F1 accept the ToolTip. You can see, the "DestroyMenu" function is returning "0".

 

Any other idea to solve the problem ??? And can you tell me what is wrong with that test script ???



Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
WinClose ahk_class #32768

 

when you click in that Gui-Menu, it will become active

 

Not if you add +E0x08000000 (WS_EX_NOACTIVATE) to the Gui's options.



Timo
  • Members
  • 26 posts
  • Last active: Mar 19 2013 12:34 PM
  • Joined: 24 Mar 2012

Hi,

 

I use the following:

 

Firstly, early in the initialization section I define:

 

LaunchWinID = undefined

 

 

Then in the mouse hook loop:

 

Global LaunchWinID

MouseGetPos, mouseXpos, mouseYpos, WindowUnderMouse, ControlUnderMouse, 3

LaunchWinID = %WindowUnderMouse%

 

 

and finally where ever I need to switch back to that window that was clicked by the mouse I do:

 

Global LaunchWinID

WinActivate, ahk_id %LaunchWinID%

 

 

At the end of each sub/function I make the LaunchWinID again to be undefined:

 

LaunchWinID = undefined

 

 

The above is a snippet from my AutoStart.AHK that runs a thing that I call as the "Geek-Button"  :-)  It is a small hidden area on the TitleBar of any open window and the button always resides next to the right of the application icon, having the same size. as the application icon. A mouse click on this area opens a menu that has (1) always available tools, (2) tools that are specific to different user(name)s, (3) tools that are specific to a certain windows, (4) and tools that are specific to different computer(name)s. The below screeencapture shows an example, but when opened from another software the menu can look way different, depending on what tools have been defined for that particular application. The "Geek-Button" is also available in the common dialogs (Open, Save, etc) so I have very many destination folders defined for quick access..

 

Paste%20Clipboard-20130303130647.gif

 

BR,

Timo

 



VanDiZ
  • Members
  • 21 posts
  • Last active: Mar 20 2013 07:40 PM
  • Joined: 25 Aug 2011

@Lexikos, with your suggestions I did a quick scripting and had this...

 

 

loop, 6
{
	Menu, MyMenu, Add, MenuItem%A_Index%, Menu_Handler
}
return

~MButton::
    If (A_PriorHotKey = A_ThisHotKey and A_TimeSincePriorHotkey < DllCall("GetDoubleClickTime")) {
		CWinID := WinActive("A")
		hMenu := MI_GetMenuHandle("MyMenu")
		TPM_Close()
		CoordMode Mouse
		MouseGetPos, x, y
		DllCall("TrackPopupMenu", "ptr", hMenu, "uint", 0, "int", x, "int", y, "int", 0, "ptr", A_ScriptHwnd, "ptr", 0)
		Sleep 1 ; Let menu command be processed.
	}
return

Menu_Handler:
	SoundBeep
	WinActivate, ahk_id %CWinID%
return

MI_GetMenuHandle(menu_name)
{
	;~ This Function is by Lexikos [http://www.autohotkey.com/board/user/2446-lexikos/]
	;~ Forum link:- http://www.autohotkey.com/board/topic/20253-menu-icons-v2
 	;~ Source Link:- http://www.autohotkey.net/~Lexikos/lib/MI.ahk
	
    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
}
return

TPM_Close() { ;Menu Closing Script
MCS=
(
#NoTrayIcon
#SingleInstance Force
swch = 0
Loop
{
	if (WinExist("ahk_class #32768")) {
		swch = 1
		break
	}
	Sleep, 20
}
return
#If swch
	~LButton::
	~RButton::
	~MButton::
		Sleep, 100 ;let the menu reply to the main script window
		WinClose ahk_class #32768
		FileDelete, `%A_ScriptFullPath`%
		ExitApp
	return
#If

)
	Loop, 5
	{
		Random, _rndm, 99999, 999999999
		rndm = %rndm%%_rndm%
	}
	ScrName = %A_Temp%\%rndm%.ahk
	FileAppend, %MCS%, %ScrName%, UTF-8
	Run, %ScrName%, %A_WorkingDir%
	return
}

 

 

This is a working script, but not without problems. You can see I used random names for the Menu-Closing-Script because of the FileAppend, but that causes another problem, I do not want each time when the menu pops-up a new Menu-Closing-Script be generated and stay there so I used the "FileDelete, `%A_ScriptFullPath`%" to delete it.

 

If I compile the hole script it will have another set of problems then...

 

It is vary vary messy and big effort for a little job...

 

Is there any neat and clean solution ???

 

BTW, the problem of window defocussing when clicking on a menu Item can be solved if we block mouse input [with hotkeys] on the menu and get which menu item is highlighted when hovering on it. That way we can conditionally and virtually go to a subroutine based on a menu item without defocussing any window.

 

And thanks for the WS_EX_NOACTIVATE suggestion, but the Gui-Menu is not a solution for me.