I can't figure out how to use SendMessage or PostMessage calls

I need to simulate a keystroke in a third-party application. Say I have a C # application that needs to send "8" to the Calculator application. I can not use SendKeys.Net or keybd_event win32 api because they both require the window to be the most active, which is not the case in my situation.

So this leaves me with calls to sendMessage and postMessage. I tried for the past three hours to try to get some results, but now I am completely hopeless.

I have the following:

[DllImport("user32.dll")] public static extern int FindWindow(string lpClassName,string lpWindowName); [DllImport("user32.dll")] public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam); [return: MarshalAs(UnmanagedType.Bool)] [DllImport("user32.dll", SetLastError = true)] public static extern bool PostMessage(int hWnd, uint Msg, int wParam, int lParam); private void button1_Click(object sender, EventArgs e) { const int WM_KEYDOWN = 0x100; const int WM_SYSCOMMAND = 0x018; const int SC_CLOSE = 0x053; int WindowToFind = FindWindow(null,"Calculator"); int result = SendMessage(WindowToFind, WM_SYSCOMMAND, SC_CLOSE, 0); Boolean result2 = PostMessage(WindowToFind, WM_SYSCOMMAND, SC_CLOSE, 0); int result3 = SendMessage(WindowToFind, WM_KEYDOWN,((int)Keys.NumPad7), 0); Boolean result4 = PostMessage(WindowToFind, WM_KEYDOWN, ((int)Keys.NumPad7), 0); } 

As you can see, I am making four attempts to contact the Calculator. Using sendMessage and PostMessage to close the window, as well as to send the key 7. Nothing works. The FindWindow method works because I get the application handler (I even tried to start the process itself and access it using process.MainWindowHandler, but no luck). There are no errors or exceptions, but nothing is done in the calculator.

I also tried the same with a notebook, and nothing has changed.

+6
c # handler keypress sendmessage postmessage
source share
4 answers

Is it likely that you are running this on a 64-bit machine? If so, I believe that all those int values ​​that are actually hWnds (the first Send / Post argument, the return value from FindWindow) should be IntPtr.


After a bit of additional verification, this looks like for SendMessage and PostMessage, the 1st, 3rd and 4th parameters should be IntPtr instead of int (as well as return values ​​for all)

So, the correct signatures will be:

 [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName,string lpWindowName); [DllImport("user32.dll")] public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 
+11
source share

CodeProject has a good article on this: http://www.codeproject.com/KB/cs/SendKeys.aspx

SendKeys is actually the right idea, but you need to get the HWND (window handle) of the target window. This MSDN example shows how to use SendKeys effectively, but not how to detect the HWND of everything except the topmost window.

Combine the two methods using the CodeProject example to find the HWND of the application you want to target, and then use the MSDN article to use SendKeys to send keystrokes (or mouse events) to the target application.

+3
source share

Your question is directly, but the difference between SendMessage and PostMessage is that Send is a blocking call, Post returns immediately (before the receiving application has processed it).

MSDN explains the difference: http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx

Also, if you are on Vista, but not on .NET 3.0, this could also be a problem:

The SendKeys class has been updated for the .NET Framework 3.0 to include it in applications running on Windows Vista. The enhanced security of Windows Vista (known as User Account Control or UAC) prevents the previous implementation from working as expected.

+2
source share

Because this is the Edit Child window inside the notepad window. You must send messages to the appropriate child window. This is a working example in C:

 #include <windows.h> #include <stdio.h> void main(void) { STARTUPINFO si; PROCESS_INFORMATION pi; HWND mainwnd,editwnd; char c; si.cb=sizeof(si); si.lpReserved=NULL; si.lpDesktop=NULL; si.lpTitle=NULL; si.dwFlags=0; si.cbReserved2=0; si.lpReserved2=NULL; if(!CreateProcess("c:\\windows\\notepad.exe",NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) { printf("Failed to run app"); return; } WaitForInputIdle(pi.hProcess,INFINITE); mainwnd=FindWindow(NULL,"Untitled - Notepad"); if(!mainwnd) { printf("Main window not found"); return; } editwnd=FindWindowEx(mainwnd,NULL,"Edit",""); if(!editwnd) { printf("Edit window not found"); return; } for(c='1';c<='9';c++) { PostMessage(editwnd,WM_CHAR,c,1); Sleep(100); } } 
+1
source share

All Articles