Powered By Blogger

2013年1月20日日曜日

MFC Debugger ファイルを開くでハングアップ

やはり、ハングアップが発生する。理由は分からないが、デバッガでファイルを開くダイアログで、新しいFileExplorerを開くとハングする時がある。常にではない。落ちるのがFile Explorerを呼び出した時点で、画面が表示された時に、ファイル一覧が出なくなる時、一覧表示された直後などで、一定ではないが、固まり方が同じで、その画面がハングした後は、別に起動していたプロセス、デスクトップと順番にクリックしていくと段々に固まっていく。実際は新しい画面を出そうとすると何かを待っているような感じだ。NVIDIAかもしれないが、一応は最新のドライバーを入れているつもりだ。

回避方法として、OpenFileDialogの呼び出しで、旧インタフェースを使うということができる。しかも、デバッガ起動しているときは旧インタフェースで、デバッガ起動でなければ通常インタフェースに切り替えるということにしておけば、デバッガ時のハングだけを回避するための措置として十分である。

以下に方法を述べる。

Appクラスのヘッダーに以下を定義する。CxxxxxxAppはAppクラスの名前

xxxxxxxApp.h に

////////////////////////////////
//// MFC DEBUGGER BUG FIX
////////////////////////////////
#define AVOID_CLASS_NAME CxxxxxxApp
BOOL AVOID_CLASS_NAME::DoPromptFileName(CString& fileName, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);
afx_msg void AVOID_CLASS_NAME::OnFileOpen();

xxxxxxxx.cppファイルに

BEGIN_MESSAGE_MAP(CxxxxxxxxApp, CWinApp)
    ON_COMMAND(ID_FILE_OPEN, OnFileOpen) <==これを追加
END_MESSAGE_MAP()

///////////////////////////////////////////////

//// MFC DEBUGGER BUG FIX
///////////////////////////////////////////////
AFX_STATIC void AFXAPI _AfxAppendFilterSuffix(CString& filter, OPENFILENAME& ofn,
    CDocTemplate* pTemplate, CString* pstrDefaultExt)
{
    ENSURE_VALID(pTemplate);
    ASSERT_KINDOF(CDocTemplate, pTemplate);

    CString strFilterExt, strFilterName;
    if (pTemplate->GetDocString(strFilterExt, CDocTemplate::filterExt) &&
        !strFilterExt.IsEmpty() &&
        pTemplate->GetDocString(strFilterName, CDocTemplate::filterName) &&
        !strFilterName.IsEmpty())
    {
        if (pstrDefaultExt != NULL)
            pstrDefaultExt->Empty();

        // add to filter
        filter += strFilterName;
        ASSERT(!filter.IsEmpty());  // must have a file type name
        filter += (TCHAR)'\0';  // next string please

        int iStart = 0;
        do
        {
            CString strExtension = strFilterExt.Tokenize( _T( ";" ), iStart );

            if (iStart != -1)
            {
                // a file based document template - add to filter list

                // If you hit the following ASSERT, your document template
                // string is formatted incorrectly.  The section of your
                // document template string that specifies the allowable file
                // extensions should be formatted as follows:
                //    .<ext1>;.<ext2>;.<ext3>
                // Extensions may contain wildcards (e.g. '?', '*'), but must
                // begin with a '.' and be separated from one another by a ';'.
                // Example:
                //    .jpg;.jpeg
                ASSERT(strExtension[0] == '.');
                if ((pstrDefaultExt != NULL) && pstrDefaultExt->IsEmpty())
                {
                    // set the default extension
                    *pstrDefaultExt = strExtension.Mid( 1 );  // skip the '.'
                    ofn.lpstrDefExt = const_cast< LPTSTR >((LPCTSTR)(*pstrDefaultExt));
                    ofn.nFilterIndex = ofn.nMaxCustFilter + 1;  // 1 based number
                }

                filter += (TCHAR)'*';
                filter += strExtension;
                filter += (TCHAR)';';  // Always append a ';'.  The last ';' will get replaced with a '\0' later.
            }
        } while (iStart != -1);

        filter.SetAt( filter.GetLength()-1, '\0' );;  // Replace the last ';' with a '\0'
        ofn.nMaxCustFilter++;
    }
}


BOOL AVOID_CLASS_NAME::DoPromptFileName(CString& fileName, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate)
{
    CFileDialog dlgFile(bOpenFileDialog, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, NULL, NULL, 0, FALSE);//旧OpenFileDialog

    CString title;
    ENSURE(title.LoadString(nIDSTitle));

    dlgFile.m_ofn.Flags |= lFlags;

    CString strFilter;
    CString strDefault;
    if (pTemplate != NULL)
    {
        ASSERT_VALID(pTemplate);
        _AfxAppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate, &strDefault);
    }
    else
    {
        // do for all doc template
        POSITION pos = this->m_pDocManager->GetFirstDocTemplatePosition(); // >m_templateList.GetHeadPosition();
        BOOL bFirst = TRUE;
        while (pos != NULL)
        {
            pTemplate = (CDocTemplate*)(this->m_pDocManager->GetNextDocTemplate(pos)); // m_templateList.GetNext(pos);
            _AfxAppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate,
                bFirst ? &strDefault : NULL);
            bFirst = FALSE;
        }
    }

    // append the "*.*" all files filter
    CString allFilter;
    VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));
    strFilter += allFilter;
    strFilter += (TCHAR)'\0';   // next string please
    strFilter += _T("*.*");
    strFilter += (TCHAR)'\0';   // last string
    dlgFile.m_ofn.nMaxCustFilter++;

    dlgFile.m_ofn.lpstrFilter = strFilter;
    dlgFile.m_ofn.lpstrTitle = title;
    dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);

    INT_PTR nResult = dlgFile.DoModal();
    fileName.ReleaseBuffer();
    return nResult == IDOK;
}

void AVOID_CLASS_NAME::OnFileOpen()
{
    if (::IsDebuggerPresent()) //デバッグ時のみ上記モジュールを使う
    {
        CString newName;
        if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,
          OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))
            return; // open cancelled
        AfxGetApp()->OpenDocumentFile(newName);
    }
    else
        CWinApp::OnFileOpen();
}

仕方ないね。

0 件のコメント:

コメントを投稿