Возможный дубликат:
C# и SendMessage (ключи) не работает
Я пишу приложение, которое отправляет нажатия клавиш другому приложению, используя функцию SendMessage, определенную в user32.dll. Я понял, как отправить одно нажатие клавиши, но я в тупике, пытаясь отправить нажатие клавиши вместе с клавишей ALT.
Для целей моего вопроса я сосредоточусь на отправке F1 и ALT + F1.
Как указано выше, я могу отправить клавишу F1 без проблем. Вот фрагмент моего кода, который отправляет клавишу F1:
// DLL Imports
//Set the active window
[DllImport("user32.dll")]
public static extern IntPtr SetActiveWindow(IntPtr hWnd);
//sends a windows message to the specified window
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, uint wParam, uint lParam);
// ...
// Some constants
#define WM_SYSKEYDOWN 260
#define WM_SYSKEYUP 261
#define WM_CHAR 258
#define WM_KEYDOWN 256
#define WM_KEYUP 257
// ...
// activate the window and send F1
SetActiveWindow(hWnd);
ushort action = (ushort)WM_SYSKEYDOWN;
ushort key = (ushort)System.Windows.Forms.Keys.F1;
SendMessage(hWnd, action, key, 0);
Одно интересное замечание заключается в том, что хотя приведенный выше код работает при отправке клавиши F1 целевому приложению, он отличается от того, что я вижу при использовании Spy++. Вот вывод журнала Spy++ всякий раз, когда я нажимаю клавишу F1 во время мониторинга целевого приложения:
<00001> 00050412 P WM_KEYDOWN nVirtKey:VK_F1 cRepeat:1 ScanCode:3B fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00002> 00050412 P WM_KEYUP nVirtKey:VK_F1 cRepeat:1 ScanCode:3B fExtended:0 fAltDown:0 fRepeat:1 fUp:1
Обратите внимание, что отправлено два сообщения: WM_KEYDOWN и WM_KEYUP.
Мой первый вопрос: почему я успешно отправляю F1 с помощью WM_SYSKEYDOWN, когда Spy++ говорит мне, что WM_KEYDOWN + WM_KEYUP — это правильная последовательность сообщений?
Переходя к моей следующей задаче по отправке ALT + F1.
Я использовал Spy++ для мониторинга сообщений, передаваемых при нажатии ALT + F1 на клавиатуре, и вот что я вижу:
<00001> 00050412 P WM_SYSKEYDOWN nVirtKey:VK_MENU cRepeat:1 ScanCode:38 fExtended:1 fAltDown:1 fRepeat:0 fUp:0
<00002> 00050412 P WM_SYSKEYDOWN nVirtKey:VK_F1 cRepeat:1 ScanCode:3B fExtended:0 fAltDown:1 fRepeat:0 fUp:0
<00003> 00050412 P WM_SYSKEYUP nVirtKey:VK_F1 cRepeat:1 ScanCode:3B fExtended:0 fAltDown:1 fRepeat:1 fUp:1
<00004> 00050412 P WM_KEYUP nVirtKey:VK_MENU cRepeat:1 ScanCode:38 fExtended:1 fAltDown:0 fRepeat:1 fUp:1
Учитывая приведенный выше захват сообщения Spy++, я попытался отправить точную последовательность сообщений, используя следующий код (упрощенный):
SetActiveWindow(hWnd);
SendMessage(hWnd, (ushort)WM_SYSKEYDOWN, (ushort)System.Windows.Forms.Keys.Menu, 0);
SendMessage(hWnd, (ushort)WM_SYSKEYDOWN, (ushort)System.Windows.Forms.Keys.F1, 0);
SendMessage(hWnd, (ushort)WM_SYSKEYUP, (ushort)System.Windows.Forms.Keys.F1, 0);
SendMessage(hWnd, (ushort)WM_KEYUP, (ushort)System.Windows.Forms.Keys.Menu, 0);
Это не сработало.
И это приводит к моему следующему вопросу. Есть ли что-нибудь еще, что я могу попробовать, или я что-то делаю не так?
Всякий раз, когда я перехватывал вывод своей программы с помощью Spy++, вот что было записано:
<00001> 00050412 S WM_SYSKEYDOWN nVirtKey:VK_MENU cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00002> 00050412 R WM_SYSKEYDOWN
<00003> 00050412 S WM_SYSKEYDOWN nVirtKey:VK_F1 cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00004> 00050412 R WM_SYSKEYDOWN
<00005> 00050412 S WM_SYSKEYUP nVirtKey:VK_F1 cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00006> 00050412 R WM_SYSKEYUP
<00007> 00050412 S WM_KEYUP nVirtKey:VK_MENU cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00008> 00050412 R WM_KEYUP
Обратите внимание, что в строках 2, 4, 6 и 8 отправляются лишние сообщения. Может ли это быть причиной того, что что-то не работает?
У меня есть последний вопрос относительно разницы между сообщениями, полученными при фактическом вводе с клавиатуры, и сообщениями, полученными с помощью моего приложения. Обратите внимание на cRepeat, ScanCode, fExtended и т. д. аргументы. Они отличны от нуля в сообщениях, которые были захвачены с помощью моей клавиатуры в качестве ввода, и все они равны нулю в сообщениях, отправленных моим приложением. Может ли это быть причиной того, что мой код не работает? Если да, то как мне изменить эти значения? (я предполагаю, что они поступают из 4-го аргумента функции SendMessage , который я установил равным нулю во всех случаях.)
Спасибо,
Ян