Win2K VC++6.0 SP5 MFC です。
現在タイトルの通り、モードレスダイアログ内の DoDataExchange() を出た
時点で Access Violation が発生してしまっています。
落ちた時点でのコールスタックを見ても '30303030()' という感じで
コール状況も解らずデバッグが難しい状況です。
そのダイアログでは、DDX変数を定義してますが、DoDataExchange() 内に
いろいろと処理を書いてしまっています。
小生DDX変数がキライなので、ダイアログ部品にアクセスするときは、
GetDlgItem() を使うようにしていますが、他者から引き継いだものなので。
DoDataExChangeと、呼び出し側の関数は以下の通り。
--------------------------------------------
// Dialog 側
void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMyDlg)
DDX_Check(pDX, IDC_STATISTICS_AAA, m_CheckAAA);
DDX_Check(pDX, IDC_STATISTICS_BBB, m_CheckBBB);
DDX_Check(pDX, IDC_STATISTICS_CCC, m_CheckCCC);
DDX_Check(pDX, IDC_RENEWAL, m_Renewal);
DDX_Check(pDX, IDC_STATISTICS_DDD, m_CheckDDD);
//}}AFX_DATA_MAP
// なんかいろんな処理
// DDX変数には触っていないように見える
...
}
// 呼び出し 側
void CMainFrame::OnHoge()
{
if (MyDlg = new CMyDlg) {
MyDlg->Create(IDD_MY_DLG, NULL);
MyDlg->m_pDoc = pDoc;
} else
return;
MyDlg->m_CheckMin = TRUE; // <- DoDataExchange する前から値設定しちゃってい
いの?
MyDlg->m_CheckMax = TRUE;
MyDlg->m_CheckAve = TRUE;
MyDlg->m_CheckAve = TRUE;
MyDlg->UpdateData(FALSE);
MyDlg->ShowWindow(SW_SHOWNORMAL);
MyDlg->SetActiveWindow();
}
--------------------------------------------
何故上記の現象の原因が解る方、同様の経験をお持ちの方、よろしかったら
以下の点に対してご教唆願います。
・DoDataExchange 内に処理を書くのは使い方の作法にかなっているか?
・DoDataExchange 前に(上記のように)データを設定するのはだいじょうぶか?
>現在タイトルの通り、モードレスダイアログ内の DoDataExchange() を出た
>時点で Access Violation が発生してしまっています。
DDX なメンバ変数の種別やIDを変更したりしてませんか?
この辺の整合が崩れると、実行時エラーになります。
>・DoDataExchange 内に処理を書くのは使い方の作法にかなっているか?
あんまりよくないかも。
>・DoDataExchange 前に(上記のように)データを設定するのはだいじょうぶか?
CMyDlg::DoModal() 前ですよね?
なら全然平気。よくある手です。
>現在タイトルの通り、モードレスダイアログ内の DoDataExchange() を出た
>時点で Access Violation が発生してしまっています。
まずは、所々にreturnを挿入して、
どの行の処理が問題を引き起こしているかを特定しましょう。
>・DoDataExchange 内に処理を書くのは使い方の作法にかなっているか?
メンバ変数とコントロール値の交換にかかわる処理なら
書いても良いと思います。
たとえば、DDXがサポートしていないdoubleとCEditの交換とか、
入力値に対する特殊な検証が必要な場合とか。
>・DoDataExchange 前に(上記のように)データを設定するのはだいじょうぶか?
UpdateData(FALSE)は、メンバ変数からコントロールへの設定、
UpdateData(TRUE)は、コントロールからメンバ変数への設定です。
週末をはさんだため、返事が遅くなってすみません>渋木様、dairygoods様。
コントロールメンバ変数を廃し、DoDataExchange 内の処理を呼び出し側の
後ろに移動することで解決しました。
自分はコントロールメンバ変数は嫌いなので、自分本来のやり方ではありますが、
今回の対処としては「逃げ」だなぁ。
アドバイスありがとうございました>両者。