3
votes

In most applications, when you click some MenuItem, a WindowsMessage is sent (usually WM_COMMAND), with a wParam representing the ID of the chosen MenuItem.

There is a certain program that has a Window Menu (the menu accessible via clicking the program's icon on the title-bar),
and I want to find what is the WindowsMessage that is sent when I choose a specific MenuItem from that Menu.

The program is soething you all know - the Command Prompt window, in Windows XP: (cmd.exe)

And here is the Window Menu:

I want to capture the WindowsMessage and wParam for a MenuItem there,
for example the "Paste" MenuItem.
(but not just it.. any other might be as well)

Here is what I tried:

Method 1:

The first method I always try is to use Spy++.
The problem is that when I try to Log Messages for this specific program (the DOS window), Spy++ gives me this messagebox:

For some reason Spy++ won't capture WindowsMessages for this program.

So I went on to the second method that I use..

Method 2:

Resource Hacker (ResHacker.exe) is also good for finding the WindowsMessage that is sent from clicked MenuItems, and it does it quite easily.

If you run Resource Hacker, and then Open some EXE file with it,
you usually see these trees, which one of them is called "Menu",
and it contains all the details including the wParam:

The problem is, that when I try to use Resource Hacker on cmd.exe,
I get this:

As it can be seen, no "Menu" tree there.

My question:

Are there other ways, in addition to the 2 methods that I usually use,
that can be used to find the WindowsMessage (and wParam) that is sent for the "Paste" MenuItem in the Window Menu of the DOS window?

1
Is your goal to send a window message or to paste text in a console window? You seem to be focussing a lot of effort on the first of these, but if the actual goal is the second, please make that clear.Damien_The_Unbeliever
Hi Damien. Actually you raise a good point. I have 2 goals here: The first, is to generate a Paste operation, in whatever way possible. Note that I know it can also be done in another way besides the Window Menu, which is via RightClicking the window, yet this specific way will not be good for me, since I don't want the mouse to move in order to achieve it. The second goal, is to learn additional ways for intercepting WindowsMessages, besides the 2 methods that I already know (and specified in the question). So there are 2 goals to this question.. :)spaceman
This is going to be difficult on Windows XP because the console runs in csrss, which is very high privilege. Even if you figure out the message number, you won't be able to send it. Consider using accessibility interfaces instead.Raymond Chen
Hi Raymond. Regarding "Even if you figure out the message number, you won't be able to send it" - this is not correct, I managed to cause a Paste operation via doing SendMessage() simulating a mouse RightClick. (on that window, RightClicking anywhere on the window, causes a Paste operation). It succeeded.. So it means I am able to use SendMessage() on that window. Now the only question is how to get the IDs for the other MenuItems..spaceman

1 Answers

2
votes

0xfff1 is the wParam, so in C# (you didn't specify the language you were using, but it should be easy enough to translate it):

[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, uint lParam);
public const int WM_KEYDOWN = 0x01000;
void PasteInCommandPrompt(IntPtr hWnd)
{
    SendMessage(handle, WM_COMMAND, 0xfff1, 0);
}

http://blogs.msdn.com/b/bill/archive/2012/06/09/programmatically-paste-clipboard-text-to-a-cmd-window-c-or-c.aspx


Edit: 22 September 2019

In the comments of Console window - programmatic command code (wParam of WM_COMMAND) (a question where a user was using the above link to Bill Lin's blog, but having trouble getting it working), @eryksun gave me the idea of looking for a ConvhostV2.dll.mui to find the all available menu commands. I couldn't find ConvhostV2.dll.mui...

But on my system I found C:\Windows\System32\en-US\ConhostV1.dll.mui, which when viewed with Resource Hacker (as @spaceman tried with cmd.exe), contains all the menu items available for cmd.exe.

The complete list of commands cmd.exe has are:

  • 0xfff0: Copy
  • 0xfff1: Paste
  • 0xfff2: Mark
  • 0xfff3: Scroll
  • 0xfff4: Find
  • 0xfff5: Select all

Besides paste (which allows you to execute arbitrary commands), select all and copy are very useful, as they let you get console output (albeit, stripping all virtual terminal sequences, the characters that specify text color).

If you are going deep into the route of manipulating command windows you may also be interested in the new "Windows Pseudo Console", which can let you have full control over cmd.exe, or any command line based application. See https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/ .