Skip to content

Instantly share code, notes, and snippets.

@donnaken15
Created December 27, 2025 12:21
Show Gist options
  • Select an option

  • Save donnaken15/9df5c72b3cb1ba9e3f05172606b2c229 to your computer and use it in GitHub Desktop.

Select an option

Save donnaken15/9df5c72b3cb1ba9e3f05172606b2c229 to your computer and use it in GitHub Desktop.
windows file dialog for shell scripting, and first time making a completely widechar based program | usage: picker [title] [filter: "label|ext(s)"] [open/save] [initial fname] [initial dir] [filter index]
#include <stdlib.h>
#include <fcntl.h>
#include <Windows.h>
#include <commdlg.h>
#include <wchar.h>
// i hate c now
#define PARAM_TITLE 0
#define PARAM_FILT 1
#define PARAM_MODE 2
#define PARAM_FNAME 3
#define PARAM_DIR 4
#define PARAM_FILTI 5
#define PARAM_FLAGS 6
#define ARG_COUNT 7
#define FNSIZE_BUF MAX_PATH
wchar_t*cfg[] = { L"Select a file", L"Any type (*.*)\0*.*\0\0", L"open", L"", L"", L"0", L"0" };
// https://stackoverflow.com/a/32496721
wchar_t*wcsrep(wchar_t*str,wchar_t repl,wchar_t with) {
wchar_t*c = str;
while (c = wcschr(c,repl))
*c = with;
return str;
}
wmain(int argc, wchar_t*argv[]) {
for (int i = 0; i+1 < argc && i < ARG_COUNT; i++)
cfg[i] = argv[i+1]; // upsetting // how do i shift argv[0]
int filtsz = 0;
wchar_t*why = cfg[PARAM_FILT];
if ((filtsz = wcslen(why)) > 0) {
filtsz += 3;
wchar_t*die = malloc(filtsz<<1);
wcscpy_s(die,filtsz,why);
wmemset(die+(filtsz-=3),L'\0',3);
wcsrep(die,L'|',L'\0');
cfg[PARAM_FILT] = die;
} else cfg[PARAM_FILT] = NULL;
//for (int i = 0; i < ARG_COUNT; i++)
// fwprintf(stderr,L"[%s] [%p]\n",cfg[i],&cfg[i]);
OPENFILENAMEW diag;
memset(&diag,0,sizeof(OPENFILENAMEW));
diag.lStructSize = sizeof(OPENFILENAMEW);
diag.nMaxFile = FNSIZE_BUF;
//diag.hwndOwner = GetConsoleWindow();
diag.lpstrFilter = cfg[PARAM_FILT];
diag.lpstrTitle = cfg[PARAM_TITLE];
diag.nFilterIndex = wtoi(cfg[PARAM_FILTI]);
// make flags comma separated (camelcase) names of flags
filtsz = wcslen(cfg[PARAM_DIR])+2;
if (filtsz > 2) {
wcscpy_s(why = malloc(filtsz<<1),filtsz,cfg[PARAM_DIR]);
wcscpy_s(why+filtsz-2,2,L"\\\0");
diag.lpstrInitialDir = why;
}
wchar_t*fn = diag.lpstrFile = malloc(FNSIZE_BUF<<1);
wcscpy_s(fn,FNSIZE_BUF,cfg[PARAM_FNAME]);
SetStdHandle(STD_OUTPUT_HANDLE,GetStdHandle(STD_ERROR_HANDLE));
if (filtsz = (((wcscmp(cfg[PARAM_MODE],L"save")) ? GetOpenFileNameW : GetSaveFileNameW)(&diag))) {
fputws(fn,stdout);
setmode(fileno(stdout), _O_BINARY); // DON'T PRINT CR
putc('\n',stdout);
}
return !filtsz;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment