-2

I am trying to send keys combination to another program like that:

// keydown ctrl
SendMessage(windowBracketsKeyListener, 0x100, (IntPtr)VK_CONTROL, (IntPtr)0x001D0001); 
// keydown S
SendMessage(windowBracketsKeyListener, 0x100, (IntPtr)VK_S, (IntPtr)0x001F0001); 
SendMessage(windowBracketsKeyListener, 0x102, (IntPtr)115, (IntPtr)0); 
// keyup ctrl 
SendMessage(windowBracketsKeyListener, 0x101, (IntPtr)VK_CONTROL, (IntPtr)0xC01D0001); 

To the last line I have an error (look at the image below).

I send the same commands as in Spy++. So firstly I automatically tried to click CTRL+S on a window then checked what I get in Spy++ and wrote the same commands.

Error:

System.OverflowException: 'Arithmetic operation resulted in an overflow.'
  • Okay, I use not Spy++, but Window Detective to be honest.

Image with my commands, commands from Window Detective and received error

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • C# hexadecimal literals are signed, which can cause sign bit problems. You might want a `u` suffix on the hex value, or else `(IntPtr)unchecked { (uint) 0xhexvalue }` to make sure that sign-extension does not kick in. – Ben Voigt May 27 '20 at 16:49
  • That 3rd line looks suspect. Are you trying to send a keyup for S? You comments in the image don't match what you are calling. Don't you want to do: keydown ctrl, keydown s, keyup s, keyup ctrl? The full exception and stack track would be useful. – shox May 27 '20 at 16:58
  • @BenVoigt , I am not sure that understand you correct. When I don't convert to IntPtr I get an error: "cannot convert from 'uint' to 'System.IntPtr'" – Eugenio Uglov May 27 '20 at 17:03
  • @shox , code on image is dirty. second and third lines there to send "s" key. And "s" key is sending without problem. As you see on Window Detective the same, but I get error on 4th line. – Eugenio Uglov May 27 '20 at 17:10
  • Isn't dec 102 the F4 key? Looks like you might not want the S keydown but rather send the character. See this: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/6424df9e-514c-405a-89c3-f88b979be41d/how-can-i-preform-a-simulation-of-a-key-pressclick-using-send-message-?forum=csharpgeneral . Just because the error is on that line doesn't mean it's not the previous line that is at fault. Again, add your stack trace. Having a commet that says "keyup ctrl" that is keydown of a different button is not good. Don't use any comments if you are going to have them wrong – shox May 27 '20 at 17:19
  • @shox , Okay. I tried code from those site. But when I executed I get symbol "<" in editor. Code which I used: [System.ComponentModel.TypeConverter(typeof(System.Windows.Forms.KeysConverter))] [System.Flags] [System.Runtime.InteropServices.ComVisible(true)] public enum Keys { ControlKey = 118, S = 62 } public void Combination(IntPtr handle) { SendMessage(handle, WM_KEYDOWN, (int)Keys.ControlKey, 0); SendMessage(handle, WM_CHAR, (int)Keys.S, 0); SendMessage(handle, WM_KEYUP, (int)Keys.ControlKey, 0); } – Eugenio Uglov May 27 '20 at 18:10
  • In "the" editor? In VS, in chrome? What does windows detective show? – shox May 27 '20 at 18:45
  • @shox , Editor - Visual Studio. In detective: keydown - VK_F7, keyup - return value = 0 – Eugenio Uglov May 27 '20 at 19:08
  • 2
    [You can't simulate keyboard input with PostMessage](https://devblogs.microsoft.com/oldnewthing/20050530-11/?p=35513) (or SendMessage()) – Remy Lebeau May 27 '20 at 21:15

1 Answers1

1

There is not much point in faking the WM_KEYDOWN/WM_KEYUP messsages, only send the message they generated. Just the two WM_CHAR messages.

Please use SendKeys.Send(String) Method instead.

To specify that any combination of SHIFT, CTRL, and ALT should be held down while several other keys are pressed, enclose the code for those keys in parentheses. For example, to specify to hold down SHIFT while E and C are pressed, use "+(EC)". To specify to hold down SHIFT while E is pressed, followed by C without SHIFT, use "+EC".

The following sample works for me:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Test
{
    static class Program
    {
        [DllImport("user32.dll")]
        public static extern int SetForegroundWindow(IntPtr hWnd);
        static void Main()
        {

            Process[] processes = Process.GetProcessesByName("notepad"); //notepad used be test

            foreach (Process proc in processes)
            {
                SetForegroundWindow(proc.MainWindowHandle);
                SendKeys.SendWait("^(s)");
            }
        }
    }
}
Strive Sun
  • 5,988
  • 1
  • 9
  • 26