• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:インライン処理)

CListCtrlの派生クラスをインラインで書きたい方法

このQ&Aのポイント
  • VS2008 MFCを使用して、CListCtrlの派生クラスをインラインで書く方法がわからない。
  • メッセージ処理を追加するとcppファイルが生成されるため、ヘッダファイルだけで使用する方法はあるか。
  • MFC初心者のため、BEGIN_MESSAGE_MAPやIMPLEMENT_DYNAMICの意味がわからず困っている。ヒントを教えてほしい。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

CWndの派生クラスでメッセージを処理する場合、GetMessageMap仮想関数とGetMessageMap関数が返す構造体がマクロ展開で作成されるので、その時点ですべてをインラインにはできなくなります。 ヘッダー部分に移動するとエラーになるのも、これらが原因です。

MI9999
質問者

お礼

的確且つ簡潔な解答、非常に感謝いたします。 そうですか…やはり無理なのですね…。 ちょっとそんな気がしていたのですが、有識者ならば何とかなるかと思い質問いたしました。 ありがとうございました。

MI9999
質問者

補足

本題から少々ずれるのですが、派生クラスでWindowProcをオーバーライドしてLVN_COLUMNCLICKからメッセージ処理関数へジャンプさせるので有れば、ヘッダファイルのみで処理できるのでしょうか? 途中までがんばったのですが、LVN_COLUMNCLICKをうまく拾えず頓挫しています…。

すると、全ての回答が全文表示されます。

その他の回答 (2)

回答No.3

>本題から少々ずれるのですが、派生クラスでWindowProcをオーバーライドしてLVN_COLUMNCLICKからメッセージ処理関数へジャンプさせるので有れば、ヘッダファイルのみで処理できるのでしょうか? MFC自体がMESSAGE_MAPの為にデフォルトのWindowProcをオーバーライドしているので、派生クラスでWindowProcをオーバーライドしても、MFCの方がメッセージを先に処理してしまい、後からオーバーライドした方に制御が移りません。 >途中までがんばったのですが、LVN_COLUMNCLICKをうまく拾えず頓挫しています…。 上記のように、MFCがメッセージをすべて奪い取ってしまっているので、派生クラスでWindowProcをオーバーライドしても効果はありません。 MFCがメッセージをすべて奪い取ってしまっている状態ですから「BEGIN_MESSAGE_MAPを使って、一部のメッセージを、お裾分けしてもらう」のです。 従って「WindowProcの事は、元から無いモノだと思って書かないといけない」のです。 そのため、CWnd::DefWindowProcとかCWnd::WindowProcとかがある訳なのですが。

MI9999
質問者

お礼

補足に解答いただきありがとうございます。 詳しく説明いただき非常に勉強になりました。 関数のオーバーライドは基本クラスの処理の前に割り込むものと思っていたのがそもそもの間違いでした…。 ヘッダと.cppペアで使用する様にします。

MI9999
質問者

補足

メッセージフックを利用してみようと思い、色々調べてみたのですが、これも.cppファイルが必要になるみたいで諦めました…。

すると、全ての回答が全文表示されます。
回答No.2

IMPLEMENT_DYNAMIC 動的オブジェクト派生クラスが実行時に階層内のクラス名と位置にアクセスするために必要となるC++の実行コードを生成します。 実際に実行されるコードが書いた位置に生成されるので、IMPLEMENT_DYNAMICは.cppの中にしか書けません。 BEGIN_MESSAGE_MAP クラスのメンバ関数を定義する実装ファイルに、つまり、.cppファイルに、メッセージ処理ルーチンを上書きする実行コードを生成し、特定のメッセージを特定の関数にオーバーライドします。 メッセージ処理を乗っ取る為の、実際に実行されるコードが書いた位置に生成されるので、BEGIN_MESSAGE_MAPは.cppの中に書きます。 BEGIN_MESSAGE_MAPはヘッダに書いても構いませんが、書いたヘッダは、1つのプロジェクトの中で1回だけしかインクルードしてはいけません。

MI9999
質問者

お礼

今まで、なんとなくMFCのお約束記述だと思い深く追求しなかったのですが、明確な説明付でご回答いただきありがとうございます。 どちらもcppファイルに記述する必要がある様なので、やはりオールインラインは難しそうです…。

MI9999
質問者

補足

後でこれをみた同じ問題を抱えている人のために…書くところが無かったのでここに記します。 結論としてヘッダファイル内オールインラインに出来ました。 もちろん、MESSAGE_MAP()関連やIMPLEMENT_DYNAMIC等すべて削除した上でです。 自身の質問にあるMFCによる"OnLvnColumnclick"オーバーライドでは無いです。"OnLvnColumnclick"を使った場合のオールインラインは回答くださった皆様のご指摘通り不可でした。 CWnd::OnNotifyをオーバーライドして、メッセージを取得し、OnLvnColumnclick相当の関数を呼び出すようにしました。 取得したメッセージは"LVN_COLUMNCLICK"ではなく"HDN_ITEMCLICK"です。 このやり方が正しいかどうか不明ですが、実装したかったCListCtrlの派生クラスで、詳細表示時の列クリックイベントをオールインラインで取得することは正常に出来ました。 protected: virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) {  NMHEADER *pNMHEADER;  pNMHEADER = (NMHEADER*)lParam;  switch(pNMHEADER->hdr.code) {   case HDN_ITEMDBLCLICK :   case HDN_ITEMCLICK :    //ここで列クリック関数を呼ぶ。列番号はpNMHEADER->iItem    break;  }  return CListCtrl::OnNotify(wParam, lParam, pResult); } ダブルクリックをシングルクリック扱いしているので、列を連続でクリックしたときのもっさり感も無くなります。

すると、全ての回答が全文表示されます。

関連するQ&A