![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
VC++超初心者です。
既出の質問(http://okwave.jp/qa2658942.html)と同様ですが、VC2005(CLR)でなく、VC++6.0の時
どのようにコーディングすればよいか教えていただけませんでしょうか。
よろしくお願いします。
**********************************
以下の2つのボタンのイベントハンドラ関数があった場合
//ボタン1のイベントハンドラ関数
void CAAAADlg::OnOK()
{
処理内容
}
//ボタン2のイベントハンドラ関数
void CBBBBDlg::OnOK()
{
}
ボタン2をクリックしたときの動作とボタン1の動作を同じにしたいと思っています。
**********************************
No.6ベストアンサー
- 回答日時:
それではサンプルを載せます
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<WPARAM>(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<HCURSOR>(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++にも詳しいとは限りません。
注意が必要です。
この回答への補足
長文にわたるご回答、ありがとうございます。
また、ご回答が遅れてしまい、申し訳ございませんでした。
本件は、結果的に他の方に任せてしまいましたが、
悔しいので自分でもやってみるつもりです。
また、この度、長文にわたって教えて頂いたソースも
まだ理解できておりませんが、確実に糧にしていきたいと
思います。
>”詳しい方"はCに詳しい方ですか?
>Cに詳しい方がそのままC++にも詳しいとは限りません。
>注意が必要です。
素人の私の意見ですが、私もそう思います。
私はC言語は学生の時からなんとなく使っていますが、
・C++、
・VC++(6.0)(MFCとういうのでしょうか?)、
・VC++/CLI(VC++ .NET)
これらは、かなり違うものなんだな、と感じています。
とにかく、勉強し直します。
今回は、No6さんの回答で本件を終了しますが、
また、宜しければご教授お願いします。
本当に、ご親切な対応ありがとうございました。
No.5
- 回答日時:
CBBBBDlgがCAAAADlgを継承しているなら、CBBBBDlgのインスタンスはCAAAADlgのインスタンスを内包しています。
なので、CAAAADlg::OnOK()はちゃんと呼び出せます。そういう指摘受けたとしたら、ちゃんとCAAAADlgを継承していないのでは?
どちらにしてもC++の知識が無さ過ぎますので、おっしゃってる関数化も多分無理だと思います。MFCの機能無しに関数化できますか?コントロールなどを参照もMFCを使えませんよ。
まぁ、後々の事を考えると関数化は止めといた方が良いと思いますが。最善の策はC++を勉強することです。あるいは、分る人に全部頼むかですね。
この回答への補足
ご回答、ありがとうございます。
(返信遅れてすみませんでした。)
ご指摘のとおりだと思います。
C++はじっくり勉強していないので、
オブジェクト指向の考え方がいまいち理解しておりません。
時間をみつけて、勉強しなおします。
No.4
- 回答日時:
簡単です。
しかも、質問者さんが
(偶然かもしれませんが)
正解を出しています。
ただ、気づいていないのは
(既にお気づきの場合はごめんなさい)
CBBBBDlgをCAAAADlgから派生させる
これだけです。
両者の基本クラスも必要ありませんし
既に作成してしまった
CAAAADlg
には一切手を加える必要はありません。
そして
CBBBBDlgでOnOKをオーバーライドします。
中身は
void CBBBBDlg::OnOK()
{
CBBBBDlgの専用処理(その1)
CAAAADlg::OnOK()
}
です。
どこかで見たコードです。
補足そのものです。
ただ
CAAAADlg::OnOK()
であって
CAAAADlg::OnOK() の処理内容
ではありません。
もちろん後者
CAAAADlg::OnOK() の処理内容
でも構いませんが、
後々(バグや仕様変更などで)
CAAAADlg::OnOK()
を修正した場合
CBBBBDlg::OnOK()
も修正しなければならない
というデメリットがあるので
前者
CAAAADlg::OnOK()
をお勧めします。
この回答への補足
ご回答ありがとうございます。
(返信送れて申し訳ございませんでした。)
なるほど、と思い早速コーディングしましたが、
コンパイルエラーが出てしまいました。
詳しい方にちょっとだけソースコードを見て頂いたら、
CAAAADlgをインスタンス化していなから、
CAAAADlg::OnOK()使えないと指摘を受けました。
やはり、動かしたい部分を関数化して切り出すしかないのでしょうか?
No.2
- 回答日時:
まったく同じでないなら、CDialogクラスを継承してCAABBDlgと言うのを作って、共通な処理させるメンバ関数を例えばCAABBDlg::OkCom()と言う名前で作ります。
で、CAAAADlgとCBBBBDlgの親クラスをCAABBDlgに書き換えます。
で実際の呼び出しは、
void CAAAADlg::OnOK()
{
OkCom();
}
void CBBBBDlg::OnOK()
{
CBBBBDlgの専用処理(その1)
OkCom();
}
ってするのはどうでしょか?
この回答への補足
ご回答、ありがとうございます。
他の方からも、zwiさんのようなアドバイスを頂きました。
void CAAAADlg::OnOK()は先人が書いたものなので、
個人的にはあまり手を加えたくありません。
そのため、CAAAADlg::OnOK()を呼び出せないかな、と
質問させていただきました。
No.1
- 回答日時:
クラスが違うが同じ処理が必要な場合は、CAAAADlgとCBBBBDlgに共通の親クラスを作ってOnOK()を継承させれば解決すると思います。
この回答への補足
CAAAADlgはすでに作成済みであり、質問に書いた「処理内容」という
部分も大規模のものになっております。
それでも可能でしょうか?
また、もう少し詳細をお話しすると
CBBBBDlg::OnOK() の内部は、CAAAADlgと全く同じではなく、
void CBBBBDlg::OnOK()
{
CBBBBDlgの専用処理(その1)
CAAAADlg::OnOK() の処理内容
}
という具合にしたいです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C++にてtemplateで受け取った任...
-
ウインドウの移動禁止
-
Win10のVS2022のForm AppからC...
-
GDI+の使用方法について
-
ドラッグしたときにマウスカー...
-
(void)0 はどんな意味ですか
-
【gcc・cygwin】multiple defin...
-
void*型の配列について
-
多重定義が起きている?--lnk20...
-
メッセージマップ(ON_CONTROL_...
-
自作DirectShow Filterのinter...
-
c言語 引数のvoidについて
-
bsearch関数
-
戻り値を返す関数の前に(void)...
-
【VC++2005】ソースの書き方:...
-
既定のコンストラクタがありま...
-
__threadを使うコードで、分割...
-
PIC16F819
-
AtCoderABC135の問題Cについて
-
信頼区間の1.96や1.65ってどこ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
既定のコンストラクタがありま...
-
【gcc・cygwin】multiple defin...
-
戻り値を返す関数の前に(void)...
-
多重定義が起きている?--lnk20...
-
C++にてtemplateで受け取った任...
-
静的でないメンバ関数の呼び出...
-
int main()、void main()、void...
-
C# Controls.Addで動的に配置し...
-
const_castのつかいどころを教...
-
void*型の配列について
-
(void)0 はどんな意味ですか
-
C# KeyDownイベントでショート...
-
VC++でGetKeyboardStateがうま...
-
クラス間でのクラスの共有?
-
gcc: incompatible pointer type
-
typedef unsigned int UINT;が...
-
コールバックって・・・
-
C言語 ① 5秒間 1秒間隔で点滅を...
-
ウインドウの移動禁止
-
Notepad++の関数リスト表示の変...
おすすめ情報