File API, windows fixes.
This commit is contained in:
parent
6bd07cf824
commit
339101c9f4
6 changed files with 198 additions and 130 deletions
44
file.go
44
file.go
|
@ -1,6 +1,50 @@
|
|||
package zenity
|
||||
|
||||
type opts struct {
|
||||
title string
|
||||
}
|
||||
|
||||
type Option func(*opts)
|
||||
|
||||
func (o *opts) Title(title string) {
|
||||
o.title = title
|
||||
}
|
||||
|
||||
type fileopts struct {
|
||||
opts
|
||||
filename string
|
||||
overwrite bool
|
||||
filters []FileFilter
|
||||
}
|
||||
|
||||
type FileOption func(*fileopts)
|
||||
|
||||
func Filename(filename string) FileOption {
|
||||
return func(o *fileopts) {
|
||||
o.filename = filename
|
||||
}
|
||||
}
|
||||
|
||||
func ConfirmOverwrite(o *fileopts) {
|
||||
o.overwrite = true
|
||||
}
|
||||
|
||||
type FileFilter struct {
|
||||
Name string
|
||||
Exts []string
|
||||
}
|
||||
|
||||
type FileFilters []FileFilter
|
||||
|
||||
func (f FileFilters) New() FileOption {
|
||||
return func(o *fileopts) {
|
||||
o.filters = f
|
||||
}
|
||||
}
|
||||
|
||||
func fileoptsParse(options []FileOption) (res fileopts) {
|
||||
for _, o := range options {
|
||||
o(&res)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -8,13 +8,15 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func SelectFile(title, defaultPath string, filters []FileFilter) (string, error) {
|
||||
func SelectFile(options ...FileOption) (string, error) {
|
||||
opts := fileoptsParse(options)
|
||||
|
||||
cmd := exec.Command("osascript", "-l", "JavaScript")
|
||||
cmd.Stdin = scriptExpand(scriptData{
|
||||
Operation: "chooseFile",
|
||||
Title: title,
|
||||
DefaultPath: defaultPath,
|
||||
Filter: appleFilters(filters),
|
||||
Operation: "chooseFile",
|
||||
Prompt: opts.title,
|
||||
Location: opts.filename,
|
||||
Type: appleFilters(opts.filters),
|
||||
})
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
|
@ -26,14 +28,16 @@ func SelectFile(title, defaultPath string, filters []FileFilter) (string, error)
|
|||
return string(out), nil
|
||||
}
|
||||
|
||||
func SelectFileMutiple(title, defaultPath string, filters []FileFilter) ([]string, error) {
|
||||
func SelectFileMutiple(options ...FileOption) ([]string, error) {
|
||||
opts := fileoptsParse(options)
|
||||
|
||||
cmd := exec.Command("osascript", "-l", "JavaScript")
|
||||
cmd.Stdin = scriptExpand(scriptData{
|
||||
Operation: "chooseFile",
|
||||
Multiple: true,
|
||||
Title: title,
|
||||
DefaultPath: defaultPath,
|
||||
Filter: appleFilters(filters),
|
||||
Operation: "chooseFile",
|
||||
Multiple: true,
|
||||
Prompt: opts.title,
|
||||
Location: opts.filename,
|
||||
Type: appleFilters(opts.filters),
|
||||
})
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
|
@ -48,12 +52,14 @@ func SelectFileMutiple(title, defaultPath string, filters []FileFilter) ([]strin
|
|||
return strings.Split(string(out), "\x00"), nil
|
||||
}
|
||||
|
||||
func SelectFileSave(title, defaultPath string, confirmOverwrite bool, filters []FileFilter) (string, error) {
|
||||
func SelectFileSave(options ...FileOption) (string, error) {
|
||||
opts := fileoptsParse(options)
|
||||
|
||||
cmd := exec.Command("osascript", "-l", "JavaScript")
|
||||
cmd.Stdin = scriptExpand(scriptData{
|
||||
Operation: "chooseFileName",
|
||||
Title: title,
|
||||
DefaultPath: defaultPath,
|
||||
Operation: "chooseFileName",
|
||||
Prompt: opts.title,
|
||||
Location: opts.filename,
|
||||
})
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
|
@ -65,12 +71,14 @@ func SelectFileSave(title, defaultPath string, confirmOverwrite bool, filters []
|
|||
return string(out), nil
|
||||
}
|
||||
|
||||
func SelectDirectory(title, defaultPath string) (string, error) {
|
||||
func SelectDirectory(options ...FileOption) (string, error) {
|
||||
opts := fileoptsParse(options)
|
||||
|
||||
cmd := exec.Command("osascript", "-l", "JavaScript")
|
||||
cmd.Stdin = scriptExpand(scriptData{
|
||||
Operation: "chooseFolder",
|
||||
Title: title,
|
||||
DefaultPath: defaultPath,
|
||||
Operation: "chooseFolder",
|
||||
Prompt: opts.title,
|
||||
Location: opts.filename,
|
||||
})
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
|
@ -93,11 +101,11 @@ func appleFilters(filters []FileFilter) []string {
|
|||
}
|
||||
|
||||
type scriptData struct {
|
||||
Operation string
|
||||
Title string
|
||||
DefaultPath string
|
||||
Filter []string
|
||||
Multiple bool
|
||||
Operation string
|
||||
Prompt string
|
||||
Location string
|
||||
Type []string
|
||||
Multiple bool
|
||||
}
|
||||
|
||||
func scriptExpand(data scriptData) io.Reader {
|
||||
|
@ -118,14 +126,14 @@ app.includeStandardAdditions = true;
|
|||
app.activate();
|
||||
|
||||
var opts = {};
|
||||
opts.withPrompt = {{.Title}};
|
||||
opts.withPrompt = {{.Prompt}};
|
||||
opts.multipleSelectionsAllowed = {{.Multiple}};
|
||||
|
||||
{{if .DefaultPath}}
|
||||
opts.defaultLocation = {{.DefaultPath}};
|
||||
{{if .Location}}
|
||||
opts.defaultLocation = {{.Location}};
|
||||
{{end}}
|
||||
{{if .Filter}}
|
||||
opts.ofType = {{.Filter}};
|
||||
{{if .Type}}
|
||||
opts.ofType = {{.Type}};
|
||||
{{end}}
|
||||
|
||||
var res;
|
||||
|
|
|
@ -5,15 +5,17 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func SelectFile(title, defaultPath string, filters []FileFilter) (string, error) {
|
||||
func SelectFile(options ...FileOption) (string, error) {
|
||||
opts := fileoptsParse(options)
|
||||
|
||||
args := []string{"--file-selection"}
|
||||
if title != "" {
|
||||
args = append(args, "--title="+title)
|
||||
if opts.title != "" {
|
||||
args = append(args, "--title="+opts.title)
|
||||
}
|
||||
if defaultPath != "" {
|
||||
args = append(args, "--filename="+defaultPath)
|
||||
if opts.filename != "" {
|
||||
args = append(args, "--filename="+opts.filename)
|
||||
}
|
||||
args = append(args, zenityFilters(filters)...)
|
||||
args = append(args, zenityFilters(opts.filters)...)
|
||||
cmd := exec.Command("zenity", args...)
|
||||
out, err := cmd.Output()
|
||||
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
|
||||
|
@ -28,15 +30,17 @@ func SelectFile(title, defaultPath string, filters []FileFilter) (string, error)
|
|||
return string(out), nil
|
||||
}
|
||||
|
||||
func SelectFileMutiple(title, defaultPath string, filters []FileFilter) ([]string, error) {
|
||||
func SelectFileMutiple(options ...FileOption) ([]string, error) {
|
||||
opts := fileoptsParse(options)
|
||||
|
||||
args := []string{"--file-selection", "--multiple", "--separator=\x1e"}
|
||||
if title != "" {
|
||||
args = append(args, "--title="+title)
|
||||
if opts.title != "" {
|
||||
args = append(args, "--title="+opts.title)
|
||||
}
|
||||
if defaultPath != "" {
|
||||
args = append(args, "--filename="+defaultPath)
|
||||
if opts.filename != "" {
|
||||
args = append(args, "--filename="+opts.filename)
|
||||
}
|
||||
args = append(args, zenityFilters(filters)...)
|
||||
args = append(args, zenityFilters(opts.filters)...)
|
||||
cmd := exec.Command("zenity", args...)
|
||||
out, err := cmd.Output()
|
||||
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
|
||||
|
@ -51,18 +55,20 @@ func SelectFileMutiple(title, defaultPath string, filters []FileFilter) ([]strin
|
|||
return strings.Split(string(out), "\x1e"), nil
|
||||
}
|
||||
|
||||
func SelectFileSave(title, defaultPath string, confirmOverwrite bool, filters []FileFilter) (string, error) {
|
||||
func SelectFileSave(options ...FileOption) (string, error) {
|
||||
opts := fileoptsParse(options)
|
||||
|
||||
args := []string{"--file-selection", "--save"}
|
||||
if title != "" {
|
||||
args = append(args, "--title="+title)
|
||||
if opts.title != "" {
|
||||
args = append(args, "--title="+opts.title)
|
||||
}
|
||||
if defaultPath != "" {
|
||||
args = append(args, "--filename="+defaultPath)
|
||||
if opts.filename != "" {
|
||||
args = append(args, "--filename="+opts.filename)
|
||||
}
|
||||
if confirmOverwrite {
|
||||
if opts.overwrite {
|
||||
args = append(args, "--confirm-overwrite")
|
||||
}
|
||||
args = append(args, zenityFilters(filters)...)
|
||||
args = append(args, zenityFilters(opts.filters)...)
|
||||
cmd := exec.Command("zenity", args...)
|
||||
out, err := cmd.Output()
|
||||
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
|
||||
|
@ -77,13 +83,15 @@ func SelectFileSave(title, defaultPath string, confirmOverwrite bool, filters []
|
|||
return string(out), nil
|
||||
}
|
||||
|
||||
func SelectDirectory(title, defaultPath string) (string, error) {
|
||||
func SelectDirectory(options ...FileOption) (string, error) {
|
||||
opts := fileoptsParse(options)
|
||||
|
||||
args := []string{"--file-selection", "--directory"}
|
||||
if title != "" {
|
||||
args = append(args, "--title="+title)
|
||||
if opts.title != "" {
|
||||
args = append(args, "--title="+opts.title)
|
||||
}
|
||||
if defaultPath != "" {
|
||||
args = append(args, "--filename="+defaultPath)
|
||||
if opts.filename != "" {
|
||||
args = append(args, "--filename="+opts.filename)
|
||||
}
|
||||
cmd := exec.Command("zenity", args...)
|
||||
out, err := cmd.Output()
|
||||
|
|
14
file_test.go
14
file_test.go
|
@ -5,11 +5,11 @@ import "testing"
|
|||
const defaultPath = ""
|
||||
|
||||
func TestSelectFile(t *testing.T) {
|
||||
res, err := SelectFile("", defaultPath, []FileFilter{
|
||||
res, err := SelectFile(Filename(defaultPath), FileFilters{
|
||||
{"Go files", []string{".go"}},
|
||||
{"Web files", []string{".html", ".js", ".css"}},
|
||||
{"Image files", []string{".png", ".gif", ".ico", ".jpg", ".webp"}},
|
||||
})
|
||||
}.New())
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -19,11 +19,11 @@ func TestSelectFile(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSelectFileMutiple(t *testing.T) {
|
||||
res, err := SelectFileMutiple("", defaultPath, []FileFilter{
|
||||
res, err := SelectFileMutiple(Filename(defaultPath), FileFilters{
|
||||
{"Go files", []string{".go"}},
|
||||
{"Web files", []string{".html", ".js", ".css"}},
|
||||
{"Image files", []string{".png", ".gif", ".ico", ".jpg", ".webp"}},
|
||||
})
|
||||
}.New())
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -33,11 +33,11 @@ func TestSelectFileMutiple(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSelectFileSave(t *testing.T) {
|
||||
res, err := SelectFileSave("", defaultPath, true, []FileFilter{
|
||||
res, err := SelectFileSave(Filename(defaultPath), ConfirmOverwrite, FileFilters{
|
||||
{"Go files", []string{".go"}},
|
||||
{"Web files", []string{".html", ".js", ".css"}},
|
||||
{"Image files", []string{".png", ".gif", ".ico", ".jpg", ".webp"}},
|
||||
})
|
||||
}.New())
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -47,7 +47,7 @@ func TestSelectFileSave(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSelectDirectory(t *testing.T) {
|
||||
res, err := SelectDirectory("", defaultPath)
|
||||
res, err := SelectDirectory(Filename(defaultPath))
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
|
143
file_windows.go
143
file_windows.go
|
@ -1,10 +1,10 @@
|
|||
package zenity
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
@ -27,60 +27,58 @@ var (
|
|||
shCreateItemFromParsingName = shell32.NewProc("SHCreateItemFromParsingName")
|
||||
)
|
||||
|
||||
func SelectFile(title, defaultPath string, filters []FileFilter) (string, error) {
|
||||
func SelectFile(options ...FileOption) (string, error) {
|
||||
var args _OPENFILENAME
|
||||
args.StructSize = uint32(unsafe.Sizeof(args))
|
||||
args.Flags = 0x80008 // OFN_NOCHANGEDIR|OFN_EXPLORER
|
||||
|
||||
if title != "" {
|
||||
args.Title = syscall.StringToUTF16Ptr(title)
|
||||
opts := fileoptsParse(options)
|
||||
if opts.title != "" {
|
||||
args.Title = syscall.StringToUTF16Ptr(opts.title)
|
||||
}
|
||||
if defaultPath != "" {
|
||||
args.InitialDir = syscall.StringToUTF16Ptr(defaultPath)
|
||||
if opts.filename != "" {
|
||||
args.InitialDir = syscall.StringToUTF16Ptr(opts.filename)
|
||||
}
|
||||
args.Filter = &windowsFilters(filters)[0]
|
||||
args.Filter = &windowsFilters(opts.filters)[0]
|
||||
|
||||
res := [32768]uint16{}
|
||||
args.File = &res[0]
|
||||
args.MaxFile = uint32(len(res))
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
n, _, _ := getOpenFileName.Call(uintptr(unsafe.Pointer(&args)))
|
||||
if n == 0 {
|
||||
n, _, _ = commDlgExtendedError.Call()
|
||||
if n == 0 {
|
||||
return "", nil
|
||||
} else {
|
||||
return "", fmt.Errorf("Common Dialog error: %x", n)
|
||||
}
|
||||
return "", commDlgError()
|
||||
}
|
||||
return syscall.UTF16ToString(res[:]), nil
|
||||
}
|
||||
|
||||
func SelectFileMutiple(title, defaultPath string, filters []FileFilter) ([]string, error) {
|
||||
func SelectFileMutiple(options ...FileOption) ([]string, error) {
|
||||
var args _OPENFILENAME
|
||||
args.StructSize = uint32(unsafe.Sizeof(args))
|
||||
args.Flags = 0x80208 // OFN_NOCHANGEDIR|OFN_ALLOWMULTISELECT|OFN_EXPLORER
|
||||
|
||||
if title != "" {
|
||||
args.Title = syscall.StringToUTF16Ptr(title)
|
||||
opts := fileoptsParse(options)
|
||||
if opts.title != "" {
|
||||
args.Title = syscall.StringToUTF16Ptr(opts.title)
|
||||
}
|
||||
if defaultPath != "" {
|
||||
args.InitialDir = syscall.StringToUTF16Ptr(defaultPath)
|
||||
if opts.filename != "" {
|
||||
args.InitialDir = syscall.StringToUTF16Ptr(opts.filename)
|
||||
}
|
||||
args.Filter = &windowsFilters(filters)[0]
|
||||
args.Filter = &windowsFilters(opts.filters)[0]
|
||||
|
||||
res := [32768 + 1024*256]uint16{}
|
||||
args.File = &res[0]
|
||||
args.MaxFile = uint32(len(res))
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
n, _, _ := getOpenFileName.Call(uintptr(unsafe.Pointer(&args)))
|
||||
if n == 0 {
|
||||
n, _, _ = commDlgExtendedError.Call()
|
||||
if n == 0 {
|
||||
return nil, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("Common Dialog error: %x", n)
|
||||
}
|
||||
return nil, commDlgError()
|
||||
}
|
||||
|
||||
var i int
|
||||
|
@ -110,72 +108,78 @@ func SelectFileMutiple(title, defaultPath string, filters []FileFilter) ([]strin
|
|||
return split, nil
|
||||
}
|
||||
|
||||
func SelectFileSave(title, defaultPath string, confirmOverwrite bool, filters []FileFilter) (string, error) {
|
||||
func SelectFileSave(options ...FileOption) (string, error) {
|
||||
var args _OPENFILENAME
|
||||
args.StructSize = uint32(unsafe.Sizeof(args))
|
||||
args.Flags = 0x80008 // OFN_NOCHANGEDIR|OFN_EXPLORER
|
||||
|
||||
if title != "" {
|
||||
args.Title = syscall.StringToUTF16Ptr(title)
|
||||
opts := fileoptsParse(options)
|
||||
if opts.title != "" {
|
||||
args.Title = syscall.StringToUTF16Ptr(opts.title)
|
||||
}
|
||||
if defaultPath != "" {
|
||||
args.InitialDir = syscall.StringToUTF16Ptr(defaultPath)
|
||||
if opts.filename != "" {
|
||||
args.InitialDir = syscall.StringToUTF16Ptr(opts.filename)
|
||||
}
|
||||
if confirmOverwrite {
|
||||
if opts.overwrite {
|
||||
args.Flags |= 0x2 // OFN_OVERWRITEPROMPT
|
||||
}
|
||||
args.Filter = &windowsFilters(filters)[0]
|
||||
args.Filter = &windowsFilters(opts.filters)[0]
|
||||
|
||||
res := [32768]uint16{}
|
||||
args.File = &res[0]
|
||||
args.MaxFile = uint32(len(res))
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
n, _, _ := getSaveFileName.Call(uintptr(unsafe.Pointer(&args)))
|
||||
if n == 0 {
|
||||
n, _, _ = commDlgExtendedError.Call()
|
||||
if n == 0 {
|
||||
return "", nil
|
||||
} else {
|
||||
return "", fmt.Errorf("Common Dialog error: %x", n)
|
||||
}
|
||||
return "", commDlgError()
|
||||
}
|
||||
return syscall.UTF16ToString(res[:]), nil
|
||||
}
|
||||
|
||||
func SelectDirectory(title, defaultPath string) (string, error) {
|
||||
func SelectDirectory(options ...FileOption) (string, error) {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
hr, _, _ := coInitializeEx.Call(0, 0x6) // COINIT_APARTMENTTHREADED|COINIT_DISABLE_OLE1DDE
|
||||
if hr < 0 {
|
||||
return "", errors.New("COM initialization failed.")
|
||||
if hr != 0x80010106 { // RPC_E_CHANGED_MODE
|
||||
if int32(hr) < 0 {
|
||||
return "", syscall.Errno(hr)
|
||||
}
|
||||
defer coUninitialize.Call()
|
||||
}
|
||||
defer coUninitialize.Call()
|
||||
|
||||
opts := fileoptsParse(options)
|
||||
|
||||
var dialog *_IFileOpenDialog
|
||||
hr, _, _ = coCreateInstance.Call(
|
||||
_CLSID_FileOpenDialog, 0, 0x17, // CLSCTX_ALL
|
||||
_IID_IFileOpenDialog, uintptr(unsafe.Pointer(&dialog)))
|
||||
if hr < 0 || dialog == nil {
|
||||
return browseForFolder(title, defaultPath)
|
||||
if int32(hr) < 0 {
|
||||
return browseForFolder(opts.title)
|
||||
}
|
||||
defer dialog.Call(dialog.vtbl.Release)
|
||||
|
||||
var opts int
|
||||
hr, _, _ = dialog.Call(dialog.vtbl.GetOptions, uintptr(unsafe.Pointer(&opts)))
|
||||
if hr < 0 {
|
||||
return "", fmt.Errorf("IFileOpenDialog.GetOptions error: %x", hr)
|
||||
var flgs int
|
||||
hr, _, _ = dialog.Call(dialog.vtbl.GetOptions, uintptr(unsafe.Pointer(&flgs)))
|
||||
if int32(hr) < 0 {
|
||||
return "", syscall.Errno(hr)
|
||||
}
|
||||
hr, _, _ = dialog.Call(dialog.vtbl.SetOptions, uintptr(opts|0x68)) // FOS_NOCHANGEDIR|FOS_PICKFOLDERS|FOS_FORCEFILESYSTEM
|
||||
if hr < 0 {
|
||||
return "", fmt.Errorf("IFileOpenDialog.SetOptions error: %x", hr)
|
||||
hr, _, _ = dialog.Call(dialog.vtbl.SetOptions, uintptr(flgs|0x68)) // FOS_NOCHANGEDIR|FOS_PICKFOLDERS|FOS_FORCEFILESYSTEM
|
||||
if int32(hr) < 0 {
|
||||
return "", syscall.Errno(hr)
|
||||
}
|
||||
|
||||
if title != "" {
|
||||
ptr := syscall.StringToUTF16Ptr(title)
|
||||
if opts.title != "" {
|
||||
ptr := syscall.StringToUTF16Ptr(opts.title)
|
||||
dialog.Call(dialog.vtbl.SetTitle, uintptr(unsafe.Pointer(ptr)))
|
||||
}
|
||||
|
||||
if defaultPath != "" {
|
||||
if opts.filename != "" {
|
||||
var item *_IShellItem
|
||||
ptr := syscall.StringToUTF16Ptr(defaultPath)
|
||||
ptr := syscall.StringToUTF16Ptr(opts.filename)
|
||||
hr, _, _ = shCreateItemFromParsingName.Call(
|
||||
uintptr(unsafe.Pointer(ptr)), 0,
|
||||
_IID_IShellItem,
|
||||
|
@ -188,17 +192,17 @@ func SelectDirectory(title, defaultPath string) (string, error) {
|
|||
}
|
||||
|
||||
hr, _, _ = dialog.Call(dialog.vtbl.Show, 0)
|
||||
if hr < 0 {
|
||||
return "", fmt.Errorf("IFileOpenDialog.Show error: %x", hr)
|
||||
if hr == 0x800704c7 { // ERROR_CANCELLED
|
||||
return "", nil
|
||||
}
|
||||
if int32(hr) < 0 {
|
||||
return "", syscall.Errno(hr)
|
||||
}
|
||||
|
||||
var item *_IShellItem
|
||||
hr, _, _ = dialog.Call(dialog.vtbl.GetResult, uintptr(unsafe.Pointer(&item)))
|
||||
if hr < 0 {
|
||||
return "", fmt.Errorf("IFileOpenDialog.GetResult error: %x", hr)
|
||||
}
|
||||
if item == nil {
|
||||
return "", nil
|
||||
if int32(hr) < 0 {
|
||||
return "", syscall.Errno(hr)
|
||||
}
|
||||
defer item.Call(item.vtbl.Release)
|
||||
|
||||
|
@ -206,8 +210,8 @@ func SelectDirectory(title, defaultPath string) (string, error) {
|
|||
hr, _, _ = item.Call(item.vtbl.GetDisplayName,
|
||||
0x80058000, // SIGDN_FILESYSPATH
|
||||
uintptr(unsafe.Pointer(&ptr)))
|
||||
if hr < 0 {
|
||||
return "", fmt.Errorf("IShellItem.GetDisplayName error: %x", hr)
|
||||
if int32(hr) < 0 {
|
||||
return "", syscall.Errno(hr)
|
||||
}
|
||||
defer coTaskMemFree.Call(ptr)
|
||||
|
||||
|
@ -215,7 +219,7 @@ func SelectDirectory(title, defaultPath string) (string, error) {
|
|||
return syscall.UTF16ToString(*(*[]uint16)(unsafe.Pointer(&res))), nil
|
||||
}
|
||||
|
||||
func browseForFolder(title, defaultPath string) (string, error) {
|
||||
func browseForFolder(title string) (string, error) {
|
||||
var args _BROWSEINFO
|
||||
args.Flags = 0x1 // BIF_RETURNONLYFSDIRS
|
||||
|
||||
|
@ -253,6 +257,15 @@ func windowsFilters(filters []FileFilter) []uint16 {
|
|||
return res
|
||||
}
|
||||
|
||||
func commDlgError() error {
|
||||
n, _, _ := commDlgExtendedError.Call()
|
||||
if n == 0 {
|
||||
return nil
|
||||
} else {
|
||||
return fmt.Errorf("Common Dialog error: %x", n)
|
||||
}
|
||||
}
|
||||
|
||||
type _OPENFILENAME struct {
|
||||
StructSize uint32
|
||||
Owner uintptr
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
package zenity
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func init() {
|
||||
user32 := syscall.NewLazyDLL("user32.dll")
|
||||
user32.NewProc("SetProcessDPIAware").Call()
|
||||
}
|
Loading…
Reference in a new issue