PostMessage WM_KEYDOWN send multiply keys?

13,338

Solution 1

You can't simulate keyboard input with PostMessage, at least not reliably use SendInput instead.

Solution 2

I have tried this so many times and it's hit or miss if it works. What you want to do is try to use WM_SYSKEYDOWN instead of WM_KEYDOWN for "system" type keys. This also means you have to use WM_SYSKEYUP. Something like this might work:

PostMessage(proc.MainWindowHandle, WM_SYSKEYDOWN, VK_CONTROL, 0); 
PostMessage(proc.MainWindowHandle, WM_SYSKEYDOWN, VK_ALT, 0); 
PostMessage(proc.MainWindowHandle, WM_KEYDOWN, VK_RIGHT, 0); 
PostMessage(proc.MainWindowHandle, WM_SYSKEYUP, VK_ALT, 0); 
PostMessage(proc.MainWindowHandle, WM_SYSKEYUP, VK_CONTROL, 0); 

Update:

I've it only to simulate key presses for single keys, it works great even for minimized applications :). When using it as a combination key for "shift" states is where it's hit or miss. The problem is most windows applications have a control and each control has it's on handle so sending a key to the window doesn't have the desired affect, you have to send ALT+S to the "Menu" handle to make a file save (in say Notepad), which also works.

Share:
13,338

Related videos on Youtube

Danpe
Author by

Danpe

Check out GlobeKeeper.

Updated on June 04, 2022

Comments

  • Danpe
    Danpe almost 2 years

    I have this code:

        public static void Next()
        {
            Process[] processes = Process.GetProcessesByName("test");
    
            foreach (Process proc in processes)
                PostMessage(proc.MainWindowHandle, WM_KEYDOWN, VK_RIGHT, 0);
        }
    

    This code sents the Right Arrow key, i want to sent ALT+CTRL+RIGHT i tried this:

        public static void Forward()
        {
            Process[] processes = Process.GetProcessesByName("test");
    
            foreach (Process proc in processes)
            {
                PostMessage(proc.MainWindowHandle, WM_KEYDOWN, VK_CONTROL, 0);
                PostMessage(proc.MainWindowHandle, WM_KEYDOWN, VK_ALT, 0);
                PostMessage(proc.MainWindowHandle, WM_KEYDOWN, VK_RIGHT, 0);
            }
        }
    

    But it doesn't work...

    Any ideas?

  • David Heffernan
    David Heffernan over 12 years
    +1 I corrected your link. Obviously you meant it to point to one of Raymond's articles.
  • David Heffernan
    David Heffernan over 12 years
    Yeah, it's not going to. Use SendInput, or, even better, UI Automation.
  • shf301
    shf301 over 12 years
    No there's no workaround - maybe UI Automation (if the client app supports it) - msdn.microsoft.com/en-us/library/ms747327.aspx
  • Erik Philips
    Erik Philips over 4 years
    @DavidHeffernan Sometimes SendInput is not a valid solution if you're trying send keys to the non-active window.
  • David Heffernan
    David Heffernan over 4 years
    You can't reliably fake input to a window unless it has input focus. You can reliably fake input to a window with input focus. So, I guess it all depends on whether or not you want something that works.