
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で質問しましょう!
似たような質問が見つかりました
- Access(アクセス) アクセス 意図せずサブプロシージャを移動してしまうのを止めたい 1 2022/09/02 09:19
- JavaScript jsで診断コンテンツのページ内切り替えについて 1 2023/04/14 17:31
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- Excel(エクセル) excelvbaでスライドショーを作りたい 2 2023/04/20 14:32
- 国産車 【日産自動車のVCターボエンジンは4WD動作を部品点数を減らした一体化したユニットにした 5 2023/05/26 23:00
- その他(パソコン・周辺機器) ボタン数の多いゲームコントローラー、ゲームパッドを探しています 2 2023/08/17 16:29
- Visual Basic(VBA) VBAで早押しゲームを作りたい 4 2022/05/12 13:46
- Access(アクセス) Access IF文でテーブルに存在しない場合の処理について 2 2022/10/10 18:09
- その他(データベース) Accessフォームからパラメーターで表示したレコードを指定のExcelのセルへ転送する方法について 2 2022/08/22 18:04
- Visual Basic(VBA) 複数ファイルのデータの統合について 12 2022/05/14 12:03
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
static constメンバ変数(配列)...
-
ソケット通信時のWSACleanup処...
-
プログラミング教えてください
-
二重定義の回避法
-
既定のコンストラクタがありま...
-
C++にてtemplateで受け取った任...
-
C#でテンキーの操作は可能でし...
-
_beginthreadにて発生するコン...
-
リージョンのフレームを描画す...
-
関数名の名前の衝突について。
-
C言語 extern について
-
メッセージマップ(ON_CONTROL_...
-
関数の戻り値にその関数のポイ...
-
int main()、void main()、void...
-
カノニカルモードの設定について
-
CTabCtrl:TABインデックス単位...
-
Aの値からBの値を除するとは??
-
「Aに対するBの割合」と「Aに対...
-
2÷3などの余りについて
-
数字以外が入力されたらエラー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【gcc・cygwin】multiple defin...
-
多重定義が起きている?--lnk20...
-
C++にてtemplateで受け取った任...
-
const_castのつかいどころを教...
-
既定のコンストラクタがありま...
-
戻り値を返す関数の前に(void)...
-
静的でないメンバ関数の呼び出...
-
int main()、void main()、void...
-
C# KeyDownイベントでショート...
-
C# Controls.Addで動的に配置し...
-
(void)0 はどんな意味ですか
-
gcc: incompatible pointer type
-
C#でラジオボタンを設定に記録...
-
_beginthreadにて発生するコン...
-
C#でテンキーの操作は可能でし...
-
C++別のオブジェクトからメンバ...
-
CTabCtrl:TABインデックス単位...
-
見た目は同じソースなのにエラ...
-
【VC++6.0】イベントハンドラ関...
-
pictureboxの画像を削除するには?
おすすめ情報