プロが教えるわが家の防犯対策術!

VC++ MFC エラーコード C2248


現在、ダイアログAにあるコンボボックス(IDC_COMBO1)に単語を登録、削除する処理をしています。

ダイアログAには他に[登録]ボタン(IDC_BUTTON1)と[削除]ボタン(IDC_BUTTON2)があります。

IDC_COMBO1 を CComboBox m_combo;

として

// [登録]ボタン押下時
void CADlg::OnBnClickedButton1()
{
CString Txt, old;
int ret = 0, count = 0, i;

m_combo.GetWindowText(Txt);

if ( strcmp(Txt, "") == 0 ) {
AfxMessageBox( _T("語句を入力してください"));
return;
}
// コンボボックスのリスト数取得
count = m_combo.GetCount();

for(i = 0; i < count; i++){
// IDC_COMBO1に登録済みの語句を順番に調べていく
m_combo.GetLBText(i, old);

// 既に登録済みの名前があった場合
if (oldFile == Txt){
ret = MessageBox( _T("上書きしますか?"), _T("語句登録"), MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2 );
}
}

if ( ret == IDYES ) {
return;

} else if ( ret == IDNO ) {
// 後ほど説明します
CBDlg dlg;
dlg.DoModal();
m_combo1.AddString(NewName);// extern CString NewName;←グローバル変数(Bダイアログから)
return;
}

// 登録されていない語句の場合
m_combo.AddString(Txt);
}

上記の登録の方、エラーなくコンパイルがとおり、コンボボックスにもちゃんと格納されています。

削除の方もエラーなくちゃんとコンボボックスから削除されます。


次に
>else if ( ret == IDNO )
の部分なのですが

[いいえ]ボタン(IDNO)が押された場合にはダイアログBが表示されます。

ダイアログBには語句を入力するエディットボックスIDC_EDIT1、[登録]ボタン(IDC_TOUROKU)、[取り消し]ボタン(IDC_TORIKESI)があります。

IDC_EDIT1 を CEdit m_ed1;

として

ここのBダイアログでもAダイアログ中のコンボボックスに格納されている語句が入力された場合はメッセージボックスを表示したいのです。


そこで


void CBDlg::OnBnClickedTouroku()
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
int rup, cnt, ret;
CString oldf;
CADlg cad;

CComboBox cfdn = cad.m_combo;

m_ed1.GetWindowText(NewName);// CString NewName;←グローバル変数

// Aダイアログ中のコンボボックスリスト数の取得
cnt = cfdn.GetCount();

for(rup = 0; rup < cnt; rup++){

// Aダイアログのコンボボックス中に登録されている語句取得
cfdn.GetLBText(rup, oldf);

if (oldf == NewName){
ret = MessageBox( _T("本当に上書きしてもいいですか?"), _T("環境設定"), MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2 );
}
}

if(ret == IDOK){
OnOK();
}
else{
return;
}
}

としました。

ここでコンパイルすると

1>c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxwin.h(1820) : error C2248: 'CObject::CObject' : private メンバ (クラス 'CObject' で宣言されている) にアクセスできません。
1> c:\program files\microsoft visual studio 8\vc\atlmfc\include\afx.h(558) : 'CObject::CObject' の宣言を確認してください。
1> c:\program files\microsoft visual studio 8\vc\atlmfc\include\afx.h(529) : 'CObject' の宣言を確認してください。
1> コンパイラでのこの診断により関数 'CCmdTarget::CCmdTarget(const CCmdTarget &)' が生成されました。

のようにエラーがでます。

調べてみると

CComboBox cfdn = cad.m_combo;

が原因のようです。

ググってみたりしたのですが解消法がわからず質問させていただきました。

よろしくお願いします。

A 回答 (4件)

 こんにちは。

補足頂きました。
 大変、すんません、CBDlgクラスのコンストラクタ内でCDialog(CBDlg::IDD, pADlg)を呼び出していませんでした。

CBDlgのソースファイルで、
/////////////////////////////////////////////////////////////////////////////
// CBDlg ダイアログ
CBDlg::CBDlg(CADlg* pADlg) : CDialog(CBDlg::IDD, pADlg), m_pADlg(pDlg)
{
//{{AFX_DATA_INIT(CBDlg)
// メモ - ClassWizard はこの位置にマッピング用のマクロを追加または削除します。
//}}AFX_DATA_INIT
}

 の様にして、DoModal()で動作しませんか。
 「Debug Libraly」のメッセージボックスが表示されるのは、此れが原因でした(当方の方でも確認)。
    • good
    • 0
この回答へのお礼

ご回答いただきありがとうございます。

この処理で無事解決することができました。

BAはこの最後の回答にさせていただきたく思います。
ありがとうございました!

お礼日時:2009/01/23 13:27

 こんにちは。

補足頂きました。

CBDlg* pBDlg = new CBDlg(this);
pBDlg->Create(CBDlg::IDD, this);
pBDlg->ShowWindow(SW_SHOW);

 又は、モーダル(ダイアログBが閉じられるまで他のウィンドウのボタンなどを操作出来なくする)したいのなら、

CBDlg BDlg(this);
BDlg.DoModal();

 で開きませんか。

この回答への補足

CBDlg BDlg(this);
BDlg.DoModal();

の方で処理をしたいのですがこれだと「Debug Libraly」のメッセージボックスが表示されてしまいます。

前者の方では正常に動いていますが…

補足日時:2009/01/23 11:39
    • good
    • 0

 こんにちは。

補足頂きました。

>>ASSERT(::IsWindow(m_hWnd)); // ここ
 ダイアログAのウィンドウハンドルが不正か、存在しないか(既に消されてしまっているか)だと思います。
 しかし、m_pADlgのポインタが不正であった場合も結果として、此の現象が発生します。

 と言う事で、m_pADlgにダイアログAのポインタをしっかりと代入しているかどうか? と言う事だと思います。

 CBDlgのヘッダーファイルで、

 class CBDlg
 {
   //コンストラクタでダイアログAのポインタを引き取る
   explicit CBDlg(CADlg* pADlg = NULL);

   //遅延通知用
   void SetDialogA(CADlg* pADlg);

   //省略
   CADlg* m_pADlg;
  };

 CBDlgのソースファイルで、

 //コンストラクタ
 ////////////////////////////////////////////////
 CBDlg::CBDlg(CADlg* pADlg) : m_pADlg(pADlg)//←ココでダイアログAのポインタを引き取る
 {

 }

 //新規追加
 void CBDlg::SetDialogA(CADlg* pADlg)
 {
   m_pADlg = pADlg;
 }

 CADlgのソースファイル中でCBDlgを開く場所で

 CBDlg pBDlg = new CBDlg(this);

 または、

 CBDlg pBDlg = new CBDlg();
 pBDlg->SetDialogA(this);

 とすれば良いと思います。
 何れにも当てはまらない場合には、CBDlgを開いている周辺のコードを見せて頂かないと分かりません・・・。

この回答への補足

お礼への補足とさせてください。

CBDlg pBDlg = new CBDlg();
 pBDlg->SetDialogA(this);

でBダイアログは生成されるのだろうと思い
この処理のみで実行してみましたが

Bダイアログは開かれませんでした。

そこで

CBDlg dlg;
dlg.DoModal();

をした場合、
「Debug Libraly」のメッセージボックスが表示されて上手い具合にいきません。

改善策を教えていただければと思います。

補足日時:2009/01/23 10:55
    • good
    • 0
この回答へのお礼

お礼が遅れ申し訳ございません。

CBDlg pBDlg = new CBDlg();
 pBDlg->SetDialogA(this);

の方でコンパイルは通りますが、

CBDlg pBDlg = new CBDlg();
 pBDlg->SetDialogA(this);

の処理のあとに

CBDlg dlg;
dlg.DoModal();

の処理は追加する必要があるのでしょうか?

初心者ゆえの質問になってしまいますがよろしくお願いいたします。

お礼日時:2009/01/23 10:43

 こんにちは。



 CComboBox cfdn = cad.m_combo;
 cad.m_comboはprivateメンバである為、外部から触る事が出来ません。コンパイラは其れを通知しているのではないでしょうか。
 CADlgのヘッダファイルにあるclass CADlgの中に

 class CBDlg;

 class CADlg
 {
    friend class CBDlg;
    //省略
 };

 と書けばコンパイルに通す事だけは出来ます。ただし、根本的な解決には成らないと思います。
 その理由なのですが、

 CADlg cad;
 CComboBox cfdn = cad.m_combo;

 と有りますが、此れではCADlgを此の場所で一時的に作成する事に成ってしまいます。
 本当に手元に欲しいのは、向こうで開かれているCADlgそのものです。

 ですので、以下の様な感じにならないと、処理が意図した通りに達成出来なくなります。

 if(!m_pADlg)
 {
   ;//error
   return;
 }
 CComboBox* pComboBox = static_cast<CComboBox*>(m_pADlg->GetDlgItem(IDC_COMBO1));
 if(!pComboBox)
 {
   ;//error
   return;
 }
 //ココで漸くダイアログAのコンボボックスが取れた事になる
 cnt = pComboBox->GetCount();

 こうする為に、class CBDlgの中に

 CADlg* m_pADlg;

 を追加して、CBDlgを開く時に、CADlg側からポインタを送り届けないと、CBDlg側からCADlgを操作する手段がない事に成ってしまいます。
 ダイアログAとダイアログBの関係と言う、此の手の質問は結構上がるのですが、

 http://oshiete1.goo.ne.jp/qa4316216.html

 辺りが其れに近いと思います。

この回答への補足

例外が発生してしまう場所は
>CComboBox* pComboBox = static_cast<CComboBox*>(m_pADlg->GetDlgItem(IDC_COMBO1));

でした。
ペーストミスです、すみません。

補足日時:2009/01/20 15:55
    • good
    • 0
この回答へのお礼

回答いただきありがとうございます。

下方にある処理で試したところエラーは解消されましたが、

実行後、Bダイアログでも同じ名前を入力したところ

>CComboBox* pComboBox = static_cast<CComboBox*>(c1tirf03->GetDlgItem(IDC_MAIN_FILMDEV_NAME));

の部分でアクセス違反が発生してしまいます。

エラー文をクリックすると以下のところに飛びます。

#include "winocc.cpp"

CWnd* CWnd::GetDlgItem(int nID) const
{
ASSERT(::IsWindow(m_hWnd)); // ここ

if (m_pCtrlCont == NULL)
return CWnd::FromHandle(::GetDlgItem(m_hWnd, nID));
else
return m_pCtrlCont->GetDlgItem(nID);
}


これは何故なのでしょうか?
初心者で解消法がわからないためお手数ですがご回答の程よろしくお願いいたします。

お礼日時:2009/01/20 15:41

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