4

この記事のコードを使用して、アプリがアイドル状態になったことを通知しようとしています。

このコードは、アプリケーションにフォームが1つしかない場合にうまく機能します。これを呼び出すApplication2.Run(myOnlyForm)と、すべてのメッセージがApplication2のフィルターを介してルーティングされます。

ただし、いずれかの時点でmySecondForm.ShowDialog()そのダイアログを呼び出しても、そのメッセージはApplication2でフィルタリングされません。

mySecondFormメッセージを「Application2」イベントフィルターに通す方法はありますか(悪い副作用はありません) ?

私が試してみました:

  1. に変更mySecondForm.ShowDialogApplication2.Run(mySecondForm)ます。
    • これにより、ウィンドウがスコープ外になったときにクリーンアップされず、必要なときに表示されなくなります。
  2. に変更mySecondForm.ShowDialogApplication2.ShowDialog(mySecondForm)ます。
    • これにより、メインメニューがmySecondForm機能しなくなります(クリックしても効果はなく、ビープ音だけが鳴ります)。
      • これは私が使用すべきもののようですが、画面にメニューを表示する必要があります。これはOpenNETCFの一般的な 問題のようです。
      • メニュー項目は壊れていません。メニューにホットキーを使用しても機能します。メニューをタップするだけでは機能しません。
  3. (true =ダイアログボックスをクリーンアップする) に変更mySecondForm.ShowDialogします。Application2.ShowDialog(mySecondForm, true)
    • 何度か閉じた後にダイアログボックスにアクセスする必要があるため、これは機能しません。

理想的には、Application2のメッセージ機能にフォームを添付する方法が必要です。

しかし、私はどんな提案も歓迎します。


編集:ctackeの提案に基づいて、これは私が行ったことです:

public static DialogResult ShowDialog2(this Form form)
{
    //form.Activated += InsertMenu;
    //Application2.ShowDialog(form);
    form.Show();
    try
    {
        do
        {
            Application2.DoEvents();
        } while (form.Visible);
    }
    catch (ObjectDisposedException)
    {
        // This just means that the form was closed.  Not a big deal.
    }
    return form.DialogResult;

}

ShowDialogではなくShowDialog2を呼び出すことになります

4

2 に答える 2

2

直接的な解決策を提供していないかもしれませんが、私はその振る舞いを説明することができます。

任意のフォームでShowを呼び出すと、フォームのイベントはデフォルトのメッセージポンプ(Runの呼び出しで設定されます)によって処理されます。ShowDialogを呼び出すと、ターゲットフォームは独自の個別のメッセージポンプを取得します。

これで、追加したフィルターがメインメッセージポンプに存在し、そこにあるすべてのメッセージを確認しますが、ShowDialog呼び出しは、ダイアログに送信されたメッセージがフィルターに到達しないことを回避します。

ここで、この問題を回避する試みとしてApplication2.ShowDialog呼び出しを追加しましたが、正直なところ、Application.Run / IMEssageFilter実装全体を作成している間、ShowDialogの回避策を実行しなかったため、実際に方法がわかりません。よく実装されました。あなたの報告に基づいて、私は「うまくいかない」と推測するのは危険ですが、それは実際には解決するのが簡単な問題ではありません。この問題の根本は、ShowとShowDialogを呼び出したときにSDFがBCLで何が起こるかを制御しないことです。私たちは単にその上に座って、可能な限り最高の動作を提供しようとしています。この場合、問題があります。

たまたま、ShowDialogの呼び出しを使用せず、代わりに、フォームをTopMostのままにするようなものと組み合わせてShowを使用できますか?これにより、フィルターは疑似ダイアログのすべてのメッセージを取得できます。私がすぐに考えることができる他のオプションは、フィルターメカニズムに通知するダイアログの基本クラスですが、それは制御が非常に困難になり始めます。

于 2010-06-23T22:15:55.813 に答える
0

質問して申し訳ありませんが、なぜこれほど単純なことでこの非常に多くの問題を経験しているのですか?WM_KEYUPリンクした記事を見ると、タイマーを開始して、イベントごとにリセットするだけWM_MOUSEMOVEです。WM_LBUTTONUP

WndProcフォームをオーバーライドするかPreProcessMessage、フォームでタイマーリセットを実行させることで、同じことを実現できます。タイマー/リセットを行う基本フォーム(*)を作成し、そこからすべてのフォームを派生させることもできます。そして、実際のグローバルソリューションでは、タイマーを静的にします。

(*)抽象としてマークしないでください。マークしないと、フォームデザイナーがヒッシーフィットをスローします。

于 2010-06-23T20:57:00.847 に答える