[win32] add file type filters to open/save dialogs

This commit is contained in:
martinfouilleul 2023-05-23 16:43:57 +02:00
parent 49de9d0290
commit ed45d88cfd
2 changed files with 53 additions and 2 deletions

View File

@ -422,13 +422,14 @@ int main()
if(ui_button("Open").clicked) if(ui_button("Open").clicked)
{ {
str8 file = mp_open_dialog(mem_scratch(), "Open File", 0, 0, 0, true); char* filters[] = {"md"};
str8 file = mp_open_dialog(mem_scratch(), "Open File", 0, 1, filters, false);
printf("selected file %.*s\n", (int)file.len, file.ptr); printf("selected file %.*s\n", (int)file.len, file.ptr);
} }
if(ui_button("Save").clicked) if(ui_button("Save").clicked)
{ {
str8 file = mp_save_dialog(mem_scratch(), "Save File", 0, 0, 0, true); str8 file = mp_save_dialog(mem_scratch(), "Save File", 0, 0, 0);
printf("selected file %.*s\n", (int)file.len, file.ptr); printf("selected file %.*s\n", (int)file.len, file.ptr);
} }
} }

View File

@ -1090,8 +1090,10 @@ str8 mp_app_get_resource_path(mem_arena* arena, const char* name)
#define interface struct #define interface struct
#include<shobjidl.h> #include<shobjidl.h>
#include<shtypes.h>
#undef interface #undef interface
MP_API str8 mp_open_dialog(mem_arena* arena, MP_API str8 mp_open_dialog(mem_arena* arena,
const char* title, const char* title,
const char* defaultPath, const char* defaultPath,
@ -1114,6 +1116,30 @@ MP_API str8 mp_open_dialog(mem_arena* arena,
dialog->lpVtbl->SetOptions(dialog, opt | FOS_PICKFOLDERS); dialog->lpVtbl->SetOptions(dialog, opt | FOS_PICKFOLDERS);
} }
if(filterCount && filters)
{
mem_arena_marker mark = mem_arena_mark(arena);
COMDLG_FILTERSPEC* filterSpecs = mem_arena_alloc_array(arena, COMDLG_FILTERSPEC, filterCount);
for(int i=0; i<filterCount; i++)
{
str8_list list = {0};
str8_list_push(arena, &list, STR8("*."));
str8_list_push(arena, &list, STR8(filters[i]));
str8 filter = str8_list_join(arena, list);
int filterWideSize = 1 + MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, NULL, 0);
filterSpecs[i].pszSpec = mem_arena_alloc(arena, filterWideSize);
MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, (LPWSTR)filterSpecs[i].pszSpec, filterWideSize);
((LPWSTR)(filterSpecs[i].pszSpec))[filterWideSize-1] = 0;
filterSpecs[i].pszName = filterSpecs[i].pszSpec;
}
hr = dialog->lpVtbl->SetFileTypes(dialog, filterCount, filterSpecs);
mem_arena_clear_to(arena, mark);
}
hr = dialog->lpVtbl->Show(dialog, NULL); hr = dialog->lpVtbl->Show(dialog, NULL);
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
@ -1158,6 +1184,30 @@ MP_API str8 mp_save_dialog(mem_arena* arena,
hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_ALL, &IID_IFileSaveDialog, (void**)&dialog); hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_ALL, &IID_IFileSaveDialog, (void**)&dialog);
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
if(filterCount && filters)
{
mem_arena_marker mark = mem_arena_mark(arena);
COMDLG_FILTERSPEC* filterSpecs = mem_arena_alloc_array(arena, COMDLG_FILTERSPEC, filterCount);
for(int i=0; i<filterCount; i++)
{
str8_list list = {0};
str8_list_push(arena, &list, STR8("*."));
str8_list_push(arena, &list, STR8(filters[i]));
str8 filter = str8_list_join(arena, list);
int filterWideSize = 1 + MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, NULL, 0);
filterSpecs[i].pszSpec = mem_arena_alloc(arena, filterWideSize);
MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, (LPWSTR)filterSpecs[i].pszSpec, filterWideSize);
((LPWSTR)(filterSpecs[i].pszSpec))[filterWideSize-1] = 0;
filterSpecs[i].pszName = filterSpecs[i].pszSpec;
}
hr = dialog->lpVtbl->SetFileTypes(dialog, filterCount, filterSpecs);
mem_arena_clear_to(arena, mark);
}
hr = dialog->lpVtbl->Show(dialog, NULL); hr = dialog->lpVtbl->Show(dialog, NULL);
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {