我正在维护一个使用 Win32 的 C++ 程序。它多年来一直运行良好,但现在我在两台运行 Windows 8 的计算机上遇到“选择文件”或“选择文件夹”功能的问题,但在另外两台运行 Windows 8 的计算机上却没有。
问题是程序在微软代码深处的“选择文件”或“选择文件夹”功能中崩溃。在显示对话框后,在用户有机会触摸任何东西之前,它会立即崩溃。
我做了很多实验,我让它随机工作,但是重新编译相同的代码会使错误再次出现。最后我制作了一个小程序,连续调用该函数 10 次,没有任何其他代码,第一次总是成功,但第二次程序崩溃了。链接到我的完整程序,它有时会在第一次调用时崩溃,有时会在第二次调用时崩溃。我的代码如下:
#include <windows.h>
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance,
LPSTR args, int nCmdShow)
{
for (int i=0; i < 10; i++) {
OPENFILENAME OFN;
char buf[1024];
memset(&OFN, 0, sizeof(OFN));
OFN.lStructSize = sizeof(OFN);
OFN.hwndOwner = NULL;
OFN.hInstance = NULL;
OFN.lpstrFilter = "PTN files\0*.ptn\0\0\0";//overkill
OFN.lpstrCustomFilter = NULL;
OFN.nMaxCustFilter = 0;
OFN.nFilterIndex = 1;
OFN.nMaxFile = sizeof(buf);
OFN.lpstrFileTitle = NULL;
OFN.nMaxFileTitle = 0;
OFN.lpstrTitle = NULL;
OFN.nFileOffset = 0;
OFN.nFileExtension = 0;
OFN.lpstrDefExt = "ptn";
OFN.lCustData = 0;
OFN.lpfnHook = 0;
OFN.lpTemplateName = NULL;
OFN.lpstrInitialDir = NULL;
strcpy(buf, "\0");//overkill
OFN.lpstrFile = buf;
OFN.Flags = OFN_LONGNAMES | OFN_HIDEREADONLY | OFN_EXPLORER;
//NB: tried both with and without OFN_EXPLORER
GetSaveFileName(&OFN);
}
return 0;
}
有什么想法吗?
最佳答案
我在您的代码中看不到任何错误。 我怀疑没有人能够回答您的问题。
只是一些想法:
1.) 您将项目编译为 MBCS 吗? Windows 8 是否仍支持 Ansi 内容? 如果 Unicode 版本出现同样的情况,您是否尝试过?
2.) 我在使用 Windows XP 中已有的这些功能时也遇到了很多麻烦。 它们肯定是有问题的,而且在 Windows 8 中它们似乎仍然存在甚至更多。例如,我发现 lpstrFile 的无效值可能会导致对话框无法打开。其他参数也很关键。
3.) 您为 _WIN32_WINNT 定义了什么值? 我建议至少使用 0x0502 或更高版本,以确保 OPENFILENAME 结构不是来自 Windows NT 时代的版本,Windows 8 可能不支持该版本。
4.) 如果您试用 MFC 版本会发生什么:
CFileDialog dlg(FALSE);
dlg.DoModal();
让所有参数都使用默认值。如果这有效,您就知道这不是 Windows 8 错误。然后研究 OFN 中哪些参数与您的代码不同。另请查看可能影响 Windows 8 行为的 sizeof(OFN)
的值。
5.) 可能需要您的应用程序/Dll 具有嵌入式 list ,Shell32 才能正常工作。
#pragma comment(linker,"\"/manifestdependency:type='win32' processorArchitecture='X86' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*'\"")
6.) 如果所有这些都没有帮助,您必须进行试验,直到找到导致问题的参数:Windows 8 是否需要 hwndOwner? Windows 8 是否需要 hInstance?是否缺少一面旗帜?是否需要 lpstrInitialDir?
7.) 我不时发生非常非常奇怪的崩溃,很难重现。经过数周令人沮丧的搜索后,我终于发现这是 Visual Studio 中的一个错误。避免崩溃代码的解决方案是在 Visual Studio 的菜单中选择“*Re*build Solution”。我只在我的一个项目中有这种效果。
关于c++ - Win32 程序在调用 GetSaveFileName() 或 SHBrowseForFolder() 时在 Windows 8 上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22193583/