简体   繁体   English

在没有 MFC 的 win32 中保存/打开常用对话框

[英]Save/Open Common Dialog boxes in win32 without MFC

How do you create the deafault Save/Open dialog boxes using pure unmanaged Win32 API ?如何使用纯非托管 Win32 API 创建默认的保存/打开对话框? Following the guide here , the following code is executed when WM_CREATE message is handled in the message loop of the main window: Ive included <Commdlg.h> also.遵循此处的指南,当在主窗口的消息循环中处理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();

However, this code gives NO output whatsoever.然而,这段代码没有给出任何输出。 Help?!帮助?!

the following code is executed when WM_CREATE message is handled处理 WM_CREATE 消息时执行以下代码

Look in the Output window and observe the first-chance exception notification for 0xc0000005, an AccessViolation exception.查看“输出”窗口并观察 0xc0000005 的第一次机会异常通知,这是一个 AccessViolation 异常。 There's a backstop in the Wow64 emulator that swallows exceptions while WM_CREATE is being dispatched.当 WM_CREATE 被分派时,Wow64 模拟器中有一个 backstop 可以吞下异常。

The exception is caused by not fully initializing the OPENFILENAMEA structure.该异常是由未完全初始化 OPENFILENAMEA 结构引起的。 Quick fix:快速解决:

 OPENFILENAMEA ofn = {0};

And favor displaying the dialog before calling ShowWindow() instead of the WM_CREATE message handler.并倾向于在调用 ShowWindow() 而不是 WM_CREATE 消息处理程序之前显示对话框。

The overall idea is right, but if you are passing the handle of the window you are creating as the owner, then it is not going to be initialized yet.总体思路是正确的,但是如果您正在传递您作为所有者创建的窗口的句柄,那么它还不会被初始化。

For diagnostics, consider creating variables to store the API function return values and examining them in the debugger.对于诊断,请考虑创建变量来存储 API 函数返回值并在调试器中检查它们。

It is also more convenient and less error-prone to initialize the structure to zero, instead of explictely zeroing out unneeded members, like this:将结构初始化为零也更方便,更不容易出错,而不是明确地将不需要的成员清零,如下所示:

OPENFILENAME ofn = { 0 };

from https://docs.microsoft.com/en-us/windows/win32/dlgbox/using-common-dialog-boxes#opening-a-file we get a utf-16 version of this, with some small changes of mine: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);

GetOpenFileName blocks (for a while), and then returns either TRUE if the dialog was closed by 'OK', or FALSE if it was cancelled. GetOpenFileName阻塞(一段时间),然后如果对话框被“OK”关闭则返回TRUE如果对话框被取消则返回FALSE

The actual result (the directory/file path) can be read from the OPENFILENAME structure.实际结果(目录/文件路径)可以从OPENFILENAME结构中读取。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM