melt日記

.NETすらまともに扱えないへたれのページ

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  111  : 記事  3  : コメント  485  : トラックバック  35

ニュース

わんくま同盟

わんくま同盟

C# と VB.NET の質問掲示板

iKnow!


Dictation



書庫

皆さんは、こんなダイアログを見たことがありますか?

busy.png

 

これは、COM のメソッドを呼び出して一定時間応答が無かった場合に発生します。

いつもいつも勝手に出てきて、再試行を選択するとすぐに出てきて、切り替えを選択してもまたすぐに出てきて、あげくキャンセルが Disable になってたりして非常にうざいダイアログです。

特に、応答が無いというのが正当な理由によるものだった場合には、思わず暴れ出したくなります。

これを何とか出さないように出来ないものでしょうか。

 

自分はずっと、これは COM のネイティブ部分が表示しているから制御するのは無理だと思っていたのですが、実際の所は全然違ってて、こいつは MFC の OLE 部分が IMessageFilter という機構を使って勝手に表示していました。

IMessageFilter は COM のメソッドが呼ばれる前にコールバックされるメソッドであり、ここで本当にメソッドを呼び出すかどうかを設定(フィルタリング)することが可能です。

例えばコネクションポイントで接続した COM にイベントを送信している途中は、その送信した COM 以外のメソッド呼び出しを弾きたい、もしくはメソッド呼び出しを待ってもらいたいという場合、IMessageFilter の HandleInComingCall() というメソッドを使って制御することが可能です。

メソッド呼び出しを待ってもらっている間は特定のメソッド(RetryRejectedCall()MessagePending())がコールされ続けられるので、そこで待ち時間のタイムアウトを設定することが可能です。

 

MFC はデフォルトで IMessageFilter を継承した COleMessageFilter というのを設定していて、こいつは一定時間(デフォルトでは10秒)以上待つことになると、COleBusyDialog というのを表示しやがります。

COleBusyDialog というのが↑のダイアログのことです。

そこまで分かれば後は簡単で、COleMessageFilter はダイアログを表示させないようにするためのメソッドがちゃんと用意されているので、

COleMessageFilter* pFilter = ::AfxOleGetMessageFilter();
pFilter->EnableBusyDialog(FALSE);
pFilter->EnableNotRespondingDialog(FALSE);

とやれば、無事ダイアログが表示されなくなります。

 

ただ、実際には何の解決にもなってないので、本当に固まっている場合はちゃんと原因を突き止めて解決しましょう。

ダイアログが出ても構わないが↑の COleMessageFilter のダイアログはかっこ悪くてダメダメだ、という場合は、COleMessageFilter を継承して OnBusyDialog() と OnNotRespondingDialog() をオーバーライドして、そこで自分の作ったダイアログを表示するようにします。

で、そのクラスをどこかで ::CoRegisterMessageFilter() してやれば、メソッド呼び出しがタイムアウトになったときに自前のダイアログが表示されるようになるかと思います。

 

ビジー状態ダイアログが表示されて困っている場合は是非試してみてください。

投稿日時 : 2007年8月9日 2:43

コメント

# re: [C++]ビジー状態 2007/08/09 11:13 とっちゃん
CoRegisterMessageFilter() の呼び出しは、COleMessageFilter::Register() でできますよ。
実際は、自動的に処理されてたと思いますが、よく覚えてないですw



# re: [C++]ビジー状態 2007/08/09 12:55 melt
あ、ほんとですね。

でもこれ、古い IMessageFilter を保存してくれてないので、元に戻すことが出来ないみたいです。

COleMessageFilter は AfxOleInit() を呼んだ段階で登録されるっぽいです。
AfxOleInit() は何かのコントロールを作ると同時に内部で呼ばれるので、何も気にしなくて良いようです。

当然、COleMessageFilter を継承した自前のクラスを使いたい場合は登録し直す必要がありますがw

# STA の難しさ 2007/12/13 18:38 melt日記
STA の難しさ

Post Feedback

タイトル
名前
Url:
コメント