3


1

Win32でのWM_NOTIFYとスーパークラス連鎖の問題

参考のために、私はhttp://www.ddj.com/184410048 [この]記事に概説されているウィンドウスーパークラスメソッドを使用しています。 私が `WM_NOTIFY`メッセージを処理したいのであれば、特定の問題が発生します。 カスタム描画の場合は、スーパークラスの基本コントロールから、親ウィンドウから反射させるか、自分のウィンドウを親として設定する必要があります( `WM_(NC)CREATE`のCREATESTRUCT内で基本クラスに渡されます)。 私が単一のスーパークラスを持っている場合、このメソッドはうまく機能します。 スーパークラスをスーパークラス化すると、問題が発生します。 今度は3つのWindowProcが同じHWND内で動作していて、 `WM_NOTIFY`メッセージを反映させる(あるいは上記の親トリックから自分に送信させる)と、それらは常に最も外側の(最も派生する)WindowProcに送られます。 それらが内部スーパークラス向けのメッセージ(基本メッセージは最初のスーパークラスに送られることになっている)か、それとも外部スーパークラス向けのメッセージ(内部スーパークラスからのメッセージは外部スーパークラス向け)かを判断する方法はありません。 これらのメッセージはすべて、同じ制御IDを持つ同じHWNDから来るため、区別がつきません。 各レベルの継承をカプセル化するための新しいウィンドウを作成せずにこれを解決する方法はありますか?

テキストの壁については申し訳ありません。 説明するのは難しい概念です。 これがダイアグラムです。

単一スーパークラス:

SuperA::WindowProc() -> Base::WindowProc()---\
             ^--------WM_NOTIFY(Base)--------/

スーパークラスのスーパークラス:

SuperB::WindowProc() -> SuperA::WindowProc() -> Base::WindowProc()---\
             ^--------WM_NOTIFY(Base)--------+-----------------------/
             ^--------WM_NOTIFY(A)-----------/

2番目のケースの `WM_NOTIFY`メッセージはすべて同じHWNDとコントロールIDから来ているので、(Baseからの)SuperAに向けられたメッセージと(SuperAからの)SuperBに向けられたメッセージを区別することはできません。 何か案は?

2 Answer


1


当然、コントロール(元の?)はPARENTにメッセージを送信しています。 おそらくあなたはこれらを傍受して元のコントロールにポストバックしているのでしょう。 もちろん、外側の層はこれらを最初に見るでしょう(そしてそれを処理したくなければそれを渡すことができます)。

あなたはどのような種類のNOTIFYメッセージを傍受したいのか、またはその理由を述べていません。 しかし、親procでそれらを送り返して管理できるようになったので、メッセージを変更しないでください。 独自のNMHDR構造体をロールし、メッセージとデータを埋め込み、そしてスーパークラスのレベルの識別を追加します。 あなたのスーパークラスで、あなたが欲しいものをはがし、あなたがそうでないものを再フォーマットし、そしてそれらを送ってください。

ちょっと面倒くさいですね。 そのレベルでは、私は基本に戻り、自分自身の共通コントロールを構築する傾向があります(もちろん、あなたが実際にやろうとしていることによります)。


1


ボーランドは、VCLでこの問題を回避するために、親レベルでメッセージIDを変更しました。 親ウィンドウがWM_NOTIFYメッセージを受信すると、メッセージIDは定義されたオフセット(CN_BASE)だけインクリメントされ、メッセージはそのメッセージが指定する子ウィンドウに直接渡されます。 子ウィンドウプロシージャ(およびその子のサブクラス)は、(CN_BASE WM_NOTIFY)メッセージを検索して、元のWM_NOTIFYデータにアクセスできます。 同じテクニックがWM_COMMANDメッセージにも適用されます。 あなたのコードで似たようなことをしてみてください。