Added OpenFile(), the first dialog to be added, and implemented it on Windows... mostly.
This commit is contained in:
parent
b6bf7402ab
commit
cb4d28cc1c
|
@ -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()
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -133,4 +133,7 @@ enum {
|
|||
extern HIMAGELIST checkboxImageList;
|
||||
extern void makeCheckboxImageList(HWND);
|
||||
|
||||
// dialog_windows.c
|
||||
extern WCHAR *openFile(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue