Link to home
Start Free TrialLog in
Avatar of l4zarus
l4zarusFlag for United States of America

asked on

C# SendMessage Keypress

I've been trying to send keypresses to another application using SendMessage in C#. So far I've gotten absolutely no results from it. I've tried sending different combinations of these functions to different applications with no luck.
ex)
SendKey("Untitled - Notepad", Keys.A);
#region Function Imports
 
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
 
        [DllImport("user32.dll")]
        static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
 
        #endregion
 
        #region Constants
 
        // Messages
        const int WM_KEYDOWN = 0x100;
        const int WM_KEYUP = 0x101;
        const int WM_CHAR = 0x105;
        const int WM_SYSKEYDOWN = 0x104;
        const int WM_SYSKEYUP = 0x105;
 
        #endregion
 
        public static void SendKey(string wName, Keys key)
        {
            IntPtr hWnd = FindWindow(null, wName);
 
            SendMessage(hWnd, WM_KEYDOWN, Convert.ToInt32(key), 0);
            SendMessage(hWnd, WM_KEYUP, Convert.ToInt32(key), 0);
        }
 
        public static void SendSysKey(string wName, Keys key)
        {
            IntPtr hWnd = FindWindow(null, wName);
 
            SendMessage(hWnd, WM_SYSKEYDOWN, Convert.ToInt32(key), 0);
            SendMessage(hWnd, WM_SYSKEYUP, Convert.ToInt32(key), 0);
        }
 
        public static void SendChar(string wName, char c)
        {
            IntPtr hWnd = FindWindow(null, wName);
 
            SendMessage(hWnd, WM_CHAR, (int)c, 0);
        }

Open in new window

Avatar of Dirk Haest
Dirk Haest
Flag of Belgium image

Are you sure that hWnd contains a value ?

To use SendMessage() you have to retrieve the window handle hWnd of the application you want to talk to.
In fact I would try the following:
Use FindWindow() or FindWindowEx() API to retrieve the hWnd,
then, before any usage of SendKey() you set the focus to the app, using SendMessage()

Const WM_SETFOCUS As Long = &H7
  dim hWnd as Long
  hWnd = FindWindow("", "your window title")
  If hWnd then SendMessage hWnd, WM_SETFOCUS, 0, 0

Open in new window

Avatar of l4zarus

ASKER

I'm fairly sure that hWnd is correct. I'm using notepad as a test.

            IntPtr hwnd = InputSender.FindWindow(null, "Untitled - Notepad");
            addText("Handle: " + hwnd.ToString());
            StringBuilder title = new StringBuilder(256);
            InputSender.GetWindowText(hwnd, title, 256);
            addText(title.ToString());

Outputs:

Handle: 4327520
Untitled - Notepad

...

WM_SETFOCUS (0x7) doesn't seem to be working either...
Avatar of l4zarus

ASKER

Okay. I just added in a GetLastError() right after the SendMessage and it gave me code 6 (ERROR_INVALID_HANDLE). Seems to be the problem after all. I'm not sure how to fix it though.
You must activate the application using SetForgroundWindow() not SetFocus().
http://msdn.microsoft.com/en-us/library/ms171548(VS.80).aspx
Yes, I'd imagine activating the app is the problem but thought I'd mention you can use the Spy utility to help diagnose this.  It can confirm the windows handle (compare it to what your program is trying to use) and it will display messages being sent.
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of l4zarus

ASKER

Working like a charm. One last thing.

If I wanted to send a combination (such as Shift+A or Alt+F4) how does that work. I thought all I had to do for alt+f4 was PostMessage(editWnd, 0x104, (int)Keys.F4, 0) but this didn't exit Notepad. Doing a keydown shift and then keydown A didn't make it a shift+A either :(
To be honest I don't know how to key combinations (or if it's even possible) with PostMessage().
for combos:
don't keyup the first key in the sequence until you keydown all you wish to be pressed