いつもお世話になっています。
Windows Xp, VC++6.0, MFC, ダイアログベースで開発しています。
早速質問なのですが、ダイアログに貼り付けたボタンを
押下した時に投げられるメッセージをそのダイアログに
貼り付けてあるコントロールで受け取りたいと思っている
のですが、何か方法はありますか?Dlgのクラスではメッセージ
を受け取れるのですが、コントロールのクラスはクラスウィザードで
ハンドラは作れたものの、イベントが発生しても呼ばれないようです。
どなたかご指導宜しくお願い致します。
ちょっと不思議な動作のようですが、
例えばボタンを押したら同じダイアログに貼り付けられているエディットコントロールにボタンに対して投げられたBN_CLICKEDがもう一度飛ぶ、と言う認識で書きます。
基本BN_CLICKEDの様な通常のメッセージは一つのウィンドウに対して投げられる(MFCだとダイアログクラス→貼り付けられた各コントロールの順で飛んでいる)筈なので、saruさんがダイアログもしくはボタンのPreTranslateMessage()で任意のハンドル・メッセージの条件が揃った時別のコントロールにも投げてやる処理を自前で用意してやる必要があると思います。
もしそれ以前の問題(コントロールでそう言ったメッセージすら捕捉できない)であればそのコントロールのクラスを継承して、サブクラス化すればOKです。
ぽちょむきんさんご指導ありがとうございます。
PreTranslateMessage()はダイアログのクラス内で
メッセージを受けて、今度はそこからコントロールに
自前のメッセージを投げてやるという使い方で良いのですか?
言葉足らずだったのか、もしくはぽちょむきんさんのコメントを
私が間違って解釈しているかもしれませんが、私がやりたかったのは
"ボタンが押下されたというメッセージがメインフレームから
コントロール内に直接飛んできて、クラスウィザードで用意した
ハンドラでそれを受け取る"という事を考えていました。
でもぽちょむきんさんの方法(←私の解釈ですが)でやってみたら
成功しました。"自前のメッセージ"というのがよく分からなかった
ので、コントロールのクラスにやりたい処理を書いた
インターフェイスを用意しておいてそれを呼びだすようにしてみました。
やはりダイアログで発生したメッセージはダイアログの
クラスで処理するのが普通なのでしょうか?
特にどちらが良いとこだわりがあるわけではないのですが。
ぽちょむきんです。
成る程メインのダイアログ(C***Dlg)を介さないで
コントロールで直接受け取りたい、と言う事でしょうか?
(間違ってたらごめんなさい)
となるとダイアログに到達する前にメッセージを横取りする必要があるので、
メッセージフックの必要があります。
サンプルなどは
http://ag5.net/~prgroad/programming/visualc_mfc/NorySpy.html
等を利用すると良いでしょう。
フックに関しての定義はMSDNライブラリ等を参照して下さい。
>やはりダイアログで発生したメッセージはダイアログの
>クラスで処理するのが普通なのでしょうか?
本来ならば本体に投げられるメッセージを、
その一部であるコントロールが横取りして受け取る事は
あまり好ましいとは言えないかも知れません。
またフックはメッセージを"横取り"する為、
プログラムによってはOS、他のプログラムに
致命的な障害を及ぼします(僕はこれをモロに見た事がある)。
ただなんでもかんでもダイアログで処理すると、
C***Dlgのソースが肥大化し、
OOPとして矛盾する点が生じるのも事実だと思います。
月並みではありますが、設計に依存するとしか言えません。
ただ今回の問題(あるコントロールが同じアプリケーション内の
メッセージを横取りしたい)は
フックで行うべきであるとは考え辛いです。
メッセージフックですか。良く聞きますがこんな風に
使えるんですね。
ただ、ぽちょむきんさんのコメントを拝見していて
やはりダイアログに投げられるメッセージはダイアログで
処理するほうが良いかと思ってきました。
どこで処理すべきかがよく分からなかったので、
処理のし易いコントロール内(データが揃っている為)を
選んだのですが、問題や手間も色々ありそうですので、
やはりダイアログで行うことにします。最初に教えて頂いた
PreTranslateMessage()を使ってやりたいと思います。
あと"設計に依存する"とありましたが、今は調査段階でして
調査とサンプルが完了次第、仕様書の作成と実装に入る
手順でした。その為いきなり作っているような感じです。
ぽちょむきんさんどうもありがとうございました。
メッセージフックも今後使う機会があるかと思いますので
そちらの方も確認しておきます。
メッセージフックは使わない方がいいと思いますが、
コントロール内で閉じている動作であれば、そのコントロールで行うのは自然ですので、
無理にダイアログに戻す必要は無いでしょう。
また、PreTranslateMessage()で、処理を呼び出すよりは、
ダイアログにボタンのハンドラを作ってそこから呼び出すことをお勧めします。
ツイート | ![]() |