2

CFileDialog を呼び出して、ユーザーがファイルを選択できるようにしようとしています。

私のプログラムは MFC アプリケーションで、VS2005 を使用しています。

これが私の問題です:

モードレス ダイアログ ボックスを作成するメイン ビューがあります。このダイアログ ボックスには、単純な CFileDialog 呼び出しを行うメニュー項目があります。

CFileDialog dlgFile(true);
dlgFile.DoModal();

しかし、プログラムは常に DoModal でハングアップします。プログラムはコマンドに応答せず、タスク マネージャーは応答を停止したと表示します。

その他の興味深い情報:

  • これは Windows 8 でのみ確認されており、Windows 7 マシンは影響を受けないようです。
  • 同じ基本的な View->modeless dialog->CFileDialog スキームで新しいプロジェクトを作成しましたが、うまくいきました。
  • MessageBox を呼び出すと、ダイアログ ボックスの後ろに表示されます (前面に表示するには Alt キーを押す必要があります) が、プログラムは応答します。
  • メイン ビューで同じ CFileDialog 呼び出しを行うと、問題なくポップアップします。
  • これに関連する、または関連しない別の厄介な問題: CFileDialog 呼び出しが機能している場合 (Win 7)、参照ウィンドウで「コンピューター」を選択すると空白の画面が表示されます (他のすべては正常に機能します)。

私が見つけることができる最も近い質問はこれです: CFileDialog::DoModal() がハングするのはなぜですか? ただし、私はスレッドを使用しません (少なくとも 95% は使用しないと確信しています。これは私のプロジェクトだけではありません)。プロジェクトは自動的にスレッド化されますか? もしそうなら、それが私に問題を引き起こしていないことをどのように確認できますか?

4

3 に答える 3

1

dlgFile.DoModal()呼び出しはモーダルルーチンを実行し、ウィンドウを有効/無効にして再フォーカスします。おそらくそれが問題です。GetOpenFileName代わりに試すことができます:

void CModeless::foo()
{
    //EnableWindow(0);
    OPENFILENAME ofn = { 0 };
    char buf[300];
    memset(buf, 0, 300);
    ofn.lpstrFile = buf;
    ofn.nMaxFile = 300;
    ofn.lStructSize = sizeof(OPENFILENAME);
    //ofn.hwndOwner = AfxGetApp()->m_pMainWnd->m_hWnd;
    GetOpenFileName(&ofn);
    //EnableWindow(1);
}

バグがない場合は、コメントEnableWindowを外してofn.hwndOwner、もう一度やり直してください。この方法を試すこともできます:

void CModeless::foo()
{
    CWnd *wnd = GetParent(); //or AfxGetApp()->m_pMainWnd
    EnableWindow(0);
    CFileDialog dlg(TRUE, 0, 0, 0, 0, wnd, 0, 1);
    dlg.DoModal();
    EnableWindow(1);

    MSG msg;
    while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        if (!AfxGetApp()->PumpMessage())
            break;

    SetFocus();
}
于 2015-04-15T23:11:36.430 に答える