5

システム トレイに表示される C# WinForms アプリケーションがあります。アプリケーションはロード時にメイン フォームを非表示にしています。

private void MainForm_Load(object sender, System.EventArgs e)
{
    Hide();
}

同じメイン フォームについて、WndProc をオーバーライドしてカスタム ウィンドウ メッセージをキャッチしました (そのメッセージはRegisterWindowMessageWin32 API 呼び出しで Windows に登録されます)。

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_MYCUSTOM_MESSAGE)
    {
        // Handle custom message
    }
}

外部の C++ アプリケーションから、同じカスタム ウィンドウ メッセージを PostMessage でブロードキャストしています。

UINT msg = RegisterWindowMessage(L"WM_MYCUSTOM_MESSAGE");
PostMessage(HWND_BROADCAST, msg, NULL, NULL);

C# アプリケーションを最初に起動した後に上記のコードを実行すると、WndProc に入りません。メイン フォームが表示された後 (システム トレイ アイコンをダブルクリックすることで、本質的Show()Hide().

イベントハンドラーHide()からの最初の後に機能しない理由を誰かが説明できますか? MainForm_Loadフォームを非表示にするのが早すぎますか?

EDIT1: Hide on load とは何の関係もないようです。最初の非表示がなくても、私のメイン フォーム WndProc は、非表示にして再表示した後にのみブロードキャスト投稿の受け入れを開始します...

4

3 に答える 3

10

小さなテスト アプリケーションを作成した後、toが設定されている場合PostMessage()に toが到達しHWND_BROADCASTないことがわかりました。Form.WndProcForm.ShowInTaskbarfalseSendMessage()HWND_BROADCAST

HWND_BROADCAST へのメッセージの送信または投稿に関する MSDN のメモはまったく同じですが。

したがって、フォームの非表示または表示とは何の関係もありませんでした。これは、Windows API の文書化されていない別の機能のようです。

于 2012-04-17T14:22:44.457 に答える
4

フォームの Load イベント ハンドラで Hide() を呼び出しても、実際にはウィンドウが非表示になりません。これを確認するには、小さなテスト Winforms アプリで試してください。

実際にウィンドウが表示されない場合、簡単な説明はウィンドウが作成されていないということです。メッセージが受信されない理由を完全に説明しています。OnHandleCreated() をオーバーライドし、それにブレークポイントを設定して、この理論を再確認します。ネイティブ ウィンドウを作成するには、Show() メソッドを呼び出す必要があります。明らかに、NotifyIcon イベント ハンドラが最初に呼び出されます。これは Application.Run() を呼び出したが、フォーム インスタンスを渡さなかった場合に発生します。

フォームが作成されているが表示されていないことを確認する方法については、この回答を確認してください。

于 2012-04-17T13:50:43.723 に答える
1

ブロードキャストを使用すると、無効または非表示の所有されていないウィンドウ、オーバーラップ ウィンドウ、ポップアップ ウィンドウを含む、システム内のすべての最上位ウィンドウにメッセージがポストされます。メッセージは子ウィンドウに投稿されません (MSDN によると)。WinSpy などのアプリケーションを使用して、最初の起動と非表示の直後にウィンドウがトップ レベルであることを確認します。また、このhttp://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/かもしれません (またはそうでないかもしれません) OnLoad がどのように機能するかについていくつかの洞察を与えます...少し複雑なようです。OnLoad ではなく、別の場所に MainForm を非表示にしてください。

于 2012-04-17T13:41:33.267 に答える