Initialize COM around file dialogs.
This commit is contained in:
parent
341ccb89d4
commit
3f5b602117
2 changed files with 43 additions and 8 deletions
|
@ -1,8 +1,10 @@
|
|||
package zenity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
@ -36,6 +38,12 @@ func selectFile(opts options) (string, error) {
|
|||
args.MaxFile = uint32(len(res))
|
||||
args.InitialDir, args.DefExt = initDirNameExt(opts.filename, res[:])
|
||||
|
||||
uninit, err := coInitialize()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer uninit()
|
||||
|
||||
defer setup(args.Owner)()
|
||||
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, nil)
|
||||
if err != nil {
|
||||
|
@ -79,6 +87,12 @@ func selectFileMultiple(opts options) ([]string, error) {
|
|||
args.MaxFile = uint32(len(res))
|
||||
args.InitialDir, args.DefExt = initDirNameExt(opts.filename, res[:])
|
||||
|
||||
uninit, err := coInitialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer uninit()
|
||||
|
||||
defer setup(args.Owner)()
|
||||
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, nil)
|
||||
if err != nil {
|
||||
|
@ -153,6 +167,12 @@ func selectFileSave(opts options) (string, error) {
|
|||
args.MaxFile = uint32(len(res))
|
||||
args.InitialDir, args.DefExt = initDirNameExt(opts.filename, res[:])
|
||||
|
||||
uninit, err := coInitialize()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer uninit()
|
||||
|
||||
defer setup(args.Owner)()
|
||||
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, nil)
|
||||
if err != nil {
|
||||
|
@ -171,17 +191,15 @@ func selectFileSave(opts options) (string, error) {
|
|||
}
|
||||
|
||||
func pickFolders(opts options, multi bool) (string, []string, error) {
|
||||
uninit, err := coInitialize()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
defer uninit()
|
||||
|
||||
owner, _ := opts.attach.(win.HWND)
|
||||
defer setup(owner)()
|
||||
|
||||
err := win.CoInitializeEx(0, win.COINIT_APARTMENTTHREADED|win.COINIT_DISABLE_OLE1DDE)
|
||||
if err != win.RPC_E_CHANGED_MODE {
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
defer win.CoUninitialize()
|
||||
}
|
||||
|
||||
var dialog *win.IFileOpenDialog
|
||||
err = win.CoCreateInstance(
|
||||
win.CLSID_FileOpenDialog, nil, win.CLSCTX_ALL,
|
||||
|
@ -320,6 +338,22 @@ func browseForFolderCallback(wnd win.HWND, msg uint32, lparam, data uintptr) uin
|
|||
return 0
|
||||
}
|
||||
|
||||
func coInitialize() (context.CancelFunc, error) {
|
||||
runtime.LockOSThread()
|
||||
err := win.CoInitializeEx(0, win.COINIT_APARTMENTTHREADED|win.COINIT_DISABLE_OLE1DDE)
|
||||
if err == nil || err == win.S_FALSE {
|
||||
return func() {
|
||||
win.CoUninitialize()
|
||||
runtime.UnlockOSThread()
|
||||
}, nil
|
||||
}
|
||||
if err == win.RPC_E_CHANGED_MODE {
|
||||
return runtime.UnlockOSThread, nil
|
||||
}
|
||||
runtime.UnlockOSThread()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func initDirNameExt(filename string, name []uint16) (dir *uint16, ext *uint16) {
|
||||
d, n, _ := splitDirAndName(filename)
|
||||
e := filepath.Ext(n)
|
||||
|
|
|
@ -24,6 +24,7 @@ const (
|
|||
|
||||
E_CANCELED = windows.ERROR_CANCELLED | windows.FACILITY_WIN32<<16 | 0x80000000
|
||||
RPC_E_CHANGED_MODE = syscall.Errno(windows.RPC_E_CHANGED_MODE)
|
||||
S_FALSE = syscall.Errno(windows.S_FALSE)
|
||||
)
|
||||
|
||||
func CoInitializeEx(reserved uintptr, coInit uint32) error {
|
||||
|
|
Loading…
Reference in a new issue