0

i have work on an app that manipulate some application context menue to extend its functions, i have checked all the common posts here on stackOverFlow on how to manipulate the menu context using Windows api in C# using functions like GetMenu(...), InsertMenuItem(...), ShowOwnedPopups(...) and that comes in vain, here is the scenario, the application i wanna manipulate it context menu has many context menus in many parts but i want to manipulate certain one which belongs to the viewer part. so i have used spy++ to figure the the handle of the viewer and a send a message WM_CONTEXTMENU using SendMessage(...) function. the menu finally appears and i have its handle.

getting the handle after sending a message

i guess after i get the handle it would be constant for the life time of the program for the single running time, but i figured out that the handle is changing every single time a i have clicked right click. and the parent of the context menu isn't the viewer area itself but the desktop that's was disappointing.

The handle is changing and the parent of the context is the desktop window itself

so i have two problems

1- i can't get the handle directly as using GetMenu(...) passing the handle of the viewer returns null, after some search if found that the context menu has a class name of "#32768" so i have filtered all the open windows to get the one that its class name equlas "#32768". and now i can access the handle from my c# code not from the spy. but here is an comming issue: if there is a sub menue.. it also have the same class and unfortunately this is totally logical :/

the parent and the child have the same class name

2- i can't get the context handle before it is shown and if it is shown, i can't manipulate it as i know. The second thing is that the context handle continuously changes every single time i right click the mouse. so i can't pass the first time i click then save the handle for the next clicks to make it work.

any suggestion are very welcomed.

  • You might have luck by subclassing (in the WIn32 API sense) the application's window and handling WM_CONTEXTMENU and maybe WM_RBUTTONUP in your subclassed WndProc. Whether this works depends on the application's implementation. – Klaus Gütter Jan 03 '23 at 13:08

1 Answers1

0

First of all you should figure out if you can just send it a WM_COMMAND message to perform your command. A context menu might not use that message but if the application also has a normal menu then it is likely that it will handle the message. Note that the command id might change between program versions.

All Win32 HMENU menus use the same class and MN_GETHMENU is the only related documented message.

The recommended solution is to use UI Automation/MSAA to navigate the UI of other applications.

Anders
  • 97,548
  • 12
  • 110
  • 164
  • thanks for your contribution but i actually want to add an item to end of the context menu. not just navigate elements and automate them. the application i target is Revit which have an API which allow adding buttons and panels to its ribbon bar, asking them what about the right click menu context, they answered "there is no ability using the API but you can surly use windows api functions.", so i had my search and ask for help from windows api experts – Ahmad Eltobshy Jan 03 '23 at 18:39
  • 1
    Then just call `AppendMenu` on the HMENU. If they are not using `TPM_RETURNCMD` then subclass the window passed to `TrackPopupMenu[Ex]` to catch `WM_COMMAND`. Otherwise I'm afraid you have to hook TrackPopupMenu with something like MS Detours. – Anders Jan 03 '23 at 20:16
  • Thanks a lot i will search for that – Ahmad Eltobshy Jan 03 '23 at 22:20