- ベストアンサー
サブクラス化について教えてください
環境 WIN98 VC++6.0 MFC にて サブクラス化と言う言葉は良く効きますが、実態が良く分かりません。 具体的に分かりやすく教えていただけないでしょうか? また、ネット上で調べた例としては、http://kerochan.no-ip.com/vcsdk/letsprog/chap30.htm が分かりやすかったのですが、これをMFCで実現するにはどのようなコードを書けば良いのでしょうか? よろしくお願い致します。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
すみません。CWnd::Attachの中確認したら、サブクラス化してませんでした。 サブクラス化を行うメソッドは、CWnd::SubclassWindow、CWnd::SubclassDlgItemでした。 解除はそれぞれUnがつきます。 で、初期処理については、CWnd::PreSubclassWindowで出来ますね。 サンプルなんですが、「CTRLTEST」がVCに付属しているらしいです。 http://www.microsoft.com/japan/developer/library/vcmfc/_mfcnotes_tn014.htm あと#2の補足のコード、OnInitDialogでお絵かきしてません? これだとがんばっても何も表示されませんね。
その他の回答 (3)
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>具体的なコードがないと理解が難しいので、ネット上を探しまくってようやく以下のコードを見つけました。 なんですが、ウィンドウのサブクラス化とまったく関係ないんですけど・・・
お礼
えぇ~ やっぱり関係ないですか。 結局、サブクラス化という言葉は良く聞くけれど、MFCで書かれたコードはまず見つからないですね。 (#4は除く) あまり、必要性がないのかも。 #4については、別途報告します。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
1.CButtonの派生クラスとして、CMyButtonを定義し、自分で作成したCDialogクラス(CMyDialogとしておきます)のメンバ変数としてm_cMyButtonを定義しておく。 2.CMyDialog::OnCreate()で、リソースエディタで作成したダイアログのボタンのCWnd*をGetDlgItem()で取得し、 m_cMyButton.Attach()の引数に渡してサブクラス化を行う。 3.CMyButtonのメッセージハンドラで好きなことをする (ただし、CMyButton::OnCreate()は呼ばれないので、初期処理を行いたい場合などは工夫が必要だったはず。urlのようなメッセージを使わなくても全然かまわないし) 4.CMyDialog::OnDestroy()なんかで、ダイアログが破棄される前にm_cMyButton.Detach()を呼び、サブクラス化を解除する。 (urlのは解除してないみたいですが) こんな感じですかね。
お礼
いつも回答ありがとうございます。 #1の回答の1行目を完全に見落として、あっさりと追加質問してしまいました。申し訳ありません。 また、#2では具体的な例をありがとうございます。 しかしながら、私の実力では簡単には理解できそうにありませんでした。
補足
具体的なコードがないと理解が難しいので、ネット上を探しまくってようやく以下のコードを見つけました。 エラーは出ませんが、何も起こりません。 どうしてなのでしょうか? ************************* ダイアログ上にピクチャーボックスを配置して、ダイアログの表示と同時に、ピクチャーボックスを塗す方法。 まず、ピクチャコントロールをClassWizardのメンバ変数タブによりm_pictureとして実態を作成します。 その後、 class CPictureDlg { private: CBitmap m_bitmap; // ... }; BOOL CPictureDlg::OnInitDialog() { CDialog::OnInitDialog(); // ... CDC desktopDC; desktopDC.Attach ( ::GetDC ( NULL ) ); CDC memDC; memDC.CreateCompatibleDC ( &desktopDC ); m_bitmap.CreateCompatibleBitmap ( &desktopDC, 100, 100 ); CBitmap *pOldBitmap = memDC.SelectObject ( &m_bitmap ); CRect rcPicture ( 0, 0, 100, 100 ); CBrush brush; brush.CreateStockObject ( WHITE_BRUSH ); memDC.FillRect ( &rcPicture, &brush ); memDC.SelectObject ( pOldBitmap ); m_picture.SetBitmap ( ( HBITMAP ) m_bitmap.GetSafeHandle () ); ReleaseDC ( &desktopDC ); memDC.DeleteDC (); }
- taka_tetsu
- ベストアンサー率65% (1020/1553)
MFCならCWnd::Attach()、CWnd::Detach()について調べてみましょう。 一番分かりやすい例では、エディットボックスに特定の文字しか入力させないようにするときなどに行います。 例として出しましたが、MFCならCEditを使えば同様の 処理は実現できるのですが、内部的にはこのサブクラス化を 行っています。
お礼
taka_tetsuさん こんばんは。 参考サイトと同じことをMFCとサブクラス化で実現するにはどうすれば良いのでしょう? よろしくお願い致します。
お礼
いつも回答ありがとうございます。 MFCでのサブクラス化 やっぱり良く分かりません。 ネット上のQ&Aを調べると、サブクラス化の言葉は山ほど見つかります。 しかし、”サブクラス化しましょう。”や ”サブクラス化しました。”という内容ばかりで、サブクラス化をどうやってするのかは、あまりありません。 1.「CTRLTEST」は確かにVCに付属しています。 2.MFCによるWindowsプログラミングと言う本に、「Colors」というサンプルもあります。 3.パワフルテクニック大全集という本にも、エディットボックスに入力する文字を制限する方法として載っています。 4.ネット上にはボタンの色を変える方法としてこれがありました。http://www.geocities.jp/chiakifujimon/bgcolor/section3_4.html 上記例は私にはとっつきにくいので、 最初に立ち返って、SDKでマウスポインタを変えるサンプル http://kerochan.no-ip.com/vcsdk/letsprog/chap30.htm が分かりやすかったのですが、これをMFCで実現するにはどのようなコードを書けば良いのでしょうか? よろしくお願い致します。
補足
下記例にて一応MFCでのサブクラス化がようやく分かりました。 例)ピクチャボックスでのWM_LBUTTONDOWNの検知 <問い> お世話になります。 現在、ダイアログ上にピクチャボックスを貼り付けて、 そのピクチャを動的サブクラス化しています。 CStaticから派生したクラスを、CMyPictクラスとして、 ダイアログのヘッダファイルに、 CMyPict m_pict; ダイアログのOnInitDialog内で、 m_pict.SubclassDlgItem( IDC_MY_PICT, this ); として、このCmyPict内で図形の描画処理(OnPaint)を行っています。 それで、このピクチャ上でのマウス処理を行うため、OnLButtonDownを オーバーライドしているのですが、メッセージが飛んできていないようです。 これができないと、CRectTrackerの操作がすべて出来なくなってしまうのですが… なぜ、WM_LBUTTONDOWNがこないのでしょうか? どなたか知っている方、ご教授を願います。 <回答> プロパティで「通知」がチェックされていないからでしょう。 <お礼> ありがとうございます。 プロパティの「通知」をチェックしたらうまくいきました。 OnPaintが何もしなくてもはしっていたので、 その他も走ると思い込んでいました。