Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1576
  • Last Modified:

SendMessage & PostMessage does not work.

Hi,

I need to send various set of keycodes to an application. For this purpose, I use the following
code:

[NativeWin32.cs]
       ...
        [DllImport("user32.dll")]
        public static extern int FindWindow(
            string lpClassName, // class name 
            string lpWindowName // window name 
        );

        [DllImport("user32.dll", SetLastError = true)]
        public static extern int FindWindowEx(
            int parentHandle, 
            int childAfter, 
            string className, 
            int windowTitle
        );

        [DllImport("user32.dll")]
        public static extern int SendMessage(
            int hWnd, // handle to destination window 
            uint Msg, // message 
            int wParam, // first message parameter 
            int lParam // second message parameter 
        );
       ...

Open in new window


and

            int iHandle = NativeWin32.FindWindow(null, txtTitle.Text);
           // int cHandle = NativeWin32.FindWindowEx(iHandle, 0, null, 0); 

            MessageBox.Show("iHandle is " + iHandle.ToString()+" "+cHandle.ToString());

            NativeWin32.SetForegroundWindow(iHandle);
            
            string keys = "";
            string space = " ";

            //  WM_KEYDOWN = 0x0100
            // NativeWin32.BTN_LEFT = 0x025
            NativeWin32.SendMessage(iHandle, NativeWin32.WM_KEYDOWN, NativeWin32.BTN_LEFT, 0);

Open in new window

     
The problem is the fact that when I send this message to the application in question, nothing happens -- I exactly know that this application supports and listens these keycodes.

What I want to do is to send the following keys to the application:

- LEFT_ARROW
- RIGHT_ARROW
- UP / DOWN
- ENTER
- ESC
and etc.

Could you please check and tell me where I am wrong?

Thanks in advance.
0
akoyuncu
Asked:
akoyuncu
1 Solution
 
AndyAinscowCommented:
Have you actually checked (eg. Spy++) that the correct window is found?
You might have to send the WM_KEYUP message as well as the WM_KEYDOWN.


Also have a look at the SendInput function in help.  That is how one ought to synthesise keyboard events.
0
 
akoyuncuAuthor Commented:
Yes, I checked and verified that it finds the correct window.
Let me try WM_KEYUP
0
 
akoyuncuAuthor Commented:
Andy;

WM_KEYUP also does not work.

I did some modifications on my code as follows:

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(
            string lpClassName, // class name 
            string lpWindowName // window name 
        );

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(
            IntPtr parentHandle, 
            int childAfter, 
            string className,
            string windowTitle
        );

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool PostMessage(
            IntPtr hWnd, 
            uint Msg,
            IntPtr wParam,
            IntPtr lParam
        );


        [DllImport("user32.dll")]
        public static extern int SendMessage(
            IntPtr hWnd, // handle to destination window 
            uint Msg, // message 
            IntPtr wParam, // first message parameter 
            IntPtr lParam // second message parameter 
        );

        [DllImport("user32.dll")]
        public static extern int SetForegroundWindow(
            IntPtr hWnd // handle to window
            );

Open in new window


and I used POSTMESSAGE instead of SENDMESSAGE,

NativeWin32.PostMessage(iHandle, 0x0101, (IntPtr) Keys.Left, IntPtr.Zero);

Open in new window


But it doesn't work!
0
Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

 
AndyAinscowCommented:
PostMessage and SendMessage differ only in that PostMessage returns immediately, SendMessage waits until the message is processed.


(I've never tried to do what you are trying from a .net application)

Have you looked at the SendInput function - that is the recommended function to simulate keyboard events, not KEYDOWN/KEYUP messages.
0
 
akoyuncuAuthor Commented:
Andy;

I checked what SENDINPUT was but I didn't try. Do you have a sample code?
0
 
AndyAinscowCommented:
I've found this for .net apps - that might be more useful (you still need to set the recipient as foreground window before using this.


http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys%28vs.71%29.aspx
0
 
akoyuncuAuthor Commented:
I
ntPtr iHandle = NativeWin32.FindWindow(null, txtTitle.Text);
            IntPtr cHandle = NativeWin32.FindWindowEx(iHandle, 0, null, null);
 
            NativeWin32.SetForegroundWindow(cHandle);
 
           System.Windows.Forms.SendKeys.Send("{LEFT}");

Open in new window


This doesn't work :/
0
 
akoyuncuAuthor Commented:
Btw, System.Windows.Forms.SendKeys.Send works for other external
applictions, but this :(

There is one more service that controls this application.

What I want is to code the similar one.
0
 
AndyAinscowCommented:
OK.  SendKeys does work (at least for some apps), progress of sorts.

What are you wanting to send the keyboard input to?
0
 
akoyuncuAuthor Commented:
Andy;

- F10
- Keyboard (A, B, C, D, F, R, M, V, W)
- ESCAPE
- ENTER
- ARROWS (UP/DOWN/LEFT/RIGHT)
- HOME

On Spy++, I noticed that there are 4 sub windows:

Window (Container)
. Child Window (ATL class)
. Child Window (Shell Embedding)
... Child Window (Shell DocObject View)
...... Child Window (Internet Explorer_Server)
0
 
AndyAinscowCommented:
Maybe the window you want to be sending the keypresses to isn't the one with the focus.  Can you check that?
0
 
akoyuncuAuthor Commented:
Yes, I double check and did this:

            IntPtr iHandle = NativeWin32.FindWindow(null, txtTitle.Text);
            IntPtr cHandle = NativeWin32.FindWindowEx(iHandle, 0, null, null);
            IntPtr dHandle = NativeWin32.FindWindowEx(cHandle, 0, null, null);
            IntPtr eHandle = NativeWin32.FindWindowEx(dHandle, 0, null, null);
            IntPtr fHandle = NativeWin32.FindWindowEx(dHandle, 0, null, null);
            IntPtr gHandle = NativeWin32.FindWindowEx(fHandle, 0, null, null);

NativeWin32.SetForegroundWindow(cHandle);

           NativeWin32.PostMessage(cHandle, 0x0101, (IntPtr)(0X25), IntPtr.Zero);
           NativeWin32.PostMessage(cHandle, 0x0101, (IntPtr)(0X50), IntPtr.Zero);

           NativeWin32.PostMessage(dHandle, 0x0101, (IntPtr)(0X25), IntPtr.Zero);
           NativeWin32.PostMessage(dHandle, 0x0101, (IntPtr)(0X50), IntPtr.Zero);

           NativeWin32.PostMessage(eHandle, 0x0101, (IntPtr)(0X25), IntPtr.Zero);
           NativeWin32.PostMessage(eHandle, 0x0101, (IntPtr)(0X50), IntPtr.Zero);

           NativeWin32.PostMessage(fHandle, 0x0101, (IntPtr)(0X25), IntPtr.Zero);
           NativeWin32.PostMessage(fHandle, 0x0101, (IntPtr)(0X50), IntPtr.Zero);

           NativeWin32.PostMessage(gHandle, 0x0101, (IntPtr)(0X25), IntPtr.Zero);
           NativeWin32.PostMessage(gHandle, 0x0101, (IntPtr)(0X50), IntPtr.Zero);

Open in new window


No use...
0
 
AndyAinscowCommented:
Would the recipient window respond to normal text?  In other words could you send "abc123" or similar.  (Preferably with SendKeys or at least with PostMessage).

I just want to see, if possible, if it has something to do with sending non text keypresses.
0
 
akoyuncuAuthor Commented:
I sent "abc123" to two applications: Notepad and the other one.

Notepad: "abc123" appears on "Edit". No problem.

My application: no reaction.
0
 
AndyAinscowCommented:
Hmmm.
I suspect that the wrong window has the focus.  I'm stuck as to what to suggest you try.
0
 
AndyAinscowCommented:
Maybe
The GetForegroundWindow function returns a handle to the foreground window (the window with which the user is currently working). The system assigns a slightly higher priority to the thread that creates the foreground window than it does to other threads.

that could give you a cross check that the window you are sending to is in fact the one you think it is.
0
 
akoyuncuAuthor Commented:
Thank you for your support.

I will dig deeply into it and get back to you if I will find something.
0
 
akoyuncuAuthor Commented:
        [DllImportAttribute("User32.DLL")]
        public static extern IntPtr GetForegroundWindow();

Open in new window


I used. Returns the same handler.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I'd agree with Andy that you are not sending the message to the correct window.  Use Spy++ to watch each of the child windows and figure out which one actually processes the messages as keys are pressed.
0
 
nffvrxqgrcfqvvcCommented:
If the window that you really want is Internet Explorer_Server and you want to send text to it you can treat it like a normal IHTMLDocument2 interface even if it's hosted in a third party application.

How to get IHTMLDocument2 from a HWND
http://support.microsoft.com/kb/249232
0
 
akoyuncuAuthor Commented:
Let me tell you about the application:

This is a Windows application that has four windows:

1st layer is container.
2nd layer is control panel
3rd and 4th layers are to display video stream over Silverlight (that's why Internet Explorer Service) is used.

Yesterday, using Spy++, I track down the log messages and verified that 1st (or 2nd) layer receives the following:

WM_KEYDOWN, VK_RIGHT/LEFT/UP/DOWN/F11/ESCAPE
WM_CHAR, Char(23/27)

However, when I tried to send WM_KEYDOWN to 1st and 2nd layers nothing happens. Today, I will also test my code on other system and let you know about the result.
0
 
akoyuncuAuthor Commented:
Found!

I need to send keycodes to Microsoft Silverlight process.

Working now.

Thank you all for your help :)
0
 
akoyuncuAuthor Commented:
Thanks.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now