非常に初歩的な質問ですがよろしくお願いいたします。
VC++ 6.0 MFCで、Waveファイルを取り扱うアプリケーションを作り始めましたが、
Viewクラスが大きくなりましたので、Dialogクラスの.hと.cppに関数定義しViewからコ
ールしてみることにしました。
Dialogクラスで下記のように定義し、
void DlgExtFunc (CDC* pDC)
{
pDC->TextOut( 50, 50, External Function Call);
}
Viewクラスで下記のように呼び出したいのですが、
void CFirFilterView::OnMenuAnalyze(CDC* pDC)
{ CDspScale Dsp;
//CDspScale::DlgExtFunc(CDC* pDC);
Dsp->DlgExtFunc(CDC* pDC);
}
コンパイルすると、Viewクラス内に定義されていないのでエラーになってしまいます。
何とか解決方法を見つけて、別のクラスの関数をコールできる形を作りたく、アドバイ
スよろしくお願いいたします。
>コンパイルすると、Viewクラス内に定義されていないのでエラーになってしまいます。
一体どんなエラーなんでしょうか?
エラーの一言だけでは私には何のことだか分かりません
クラス CDspScale なんか知らないと言っているのですか?
それとも void DlgExtFunc (CDC* pDC) なんて知らないといっているのですか?
>Dialogクラスで下記のように定義し、
>
> void DlgExtFunc (CDC* pDC)
>{
> pDC->TextOut( 50, 50, External Function Call);
>}
なんて書いてもダイアログクラスのメンバー関数なんかじゃありませんよ
>何とか解決方法を見つけて、別のクラスの関数をコールできる形を作りたく、
>アドバイスよろしくお願いいたします。
アドバイスがお望みなのでアドバイスしかしません
落ち着いてよく考えましょう
>コンパイルすると、Viewクラス内に定義されていないのでエラーになってしまいます。
何が定義されていないの?
話がそれるけど
そもそもDialogクラス?
Viewクラスが大きくなったからDialogクラス?
> void DlgExtFunc (CDC* pDC)
だからじゃないの?
> Dialogクラスで下記のように定義し、
>
> void DlgExtFunc (CDC* pDC)
> {
> pDC->TextOut( 50, 50, External Function Call);
>
> }
case 1:
これが、Dialog用のcppファイルに記述されているだけならば、
単なるグローバルの関数であり、Viewのcppから参照できません。
Dialog用のhファイルに、
void DlgExtFunc (CDC* pDC);
と宣言し、このhファイルをViewのcppでインクルードすると良いでしょう。
呼出しは、単にDlgExtFunc(CDC* pDC); のみです。
case 2:
CDspScaleというのが、追加したダイアログの名前であり、
このメンバ関数がDlgExtFuncということにしたいのならば、
// hファイル
class CDspScale : public CDialog {
...
public:
void DlgExtFunc (CDC* pDC);
};
// cppファイル
void CDspScale::DlgExtFunc (CDC* pDC) {
...
}
とします。
たいちろうさん、wclrp ( 'o')さん、しまさん、
舌足らずの質問への早速の書き込みありがとうございます。
早速試してみました。
整理の意味で、今回はエラーメッセージと該当するソース部分をリストしました。
エラーメッセージは、
「
1>c:\documents and settings\visual studio 2005
\projects\firfilter\firfilterview.cpp(1404) :
error C2511: 'void CFirFilterView::OnMenuAnalyze(CDC *)' :
オーバーロードされたメンバ関数が 'CFirFilterView' にありませ
ん。
」
「
1> c:\documents and settings\visual studio 2005
\projects\firfilter\firfilterview.h(13) :
'CFirFilterView' の宣言を確認してください。
」
と出てきます。
該当するソースを掲示させてください。
////////////// DspScale.h ファイル
class CDspScale : public CDialog
{
DECLARE_DYNAMIC(CDspScale)
public:
CDspScale(CWnd* pParent = NULL); // 標準コンストラクタ
virtual ~CDspScale();
// ダイアログ データ
enum { IDD = IDD_DSPSCALE };
int Random_Selected, Delay_Selected;
double Delay_Time;//mS
public:
void DlgExtFunc (CDC* pDC);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV サポー
ト
DECLARE_MESSAGE_MAP()
};
////////////// DspScale.cppファイル
IMPLEMENT_DYNAMIC(CDspScale, CDialog)
CDspScale::CDspScale(CWnd* pParent /*=NULL*/)
: CDialog(CDspScale::IDD, pParent)
{
中略
}
CDspScale::~CDspScale()
{
}
void CDspScale::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
中略
void CDspScale::DlgExtFunc (CDC* pDC)
{
pDC->TextOut( 50, 50, External Function Call);
}
BEGIN_MESSAGE_MAP(CDspScale, CDialog)
END_MESSAGE_MAP()
///////////// View ファイル FirFilterView.cpp
#include stdafx.h
中略
#include DspScale.h
/////////////////////////////////////////////////////////////////////////////
// CFirFilterView
IMPLEMENT_DYNCREATE(CFirFilterView, CView)
BEGIN_MESSAGE_MAP(CFirFilterView, CView)
ON_COMMAND(ID_SCALE_SCALEDISP, OnScaleDisp)
中略
ON_COMMAND(IDD_DSPANLZ, OnMenuAnalyze)
END_MESSAGE_MAP()
中略
void CFirFilterView::OnMenuAnalyze(CDC* pDC)
{
DlgExtFunc(CDC* pDC);
}
//////////////////////////////////////////
以上のように定義していますが、コンパイルエラーになってしまいます。
CDCのような書き出し機能を使っているのがいけないのでしょうか。
クラスの考え方が整理されていませんで、混乱しています。
最終的に、スムースに機能追加していく形を作りたく思っています。
よろしくお願いいたします。
ON_COMMANDマクロでどんな関数でも呼び出せるわけではない。
CFirFilterView::OnMenuAnalyze()を引数無しにしたら呼び出せると思うので、
ブレークポイントを設定したりして、呼び出せたことを確認してください。
ここにないけど、CFirFilterViewの宣言の中で、
OnMenuAnalyze()も同じ型で追加しておいてね。
ダイアログの呼出をどうするかはその次の話。
たいちろうさん、wclrp ( 'o')さん、しまさん、
しばらく時間がたってしまいました。すみません。別件で出張が入ったりしてしまいま
した。
お教えいただいた手法でやってみました。
CDC* pDC の受け渡しはできないのですが、関数のコールとして、うまくいきました。以
下はその経緯です。
(1)View内でのON_COMMANDマクロでの引数を取り外し、
ON_COMMAND(IDD_DSPANLZ, OnMenuAnalyze)
(2)Viweからの呼び出しを、
void CFirFilterView::OnMenuAnalyze()
{
CDspScale::DlgExtFunc();
}
として、
DspScale.hでのプロトタイプ宣言では、staticをつけ
static void DlgExtFunc();
としました。(こうしないと、「静的でないメンバ関数の呼び出しが正しくあ
りません」となってしまうためです。
こうすることで、関数のコールをすることができました。ありがとうございます。
(3)ただ、この場合、DspScale.h内で定義したクラス変数へのアクセスができず、ま
たpDCを引き渡せないのでグラフィックスの描画もできません。
(4)OnDrawのなかから直接 CDspScale::DlgExtFunc(pDC); をコールするとpDCの受
け渡しができるようですが、やはり同様にstaticの宣言をしないといけないので、
CDspScaleクラスの変数にはアクセスがかなわないようです。
(5)もうひとつ、ON_COMMAND(IDD_DSPANLZ, CDspScale::DlgExtFunc)と直接コールす
る形をとるとpDCの受け渡しはできませんが、CDspScale無いの変数にはアクセスが可能
です。
お知恵を拝借したいのですが。
今、私が主に関数の定義をしている、FirFilterView.cppに今後更に機能を追加していま
す。
FirFilterView.h内の変数を利用しながら拡張しています。
機能ごとに別ファイルにして増やして行きたいのですが(もし可能であれば)、
A.グローバル変数定義を利用したほうが良いでしょうか?
B.staticとしてプロトタイプ宣言しないと(CDspScale.h)コンパイラが受け付けてくれ
ないのですが、何かいい方法はありますでしょうか。
C.単に、ベースクラスのないクラスを付け足して、pDCを受け渡しグローバル変数のみに
頼って増やしていく形になるのでしょうか。
よいアドバイスありましたらご教示よろしくお願いいたします。
nickt
CFirFilterViewとCDspScaleの関係は?
m_dlgがCFirFilterViewのメンバである
CDspScaleだとすると、次のようになる。
staticは不要。
void CFirFilterView::OnMenuAnalyze()
{
CClientDC dc(this);
m_dlg.DlgExtFunc(&dc);
}
そうでない場合は、両者の関係を詳しく書いてください。
どうやってダイアログを表示しているかとか。
だからぁ!
void DlgExtFunc (CDC* pDC)
{
pDC->TextOut( 50, 50, External Function Call);
}
と書くのは、Cスコープの関数。
これのプロトタイプはドコでどのように宣言してますか?
CFirFilterViewはC++スコープ・・・。
コンパイラのメッセージ通りみたいですけど?
”オーバーロードされたメンバ関数が 'CFirFilterView' にありません。”
へんなとこで送信してまったorz
やりたいことは、こんなことじゃないの?
void CDspScale::DlgExtFunc (CDC* pDC)
{
pDC->TextOut( 50, 50, External Function Call);
}
void CFirFilterView::OnMenuAnalyze(CDC* pDC)
{
CDspScale *Dsp;
Dsp->DlgExtFunc(pDC);
}
>これのプロトタイプはドコでどのように宣言してますか?
は、質問では無く確認してね。って意味ですよ。
>(1)View内でのON_COMMANDマクロでの引数を取り外し、
> ON_COMMAND(IDD_DSPANLZ, OnMenuAnalyze)
●CFirFilterViewでメニューコマンド受け取るのですね。
>(2)Viweからの呼び出しを、
>void CFirFilterView::OnMenuAnalyze()
>{
> CDspScale::DlgExtFunc();
>}
●これ!意味わかりません!
●CDspScaleのインスタンスは?CDspScaleの実体はどこでしょう?
●実体居ないのにDCが渡せるわけもなく。
>(5)もうひとつ、ON_COMMAND(IDD_DSPANLZ, CDspScale::DlgExtFunc)と直接コール
す
>る形をとるとpDCの受け渡しはできませんが、CDspScale無いの変数にはアクセスが可
能
>です。
●CFirFilterViewのイベントハンドラから。ですか??
●ON_COMMANDをMSDNで調べてください。
そもそも。
> VC++ 6.0 MFCで、Waveファイルを取り扱うアプリケーションを作り始めましたが、
> Viewクラスが大きくなりましたので、Dialogクラスの.hと.cppに関数定義しViewから
コ
> ールしてみることにしました。
ヘンです。
Viewクラスが大きくなって、なんで突然Dialogクラスなんですか?
通常、1つのクラスが肥大化してどうしょうもないなら、
例えばCView.cppなら、CView01.cppとCView02.cppに分割すると思いますけど?
たいちろうさん、苑一さん、
ソースコードとしてFirFilterView1.cppを追加しました。必要なファイルをインクルー
ドしてうまくいきました。
こんな簡単なことだったんですね。なにやら恥ずかしいような気がします。
いろいろ外部のクラスに関数を埋め込もうとしたり、余計なことしていたようです。
Dialogクラスは勉強した例の中に出てきましたので、特にこのクラスで無いといけない
わけではないです。
アドバイスありがとうございました。大変参考になりました。
ちなみに、CDspScale *dsp; として、インスタンスを生成しようとすると、
「Run-Time Check Failure #3 - The variable 'dsp' is being used without being
defined.」
となって停止してしまうようです。何か他の方法があればと思います。今後の解決課題
として更に調べてみます。
DlgExtFuncは、
////////////// CDspScale.cpp///////////
// CDspScale ダイアログ
IMPLEMENT_DYNAMIC(CDspScale, CDialog)
BEGIN_MESSAGE_MAP(CDspScale, CDialog)
END_MESSAGE_MAP()
CDspScale::CDspScale(CWnd* pParent /*=NULL*/)
: CDialog(CDspScale::IDD, pParent)
{
}
CDspScale::~CDspScale()
{
}
void CDspScale::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Radio(pDX, IDC_RADIO1, Delay_Selected); // supposed to be a
group
DDX_Radio(pDX, IDC_RADIO3, Random_Selected);// supposed to be another
group
DDX_Text(pDX, IDC_EDIT1, Delay_Time); // setting delay time
}
void CDspScale::DlgExtFunc (CDC* pDC)
{
ccc = aaa + bbb;
pDC->TextOutA(100, 200, DspScale DlgExtFunc Calling !!!! Using local class
variables aaa, bbb, ccc);
}
///////////////////////////////////////
//////// FirFilterView.cpp////////////
void CFirFilterView::DoIntSpr5(CDC* pDC)
{
CDspScale *dsp;
pDC->TextOutA(100, 100, File Addition FirFilterView1.cpp);
dsp->DlgExtFunc(pDC); //エラー発生!!!
// Run-Time Check Failure #3 - The
variable 'dsp' is being used without being defined.
}
/////////////////////////////////////////