1

I'm trying to replicate a CTRL + UP ARROW message but it's like ignoring the CTRL key, the result is like only sending UP ARROW, without sending CTRL

This is how the Spy++ results looks: enter image description here

CTRL KEYDOWN:

enter image description here

UP ARROW KEYDOWN:

enter image description here

UP ARROW KEYUP:

enter image description here

CTRL KEYUP:

enter image description here

This is the code I'm using:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, uint lParam);

SendMessage(whandle, 0x100, 0x00000011, 0x011D0001);
SendMessage(whandle, 0x100, 0x00000026, 0x01480001);
SendMessage(whandle, 0x101, 0x00000026, 0xC1480001);
SendMessage(whandle, 0x101, 0x00000011, 0xC11D0001);

I've changed this SendMessage signature to accept KEYUP lParams:

private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, uint lParam);

Maybe the signature is wrong? I don't really know what I'm missing

I can't use SendKeys or any method that requires setting the window in front, it must work in background, neither SetKeyBoardState that could affect to other programs running

EDIT:

Tested with PostMessage and I get the same results, CTRL key is ignored

PostMessage(whandle, 0x100, 0x00000011, 0x011D0001);
PostMessage(whandle, 0x100, 0x00000026, 0x01480001);
PostMessage(whandle, 0x101, 0x00000026, 0xC1480001);
PostMessage(whandle, 0x101, 0x00000011, 0xC11D0001);
kuhi
  • 531
  • 5
  • 23
  • Have you tried using [PostMessage](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagea) instead of SendMessage? – schgab Mar 27 '20 at 11:50
  • Same result, just tested and it's ignoring CTRL key – kuhi Mar 27 '20 at 16:44
  • Maybe try increasing the count of KeyDowns send. Try 0x011D0050 instead of 0x011D0001. Basically you do the same when you hold down the key by yourself. BTW those are just some wild guesses. – schgab Mar 27 '20 at 16:54
  • Notorious fail, the code only *pretends* that the CTRL key is down. But it isn't actually down. So if the client code that processes the VK_UP notification checks the modifier key state then it will conclude that CTRL is not down. SendInput() required. – Hans Passant Mar 27 '20 at 17:05
  • But SendInput() need the window to be focus? Because I need it to work in background – kuhi Mar 27 '20 at 20:18
  • just for the sake of comparison, did you try to use SendKeys with `^{UP}`? https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys.send – DoronG Mar 31 '20 at 13:34
  • Yes, SendKeys it's working but I need it to run in background – kuhi Mar 31 '20 at 17:23

2 Answers2

1

Using SendMessage (or PostMessage) you cannot simulate the state of the modifiers keys, like e.g. CTRL. You have to use SendInput instead. [1] [2]

However, using SendInput you are only able to send keys to the active window. So, if sending to a minimized/background window is a strict requirement, I fear that what you are trying to do is not possible. [2] [3]

If you can change your requirement and sending the key strokes to the active window is enough, or you can temporary pull the window you want to send the key strokes to to the foreground, you might consider using the Input Simulator library.

Sources:
[1] https://stackoverflow.com/a/5145435/2498301
[2] How to send Ctrl/Shift/Alt + Key combinations to an application window? (via SendMessage)
[3] https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput

Lukas Makor
  • 1,947
  • 2
  • 17
  • 24
0

I've just solved similar issue (using non managed C++) however i am sending keystroke to DOS window and by one key not 2 or more simultaneously, you could see original issue here: How to send keyboard input to dos application running in window mode in Windows98

I have used many approaches: SendMessage, SendInput and VxD driver, i also solved issue with activating window before sending keystroke, you could find project on github - https://github.com/MossbauerLab/Sm2201Autosave. in MossbauerLab.Sm2201.ExtSaveUtility/src/saveManager you could find method:

void activateWindow(HWND window);

I am using executable name and window name to search HWND (see MossbauerLab.Sm2201.ExtSaveUtility/src/utils/windows/windowsInfo.h) Most of classes were tested with MS tests (managed C++), test project is also in this repo: MossbauerLab.Sm2201.ExtSaveUtility.Tests

Maybe it could be helpful for you

Michael Ushakov
  • 1,639
  • 1
  • 10
  • 18