summaryrefslogtreecommitdiff
path: root/redo/dialog_windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'redo/dialog_windows.c')
-rw-r--r--redo/dialog_windows.c87
1 files changed, 37 insertions, 50 deletions
diff --git a/redo/dialog_windows.c b/redo/dialog_windows.c
index ad48cd5..10fb75c 100644
--- a/redo/dialog_windows.c
+++ b/redo/dialog_windows.c
@@ -3,73 +3,60 @@
#include "winapi_windows.h"
#include "_cgo_export.h"
-static LRESULT CALLBACK dialogSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR data)
-{
- switch (uMsg) {
- case WM_COMMAND:
- // we must re-enable other windows in the right order (see http://blogs.msdn.com/b/oldnewthing/archive/2004/02/27/81155.aspx)
- // see http://stackoverflow.com/questions/25494914/is-there-something-like-cdn-filecancel-analogous-to-cdn-fileok-for-getting-when
- if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL)
- SendMessageW(msgwin, msgEndModal, 0, 0);
- break; // let the dialog handle it now
- case WM_NCDESTROY:
- if ((*fv_RemoveWindowSubclass)(hwnd, dialogSubProc, id) == FALSE)
- xpanic("error removing dialog subclass (which was for its own event handler)", GetLastError());
- }
- return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
-}
-
// this should be reasonable
#define NFILENAME 4096
-static UINT_PTR CALLBACK openSaveFileHook(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- if (uMsg == WM_INITDIALOG) {
- HWND parent;
-
- parent = GetParent(hwnd);
- if (parent == NULL)
- xpanic("error gettign parent of OpenFile() dialog for event handling", GetLastError());
- if ((*fv_SetWindowSubclass)(parent, dialogSubProc, 0, (DWORD_PTR) NULL) == FALSE)
- xpanic("error subclassing OpenFile() dialog to give it its own event handler", GetLastError());
- } else if (uMsg == WM_NOTIFY) {
- OFNOTIFY *of = (OFNOTIFY *) lParam;
-
- if (of->hdr.code == CDN_FILEOK)
- SendMessageW(msgwin, msgEndModal, 0, 0);
- }
- return 0;
-}
+struct openFileData {
+ HWND parent;
+ void *f;
+ WCHAR *filenameBuffer;
+};
-WCHAR *openFile(void)
+static DWORD WINAPI doOpenFile(LPVOID data)
{
+ struct openFileData *o = (struct openFileData *) data;
OPENFILENAMEW ofn;
DWORD err;
- WCHAR *filenameBuffer;
- // freed on the Go side
- filenameBuffer = (WCHAR *) malloc((NFILENAME + 1) * sizeof (WCHAR));
- if (filenameBuffer == NULL)
- xpanic("memory exhausted in OpenFile()", GetLastError());
- filenameBuffer[0] = L'\0'; // required by GetOpenFileName() to indicate no previous filename
+ o->filenameBuffer[0] = L'\0'; // required by GetOpenFileName() to indicate no previous filename
ZeroMemory(&ofn, sizeof (OPENFILENAMEW));
ofn.lStructSize = sizeof (OPENFILENAMEW);
- ofn.hwndOwner = NULL;
+ ofn.hwndOwner = o->parent;
ofn.hInstance = hInstance;
ofn.lpstrFilter = NULL; // no filters
- ofn.lpstrFile = filenameBuffer;
+ ofn.lpstrFile = o->filenameBuffer;
ofn.nMaxFile = NFILENAME + 1; // TODO include + 1?
ofn.lpstrInitialDir = NULL; // let system decide
ofn.lpstrTitle = NULL; // let system decide
// TODO OFN_SHAREAWARE?
- ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_FORCESHOWHIDDEN | OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_NOCHANGEDIR | OFN_NODEREFERENCELINKS | OFN_NOTESTFILECREATE | OFN_PATHMUSTEXIST;
- ofn.lpfnHook = openSaveFileHook;
- SendMessageW(msgwin, msgBeginModal, 0, 0);
+ 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
- return NULL;
- xpaniccomdlg("error running open file dialog", err);
+ 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;
}
- return filenameBuffer;
+ 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());
}