いつもお世話になっています。ミミです。
2つのダイアログAとBがあり、A内のボタンを押すとBを DoModal します。
Bには EditBox があり、Bが表示される時に初期値を表示します。
(1)Bに中間ワーク的なメンバ変数を設け、A内のボタンを押した時にBのメンバ変数に
表示したい値を設定し、Bの InitDialog()で表示する。
DialogA::OnButton1() {
DialogB dlgB;
dlgB.m_sIF = テスト; // m_sIF は CString型とします
dlgB.DoModal();
}
DialogB::OnInitDialog() {
m_edMsg = m_sIF; // m_edMsg は EditBoxのメンバ変数(CString型)です
UpdateData(FALSE);
}
と言うように、今まで中間ワークを経由させていました。
一方で、下記に示すような方法も考えられます。
(2) 呼び出し時にダイアログBのコントロールのメンバ変数(CString型)に直接設定
DialogA::OnButton1() {
DialogB dlgB;
dlgB.m_edMsg = テスト;
dlgB.DoModal();
}
(3) 呼び出し時にダイアログBのメンバ変数(コントロール変数)を利用して設定
DialogA::OnButton1() {
DialogB dlgB; // m_edcMsg は EditBoxのメンバ変数(CEdit型)です
dlgB.m_edcMsg.SetWindowText(テスト);
dlgB.DoModal();
}
(3)に関しては、ダイアログが表示される前に SetWindowText() をしていることになります。
ですが、ウィンドゥハンドルがNULLのため、MFC 内部のSetWindowText()にて Assertにて
異常終了します。
しかし、同じコントロールに関係するメンバ変数であっても、(2)に関しては、
意図するとおりの初期表示が行われます。
【質問】
・(2)の様な DoModal() する前にコントロールのメンバ変数(MFCによって作成された変数)
に値を設定する行為は問題ないのでしょうか。
それとも、コントロールに関係するメンバ変数へのアクセスは、DoModal() する前は
行わないほうがよいのでしょうか。( (3)に示す様に )
・(別スレッドにしたほうがよいのかも知れませんが...)
(3)は DialogB dlgB; にてインスタンスを作っているにもかかわらず、ウィンドゥ
ハンドルが取れないのはなぜでしょうか。
やはりダイアログBが表示されていないからでしょうか。
以上、よろしくご教授のほどお願いいたします。
(環境:Windows2000 SP4、VC6、MFC利用)
(2)の方法はOK
(3)の方法は、
インスタンスは作ってあっても、「ウィンドウ」が作られてないから
例)
CXXXWnd *wnd
wnd = new CXXXWnd; ←ここの状態(*1)
wnd->Create(......);←これをしないと「ウィンドウ」として使えない
DoModalする前は*1のところにあたる。
メンバ変数は実体があるので値は入れられるが
コントロールは親ウィンドウにあたるダイアログが作成されてないので
当然、子ウィンドウとして作成されていない。
よって「ウィンドウとしての操作」はできない。
ミミです。
rin 様、ありがとうございました。
(2)も(3)も、「インスタンスが作成されているから」という条件は同じであっても、
(3)については、ダイアログが作られていないので、子ウィンドゥもない、
即ち、DoModal()する前の段階では「コントロールに対し、ウィンドゥとしての操作
はできない」というご説明、納得できました。
> VC6付属のMSDN「一般的なウィンドウ作成手順」より参照
>> Create メンバ関数は、Windows のウィンドウを作成し、その HWND を
>> C++ オブジェクトのパブリック データメンバm_hWnd に格納します。
2つ目の質問である、ウィンドゥハンドルがNULLの理由も、
「まだDoModal()していない(ウィンドゥがない)から」ですね。
とてもわかり易いご解説、ありがとうございました。