【发布时间】:2013-04-02 16:36:42
【问题描述】:
GetOpenFileName 因访问冲突而失败。文件必须在桌面上并且具有长名称。 只有在第一次成功打开文件后才会出现问题。当鼠标光标悬停在文件上时会出现问题,因为工具提示即将显示。
请看下面的答案。我将在下面留下原始问题描述。
迈克 D.
=========================
我正在使用 GetOpenFileName。我有时会在 shell32 内部遇到访问冲突。第一次使用此代码时不会发生违规,通常需要五六次尝试。此外,如果在打开文件窗口弹出后的一两秒内选择一个文件,则不会发生违规。此外,我调试时显示的调用堆栈不包括我的任何代码。就好像某个独立的线程正在醒来做某事。
任何关于我如何调试它的见解都非常感谢!
我制作了一个显示相同行为的“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_+DST_E2_2_second.TXT
我用 NOTEPAD 尝试过同样的事情,但出现了同样的问题!
【问题讨论】:
-
没有符号就没用。
-
如果您使用的是 Visual Studio,您应该能够通过右键单击堆栈并选择“从 Microsoft 符号服务器加载符号”来获取符号。
-
我会非常仔细地检查您传入的 OPENFILENAME 结构。特别是与过滤器相关的字段,因为过滤器可以被函数记住并在将来重复使用。
-
过滤器设置如下 char filter[32]="Text Files\0*.TXT;\0\0";
-
嘿,你删除了堆栈跟踪。请包含带有符号的堆栈跟踪。
标签: windows shell32 getopenfilename createthread