2012-04-17 15 views
3

システムトレイに表示されるC#WinFormsアプリケーションがあります。アプリケーションが負荷にメインフォームを非表示にされます。同じメインフォームの隠しフォームへのPostMessageは初めて動作しません。

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

、私は(そのメッセージがRegisterWindowMessageのWin32 API呼び出しを使用してWindowsに登録されている)カスタムウィンドウメッセージをキャッチするためにWndProcメソッドをオーバーライドしてきました。

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

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

私は上記のコードを実行すると、それはWndProcメソッドに取得していません。メインフォームが表示された後(本質的にはShow()のシステムトレイアイコンをダブルクリックすると)、ブロードキャストメッセージをキャッチすると、Hide()というフォームを隠してから作業を続けます。

MainForm_Loadイベントハンドラの最初のHide()の後に、なぜそれが機能しないのか説明できますか?フォームをあまりにも早く隠していますか?

EDIT1:ロード時に非表示とは関係がないようです。最初の非表示がなくても、私のメインフォームのWndProcは、それが隠されて再表示された後で放送投稿の受け入れを開始するだけです...

+0

'PostMessage'の代わりに' SendMessage(HWND_BROADCAST、msg、NULL、NULL) 'が最初から動作しますが、メッセージを投稿したいと思います。 –

答えて

6

小テストアプリケーションを作成した後、私はSendMessage()HWND_BROADCASTには行いながらForm.ShowInTaskbarfalseに設定されている場合PostMessage()HWND_BROADCASTにはForm.WndProcに到着しないことを見出しました。

HWND_BROADCASTへのメッセージの送信またはポストに関するMSDNの注釈はまったく同じですが、

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

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を非表示にしてください。

+0

私のアプリケーションでは、ロードロードハンドラでウィンドウを隠さないときも発生します...新しいWinFormsアプリケーションで問題を再現しようとしましたが、そこにPostMessageが動作するようです...多分何かがあります私のアプリケーションでは、メッセージループをロックします。 –

3

何か別のことが起こります。フォームのLoadイベントハンドラでHide()を呼び出すと、実際にウィンドウが隠されることはありません。これを見て少しテストWinformsアプリで試してみてください。

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

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

+0

+1うーん、 'SetVisibleCore'は、フォームを表示せずにハンドルを作成する方法です。それは私が逃した知識の一部です。 –

+0

デザイナーでWindowStateを最小化に設定しました。これにより、プログラムボタンがタスクバーに残ります。オンロードハンドラでHideを呼び出すと、タスクバーからボタンが削除されます。 –

+1

私は、 'Form.ShowInTaskbar'が' false'に設定されていると、フォームがPostブロードキャストを受信しないことを発見しました。 'true'に設定されている場合、trueになります。 –

関連する問題