如何使用纯非托管Win32 API创建deafault Save / Open对话框?
在指南here之后,在主窗口的消息循环中处理WM_CREATE
消息时,将执行以下代码:
我也included <Commdlg.h>
。
OPENFILENAMEA ofn;
char Buffer[300];
fill(Buffer, Buffer + 300, '\0');
ofn.lStructSize = sizeof(OPENFILENAMEA);
ofn.hwndOwner = hWnd;
ofn.lpstrFile = Buffer;
ofn.nMaxFile = 300;
ofn.Flags = OFN_EXPLORER;
ofn.lpstrFilter = NULL;
ofn.lpstrCustomFilter = NULL;
ofn.nFilterIndex = 0;
ofn.lpstrFileTitle = NULL;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL;
out << GetOpenFileNameA(&ofn) << endl;
out << Buffer << (int)CommDlgExtendedError();
但是,此代码无论如何都会提供 NO 输出。帮助?!
答案 0 :(得分:7)
处理WM_CREATE消息时执行以下代码
在Output窗口中查看并观察0xc0000005的第一次机会异常通知,即AccessViolation异常。 Wow64模拟器中有一个支持,可以在调度WM_CREATE时吞下异常。
异常是由于未完全初始化OPENFILENAMEA结构引起的。快速修复:
OPENFILENAMEA ofn = {0};
并且在调用ShowWindow()而不是WM_CREATE消息处理程序之前显示对话框。
答案 1 :(得分:2)
总的想法是正确的,但是如果你传递的是你正在创建的窗口的句柄,那么它就不会被初始化了。
对于诊断,请考虑创建变量以存储API函数返回值并在调试器中检查它们。
将结构初始化为零也更方便,更不容易出错,而不是明确地将不需要的成员清零,如下所示:
OPENFILENAME ofn = { 0 };
答案 2 :(得分:0)
GetOpenFileName
阻止(一段时间),如果对话框已被“确定”关闭,则返回TRUE
,如果已取消,则返回FALSE
。
可以从OPENFILENAME
结构中读取实际结果(目录/文件路径)。
答案 3 :(得分:0)
从https://docs.microsoft.com/en-us/windows/win32/dlgbox/using-common-dialog-boxes#opening-a-file中我们获得了utf-16版本,但做了一些小的改动:
OPENFILENAME ofn = { 0 }; // common dialog box structure
WCHAR szFile[260]; // buffer for file name
HWND hwnd; // owner window
HANDLE hf; // file handle
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not
// use the contents of szFile to initialize itself.
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
// Display the Open dialog box.
if (GetOpenFileName(&ofn)==TRUE)
hf = CreateFile(ofn.lpstrFile,
GENERIC_READ,
0,
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);