Microsoft KB Archive/216503

= An assertion failure occurs or some keys do not work as expected when displaying the ATL dialog box object as a modeless dialog box =

Article ID: 216503

Article Last Modified on 10/3/2005

-

APPLIES TO

 Microsoft ActiveX Template Library 3.0, when used with:  Microsoft Visual C++ 5.0 Enterprise Edition

 Microsoft Visual C++ 6.0 Enterprise Edition

 Microsoft Visual C++ 5.0 Professional Edition

 Microsoft Visual C++ 6.0 Professional Edition</li></ul>

 Microsoft Visual C++ 6.0 Standard Edition</li></ul>

 Microsoft Visual C++ .NET 2002 Standard Edition</li></ul>

 Microsoft Visual C++ .NET 2003 Standard Edition</li></ul> </li> Microsoft ActiveX Template Library 2.1, when used with:  Microsoft Visual C++ 5.0 Enterprise Edition</li></ul>

 Microsoft Visual C++ 6.0 Enterprise Edition</li></ul>

 Microsoft Visual C++ 5.0 Professional Edition</li></ul>

 Microsoft Visual C++ 6.0 Professional Edition</li></ul>

 <li>Microsoft Visual C++ 6.0 Standard Edition</li></ul>

<ul> <li>Microsoft Visual C++ .NET 2002 Standard Edition</li></ul>

<ul> <li>Microsoft Visual C++ .NET 2003 Standard Edition</li></ul> </li></ul>

-

<div class="notice_section">

This article was previously published under Q216503

<div class="symptoms_section">

SYMPTOMS
The ATL Object Wizard dialog box provides an option to create an ATL dialog box object. However, the following problems are found when displaying the ATL dialog box object as a modeless dialog box from within an ATL .exe project:
 * Clicking OK or Cancel causes an assertion failure.
 * The TAB or accelerator key does not work as expected.

<div class="cause_section">

CAUSE
The code generated by the ATL wizard is designed to show the dialog box as a modal dialog box.

<div class="resolution_section">

RESOLUTION
Add/modify the code below to the ATL .exe project to show the ATL dialog box as modeless dialog box: <ol> <li> The EndDialog call in both the OnOK and OnCancel functions cause the assertion failure. Call DestroyWindow instead for modeless dialog box. LRESULT OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) {  DestroyWindow; PostQuitMessage(0); // OPTIONAL - call this to terminate the app. return 0; }

LRESULT OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) {  DestroyWindow; PostQuitMessage(0); // OPTIONAL - call this to terminate the app. return 0; }                       </li> <li> Modify the GetMessage loop in the _tWinMain function so IsDialogMessage is called for a modeless dialog box. This method takes care of both the tab and accelerator keys processing problem. MSG msg; while (GetMessage(&msg, 0, 0, 0)) {  if ((gModelessDlg) &&       (!::IsDialogMessage(gModelessDlg->m_hWnd,&msg))) DispatchMessage(&msg); } Note TranslateMessage is not required in the GetMessage loop. </li></ol>

<div class="status_section">

STATUS
This behavior is by design.

<div class="moreinformation_section">

Steps to reproduce the behavior
<ol> <li>Use the ATL COM Wizard to generate an ATL .exe project.</li> <li>Create a dialog box class named CMyDialog:

Visual C++ 6.0 <ol style="list-style-type: lower-alpha;"> <li>On the Insert menu, click New ATL Object to insert a dialog box object from the Miscellaneous category of the ATL Object Wizard dialog box.</li> <li>Name the dialog box class CMyDialog.</li></ol>

Visual C++ .NET <ol style="list-style-type: lower-alpha;"> <li>On the Project menu, click Add Class.</li> <li>In the Add Class dialog box, select ATL Dialog under Templates, and then click Open.</li> <li>In the ATL Dialog wizard, name the dialog box class CMyDialog, and then click Finish.</li></ol> </li> <li> Add the following code to the file that contains the _tWinMain function to show CMyDialog as a modeless dialog box. // Include the header file for CMyDialog and declare a global variable of // CMyDialog type. CMyDialog* gMainDialog = NULL;
 * 1) include "mydialog.h"

extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,   HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/) {  // ... other stuff

// Show the CMyDialog as a modeless dialog box. gMainDialog = new CMyDialog; gMainDialog->Create(GetDesktopWindow); gMainDialog->ShowWindow(SW_SHOW);

MSG msg; while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg);

// ... other stuff

// Destroy the C++ object for the modeless dialog box. if (gMainDialog) delete gMainDialog;

// ... other stuff }                       </li></ol>

<div class="references_section">