0

重複の可能性:
C#とSendMessage(キー)が機能していない

user32.dllで定義されているSendMessage関数を使用して、キーストロークを別のアプリケーションに送信するアプリケーションを作成しています。単一のキーストロークを送信する方法を理解しましたが、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++を使用して見たものと同じではありません。ターゲットアプリケーションの監視中にF1キーを押すたびに、Spy++ログが出力されます。

<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の2つであることに注意してください。

私の最初の質問は、Spy++がWM_KEYDOWN+ WM_KEYUPが適切なメッセージシーケンスであると私に言ったのに、なぜWM_SYSKEYDOWNを使用してF1を送信することに成功したのかということです。

ALT+F1を送信しようとする私の次の課題に移ります。

キーボードのALT+F1を押したときに渡されるメッセージを監視するために、Spy ++を使用しました。これは、次のように表示されます。

<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行目に余分なメッセージが送信されていることに注意してください。これが機能しない理由でしょうか。

実際のキーボード入力からキャプチャされたメッセージと、アプリケーションを使用してキャプチャされたメッセージの違いについて、最後に1つ質問があります。cRepeatScanCodefExtendedなどの引数に注意してください。キーボードを入力として使用してキャプチャされたメッセージではゼロ以外であり、アプリケーションによって送信されたメッセージではすべてゼロです。これが私のコードが機能しない理由でしょうか? もしそうなら、どうすればこれらの値を変更できますか?(これらは、すべての場合にゼロに設定したSendMessage関数の4番目の引数からのものであると想定しています。)

ありがとうございました、

1月

4

2 に答える 2

2

別の解決策。WM_SYSKEYDOWNのlparamに何も渡していないようです。それでも、ドキュメントは、ALTキーが押されたことを示すためにlparamのビット29を設定する必要があることを明確に示唆しています。

ushort action = (ushort)WM_SYSKEYDOWN;
ushort key = (ushort)System.Windows.Forms.Keys.F1;
uint lparam = (0x01 << 28);
SendMessage(hWnd, action, key, lparam);
于 2012-12-02T06:50:15.097 に答える
1

SendMessageとWM_SYSKEYDOWNはあなたが使いたいものではないと思います。代わりに、SendInput関数を使用してください。思い出すと、シミュレートするキーストロークごとに4つの入力を渡す可能性があります。Altキーの「ダウン」イベント用の1つ。対応するキーの別のダウンイベント。次に、それぞれに2つのアップイベント。

このようなコードを書かなければならなかったのは久しぶりですが、ドキュメントではVK_MENUが「alt」キーのコードであると示唆されていると思います。

于 2012-12-02T06:41:54.150 に答える