Created
December 27, 2025 12:21
-
-
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]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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