| 635 | } |
| 636 | |
| 637 | static cc_result OpenSaveFileDialog(const cc_string* filters, FileDialogCallback callback, cc_bool load, |
| 638 | const char* const* fileExts, const cc_string* defaultName) { |
| 639 | union OPENFILENAME_union { |
| 640 | OPENFILENAMEW wide; |
| 641 | OPENFILENAMEA ansi; |
| 642 | } ofn = { 0 }; // less compiler warnings this way |
| 643 | HWND hwnd = Window_Main.Handle.ptr; |
| 644 | |
| 645 | cc_string path; char pathBuffer[NATIVE_STR_LEN]; |
| 646 | cc_winstring str = { 0 }; |
| 647 | cc_winstring filter; |
| 648 | cc_result res; |
| 649 | BOOL ok; |
| 650 | int i; |
| 651 | |
| 652 | Platform_EncodeString(&str, defaultName); |
| 653 | Platform_EncodeString(&filter, filters); |
| 654 | /* NOTE: OPENFILENAME_SIZE_VERSION_400 is used instead of sizeof(OFN), because the size of */ |
| 655 | /* OPENFILENAME increased after Windows 9x/NT4 with the addition of pvReserved and later fields */ |
| 656 | /* (and Windows 9x/NT4 return an error if a lStructSize > OPENFILENAME_SIZE_VERSION_400 is used) */ |
| 657 | ofn.wide.lStructSize = OPENFILENAME_SIZE_VERSION_400; |
| 658 | /* also note that this only works when OFN_HOOK is *not* included in Flags - if it is, then */ |
| 659 | /* on modern Windows versions the dialogs are altered to show an old Win 9x style appearance */ |
| 660 | /* (see https://github.com/geany/geany/issues/578 for example of this problem) */ |
| 661 | |
| 662 | ofn.wide.hwndOwner = hwnd; |
| 663 | ofn.wide.lpstrFile = str.uni; |
| 664 | ofn.wide.nMaxFile = MAX_PATH; |
| 665 | ofn.wide.lpstrFilter = filter.uni; |
| 666 | ofn.wide.nFilterIndex = 1; |
| 667 | ofn.wide.Flags = OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | (load ? OFN_FILEMUSTEXIST : OFN_OVERWRITEPROMPT); |
| 668 | |
| 669 | String_InitArray(path, pathBuffer); |
| 670 | ok = load ? GetOpenFileNameW(&ofn.wide) : GetSaveFileNameW(&ofn.wide); |
| 671 | |
| 672 | if (ok) { |
| 673 | /* Successfully got a unicode filesystem path */ |
| 674 | for (i = 0; i < MAX_PATH && str.uni[i]; i++) |
| 675 | { |
| 676 | String_Append(&path, Convert_CodepointToCP437(str.uni[i])); |
| 677 | } |
| 678 | } else if ((res = CommDlgExtendedError()) == 2) { |
| 679 | /* CDERR_INITIALIZATION - probably running on Windows 9x */ |
| 680 | ofn.ansi.lpstrFile = str.ansi; |
| 681 | ofn.ansi.lpstrFilter = filter.ansi; |
| 682 | |
| 683 | ok = load ? GetOpenFileNameA(&ofn.ansi) : GetSaveFileNameA(&ofn.ansi); |
| 684 | if (!ok) return CommDlgExtendedError(); |
| 685 | |
| 686 | for (i = 0; i < MAX_PATH && str.ansi[i]; i++) |
| 687 | { |
| 688 | String_Append(&path, str.ansi[i]); |
| 689 | } |
| 690 | } else { |
| 691 | return res; |
| 692 | } |
| 693 | |
| 694 | /* Add default file extension if user didn't provide one */ |
no test coverage detected