DOCUMENT:Q245002 05-DEC-1999 [visualc] TITLE :BUG: CFileDialog Causes Help Window to Appear on WinCE 2.11 PRODUCT :Microsoft C Compiler PROD/VER:winnt: OPER/SYS: KEYWORDS:kbCmnDlg kbMFC kbVC600bug kbOSWinCEsearch kbOSWinCE211 kbGrpDSMFCATL ====================================================================== ------------------------------------------------------------------------------- The information in this article applies to: - The Microsoft Foundation Classes (MFC), included with: - Microsoft Windows CE Toolkit for Visual C++ 6.0 ------------------------------------------------------------------------------- SYMPTOMS ======== On an H/PC Pro device running the Microsoft Windows CE 2.11 operating system, if you have an MFC application that calls CFileDialg::DoModal and uses multiple file types, when you change the file type in the Open file name dialog box and click OK to open the file, the application's Help window is displayed, instead of opening the file. The Help window only appears if the application handles the ID_HELP command; otherwise, nothing happens. CAUSE ===== The CFileDialog class specifies a hook function, and sets the OFN_ENABLEHOOK flag in the OPENFILENAME structure. The CFileDialog class then passes this structure to the ::GetOpenFilenames function. The CFileDialog class expects to receive a WM_INITDIALOG message from the dialog box that is created from calling ::GetOpenFilenames. However, the CFileDialog class does not receive this message, and some necessary variables are not initialized correctly. These variables are custom Windows messages that are sent to the hook procedure when certain events occur. The two variables that cause this bug (although they are only part of the problem) are _afxMsgFILEOK and _afxMsgHELP. Both of these variables are initially set to 0 (zero) and should be initialized in the WM_INITDIALOG handler. The problem occurs only when you change the file type in the Open file name dialog box, because the only message sent to the hook procedure is a WM_NOTIFY message with the CDN_TYPECHANGE code. When this message is handled by the CFileDialog procedure, the dialog box window is subclassed so that MFC's hook procedure receives all other messages going to the dialog box. When the OK button is clicked, the hook procedure is sent a _afxMsgFILEOK message. However, because the _afxMsgFILEOK and _afxMsgHELP variables were not initialized correctly, the value of _afxMsgFILEOK is 0 (zero), which is the same as a _afxMsgHELP message. Therefore, when the following code in the CFileDialog hook procedure is called, the Help window is displayed: if (message == _afxMsgHELP || (message == WM_COMMAND && LOWORD(wParam) == pshHelp)) { // Translate the message into the AFX standard help command. SendMessage(hWnd, WM_COMMAND, ID_HELP, 0); return 1; } RESOLUTION ========== Windows CE does not support the lpfnHook and OFN_ENABLEHOOK flags of the OPENFILENAME structure. Therefore, you must create a new class that derives from CFileDialog and overrides DoModal. The following code demonstrates how to override DoModal in the derived class. In the new class, add a declaration for DoModal as follows: virtual int DoModal(); Include Afxpriv.h and implement DoModal as follows in the class .cpp file: int CMyFileDialog::DoModal() { ASSERT_VALID(this); m_ofn.Flags &= ~OFN_ENABLEHOOK; m_ofn.lpfnHook = NULL; // Zero out the file buffer for constant parsing later. ASSERT(AfxIsValidAddress(m_ofn.lpstrFile, m_ofn.nMaxFile)); memset(m_ofn.lpstrFile, 0, m_ofn.nMaxFile); // WINBUG: This is a special case for the file Open/Save dialog box, // which sometimes pumps while it is coming up but before it has // disabled the main window. HWND hWndFocus = ::GetFocus(); BOOL bEnableParent = FALSE; m_ofn.hwndOwner = PreModal(); AfxUnhookWindowCreate(); if (m_ofn.hwndOwner != NULL && ::IsWindowEnabled(m_ofn.hwndOwner)) { bEnableParent = TRUE; ::EnableWindow(m_ofn.hwndOwner, FALSE); } _AFX_THREAD_STATE* pThreadState = AfxGetThreadState(); ASSERT(pThreadState->m_pAlternateWndInit == NULL); #if !defined(_WIN32_WCE) if (m_ofn.Flags & OFN_EXPLORER) pThreadState->m_pAlternateWndInit = this; else AfxHookWindowCreate(this); #endif // _WIN32_WCE int nResult; if (m_bOpenFileDialog) nResult = ::GetOpenFileName(&m_ofn); else nResult = ::GetSaveFileName(&m_ofn); #if defined(_WIN32_WCE_PSPC) // WinCE: By default (no choice in "Location" is selected), m_ofn.lpstrFile has // double slashes in front of it. Get rid of one if necessary. if (!m_bOpenFileDialog && (*m_ofn.lpstrFile == _T('\\')) && (*(m_ofn.lpstrFile+1) == _T('\\'))) memmove((void*)m_ofn.lpstrFile, (void*)(m_ofn.lpstrFile + 1), _tcslen(m_ofn.lpstrFile)*sizeof(TCHAR)); #endif // _WIN32_WCE_PSPC if (nResult) ASSERT(pThreadState->m_pAlternateWndInit == NULL); pThreadState->m_pAlternateWndInit = NULL; // WINBUG: Second part of special case for File Open/Save dialog box. if (bEnableParent) ::EnableWindow(m_ofn.hwndOwner, TRUE); if (::IsWindow(hWndFocus)) ::SetFocus(hWndFocus); PostModal(); return nResult ? nResult : IDCANCEL; } STATUS ====== Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. MORE INFORMATION ================ Steps to Reproduce Behavior --------------------------- 1. Use the Application Wizard to create an MFC Windows CE Single Document application, and make sure to select the Windows Help check box in step 2 of the wizard. 2. Edit the menu resource and add a menu item to the edit menu that is named Do File Dialog, and then use the MFC ClassWizard to add a handler for it. 3. Add the following code to the menu handler created in step 2: void CTestApp::OnDoFileDialog() { CString OpenFilter; OpenFilter = "Text File (*.txt)|*.txt|"; OpenFilter += "HTML File (*.htm;*.html)|*.htm;*.html|"; OpenFilter += "All Files (*.*)|*.*||"; CFileDialog FileOpenDialog( TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, OpenFilter, // filter AfxGetMainWnd()); // the parent window FileOpenDialog.DoModal(); } 4. Build the application, download it to the device, and then run it. 5. Save a file with the .htm extension. 6. Choose the menu item created in step 2, which will display the Open file name dialog box, and change the file filter to HTML files. 7. Try to open the file saved above and notice that the Help window is displayed. Additional query words: ====================================================================== Keywords : kbCmnDlg kbMFC kbVC600bug kbOSWinCEsearch kbOSWinCE211 kbGrpDSMFCATL Technology : kbAudDeveloper kbMFC Version : winnt: Issue type : kbbug ============================================================================= THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY. Copyright Microsoft Corporation 1999.