diff options
Diffstat (limited to 'dialog_windows.c')
| -rw-r--r-- | dialog_windows.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/dialog_windows.c b/dialog_windows.c new file mode 100644 index 0000000..f8ef687 --- /dev/null +++ b/dialog_windows.c @@ -0,0 +1,62 @@ +// 18 august 2014 + +#include "winapi_windows.h" +#include "_cgo_export.h" + +// this should be reasonable +#define NFILENAME 4096 + +struct openFileData { + HWND parent; + void *f; + WCHAR *filenameBuffer; +}; + +static DWORD WINAPI doOpenFile(LPVOID data) +{ + struct openFileData *o = (struct openFileData *) data; + OPENFILENAMEW ofn; + DWORD err; + + o->filenameBuffer[0] = L'\0'; // required by GetOpenFileName() to indicate no previous filename + ZeroMemory(&ofn, sizeof (OPENFILENAMEW)); + ofn.lStructSize = sizeof (OPENFILENAMEW); + ofn.hwndOwner = o->parent; + ofn.hInstance = hInstance; + ofn.lpstrFilter = NULL; // no filters + ofn.lpstrFile = o->filenameBuffer; + ofn.nMaxFile = NFILENAME + 1; // seems to include null terminator according to docs + ofn.lpstrInitialDir = NULL; // let system decide + ofn.lpstrTitle = NULL; // let system decide + // TODO OFN_SHAREAWARE? + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_FORCESHOWHIDDEN | OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_NOCHANGEDIR | OFN_NODEREFERENCELINKS | OFN_NOTESTFILECREATE | OFN_PATHMUSTEXIST; + if (GetOpenFileNameW(&ofn) == FALSE) { + err = CommDlgExtendedError(); + if (err != 0) // user cancelled + xpaniccomdlg("error running open file dialog", err); + free(o->filenameBuffer); // free now so we can set it to NULL without leaking + o->filenameBuffer = NULL; + } + if (PostMessageW(msgwin, msgOpenFileDone, (WPARAM) (o->filenameBuffer), (LPARAM) (o->f)) == 0) + xpanic("error posting OpenFile() finished message to message-only window", GetLastError()); + free(o); // won't free o->f or o->filenameBuffer in above invocation + return 0; +} + +void openFile(HWND hwnd, void *f) +{ + struct openFileData *o; + + // freed by the thread + o = (struct openFileData *) malloc(sizeof (struct openFileData)); + if (o == NULL) + xpanic("memory exhausted allocating data structure in OpenFile()", GetLastError()); + o->parent = hwnd; + o->f = f; + // freed on the Go side + o->filenameBuffer = (WCHAR *) malloc((NFILENAME + 1) * sizeof (WCHAR)); + if (o->filenameBuffer == NULL) + xpanic("memory exhausted allocating filename buffer in OpenFile()", GetLastError()); + if (CreateThread(NULL, 0, doOpenFile, (LPVOID) o, 0, NULL) == NULL) + xpanic("error creating thread for running OpenFIle()", GetLastError()); +} |
