質問: 【vc++6.0】イベントハンドラ関数を流用したいのですが、、、 vc++超初心者です。 既出の質問(http://okwave.jp/qa2658942.html)と同様ですが、vc2005(clr)でなく、vc++6.0の時 どのようにコーディングすればよいか教えていただけませんでしょうか。 よろしくお願いします。 ********************************** 以下の2つのボタンのイベントハンドラ関数があった場合 //ボタン1のイベントハンドラ関数 void caaaadlg::onok() { 処理内容 } //ボタン2のイベントハンドラ関数 void cbbbbdlg::onok() { } ボタン2をクリックしたときの動作とボタン1の動作を同じにしたいと思っています。 **********************************
回答: それではサンプルを載せます aaaadlg.cpp ここから ============================================== // aaaadlg.cpp : 実装ファイル // #include "stdafx.h" #include "dlgtest.h" #include "aaaadlg.h" // caaaadlg ダイアログ implement_dynamic(caaaadlg, cdialog) caaaadlg::caaaadlg(cwnd* pparent /*=null*/) : cdialog(caaaadlg::idd, pparent) { } caaaadlg::~caaaadlg() { } void caaaadlg::dodataexchange(cdataexchange* pdx) { cdialog::dodataexchange(pdx); } begin_message_map(caaaadlg, cdialog) end_message_map() // caaaadlg メッセージ ハンドラ aaaadlg.cpp ここまで ============================================== bbbbdlg.cpp ここから ============================================== #include "stdafx.h" #include "resource.h" // これがないと'idd_aaaa'が未定義のコンパイルエラーとなります #include "bbbbdlg.h" cbbbbdlg::cbbbbdlg(void) { } cbbbbdlg::~cbbbbdlg(void) { } void cbbbbdlg::onok() { if (afxmessagebox(_t("ダイアログを閉じます。よろしいですか?"), mb_okcancel) == idcancel) return; caaaadlg::onok(); } bbbbdlg.cpp ここまで ============================================== dlgtestdlg.cpp ここから============================================= // dlgtestdlg.cpp : 実装ファイル // #include "stdafx.h" #include "dlgtest.h" #include "dlgtestdlg.h" #include "bbbbdlg.h" #ifdef _debug #define new debug_new #endif // アプリケーションのバージョン情報に使われる caboutdlg ダイアログ class caboutdlg : public cdialog { public: caboutdlg(); // ダイアログ データ enum { idd = idd_aboutbox }; protected: virtual void dodataexchange(cdataexchange* pdx); // ddx/ddv サポート // 実装 protected: declare_message_map() }; caboutdlg::caboutdlg() : cdialog(caboutdlg::idd) { } void caboutdlg::dodataexchange(cdataexchange* pdx) { cdialog::dodataexchange(pdx); } begin_message_map(caboutdlg, cdialog) end_message_map() // cdlgtestdlg ダイアログ cdlgtestdlg::cdlgtestdlg(cwnd* pparent /*=null*/) : cdialog(cdlgtestdlg::idd, pparent) { m_hicon = afxgetapp()->loadicon(idr_mainframe); } void cdlgtestdlg::dodataexchange(cdataexchange* pdx) { cdialog::dodataexchange(pdx); } begin_message_map(cdlgtestdlg, cdialog) on_wm_syscommand() on_wm_paint() on_wm_querydragicon() //}}afx_msg_map on_bn_clicked(idc_test, &cdlgtestdlg::onbnclickedtest) end_message_map() // cdlgtestdlg メッセージ ハンドラ bool cdlgtestdlg::oninitdialog() { cdialog::oninitdialog(); // "バージョン情報..." メニューをシステム メニューに追加します。 // idm_aboutbox は、システム コマンドの範囲内になければなりません。 assert((idm_aboutbox & 0xfff0) == idm_aboutbox); assert(idm_aboutbox < 0xf000); cmenu* psysmenu = getsystemmenu(false); if (psysmenu != null) { bool bnamevalid; cstring straboutmenu; bnamevalid = straboutmenu.loadstring(ids_aboutbox); assert(bnamevalid); if (!straboutmenu.isempty()) { psysmenu->appendmenu(mf_separator); psysmenu->appendmenu(mf_string, idm_aboutbox, straboutmenu); } } // このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、 // framework は、この設定を自動的に行います。 seticon(m_hicon, true);// 大きいアイコンの設定 seticon(m_hicon, false);// 小さいアイコンの設定 // todo: 初期化をここに追加します。 return true; // フォーカスをコントロールに設定した場合を除き、true を返します。 } void cdlgtestdlg::onsyscommand(uint nid, lparam lparam) { if ((nid & 0xfff0) == idm_aboutbox) { caboutdlg dlgabout; dlgabout.domodal(); } else { cdialog::onsyscommand(nid, lparam); } } // ダイアログに最小化ボタンを追加する場合、アイコンを描画するための // 下のコードが必要です。ドキュメント/ビュー モデルを使う mfc アプリケーションの場合、 // これは、framework によって自動的に設定されます。 void cdlgtestdlg::onpaint() { if (isiconic()) { cpaintdc dc(this); // 描画のデバイス コンテキスト sendmessage(wm_iconerasebkgnd, reinterpret_cast(dc.getsafehdc()), 0); // クライアントの四角形領域内の中央 int cxicon = getsystemmetrics(sm_cxicon); int cyicon = getsystemmetrics(sm_cyicon); crect rect; getclientrect(&rect); int x = (rect.width() - cxicon + 1) / 2; int y = (rect.height() - cyicon + 1) / 2; // アイコンの描画 dc.drawicon(x, y, m_hicon); } else { cdialog::onpaint(); } } // ユーザーが最小化したウィンドウをドラッグしているときに表示するカーソルを取得するために、 // システムがこの関数を呼び出します。 hcursor cdlgtestdlg::onquerydragicon() { return static_cast(m_hicon); } void cdlgtestdlg::onbnclickedtest() { cbbbbdlg dlg; dlg.domodal(); } dlgtestdlg.cpp ここまで============================================= aaaadlg.h ここから============================================= #pragma once // caaaadlg ダイアログ class caaaadlg : public cdialog { declare_dynamic(caaaadlg) public: caaaadlg(cwnd* pparent = null); // 標準コンストラクタ virtual ~caaaadlg(); // ダイアログ データ enum { idd = idd_aaaa }; protected: virtual void dodataexchange(cdataexchange* pdx); // ddx/ddv サポート declare_message_map() }; aaaadlg.h ここまで============================================= bbbbdlg.h ここから============================================= #pragma once #include "aaaadlg.h" class cbbbbdlg : public caaaadlg { public: cbbbbdlg(void); virtual ~cbbbbdlg(void); protected: virtual void onok(); }; bbbbdlg.h ここまで============================================= 以上は私が作成したサンプルの一部です。 きちんと動作確認してあります。 コンパイル・エラーは #include "bbbbdlg.h"の前に #include "resoure.h"がなかったためではないでしょうか? 注目して頂きたいのは cdlgtestdlg::onbnclickedtest()の中身です。 cbbbbdlg dlg; dlg.domodal(); ごく普通にcbbbbdlgを使っています (caaaadlgは出てきていません) また cbbbbdlgのh/cppのどこでも "明示的には" caaaadlgのコンストラクタを呼び出していないことにも注目です。 一見すると caaaadlgをインスタンス化していない ように見えますが cbbbbdlgはcaaaadlgの派生なので cbbbbdlgのインスタンスの中にcaaaadlgのインスタンスがあります。 サンプルの概要はこうです caaaadlgは"hello world!"と表示するだけのダイアログで okボタンのみ持っています。 これを一切いじれないものと仮定します。 cbbbbdlgは基本的にはcaaaadlgと全く同じです。 しかし、 onokでメッセージボックスを表示し 閉じてよいかの確認をする この点の差異があります。 >詳しい方にちょっとだけソースコードを見て頂いたら、 >caaaadlgをインスタンス化していなから、 >caaaadlg::onok()使えないと指摘を受けました。 c++ではクラスのメソッド呼び出しに class::method() が使用できます。これは上でみたように派生クラスのメソッド内部で 基本クラスのメソッドを呼び出す際に使われます。 また、staticなメソッドを呼ぶ際にも使えます。 この場合 インスタンス化していなくても、用いることが可能です。 ”詳しい方"はcに詳しい方ですか? cに詳しい方がそのままc++にも詳しいとは限りません。 注意が必要です。