6

私は 2 つのアプリを持っています。1 つは隠しウィンドウ (「hW」)、もう 1 つはコンソール アプリ (「CA」) で、そこから hW にコマンドを送信することを想定しています。コンソール アプリで hW ハンドルを取得しています。ここに質問があります。実行中の場合:

PostMessage(hwnd, WM_QUIT, NULL, NULL);

すべて正常に動作し、メッセージが hW に到達してオフになります。

PostMessage(hwnd, WM_SETTEXT, NULL, (LPARAM)"texttext");

メッセージはハードウェアにまったく到達しません。Spy++ は、メッセージが hW に届かないことも示しています。それを防ぐ WM_SETTEXT に固有のものはありますか? 前もって感謝します。

わかった。ここで答えが見つかりましたhttp://cboard.cprogramming.com/windows-programming/72589-wm_settext-postmessage.html

API がスコープの問題から私を守ろうとしていることがわかりました。PostMessage()
WM_SETTEXT、またはその他のシステム定義メッセージで常に失敗します。
パラメータとしてのポインタ。
非同期メッセージングが欲しかったので....


PPS
また、次のように見えます

SendMessage(hwnd, WM_QUIT, NULL, NULL);

アプリをターゲットにすることは何もしません。

 HWND hNote;
 if (!(hNote=FindWindow(L"Notepad",NULL)))
        exit(1);
 SendMessage(hNote, WM_QUIT, NULL, NULL);

その間

PostMessage(hNote, WM_QUIT, NULL, NULL);

動作します。
私には論理的ではないように見えます...どんな種類のメッセージでも適切に機能する普遍的な機能はありますか?

4

3 に答える 3

8

メッセージが異なれば、要件も異なります。一部はキューにポストする必要があります。また、同期的に配信する必要があるものもあります。そのため、システムは両方の配信メカニズムを必要とするように設計されています。

の場合WM_SETTEXT、常に同期的に配信する必要があります。これは、ウィンドウ マネージャーがテキスト データの有効期間を管理できる必要があるためです。Raymond Chen はこの問題について次のように述べています。

SendMessageウィンドウが別のプロセスにある場合の呼び出しには危険があります。他のプロセスがハングした場合、そのプロセスもハングすることはありません。SendMessage同期だからです。

解決策は、 を呼び出すことSendMessageTimeoutです。これにより、文字列データが他のプロセスにマーシャリングされます。また、タイムアウトを設定して、他のプロセスがハングした場合にプロセスがその運命を回避できるようにすることができます。

于 2012-11-13T21:25:43.260 に答える
1

最後の質問から始めてください。いいえ、あなたが望むことをする普遍的なメッセージ機能はありません。

あなたのケースを分析しましょう:

  1. WM_SETTEXT: そのメッセージはポインターを受け取るため、プロセス間で安全に投稿することはできません。プロセス間でメモリ アドレスが分離され、1 つのプロセスからのポインターが他のプロセスにとって無意味になるためです。Windows はメッセージを認識し、裏でデータをコピーし、追加のハッキングを行うため、使用できます。SendMessage()しかし、PostMessage()そんな魔法はありません(ありえません)。

  2. WM_QUIT: これは、メッセージ ループを中断させる特別なメッセージです。簡単に言うと、GetMessagereturnをFALSE行うだけなので、標準メッセージ loop(1) は終了します。しかし、ああ!それはあなたがそうする場合にのみ機能しますPostMessage()。メッセージをSendMessage()送信すると、メッセージ キューで停止することなく、関連するウィンドウ関数に直接送信されます。そして、ウィンドウWM_QUITは単にそれを期待していないため、何もしません。実際には、投稿されても、通常のループでは呼び出されないため、このメッセージはウィンドウに届きませんDispatchMessage()。そのため、通常はウィンドウなしでスレッドに投稿されるため、そのすべてを実行する関数が存在しますPostQuitMessage()

(1) 標準メッセージループ:

while (GetMessage(&msg, 0, 0, 0))
    DispatchMessage(&msg);

脚注として、いくつかのトリックを使用してプロセス間でデータを移動できます。

  1. を使用しWM_COPYDATAます。AFAIK では使用できませんがPostMessage()、ターゲット プロセスに 2 つのスレッドを作成して、最初のスレッドが を受け取ってWM_COPYDATAすぐに戻り、2 番目のスレッドによってキューに入れられるようにポストすることができます。

  2. 共有メモリ ( を検索CreateFileMapping()) とPostMessage()そのメモリへのオフセットを使用します。WM_APP + xシステムのメッセージではなく、ユーザー定義のメッセージを使用する必要があります。ただし、同期の問題に注意してください。ミューテックスなどが必要になります。

  3. 名前付きパイプ!(私のお気に入り)

  4. ソケット。

于 2012-11-13T21:04:46.077 に答える
0

あなたがやろうとしているのは、2 つの別々のプロセスを通信することです。通常のメッセージは機能しませんが、トリックを行うことができるWM_COPYDATAメッセージがあります。関連する質問はここにあります

于 2012-11-13T20:49:26.153 に答える