-
Notifications
You must be signed in to change notification settings - Fork 65
/
fileDialogWin32.c
114 lines (102 loc) · 3.02 KB
/
fileDialogWin32.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// only locally define UNICODE in this compilation unit
// FIXME: Unicode should be used everywhere.
#ifndef UNICODE
#define UNICODE
#endif
#include "pharovm/fileDialog.h"
#include "pharovm/stringUtilities.h"
#include <windows.h>
#include <Shobjidl.h>
bool
vm_file_dialog_is_nop(void)
{
return false;
}
VMErrorCode
vm_file_dialog_run_modal_open(VMFileDialog *dialog)
{
// Convert the filter description and extension.
WCHAR *filterDescription = vm_string_convert_utf8_to_utf16(dialog->filterDescription);
char *filterPattern = vm_string_concat("*", dialog->filterExtension);
WCHAR *filterExtension = vm_string_convert_utf8_to_utf16(filterPattern);
free(filterPattern);
COMDLG_FILTERSPEC filters[2];
filters[0].pszName = filterDescription;
filters[0].pszSpec = filterExtension;
filters[1].pszName = L"All files";
filters[1].pszSpec = L"*.*";
HRESULT hresult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if(FAILED(hresult))
{
free(filterDescription);
free(filterExtension);
return VM_ERROR;
}
// Create the FileOpenDialog object.
IFileOpenDialog *fileOpenDialog;
hresult = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_ALL, &IID_IFileOpenDialog, (void**)&fileOpenDialog);
VMErrorCode resultCode = VM_SUCCESS;
dialog->succeeded = false;
if (SUCCEEDED(hresult))
{
// Show the Open dialog box.
fileOpenDialog->lpVtbl->SetTitle(fileOpenDialog, L"Select Pharo Image to Open");
fileOpenDialog->lpVtbl->SetFileTypes(fileOpenDialog, 2, filters);
fileOpenDialog->lpVtbl->SetFileTypeIndex(fileOpenDialog, 1); //Selects the first, it is 1 based!
hresult = fileOpenDialog->lpVtbl->Show(fileOpenDialog, NULL);
// Get the file name from the dialog box.
if (SUCCEEDED(hresult))
{
IShellItem *item;
hresult = fileOpenDialog->lpVtbl->GetResult(fileOpenDialog, &item);
if (SUCCEEDED(hresult))
{
PWSTR filePath;
hresult = item->lpVtbl->GetDisplayName(item, SIGDN_FILESYSPATH, &filePath);
if (SUCCEEDED(hresult))
{
char *resultString = vm_string_convert_utf16_to_utf8(filePath);
if(resultString)
{
dialog->selectedFileName = resultString;
dialog->succeeded = true;
}
else
{
free(resultString);
}
CoTaskMemFree(filePath);
}
else
{
resultCode = VM_ERROR;
}
item->lpVtbl->Release(item);
}
else
{
resultCode = VM_ERROR;
}
}
else
{
if (hresult == HRESULT_FROM_WIN32(ERROR_CANCELLED))
{
resultCode = VM_SUCCESS;
}
else
{
resultCode = VM_ERROR;
}
}
fileOpenDialog->lpVtbl->Release(fileOpenDialog);
}
else
{
resultCode = VM_ERROR;
}
CoUninitialize();
free(filterDescription);
free(filterExtension);
return resultCode;
}