ACC.AHK - Get IAccessible for Context menu

Get help with using AutoHotkey and its commands and hotkeys
sancarn
Posts: 189
Joined: 01 Mar 2016, 14:52

ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 11:36

Hi all,

I'm trying to get the IAccessible interface for the right-click context menu using acc.ahk.

I've noticed that "Context" is a direct child of the Desktop client window, so I'm trying to loop over all children of the Desktop window until accName=="Context" and accRole==0xb

So far I've managed to get the IAccessible interface for the desktop client window:

Code: [Select all] [Download] GeSHi © Codebox Plus

getRoot(){
return acc_ObjectFromWindow(dllcall("GetDesktopWindow"))
}


I can tell this is indeed the desktop window because: msgbox, % getRoot().accChildCount ;==> 351 which is the same as the count that I see in Inspect.exe.

However when I try to use msgbox, % """" Acc_Child(getRoot(),1).accName """" I get "".

Looking deeper into the issue ComObjType(Acc_Child(getRoot(),1)) returns an empty string. I.E. Acc_Child does not return a COM Object...

Any ideas why this doesn't work?

Edit:

When running getRoot().accChild(1), I get an error "The parameter is incorrect." ... Specifically accChild.

Edit2:

I found that someone using AutoIt got a similar error:

https://www.autoitscript.com/forum/topi ... ent=251855
qwerty12
Posts: 422
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 12:40

Hi,

While I don't know what your end goal here is, the first thought that comes to mind is why bother with MSAA here? Use ShellContextMenu if you want the context menu for a file or the desktop (pass "Desktop" as sPath if you want the desktop's context menu).

There are two caveats though:

  • ShellContextMenu hosts everything inside your process, so you get a metric shitton of DLLs loaded - and it shows when the memory usage of your script goes way up
  • You need to add fragman's additions if you want to directly invoke something without even seeing the context menu. However, that code is for 32-bit AHK only. I have a port of it to 64-bit AHK somewhere that I did but I must warn you that I did it to put into practice the IUnknown stuff I learnt after reading maul-esel's tutorial - I still don't know to this day if the code is correct (mainly because I don't have a need for the function any more - with Windows 8, Microsoft finally added a proper interface to move to the next desktop slideshow pic).
User avatar
jeeswg
Posts: 2650
Joined: 19 Dec 2016, 01:58
Location: UK

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 12:45

It may be that you can only access a context menu via Acc (or by any means) while it's showing. It may be that you can access the submenus of menu bars, while they are not shown, via DllCall (but perhaps not via Acc).

Btw if you mention what you're hoping to do, maybe there's another way. Are you trying to invoke a Desktop context menu item?

Sometimes just sending WM_COMMAND to the right window/control works:
Get Info from Context Menu (x64/x32 compatible) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=31971
sancarn
Posts: 189
Joined: 01 Mar 2016, 14:52

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 16:42

qwerty12 wrote:Hi,

While I don't know what your end goal here is, the first thought that comes to mind is why bother with MSAA here? Use ShellContextMenu if you want the context menu for a file or the desktop (pass "Desktop" as sPath if you want the desktop's context menu).


I'm not sure this will work. One of the software applications I use uses a context menu as a 'popup menu' from a button within it's GUI. I need to click the button (which is easy with MSAA) and then click the 'Find' button on the context menu.

Now WM_COMMAND has been suggested, and I would use this but for some reason this software is terribly unstable with WM_COMMAND, which can often cause instantaneous crashes... So I'm trying to stick with the UI as much as I can, because so far that hasn't failed me.

My last resort is using Acc_ObjectFromPoint, which is what other people have used in the past apparently. But it's not clean of course...

@jeeswg It's got nothing to do with accessing the context menu while it's showing, because there are plenty of other windows in the desktop window (literally every window on the desktop), and all windows are inaccessible for some reason... Look at this image:

Image

As you can see, all windows are stored within the desktop client area. This includes the context menu.

Edit:

Hmm actually... I could probably get the context menu's hwnd with UI Automation via CLR... That's not very clean either but it would be general at least...
User avatar
jeeswg
Posts: 2650
Joined: 19 Dec 2016, 01:58
Location: UK

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 17:04

I have this example for 'Edit, Invert Selection' in Explorer via Acc.
AccViewer crashing, Acc.ahk failing (invoke items, retrieve text, IE/Explorer/VLC) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=26483&p=127439#p127439

Although I later found out that I could do it more directly via WM_COMMAND:
Windows 7 - invert selection, set details view/list view (trigger Explorer/Internet Explorer menu items) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=27564
sancarn
Posts: 189
Joined: 01 Mar 2016, 14:52

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 17:17

jeeswg wrote:I have this example for 'Edit, Invert Selection' in Explorer via Acc.
AccViewer crashing, Acc.ahk failing (invoke items, retrieve text, IE/Explorer/VLC) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=26483&p=127439#p127439

Although I later found out that I could do it more directly via WM_COMMAND:
Windows 7 - invert selection, set details view/list view (trigger Explorer/Internet Explorer menu items) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=27564


Sadly in my case it is using windows message's WM_COMMAND which causes the crash and not the other way round. Otherwise I would quite happily use WM_COMMAND for everything.
qwerty12
Posts: 422
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 17:21

sancarn wrote:I'm not sure this will work. One of the software applications I use uses a context menu as a 'popup menu' from a button within it's GUI. I need to click the button (which is easy with MSAA) and then click the 'Find' button on the context menu.

Now WM_COMMAND has been suggested, and I would use this but for some reason this software is terribly unstable with WM_COMMAND, which can often cause instantaneous crashes... So I'm trying to stick with the UI as much as I can, because so far that hasn't failed me.


You might consider an event hook to detect when a popup menu has been displayed. I do this with f.lux so that I can put it into movie mode automatically when I start PotPlayer. I don't know of any synchronous ways of doing this (which I'd like. WM_COMMAND won't work here as f.lux creates its menu on demand using TrackPopupMenu with TPM_RETURNCMD - which I think creates another message loop that I have no idea how to message - and f.lux doesn't listen for menu-related WM_COMMAND messages at any other point). Thanks, jeeswg

I can't give a concrete example (the code I have currently to do this is a mess, and decoupling it would take me too much time), but you can shove a MsgBox in this to see if the context menu you speak of is detected by the event hook (and if so, read the forum post linked to find out what to do next):

Code: [Select all] [Expand] [Download] (Untitled.ahk)GeSHi © Codebox Plus

Last edited by qwerty12 on 16 Jul 2017, 17:26, edited 1 time in total.
User avatar
jeeswg
Posts: 2650
Joined: 19 Dec 2016, 01:58
Location: UK

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 17:23

In my Acc script for invert selection (no WM_COMMAND), I do this:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



These lines wait for a context menu to appear, and then click an item:
WinWait, ahk_class #32768
WinGet, hWnd, ID, ahk_class #32768

I would have thought that you could use that to get the context menu hWnd, once it's visible, and then invoke a menu item.
sancarn
Posts: 189
Joined: 01 Mar 2016, 14:52

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 17:48

jeeswg wrote:These lines wait for a context menu to appear, and then click an item:
WinWait, ahk_class #32768
WinGet, hWnd, ID, ahk_class #32768
I would have thought that you could use that to get the context menu hWnd, once it's visible, and then invoke a menu item.


Hey, I completely forgot that context menus had the class #32768! That does work well, although I worry somewhat that there may be multiple windows with the class #32768.
sancarn
Posts: 189
Joined: 01 Mar 2016, 14:52

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 17:50

qwerty12 wrote:I can't give a concrete example (the code I have currently to do this is a mess, and decoupling it would take me too much time), but you can shove a MsgBox in this to see if the context menu you speak of is detected by the event hook (and if so, read the forum post linked to find out what to do next):


Thanks qwerty12, I will give this a go as i think it will have more stable results.

Edit:

Also works like a charm! I think I will settle with this option.
Last edited by sancarn on 16 Jul 2017, 17:55, edited 1 time in total.
User avatar
jeeswg
Posts: 2650
Joined: 19 Dec 2016, 01:58
Location: UK

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 17:51

The PID and process name/path will match the process, you can add these to the window criteria (in the WinWait and WinGet lines). Also, you can use Acc to confirm the text of the menu items.
sancarn
Posts: 189
Joined: 01 Mar 2016, 14:52

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 17:57

jeeswg wrote:The PID and process name/path will match the process, you can add these to the window criteria (in the WinWait and WinGet lines). Also, you can use Acc to confirm the text of the menu items.


My worry really is that the program might have 2 menus open with the same window class... If that case does arise there would be no way to get the other window if the found window is incorrect... right?
User avatar
jeeswg
Posts: 2650
Joined: 19 Dec 2016, 01:58
Location: UK

Re: ACC.AHK - Get IAccessible for Context menu

16 Jul 2017, 18:24

You'd just list the windows, and check for the right one:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



If anyone can find a common program that can have 2 context menus open at the same time, I would like to know, to test/to see if it's possible.
sancarn
Posts: 189
Joined: 01 Mar 2016, 14:52

Re: ACC.AHK - Get IAccessible for Context menu

17 Jul 2017, 14:53

jeeswg wrote:If anyone can find a common program that can have 2 context menus open at the same time, I would like to know, to test/to see if it's possible.


I'm quite certain 1 program can't have 2 context menus, but context menus aren't the only windows that I have seen which use the class #32768. So I wouldn't be surprised if you could have more than 1 of these, though I haven't got an explicit example either.
User avatar
jeeswg
Posts: 2650
Joined: 19 Dec 2016, 01:58
Location: UK

Re: ACC.AHK - Get IAccessible for Context menu

17 Jul 2017, 15:14

Well from experience:
context menus: #32768
ComboBox drop-down menus: #32769
dialog windows (and tab controls): #32770

This link doesn't say too much:
About Window Classes (Windows)
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx
#32768 The class for a menu.
#32769 The class for the desktop window.
#32770 The class for a dialog box.
#32771 The class for the task switch window.
#32772 The class for icon titles.

If anyone has anything to add. Thanks.
sancarn
Posts: 189
Joined: 01 Mar 2016, 14:52

Re: ACC.AHK - Get IAccessible for Context menu

18 Jul 2017, 07:07

jeeswg wrote:Well from experience:
context menus: #32768
ComboBox drop-down menus: #32769
dialog windows (and tab controls): #32770

This link doesn't say too much:
About Window Classes (Windows)
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx
#32768 The class for a menu.
#32769 The class for the desktop window.
#32770 The class for a dialog box.
#32771 The class for the task switch window.
#32772 The class for icon titles.

If anyone has anything to add. Thanks.


Oh... Perhaps I am mistaken then! I didn't realize there were other #.... classes, so that may explain it.
sancarn
Posts: 189
Joined: 01 Mar 2016, 14:52

Re: ACC.AHK - Get IAccessible for Context menu

18 Jul 2017, 07:13

Related to the OP:

Supposedly this also works to get a handle of the context menu:

Code: [Select all] [Download] GeSHi © Codebox Plus

FindWindowEx( NULL, NULL, MAKEINTATOM(0x8000), NULL );


Edit:

Apparently the application who the context menu belongs to can execute this to retrieve the HWND of that menu, but not any arbitrary application.

Return to “Ask For Help”

Who is online

Users browsing this forum: Albireo, chngrcn, Delta Pythagorean, Hyouka, Meany, Odlanir, Rohwedder and 76 guests