アプリ版:「スタンプのみでお礼する」機能のリリースについて

VC++超初心者です。

既出の質問(http://okwave.jp/qa2658942.html)と同様ですが、VC2005(CLR)でなく、VC++6.0の時
どのようにコーディングすればよいか教えていただけませんでしょうか。
よろしくお願いします。
**********************************
以下の2つのボタンのイベントハンドラ関数があった場合

//ボタン1のイベントハンドラ関数
void CAAAADlg::OnOK()
{
処理内容
}

//ボタン2のイベントハンドラ関数
void CBBBBDlg::OnOK()
{

}

ボタン2をクリックしたときの動作とボタン1の動作を同じにしたいと思っています。
**********************************

A 回答 (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さんの回答で本件を終了しますが、
また、宜しければご教授お願いします。

本当に、ご親切な対応ありがとうございました。

補足日時:2009/04/25 22:28
    • good
    • 0

CBBBBDlgがCAAAADlgを継承しているなら、CBBBBDlgのインスタンスはCAAAADlgのインスタンスを内包しています。

なので、CAAAADlg::OnOK()はちゃんと呼び出せます。
そういう指摘受けたとしたら、ちゃんとCAAAADlgを継承していないのでは?

どちらにしてもC++の知識が無さ過ぎますので、おっしゃってる関数化も多分無理だと思います。MFCの機能無しに関数化できますか?コントロールなどを参照もMFCを使えませんよ。
まぁ、後々の事を考えると関数化は止めといた方が良いと思いますが。最善の策はC++を勉強することです。あるいは、分る人に全部頼むかですね。

この回答への補足

ご回答、ありがとうございます。
(返信遅れてすみませんでした。)

ご指摘のとおりだと思います。
C++はじっくり勉強していないので、
オブジェクト指向の考え方がいまいち理解しておりません。

時間をみつけて、勉強しなおします。

補足日時:2009/04/25 22:07
    • good
    • 0

簡単です。


しかも、質問者さんが
(偶然かもしれませんが)
正解を出しています。

ただ、気づいていないのは
(既にお気づきの場合はごめんなさい)

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()使えないと指摘を受けました。

やはり、動かしたい部分を関数化して切り出すしかないのでしょうか?

補足日時:2009/04/13 22:08
    • good
    • 0

CAAAADlgとCBBBBdlgは親子関係あるのでしょうか


まったく別物ということですか

CAAAADlg::OnOKの中でCAAAADlgのコントロールなどを参照しているのですか
たとえばどこかのテキストボックスの値のチェックとか

この回答への補足

ご回答、ありがとうございます。

>CAAAADlg::OnOKの中でCAAAADlgのコントロールなどを参照しているのですか
参照しています。

補足日時:2009/04/10 13:15
    • good
    • 0

まったく同じでないなら、CDialogクラスを継承してCAABBDlgと言うのを作って、共通な処理させるメンバ関数を例えばCAABBDlg::OkCom()と言う名前で作ります。


で、CAAAADlgとCBBBBDlgの親クラスをCAABBDlgに書き換えます。
で実際の呼び出しは、
void CAAAADlg::OnOK()
{
OkCom();
}
void CBBBBDlg::OnOK()
{
CBBBBDlgの専用処理(その1)
OkCom();
}
ってするのはどうでしょか?

この回答への補足

ご回答、ありがとうございます。

他の方からも、zwiさんのようなアドバイスを頂きました。
void CAAAADlg::OnOK()は先人が書いたものなので、
個人的にはあまり手を加えたくありません。

そのため、CAAAADlg::OnOK()を呼び出せないかな、と
質問させていただきました。

補足日時:2009/04/10 13:18
    • good
    • 0

クラスが違うが同じ処理が必要な場合は、CAAAADlgとCBBBBDlgに共通の親クラスを作ってOnOK()を継承させれば解決すると思います。

この回答への補足

CAAAADlgはすでに作成済みであり、質問に書いた「処理内容」という
部分も大規模のものになっております。
それでも可能でしょうか?

また、もう少し詳細をお話しすると
CBBBBDlg::OnOK() の内部は、CAAAADlgと全く同じではなく、

void CBBBBDlg::OnOK()
{
CBBBBDlgの専用処理(その1)
CAAAADlg::OnOK() の処理内容
}

という具合にしたいです。

補足日時:2009/04/09 09:03
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!