Register
handmade.network » Wiki » File Dialogs

Windows

Includes and libraries

1
2
3
4
5
6
7
#include <windows.h>
#include <shobjidl.h>
#pragma comment (lib, "shell32.lib")
#pragma comment (lib, "advapi32.lib")
#pragma comment (lib, "comctl32.lib")
#pragma comment (lib, "ole32.lib")
#pragma comment (lib, "Comdlg32.lib")

Save

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
OPENFILENAME config = {};
config.lStructSize = sizeof(OPENFILENAME);
config.hwndOwner = mainWindow; // Put the owner window handle here.
config.lpstrFilter = L"Text files\0*.txt\0"; // Put the file extension here.
wchar_t path[MAX_PATH];
path[0] = 0;
config.lpstrFile = path;
config.lpstrDefExt = FILE_EXT + 1;
config.nMaxFile = sizeof(path) / sizeof(path[0]);
config.Flags = OFN_OVERWRITEPROMPT;

if (GetSaveFileName(&config)) {
    // `path` contains the file.
}

Open

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
OPENFILENAME config = {};
config.lStructSize = sizeof(OPENFILENAME);
config.hwndOwner = mainWindow; // Put the owner window handle here.
config.lpstrFilter = L"Text files\0*.txt\0"; // Put the file extension here.
wchar_t path[MAX_PATH];
path[0] = 0;
config.lpstrFile = path;
config.lpstrDefExt = FILE_EXT + 1;
config.nMaxFile = sizeof(path) / sizeof(path[0]);
config.Flags = OFN_FILEMUSTEXIST;

if (GetOpenFileName(&config)) {
    // `path` contains the file
}

Open directory

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
CoInitialize(NULL); // Initialise COM if you haven't already.

IFileOpenDialog *dialog;
IShellItem *item;
wchar_t *path;
HRESULT result = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, IID_IFileOpenDialog, (void **) &dialog);
if (!SUCCEEDED(result)) { goto error; }
result = dialog->SetOptions(FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_NOCHANGEDIR);
if (!SUCCEEDED(result)) { dialog->Release(); goto error; }
result = dialog->Show(mainWindow); // Put the owner window handle here.
if (!SUCCEEDED(result)) { dialog->Release(); goto error; }
result = dialog->GetResult(&item);
if (!SUCCEEDED(result)) { dialog->Release(); goto error; }
result = item->GetDisplayName(SIGDN_FILESYSPATH, &path);
if (!SUCCEEDED(result)) { item->Release(); dialog->Release(); goto error; }

// `path` contains the directory.

CoTaskMemFree(path);
error: