VC++.NET で、コモンコントロールの通知メッセージハンドラを追加 – プログラミング – Home

VC++.NET で、コモンコントロー...
 
通知
すべてクリア

VC++.NET で、コモンコントロールの通知メッセージハンドラを追加


aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
Topic starter  

わかりにくいタイトルで申し訳ありませんが、コード上ではなく IDE の話です。
VC++.NET では、VC++ 6.0 のクラスウィザードがいくつかに分割されました。
その中のひとつ、メッセージハンドラ追加ウィザードについてです。

例えば、IDE 上で CListView から派生したカスタムビューが選択されていると、このメ
ッセージ一覧に、ウィンドウメッセージ(WM_XXX)の他に、リストビューの通知メッセ
ージである LVN_XXX などが(先頭に = がついて)表示されています。

現在、CListView を真似て、CCtrlView から派生し CMonthCalCtrl を内包する
CMonthCalView というのを作っているのですが、これは選択されていてもメッセージ一
覧に月間予定表コントロールの通知メッセージである MCN_XXX などは表示されていませ
ん。
ここに MCN_XXX を表示するにはどうしたらいいか、ご存知の方はいらっしゃいません
か?

環境は VS.NET 2003 です(2002 でも同じかな?)
よろしくお願いします。


引用
トピックタグ
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

すいません、あまり詳しくないのに書き込んで申し訳ないんですが、
内包するというのはhave aの関係と見て良いでしょうか?
私の記憶では、クラスウィザード絡みの部分は、is aの関係でないと
うまくいかなかったような気がするのですが。

少なくともVC6ではそうですし、VC6の場合、直上の親クラスがMFCのクラスでないと
メッセージ関連は出てこなかったと記憶しています。
(つまり、CButtonから派生したクラスからさらに派生した場合はウィザードで
直接扱えない。#defineでだませば、何とかなったと思いますけれど)


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
Topic starter  

すいません、内包っていうのは言葉が悪かったですね。
have a ではありません。が、is a とも言い難いです。

CMonthCalView は CCtrlView から派生しますが、CMonthCalCtrl からは派生しません。
つまり、CMonthCalView is a CCtrlView ですが、CMonthCalView is not a
CMonthCalCtrl です。
ついでに、CMonthCalView has not a CMonthCalCtrl です。

これは CListView も同じです。
CListView is a CCtrlView ですが、CListView is not a CListCtrl です。
で、ClistView has not a CListCtrl です。

事実、CListView のソースをそっくりそのまま、名前だけ変えたようなものなので、差
異は
>直上の親クラスがMFCのクラスでないと
だけだと思います。要するに、CMonthCalView は MFC クラスではありません。

これは、「CListView は MFC クラスである」という記述がどこかになされているのでし
ょうか?
それが変更できるなら、そこに CMonthCalView も MFC クラスである、と書いてしまえ
ばいいと思うのですが、どこに書いてあるかご存じないでしょうか?


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
Topic starter  

長くなるので書き込みを分割します。
CMonthCalView の作り方。

1・SDI プロジェクトを立ち上げます。ビューの基底クラスは CListView にします。
ClassWizard でメッセージマップを見ると、リストビューの通知メッセージである
LVN_XXX とか HDN_XXX が確認できます。
2・プロジェクトに新しいクラスを追加します。基底クラスは CCtrlView にします。
MFC クラスだと CCtrlView が基底クラスに選べないので、一般クラスを選択しま
す。
3・CListView の宣言と定義を探し出します。
クラス定義は afxcview.h
コンストラクタと GetListCtrl は afxcview.inl
その他のメンバは viewcmn.cpp に書かれています。
4・MonthCalView.h にある CMonthCalView の宣言を afxcview.h にある CListView の
宣言で上書きした後で、List を MonthCal に置換します。
DrawItem、RemoveImageList、OnChildNotify、OnNcDestroy の宣言を削除します。
5・afxcview.inl と viewcmn.cpp から CListView の定義を持ってきて、
MonthCalView.cpp の宣言を上書きします。viewcmn.cpp の一番下に
IMPLEMENT_DYNCREATE マクロがあるので、これも忘れずに移植します。
4同様に List を MonthCal に置換し、宣言から削除したメンバ関数の定義を
削除します。
6・CMonthCalView のコンストラクタで CCtrlView を初期化している部分は
WC_LISTVIEW を MONTHCAL_CLASS に書き換えます。
これで CMonthCalView 自体は完成です。
7・SDI のビュークラスのファイルで MonthCalView.h をインクルードし、CListView
を CMonthCalView に置換します。

ビルドして実行すると、ビューの真ん中に数ヵ月分のカレンダーが表示されると思いま
す。
これで、CMonthCalView が CListView に完全に取って代わったはずです。
が、ClassWizard のメッセージマップを見ても、月間予定表コントロールの通知メッセ
ージである MCN_XXX が表示されていません。
さてどうしましょう?というわけです。

長文失礼いたしました。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

私見になりますが、

VC6のクラスウィザードの動作を見ているとウインドウメッセージ関連の部分は
クラスの解析を行って云々と言うのではなくて単純にMFCの各クラスが扱うメッセージの
種類や内容を把握していてウィザードが認識しているMFCのクラスと直接の派生関係に
ある場合のみにメッセージハンドラの追加が出来るような作りになっていると
私は考えています。MFCのクラスごとのメッセージマップをクラスウィザードが内蔵して
いるのか、外部にデータベースファイルを持っているのかはわかりませんが、
シャノンさんがやったような直接ファイルを書き換えるような実装方法をとった場合は
クラスウィザードが認識できないのではないかと思います。

役に立たない情報ですいません。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

うろ覚えで申し訳ないのですが、

VC6のクラスウィザードは確か

IMPLEMENT_DYNAMIC(CCustomButton,CButton)

というマクロで派生関係を認識していたと記憶しています。
(上記ですとCCustomButtonがCButtonから派生している)

で、これが派生の派生になっている場合、

IMPLEMENT_DYNAMIC(CCustomButton,CColorButton)

となっているとクラスウィザードはCCustomButtonがMFCとは無関係なクラスだと
認識していたと思います。

そこでクラスウィザードを騙すためだけに

#define CButton CColorButton
IMPLEMENT_DYNAMIC(CCustomButton,CButton)
#undef CButton

とするとクラスウィザードは、CCustomButtonがCButtonから派生していると誤解して
メッセージハンドラの追加にボタン関連のメッセージが出るようになります。
コンパイラはプリプロセッサで切り替えているので正常にコンパイルが出来ます。

クラスウィザードはおそらくクラス名でMFCのクラスと派生関係であると言う認識を
持っていると思うので、シャノンさんの実装では多分無理だと思います。
これは、VC6での実装を元に書いているのでもしかしたら.netでは違っているかも
しれません。

もしかしたら記憶違いがあるかもしれません。
識者の方、間違っている部分が有りましたら指摘してください。
よろしくお願いします。


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
Topic starter  

レスありがとうございます。
う~ん…

>#define CButton CColorButton
>IMPLEMENT_DYNAMIC(CCustomButton,CButton)
>#undef CButton

これは結局、CCustomButton が CButton の間接的な派生クラスだからできるわけで
このケースの場合は不可能ですよねぇ。

まぁ、MSDN でメッセージの詳細を探しだして手動でハンドラを追加すればいいことなの
で、この件は「不可能」と諦めて解決としたいと思います。

返信が送れて申し訳ありませんでした。
ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました