viraj
viraj

Reputation: 1814

Save/Open Common Dialog boxes in win32 without MFC

How do you create the deafault Save/Open dialog boxes using pure unmanaged 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.

            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?!

Upvotes: 3

Views: 7794

Answers (4)

V&#237;ctor Ponce
V&#237;ctor Ponce

Reputation: 1

from https://learn.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:

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);

Upvotes: 0

Don Reba
Don Reba

Reputation: 14051

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.

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 };

Upvotes: 2

Hans Passant
Hans Passant

Reputation: 942267

the following code is executed when WM_CREATE message is handled

Look in the Output window and observe the first-chance exception notification for 0xc0000005, an AccessViolation exception. There's a backstop in the Wow64 emulator that swallows exceptions while WM_CREATE is being dispatched.

The exception is caused by not fully initializing the OPENFILENAMEA structure. Quick fix:

 OPENFILENAMEA ofn = {0};

And favor displaying the dialog before calling ShowWindow() instead of the WM_CREATE message handler.

Upvotes: 7

valdo
valdo

Reputation: 12951

GetOpenFileName blocks (for a while), and then returns either TRUE if the dialog was closed by 'OK', or FALSE if it was cancelled.

The actual result (the directory/file path) can be read from the OPENFILENAME structure.

Upvotes: 0

Related Questions