2

I am trying to shortcut the call to a procedure that is activated when clicking on a menu item.

I injected a DLL on the process that creates this window with the menu bar.

I used Spy++ from VisualStudio to obtain the Menu Identifier for this specific item (wid: 40003). Now I am calling

CallWindowProcW(wndproc, hwnd, WM_COMMAND, 40003, 0);

However, the item procedure is not triggered. I cannot call the procedure directly because I do not know what it is. I just know that when I click this menu it activates it.

I have obtained windproc and hwnd doing the following inside my DLL:

 void Init()
 {
     DWORD procID = GetProcessId(GetCurrentProcess());
     EnumWindows(myCallback, procID);
 }

 BOOL CALLBACK myCallback(HWND hWnd, LPARAM lParam)
 {
     DWORD wndId;

     GetWindowThreadProcessId(hWnd, &wndId);
     if(wndId == (DWORD)lParam) //Found the right window handle
     {
         WNDPROC windowFunc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC);
         LRESULT result = CallWindowProcW(windowFunc, hWnd, WM_COMMAND, 40003, 0);
         return FALSE;
     }
     return TRUE;
  }

EDIT: Have also tried SendMessageA, PostMessageA and DispatchMessageA and failed

EDIT2: See answer below for working PostMessageA.

1

I have identified the problem. It comes in two steps:

1. Use PostMessageA instead of CallWindowProc

PostMessageA(hWnd, WM_COMMAND, 40003, 0) does the heavy lifting and calls the WindowProc on the desired window.

2. Make sure that the Window is Top-Level

I had ignored this before because the application window was visible and I thought it was top-level.

However, since I am executing EnumWindows on the Init procedure of my injected dll, my launcher process was still running and the window was child of my launcher.

I had to wait for the launcher to quit, and then called EnumWindows and PostMessage.

0

I would like to have made this a comment but do not have enough points to do so so this would have been a comment on the answer.

Simply put, the topmost window in a windows environment receives the RawInputThread (RIT). The RIT automatically receives the mouse and keyboard messages and sends them to that window which is at the top of the Z order. Having done a lot of this stuff in the distant past, if you ever need to take total control, a trick that can be done is to implement a top most window (z order) window which covers the whole screen, RIT will give it all messages, and you do what you want with them.

Back when I was doing this there was little to no documentation on RIT but now you can find lots of documentation. I found this on MSDN Raw Input, but it looks like they are making it more complicated than it really needs to be. MSFT has done things over the years where they hide a topic, then clarify, then put the topic back into hiding. duckduckgo shows numerous hits and yielded a nice gem google didn't find on its first page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.