Use IFileSaveDialog where available.
This commit is contained in:
parent
c56588920f
commit
77da6e29f3
2 changed files with 96 additions and 0 deletions
|
@ -130,6 +130,10 @@ func selectFileMultiple(opts options) ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func selectFileSave(opts options) (string, error) {
|
func selectFileSave(opts options) (string, error) {
|
||||||
|
name, shown, err := fileSaveDialog(opts)
|
||||||
|
if shown || opts.ctx != nil && opts.ctx.Err() != nil {
|
||||||
|
return name, err
|
||||||
|
}
|
||||||
if opts.directory {
|
if opts.directory {
|
||||||
return selectFile(opts)
|
return selectFile(opts)
|
||||||
}
|
}
|
||||||
|
@ -280,6 +284,86 @@ func fileOpenDialog(opts options, multi bool) (string, []string, bool, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fileSaveDialog(opts options) (string, bool, error) {
|
||||||
|
uninit, err := coInitialize()
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
defer uninit()
|
||||||
|
|
||||||
|
owner, _ := opts.attach.(win.HWND)
|
||||||
|
defer setup(owner)()
|
||||||
|
|
||||||
|
var dialog *win.IFileSaveDialog
|
||||||
|
err = win.CoCreateInstance(
|
||||||
|
win.CLSID_FileSaveDialog, nil, win.CLSCTX_ALL,
|
||||||
|
win.IID_IFileSaveDialog, unsafe.Pointer(&dialog))
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
defer dialog.Release()
|
||||||
|
|
||||||
|
flgs, err := dialog.GetOptions()
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
flgs |= win.FOS_NOCHANGEDIR | win.FOS_PATHMUSTEXIST | win.FOS_NOREADONLYRETURN | win.FOS_FORCEFILESYSTEM
|
||||||
|
if opts.confirmOverwrite {
|
||||||
|
flgs |= win.FOS_OVERWRITEPROMPT
|
||||||
|
}
|
||||||
|
if opts.confirmCreate {
|
||||||
|
flgs |= win.FOS_CREATEPROMPT
|
||||||
|
}
|
||||||
|
if opts.showHidden {
|
||||||
|
flgs |= win.FOS_FORCESHOWHIDDEN
|
||||||
|
}
|
||||||
|
err = dialog.SetOptions(flgs)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.title != nil {
|
||||||
|
dialog.SetTitle(strptr(*opts.title))
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.filename != "" {
|
||||||
|
var item *win.IShellItem
|
||||||
|
dir, name, _ := splitDirAndName(opts.filename)
|
||||||
|
dialog.SetFileName(strptr(name))
|
||||||
|
if ext := filepath.Ext(name); len(ext) > 1 {
|
||||||
|
dialog.SetDefaultExtension(strptr(ext[1:]))
|
||||||
|
}
|
||||||
|
win.SHCreateItemFromParsingName(strptr(dir), nil, win.IID_IShellItem, &item)
|
||||||
|
if item != nil {
|
||||||
|
defer item.Release()
|
||||||
|
dialog.SetFolder(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
defer unhook()
|
||||||
|
|
||||||
|
err = dialog.Show(owner)
|
||||||
|
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||||
|
return "", true, opts.ctx.Err()
|
||||||
|
}
|
||||||
|
if err == win.E_CANCELED {
|
||||||
|
return "", true, ErrCanceled
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return "", true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
str, err := shellItemPath(dialog.GetResult())
|
||||||
|
if err != nil {
|
||||||
|
return "", true, err
|
||||||
|
}
|
||||||
|
return str, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
func shellItemPath(item *win.IShellItem, err error) (string, error) {
|
func shellItemPath(item *win.IShellItem, err error) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|
|
@ -123,7 +123,9 @@ type IDLIST struct{}
|
||||||
var (
|
var (
|
||||||
IID_IShellItem = guid("\x1e\x6d\x82\x43\x18\xe7\xee\x42\xbc\x55\xa1\xe2\x61\xc3\x7b\xfe")
|
IID_IShellItem = guid("\x1e\x6d\x82\x43\x18\xe7\xee\x42\xbc\x55\xa1\xe2\x61\xc3\x7b\xfe")
|
||||||
IID_IFileOpenDialog = guid("\x88\x72\x7c\xd5\xad\xd4\x68\x47\xbe\x02\x9d\x96\x95\x32\xd9\x60")
|
IID_IFileOpenDialog = guid("\x88\x72\x7c\xd5\xad\xd4\x68\x47\xbe\x02\x9d\x96\x95\x32\xd9\x60")
|
||||||
|
IID_IFileSaveDialog = guid("\x23\xcd\xbc\x84\xde\x5f\xdb\x4c\xae\xa4\xaf\x64\xb8\x3d\x78\xab")
|
||||||
CLSID_FileOpenDialog = guid("\x9c\x5a\x1c\xdc\x8a\xe8\xde\x4d\xa5\xa1\x60\xf8\x2a\x20\xae\xf7")
|
CLSID_FileOpenDialog = guid("\x9c\x5a\x1c\xdc\x8a\xe8\xde\x4d\xa5\xa1\x60\xf8\x2a\x20\xae\xf7")
|
||||||
|
CLSID_FileSaveDialog = guid("\xf3\xe2\xb4\xc0\x21\xba\x73\x47\x8d\xba\x33\x5e\xc9\x46\xeb\x8b")
|
||||||
)
|
)
|
||||||
|
|
||||||
type IFileOpenDialog struct{ IFileDialog }
|
type IFileOpenDialog struct{ IFileDialog }
|
||||||
|
@ -142,6 +144,16 @@ func (u *IFileOpenDialog) GetResults() (res *IShellItemArray, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IFileSaveDialog struct{ IFileDialog }
|
||||||
|
type IFileSaveDialogVtbl struct {
|
||||||
|
iFileDialogVtbl
|
||||||
|
SetSaveAsItem uintptr
|
||||||
|
SetProperties uintptr
|
||||||
|
SetCollectedProperties uintptr
|
||||||
|
GetProperties uintptr
|
||||||
|
ApplyProperties uintptr
|
||||||
|
}
|
||||||
|
|
||||||
type IFileDialog struct{ IModalWindow }
|
type IFileDialog struct{ IModalWindow }
|
||||||
type iFileDialogVtbl struct {
|
type iFileDialogVtbl struct {
|
||||||
iModalWindowVtbl
|
iModalWindowVtbl
|
||||||
|
|
Loading…
Reference in a new issue