MFCにおけるモードダイアログと非モードダイアログの違い

3628 ワード

MFCには、モードダイアログ(model dialog box)と非モードダイアログ(modeless dialog box)の2つの形式があります.両者の違いは、ダイアログが開いたときに、ユーザが他のオブジェクトの操作を許可するかどうかです.
一、モードダイアログ(model dialog box)
プログラムの実行中にモダリティダイアログボックスが表示されると、メインウィンドウはモダリティダイアログボックスが終了するまでメッセージを送信できません.モードダイアログボックスのOKボタンをクリックすると、モードダイアログボックスが破棄されます.
モダリティダイアログボックスのコードを作成します.
//           
CTestDialog td;  
td.DoModal();   

このうちCTestDialogは、自分が新しく作成したダイアログリソースに関連付けられたダイアログクラスです.
レイアウトモードダイアログクラス変数を作成できます.関数が戻るにつれて破棄される心配はありません.DoModal()関数の1つの機能は、現在このモードダイアログボックスのみを実行し、モードダイアログボックスが終了するまでメインウィンドウの実行を停止することです.
DoModal()関数にはダイアログを表示する機能もあるので、他の関数を呼び出してダイアログを表示する必要もありません.
二、非モードダイアログ(modaless dialog box)
プログラムの実行中に非モードダイアログボックスが表示されると、メインウィンドウからメッセージを送信することもできます.
非モードダイアログボックスのOKボタンをクリックすると、非モードダイアログボックスは破棄されず、非表示になります.OKボタンをクリックしたい場合、非モダリティダイアログボックスも破棄されると、CTestDialogクラスは、そのベースクラスCDialogの虚関数OnOK()を再ロードし、この関数ではDestroyWindow()を呼び出してダイアログボックスを破棄する必要があります.
非モードダイアログを作成するには、2つの関数Create()ShowWindow()を呼び出す必要があります.
上記と同様に非モデリングダイアログボックスを作成すると、次のようになります.
CTestDialog td;  
td.Create(IDD_DIALOG1); //            
td.ShowWindow(SW_SHOWNORMAL); //          

では、実行時にこのダイアログボックスが表示されないことに気づきます.これは、宣言したダイアログ変数tdがローカル変数であるためですが、この関数が戻るとtdも解析されるため、このダイアログを表示できません.
非モダリティダイアログボックスを作成するには、CTestDialogクラスへのポインタ変数を宣言し、ダイアログボックスを表示するには、表示する呼び出しShowWindow()を宣言する必要があります.作成方法は2つあります.
  • ローカル変数を使用して非モードダイアログ
     //                  
     CTestDialog *pTD = new CTestDialog();  
     pTD->Create(IDD_DIALOG1); //            
     pTD->ShowWindow(SW_SHOWNORMAL); //          
    
    を作成します.ポインタは宣言時にスタックに配置され、アプリケーション全体が閉じてから破棄されるため、ダイアログボックスを正常に表示できます.この方法はプログラムの実行には影響しないが,ポインタpTDが指すメモリが利用できないため,このようなプログラミングはよくない.
  • メンバー変数を使用して非モデリングダイアログボックスを作成します.まず、作成するクラスのヘッダファイルにポインタ変数を宣言します.
     private:  
     	CTestDialog *pTD;  
    
    その後、対応するCPPファイルを作成します.ダイアログボックスを作成する場所に次のコードを追加します.
     //                  
     pTD = new CTestDialog(); //         
     pTD->Create(IDD_DIALOG1); //            
     pTD->ShowWindow(SW_SHOWNORMAL); //          
    
    最後に、クラスの構造関数でpTDが指すメモリを回収します.
     delete pTD;  
    
  • 三、廃棄の違い
    モダリティダイアログボックスの破棄はEndDialogであり、モダリティダイアログボックスの破棄はDestroyWindowではない.ダイアログボックスを破棄するときも、それを区別します.
    非モードダイアログ、ユーザーがダイアログを閉じると、ダイアログメッセージ処理関数はWM_CLOSEメッセージを受け取り、その後DestroyWindowを呼び出して非モードダイアログを破棄します.
    モダリティダイアログボックスでは、IDOKおよびIDCANCELが一般的に応答する.PPCではOKキーとXキーの取り扱いに注意する.
    四、注意事項
    非モードダイアログボックスオブジェクトは、メンバー変数として他のオブジェクトに埋め込まれたり、ローカル変数としてスタックに構築されたりするのではなく、newオペレータを使用してスタック内で動的に作成されます.通常、ダイアログ・ボックスの所有者ウィンドウ・クラスに、ダイアログ・ボックス・オブジェクトにアクセスできるポインタ・メンバー変数を宣言します.
    DoModalではなくCreate関数を呼び出してダイアログボックスを起動します.これは非モードダイアログボックスの鍵です.Create関数は新しいメッセージループを起動しないため、ダイアログボックスはアプリケーションと同じメッセージループを共有し、ダイアログボックスがユーザーの入力を独占しません.Createはダイアログボックスが表示されるとすぐに戻り、そしてDoModalは(モダリティダイアログ)は、ダイアログが閉じられてから戻ってくることが知られている.MFCプログラムでは、ウィンドウオブジェクトの生存期間は、対応するウィンドウよりも長くなければならない.つまり、画面上のウィンドウを閉じていない場合に、まず対応するウィンドウオブジェクトを削除することはできない.Createが戻ってきてから、ダイアログが閉じているかどうかを判断することはできないため、ダイアログペアを特定することはできない象の生存期間は,スタック内で非モードダイアログオブジェクトを構築するしかなく,局所変数の形で構築することはできない.
    newオペレータで非モードダイアログオブジェクトを構築するため、ダイアログボックスが閉じた後、deleteオペレータでダイアログオブジェクトを削除する必要があります.
    非モードダイアログボックスが開いているかどうかを示すフラグが必要です.これは、ユーザがモードダイアログボックスを開いた場合に、再びコマンドを開くことを選択する可能性があるためです.プログラムは、フラグに基づいて、新しいダイアログを開くか、元のダイアログをアクティブにするかを決定します.通常、このフラグとして、所有者ウィンドウのダイアログ・オブジェクトへのポインタを使用できます.ダイアログ・ボックスが閉じたときに、そのポインタにNULL値を割り当てて、ダイアログ・オブジェクトが存在しないことを示します.