Added OpenFile(), the first dialog to be added, and implemented it on Windows... mostly.

This commit is contained in:
Pietro Gagliardi 2014-08-18 19:01:56 -04:00
parent b6bf7402ab
commit cb4d28cc1c
6 changed files with 102 additions and 2 deletions

10
redo/dialog.go Normal file
View File

@ -0,0 +1,10 @@
// 18 august 2014
package ui
// OpenFile opens a dialog box that asks the user to choose a file.
// It returns the selected filename, or an empty string if no file was chosen.
// All events stop while OpenFile is executing. (TODO move to doc.go)
func OpenFile() (filename string) {
return openFile()
}

40
redo/dialog_windows.c Normal file
View File

@ -0,0 +1,40 @@
// 18 august 2014
#include "winapi_windows.h"
#include "_cgo_export.h"
// this should be reasonable
#define NFILENAME 4096
WCHAR *openFile(void)
{
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
ZeroMemory(&ofn, sizeof (OPENFILENAMEW));
ofn.lStructSize = sizeof (OPENFILENAMEW);
ofn.hwndOwner = NULL;
ofn.hInstance = hInstance;
ofn.lpstrFilter = NULL; // no filters
ofn.lpstrFile = filenameBuffer;
ofn.nMaxFile = NFILENAME + 1; // TODO include + 1?
ofn.lpstrInitialDir = NULL; // let system decide
ofn.lpstrTitle = NULL; // let system decide
// TODO OFN_SHAREAWARE?
// TODO remove OFN_NODEREFERENCELINKS? or does no filters ensure that anyway?
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_FORCESHOWHIDDEN | OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_NOCHANGEDIR | OFN_NODEREFERENCELINKS | OFN_NOTESTFILECREATE | OFN_PATHMUSTEXIST;
if (GetOpenFileNameW(&ofn) == FALSE) {
// TODO stringify
err = CommDlgExtendedError();
if (err == 0) // user cancelled
return NULL;
xpanic("error running open file dialog", GetLastError());
}
return filenameBuffer;
}

33
redo/dialog_windows.go Normal file
View File

@ -0,0 +1,33 @@
// 18 august 2014
package ui
import (
"syscall"
"unsafe"
"reflect"
)
// #include "winapi_windows.h"
import "C"
// TODO move to common_windows.go
func wstrToString(wstr *C.WCHAR) string {
n := C.wcslen((*C.wchar_t)(unsafe.Pointer(wstr)))
xbuf := &reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(wstr)),
Len: int(n + 1),
Cap: int(n + 1),
}
buf := (*[]uint16)(unsafe.Pointer(xbuf))
return syscall.UTF16ToString(*buf)
}
func openFile() string {
name := C.openFile()
if name == nil {
return ""
}
defer C.free(unsafe.Pointer(name))
return wstrToString(name)
}

View File

@ -9,7 +9,7 @@ import (
)
// #cgo CFLAGS: --std=c99
// #cgo LDFLAGS: -luser32 -lkernel32 -lgdi32 -luxtheme -lmsimg32
// #cgo LDFLAGS: -luser32 -lkernel32 -lgdi32 -luxtheme -lmsimg32 -lcomdlg32
// #include "winapi_windows.h"
import "C"

View File

@ -133,4 +133,7 @@ enum {
extern HIMAGELIST checkboxImageList;
extern void makeCheckboxImageList(HWND);
// dialog_windows.c
extern WCHAR *openFile(void);
#endif

View File

@ -38,6 +38,8 @@ type testwin struct {
festart Button
felabel Label
festop Button
openbtn Button
fnlabel Label
icons []icon
il ImageList
icontbl Table
@ -89,7 +91,19 @@ func (tw *testwin) addfe() {
tw.fe = nil
}
})
tw.festack = NewVerticalStack(tw.festart, tw.felabel, tw.festop)
tw.openbtn = NewButton("Open")
tw.openbtn.OnClicked(func() {
fn := OpenFile()
if fn == "" {
fn = "<no file selected>"
}
tw.fnlabel.SetText(fn)
})
tw.fnlabel = NewStandaloneLabel("<no file selected>")
tw.festack = NewVerticalStack(tw.festart, tw.felabel, tw.festop,
Space(),
tw.openbtn, tw.fnlabel)
tw.festack.SetStretchy(3)
tw.t.Append("Foreign Events", tw.festack)
}