- ベストアンサー
モードレスダイアログについて
いつもお世話になっています。 WIN98 VC++6.0 MFC モードレスダイアログにおいて、 子ダイアログが表示されていても親ダイアログの操作が出来ますが、親ダイアログを子ダイアログの前に持ってくるにはどうすれば良いのでしょうか?
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
>私もこれで勝手に悩んでしまいましたが、オーバーライドされています。 引数の型や数が違うようなので、正式にはオーバーロードですね。 >終了時の処理は以下となっており、モードレスダイアログの生成をm_pTest->Create(this);でおこなっている時は、まったく問題ありません。 サンプルのコードは、CTestDlgダイアログの親が必ずCModelessDlgであるということを想定したコードです。 そのため、 ((CModelessDlg *)m_pParent)->EndTestDlg(); が正常に動作します。はっきりいって、このキャストでCModelessDlg*に変換するのはあまりよくないですね。 EndTestDlg()の定義がわかりませんが、仮想関数なのでしょうか。 私ならこうします。 CTestDlgクラスで定義されているm_pParentの型をCWnd* からCTestDlg*に変更 BOOL CTestDlg::Create(CWnd *pWnd, CTestDlg *pCallWnd) { m_pParent = pCallWnd; BOOL bret = CDialog::Create(CTestDlg::IDD, pWnd); if( bret == TRUE) { this->ShowWindow( SW_SHOW); } return bret; } m_pTest = new CTestDlg; m_pTest->Create(GetDesktopWindow(), this); void CTestDlg::PostNcDestroy() { // TODO: この位置に固有の処理・・・ if( pParent != NULL) { pParent ->EndTestDlg(); delete this; }
その他の回答 (5)
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>SetParent(NULL);としたところ、親ダイアログがアクティブになりましたが、前面には表示されませんでした。 m_pTest->SetParent(NULL); こう記述してだめでしたか? 手元に確認できる環境がないんで未確認ですが。
お礼
回答ありがとうございます。 SetParent(NULL);このように記述してダメでした。 m_pTest->SetParent(NULL); に変更しても現象は変わりませんでした。
- darksky
- ベストアンサー率66% (38/57)
CDialogでモードレスダイアログを生成するには、以下のCreate関数を呼び出す必要がありますが、 virtual BOOL Create( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL ); virtual BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL ); コードを見ると、 m_pTest = new CTestDlg; m_pTest->Create(GetDesktopWindow()); となっていますが、CTestDlgクラスでCreateを定義しているのでしょうか? 通常は、 if( m_pTest == NULL) { m_pTest = new CTestDlg; m_pTest->Create(CTestDlg::IDD, GetDesktopWindow()); } かと思うんですが。 あと、 >但し、子ダイアログを閉じ、再び子ダイアログを表示しようとするとエラーが出て落ちます。 とありますが、m_pTestクラスが閉じられた後の処理が記述されていないので明確にはわかりませんが、 m_pTestが閉じられるときは、m_pTestのウィンドウを終了するためにDestoryWindow()を呼び出す必要があります。 その後、newで生成したm_pTestを解放してm_pTest=NULLとして再度、newとCreateをするか、m_pTestインスタンスを再利用するならまた、Createを行う必要があります。 子ダイアログを閉じた後、再表示する時の処理に誤りがあるようですので、見直してみてください。
お礼
http://www.athomejp.com/goldfish/mfc/dialog/modeless.html これを参考にモードレスダイアログを勉強しています。 >m_pTest->Create(GetDesktopWindow()); >となっていますが、CTestDlgクラスでCreateを定義しているのでしょうか? 私もこれで勝手に悩んでしまいましたが、オーバーライドされています。 終了時の処理は以下となっており、モードレスダイアログの生成をm_pTest->Create(this);でおこなっている時は、まったく問題ありません。 void CTestDlg::PostNcDestroy() { // TODO: この位置に固有の処理・・・ if( m_pParent != NULL) { ((CModelessDlg *)m_pParent)->EndTestDlg(); delete this; } CDialog::PostNcDestroy(); } void CTestDlg::OnClose() { // TODO: この位置に・・・ if( m_pParent != NULL) { DestroyWindow(); } else { CDialog::OnClose(); } }
- taka_tetsu
- ベストアンサー率65% (1020/1553)
失礼しました。 単純にCDialog::Createで親ウィンドウをNULLにすると、 親がアプリケーションのメインウィンドウになってしまうんですね。 Createをオーバーライドして何とかする方法もありますが、やめておきます。 親子の関係を切れば独立します。 SetParent()でNULLを指定してください。 SetWindowPosはだめでしたね。 確認しました。
お礼
SetParent(NULL);としたところ、親ダイアログがアクティブになりましたが、前面には表示されませんでした。
- darksky
- ベストアンサー率66% (38/57)
モードレスダイアログを作成するときのCreate関数の第2引数に CWnd::GetDesktopWindow() を指定する。 いいのかなぁ~
お礼
回答ありがとうございます。 void CModelessDlg::OnButton1() { if( m_pTest == NULL) { m_pTest = new CTestDlg; m_pTest->Create(GetDesktopWindow()); } ・ ・ ↑出来ました。 但し、子ダイアログを閉じ、再び子ダイアログを表示しようとするとエラーが出て落ちます。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
常に:SetWindowPos クリックしたときだけ:ダイアログを作成する時の親ウィンドウにNULLを指定
お礼
いつもお世話になります。 void CModelessDlg::OnButton1() { if( m_pTest == NULL) { m_pTest = new CTestDlg; m_pTest->Create(NULL); } ↑アクティブにはなりますが、前には来ませんでした。 void CModelessDlg::OnButton1() { if( m_pTest == NULL) { m_pTest = new CTestDlg; ::SetWindowPos(this->m_hWnd, HWND_TOPMOST,0,0,800,800,SWP_SHOWWINDOW); } ↑アクティブにはなりますが、前には来ませんでした。
お礼
回答ありがとうございます。 m_pTest->Create(GetDesktopWindow(), (CTestDlg *)this); thisをキャストすることでうまく行きました。