GetOpenFileName因访问冲突而失败。文件必须在桌面上并且具有长名称。
只有在首次成功打开文件后才会出现问题。当鼠标光标悬停在将要显示的工具提示文件上时出现问题。
请看下面的答案。我把原始的问题描述留在下面。
迈克D
=======================
我正在使用getopenfilename。我有时会在32号外壳的深处发现一个访问违规。在第一次使用此代码时,通常需要五到六次尝试才能发生冲突。另外,如果在弹出“打开文件”窗口后的一两秒钟内选择了一个文件,则不会发生冲突。另外,调试时显示的调用堆栈不包括任何代码。好像有一条独立的线在醒来做什么。
任何关于我如何调试的见解都非常感谢!
我制作了一个“hello”世界应用程序,展示了相同的行为。然而,它需要更多的尝试才能失败。似乎还必须在失败之前切换目录。
gofn是从一个专为这个目的而创建的线程完成的。下面是“hello world”应用程序的代码。

typedef struct
{
public:
    HWND        hWnd;
    HINSTANCE   hInst;
} def_params, *p_params;

DWORD WINAPI ReadLogFile_DataRecorderThread (PVOID pvoid);

void ReadLogFile_DataRecorder (HWND hWnd, HINSTANCE hInst)  // ***************************
{
    static def_params Params;

    Params.hWnd = hWnd;
    Params.hInst = hInst;

    HANDLE T = CreateThread (NULL,0,ReadLogFile_DataRecorderThread,&Params,0,NULL);

    CloseHandle (T);

    return;
}

DWORD WINAPI ReadLogFile_DataRecorderThread (PVOID pvoid)
{
    p_params P = (p_params) pvoid;

    HWND hWnd = P->hWnd;
    HINSTANCE hInst = P->hInst;

    char    ReadLogFileLastDir[256];

//  static def_OpenFileHook Hook;

    OPENFILENAME    ofn;
    char            fn[MAX_PATH]="\0";
    char            filter[32]="Text Files\0*.TXT;\0\0";
    char            title[]="Open IMC Data Recorder Log File";
    char            defext[]="TXT";
    int             status;

// Get File Name

    fn[0] = '\0';
    ReadLogFileLastDir[0] = '\0';

    ZeroMemory(&ofn, sizeof(ofn));

    ofn.lStructSize         = sizeof(ofn);
    ofn.hwndOwner           = hWnd;
    ofn.hInstance           = hInst;
    ofn.hInstance           = (HINSTANCE) GetWindowLong (hWnd, GWL_HINSTANCE);

    ofn.lpstrFilter         = filter;
    ofn.nFilterIndex        = 0;
    ofn.lpstrCustomFilter   = NULL ;
    ofn.nMaxCustFilter      = 0 ;
    ofn.lpstrFile           = fn;
    ofn.nMaxFile            = sizeof(fn);
    ofn.lpstrFileTitle      = NULL;

    if (ReadLogFileLastDir[0] == '\0')
    {
        SHGetSpecialFolderPath (NULL,ReadLogFileLastDir,0x0005,false);
    };
    ofn.lpstrInitialDir = ReadLogFileLastDir;
    ofn.lpstrTitle          = title;
    ofn.Flags               = OFN_FILEMUSTEXIST  |
                              OFN_PATHMUSTEXIST  |
                              OFN_EXPLORER       |
                              // OFN_ENABLETEMPLATE |
                              OFN_ENABLESIZING   |
                              // OFN_ENABLEHOOK     |
                              OFN_READONLY;
    ofn.lpstrDefExt         = NULL;
    ofn.lpfnHook            = NULL;         // Hook.DialogHook; // hook routine
    ofn.lCustData           = NULL;          // (long) &Hook;       // data for hook routine
    ofn.lpTemplateName      = NULL;          // MAKEINTRESOURCE(IDD_HOOKFILEOPEN);
    ofn.nFileOffset         = 0 ;
    ofn.nFileExtension      = 0 ;
    ofn.lpstrDefExt         = defext;

    status = GetOpenFileName (&ofn);

    int S;

    S = CommDlgExtendedError();

    return 0;
}

当它失败时,调用堆栈看起来像这样…
SHELL32! 7ca4e035()
SHELL32! 7cb2dc16()
SHELL32! 7cb2dd5a()
SHELL32! 7cb27361()
SHELL32! 7c9f40a3()
BROWSEUI! 75f81b9a()
SHLWAPI! 77f69548()
NTDLL! 7c927545()
NTDLL! 7c927583()
NTDLL! 7c927645()
NTDLL! 7c92761c()
KERNEL32! 7c80b50b()

抱歉,但我不能得到这些符号,因为我有一个旧的Visual C++:
在我看来,当gofn的东西即将打开描述文件的弹出窗口时,鼠标光标悬停在文件名上,问题就出现了。
导致这个问题的一系列情况有些奇怪。实验表明,在gofn窗口中必须执行以下操作:
在桌面上打开文件
将鼠标悬停在长文件名上
如果我这样做两次,总是失败。我使用的文件名是
imclog_20120323_1658_20120324_0653_cst_u+dst_e2_2_second.txt
我用记事本做了同样的尝试,同样的问题也发生了!

最佳答案

我发现许多关于同一问题的报道。例如:
Social.MSDN Problem report
CodeProject question
CodeGuru thread
还有一个google缓存的链接指向一个自删除ms connect错误报告。正如您所发现的,这个问题似乎是桌面上的文件所特有的。
我找到的唯一建议的解决方案是在线程开始时调用CoInitializeEx(NULL),在结束时调用CoUninitialize(),因此值得尝试。
此外,GetOpenFileName()的msdn文档还说:
从Windows Vista开始,“打开”和“另存为”公用对话框已被“公用项”对话框取代。
因此,完全抛弃GetOpenFileName()可能是值得的。

10-08 09:16