Refactor (windows).
This commit is contained in:
parent
6928e74895
commit
e2dc86414f
7 changed files with 265 additions and 169 deletions
|
@ -89,11 +89,11 @@ func (dlg *calendarDialog) setup(text string, opts options) (time.Time, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.time != nil {
|
if opts.time != nil {
|
||||||
var date _SYSTEMTIME
|
var date win.SYSTEMTIME
|
||||||
year, month, day := opts.time.Date()
|
year, month, day := opts.time.Date()
|
||||||
date.year = uint16(year)
|
date.Year = uint16(year)
|
||||||
date.month = uint16(month)
|
date.Month = uint16(month)
|
||||||
date.day = uint16(day)
|
date.Day = uint16(day)
|
||||||
win.SendMessagePointer(dlg.dateCtl, win.MCM_SETCURSEL, 0, unsafe.Pointer(&date))
|
win.SendMessagePointer(dlg.dateCtl, win.MCM_SETCURSEL, 0, unsafe.Pointer(&date))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,9 +168,9 @@ func calendarProc(wnd win.HWND, msg uint32, wparam uintptr, lparam *unsafe.Point
|
||||||
default:
|
default:
|
||||||
return 1
|
return 1
|
||||||
case win.IDOK, win.IDYES:
|
case win.IDOK, win.IDYES:
|
||||||
var date _SYSTEMTIME
|
var date win.SYSTEMTIME
|
||||||
win.SendMessagePointer(dlg.dateCtl, win.MCM_GETCURSEL, 0, unsafe.Pointer(&date))
|
win.SendMessagePointer(dlg.dateCtl, win.MCM_GETCURSEL, 0, unsafe.Pointer(&date))
|
||||||
dlg.out = time.Date(int(date.year), time.Month(date.month), int(date.day), 0, 0, 0, 0, time.UTC)
|
dlg.out = time.Date(int(date.Year), time.Month(date.Month), int(date.Day), 0, 0, 0, 0, time.UTC)
|
||||||
case win.IDCANCEL:
|
case win.IDCANCEL:
|
||||||
dlg.err = ErrCanceled
|
dlg.err = ErrCanceled
|
||||||
case win.IDNO:
|
case win.IDNO:
|
||||||
|
|
171
file_windows.go
171
file_windows.go
|
@ -3,7 +3,6 @@ package zenity
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
@ -201,22 +200,21 @@ func pickFolders(opts options, multi bool) (str string, lst []string, err error)
|
||||||
defer win.CoUninitialize()
|
defer win.CoUninitialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
var dialog *_IFileOpenDialog
|
var dialog *win.IFileOpenDialog
|
||||||
err = win.CoCreateInstance(
|
err = win.CoCreateInstance(
|
||||||
_CLSID_FileOpenDialog, nil, win.CLSCTX_ALL,
|
win.CLSID_FileOpenDialog, nil, win.CLSCTX_ALL,
|
||||||
_IID_IFileOpenDialog, unsafe.Pointer(&dialog))
|
win.IID_IFileOpenDialog, unsafe.Pointer(&dialog))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if multi {
|
if multi {
|
||||||
return "", nil, fmt.Errorf("%w: multiple directory", ErrUnsupported)
|
return "", nil, fmt.Errorf("%w: multiple directory", ErrUnsupported)
|
||||||
}
|
}
|
||||||
return browseForFolder(opts)
|
return browseForFolder(opts)
|
||||||
}
|
}
|
||||||
defer dialog.Call(dialog.Release)
|
defer dialog.Release()
|
||||||
|
|
||||||
var flgs int
|
flgs, err := dialog.GetOptions()
|
||||||
hr, _, _ := dialog.Call(dialog.GetOptions, uintptr(unsafe.Pointer(&flgs)))
|
if err != nil {
|
||||||
if int32(hr) < 0 {
|
return "", nil, err
|
||||||
return "", nil, syscall.Errno(hr)
|
|
||||||
}
|
}
|
||||||
flgs |= _FOS_NOCHANGEDIR | _FOS_PICKFOLDERS | _FOS_FORCEFILESYSTEM
|
flgs |= _FOS_NOCHANGEDIR | _FOS_PICKFOLDERS | _FOS_FORCEFILESYSTEM
|
||||||
if multi {
|
if multi {
|
||||||
|
@ -225,24 +223,21 @@ func pickFolders(opts options, multi bool) (str string, lst []string, err error)
|
||||||
if opts.showHidden {
|
if opts.showHidden {
|
||||||
flgs |= _FOS_FORCESHOWHIDDEN
|
flgs |= _FOS_FORCESHOWHIDDEN
|
||||||
}
|
}
|
||||||
hr, _, _ = dialog.Call(dialog.SetOptions, uintptr(flgs))
|
err = dialog.SetOptions(flgs)
|
||||||
if int32(hr) < 0 {
|
if err != nil {
|
||||||
return "", nil, syscall.Errno(hr)
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.title != nil {
|
if opts.title != nil {
|
||||||
ptr := strptr(*opts.title)
|
dialog.SetTitle(strptr(*opts.title))
|
||||||
dialog.Call(dialog.SetTitle, uintptr(unsafe.Pointer(ptr)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.filename != "" {
|
if opts.filename != "" {
|
||||||
var item *win.IShellItem
|
var item *win.IShellItem
|
||||||
ptr := strptr(opts.filename)
|
win.SHCreateItemFromParsingName(strptr(opts.filename), nil, win.IID_IShellItem, &item)
|
||||||
win.SHCreateItemFromParsingName(ptr, nil, _IID_IShellItem, &item)
|
if item != nil {
|
||||||
|
dialog.SetFolder(item)
|
||||||
if int32(hr) >= 0 && item != nil {
|
item.Release()
|
||||||
dialog.Call(dialog.SetFolder, uintptr(unsafe.Pointer(item)))
|
|
||||||
item.Call(item.Release)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,59 +250,54 @@ func pickFolders(opts options, multi bool) (str string, lst []string, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
owner, _ := opts.attach.(win.HWND)
|
owner, _ := opts.attach.(win.HWND)
|
||||||
hr, _, _ = dialog.Call(dialog.Show, uintptr(owner))
|
err = dialog.Show(owner)
|
||||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||||
return "", nil, opts.ctx.Err()
|
return "", nil, opts.ctx.Err()
|
||||||
}
|
}
|
||||||
if hr == uintptr(win.E_CANCELED) {
|
if err == win.E_CANCELED {
|
||||||
return "", nil, ErrCanceled
|
return "", nil, ErrCanceled
|
||||||
}
|
}
|
||||||
if int32(hr) < 0 {
|
if err != nil {
|
||||||
return "", nil, syscall.Errno(hr)
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
shellItemPath := func(obj *win.COMObject, trap uintptr, a ...uintptr) error {
|
shellItemPath := func(item *win.IShellItem) error {
|
||||||
var item *win.IShellItem
|
defer item.Release()
|
||||||
hr, _, _ := obj.Call(trap, append(a, uintptr(unsafe.Pointer(&item)))...)
|
str, err := item.GetDisplayName(_SIGDN_FILESYSPATH)
|
||||||
if int32(hr) < 0 {
|
if err == nil {
|
||||||
return syscall.Errno(hr)
|
lst = append(lst, str)
|
||||||
}
|
}
|
||||||
defer item.Call(item.Release)
|
return err
|
||||||
|
|
||||||
var ptr win.Pointer
|
|
||||||
hr, _, _ = item.Call(item.GetDisplayName,
|
|
||||||
_SIGDN_FILESYSPATH, uintptr(unsafe.Pointer(&ptr)))
|
|
||||||
if int32(hr) < 0 {
|
|
||||||
return syscall.Errno(hr)
|
|
||||||
}
|
|
||||||
defer win.CoTaskMemFree(ptr)
|
|
||||||
|
|
||||||
var res []uint16
|
|
||||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&res))
|
|
||||||
hdr.Data, hdr.Len, hdr.Cap = uintptr(ptr), 32768, 32768
|
|
||||||
str = syscall.UTF16ToString(res)
|
|
||||||
lst = append(lst, str)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if multi {
|
if multi {
|
||||||
var items *_IShellItemArray
|
items, err := dialog.GetResults()
|
||||||
hr, _, _ = dialog.Call(dialog.GetResults, uintptr(unsafe.Pointer(&items)))
|
if err != nil {
|
||||||
if int32(hr) < 0 {
|
return "", nil, err
|
||||||
return "", nil, syscall.Errno(hr)
|
|
||||||
}
|
}
|
||||||
defer items.Call(items.Release)
|
defer items.Release()
|
||||||
|
|
||||||
var count uint32
|
count, err := items.GetCount()
|
||||||
hr, _, _ = items.Call(items.GetCount, uintptr(unsafe.Pointer(&count)))
|
if err != nil {
|
||||||
if int32(hr) < 0 {
|
return "", nil, err
|
||||||
return "", nil, syscall.Errno(hr)
|
|
||||||
}
|
}
|
||||||
for i := uintptr(0); i < uintptr(count) && err == nil; i++ {
|
for i := uint32(0); i < count; i++ {
|
||||||
err = shellItemPath(&items.COMObject, items.GetItemAt, i)
|
item, err := items.GetItemAt(i)
|
||||||
|
if err == nil {
|
||||||
|
err = shellItemPath(item)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = shellItemPath(&dialog.COMObject, dialog.GetResult)
|
item, err := dialog.GetResult()
|
||||||
|
if err == nil {
|
||||||
|
err = shellItemPath(item)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -389,70 +379,3 @@ func initFilters(filters FileFilters) []uint16 {
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/wine-mirror/wine/blob/master/include/shobjidl.idl
|
|
||||||
|
|
||||||
var (
|
|
||||||
_IID_IShellItem = uuid("\x1e\x6d\x82\x43\x18\xe7\xee\x42\xbc\x55\xa1\xe2\x61\xc3\x7b\xfe")
|
|
||||||
_IID_IFileOpenDialog = uuid("\x88\x72\x7c\xd5\xad\xd4\x68\x47\xbe\x02\x9d\x96\x95\x32\xd9\x60")
|
|
||||||
_CLSID_FileOpenDialog = uuid("\x9c\x5a\x1c\xdc\x8a\xe8\xde\x4d\xa5\xa1\x60\xf8\x2a\x20\xae\xf7")
|
|
||||||
)
|
|
||||||
|
|
||||||
type _IFileOpenDialog struct {
|
|
||||||
win.COMObject
|
|
||||||
*_IFileOpenDialogVtbl
|
|
||||||
}
|
|
||||||
|
|
||||||
type _IShellItemArray struct {
|
|
||||||
win.COMObject
|
|
||||||
*_IShellItemArrayVtbl
|
|
||||||
}
|
|
||||||
|
|
||||||
type _IFileOpenDialogVtbl struct {
|
|
||||||
_IFileDialogVtbl
|
|
||||||
GetResults uintptr
|
|
||||||
GetSelectedItems uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
type _IFileDialogVtbl struct {
|
|
||||||
_IModalWindowVtbl
|
|
||||||
SetFileTypes uintptr
|
|
||||||
SetFileTypeIndex uintptr
|
|
||||||
GetFileTypeIndex uintptr
|
|
||||||
Advise uintptr
|
|
||||||
Unadvise uintptr
|
|
||||||
SetOptions uintptr
|
|
||||||
GetOptions uintptr
|
|
||||||
SetDefaultFolder uintptr
|
|
||||||
SetFolder uintptr
|
|
||||||
GetFolder uintptr
|
|
||||||
GetCurrentSelection uintptr
|
|
||||||
SetFileName uintptr
|
|
||||||
GetFileName uintptr
|
|
||||||
SetTitle uintptr
|
|
||||||
SetOkButtonLabel uintptr
|
|
||||||
SetFileNameLabel uintptr
|
|
||||||
GetResult uintptr
|
|
||||||
AddPlace uintptr
|
|
||||||
SetDefaultExtension uintptr
|
|
||||||
Close uintptr
|
|
||||||
SetClientGuid uintptr
|
|
||||||
ClearClientData uintptr
|
|
||||||
SetFilter uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
type _IModalWindowVtbl struct {
|
|
||||||
_IUnknownVtbl
|
|
||||||
Show uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
type _IShellItemArrayVtbl struct {
|
|
||||||
_IUnknownVtbl
|
|
||||||
BindToHandler uintptr
|
|
||||||
GetPropertyStore uintptr
|
|
||||||
GetPropertyDescriptionList uintptr
|
|
||||||
GetAttributes uintptr
|
|
||||||
GetCount uintptr
|
|
||||||
GetItemAt uintptr
|
|
||||||
EnumItems uintptr
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
package win
|
package win
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
@ -33,12 +34,18 @@ func CoUninitialize() { windows.CoUninitialize() }
|
||||||
|
|
||||||
// https://github.com/wine-mirror/wine/blob/master/include/unknwn.idl
|
// https://github.com/wine-mirror/wine/blob/master/include/unknwn.idl
|
||||||
|
|
||||||
type IUnknownVtbl struct {
|
type _IUnknownBase struct{ COMObject }
|
||||||
|
type _IUnknownVtbl struct {
|
||||||
QueryInterface uintptr
|
QueryInterface uintptr
|
||||||
AddRef uintptr
|
AddRef uintptr
|
||||||
Release uintptr
|
Release uintptr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *_IUnknownBase) Release() {
|
||||||
|
vtbl := (*(**_IUnknownVtbl)(unsafe.Pointer(c)))
|
||||||
|
c.Call(vtbl.Release)
|
||||||
|
}
|
||||||
|
|
||||||
type COMObject struct{}
|
type COMObject struct{}
|
||||||
|
|
||||||
//go:uintptrescapes
|
//go:uintptrescapes
|
||||||
|
@ -57,3 +64,7 @@ func (o *COMObject) Call(trap uintptr, a ...uintptr) (r1, r2 uintptr, lastErr er
|
||||||
|
|
||||||
//sys CoCreateInstance(clsid uintptr, unkOuter *COMObject, clsContext int32, iid uintptr, address unsafe.Pointer) (res error) = ole32.CoCreateInstance
|
//sys CoCreateInstance(clsid uintptr, unkOuter *COMObject, clsContext int32, iid uintptr, address unsafe.Pointer) (res error) = ole32.CoCreateInstance
|
||||||
//sys CoTaskMemFree(address Pointer) = ole32.CoTaskMemFree
|
//sys CoTaskMemFree(address Pointer) = ole32.CoTaskMemFree
|
||||||
|
|
||||||
|
func uuid(s string) uintptr {
|
||||||
|
return (*reflect.StringHeader)(unsafe.Pointer(&s)).Data
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
package win
|
package win
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BIF_RETURNONLYFSDIRS = 0x00000001
|
BIF_RETURNONLYFSDIRS = 0x00000001
|
||||||
|
|
||||||
|
@ -43,13 +49,131 @@ type NOTIFYICONDATA struct {
|
||||||
// BalloonIcon Handle // NOTIFYICONDATAA_V3_SIZE
|
// BalloonIcon Handle // NOTIFYICONDATAA_V3_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
type IShellItem struct {
|
// https://github.com/wine-mirror/wine/blob/master/include/shobjidl.idl
|
||||||
COMObject
|
|
||||||
*_IShellItemVtbl
|
var (
|
||||||
|
IID_IShellItem = uuid("\x1e\x6d\x82\x43\x18\xe7\xee\x42\xbc\x55\xa1\xe2\x61\xc3\x7b\xfe")
|
||||||
|
IID_IFileOpenDialog = uuid("\x88\x72\x7c\xd5\xad\xd4\x68\x47\xbe\x02\x9d\x96\x95\x32\xd9\x60")
|
||||||
|
CLSID_FileOpenDialog = uuid("\x9c\x5a\x1c\xdc\x8a\xe8\xde\x4d\xa5\xa1\x60\xf8\x2a\x20\xae\xf7")
|
||||||
|
)
|
||||||
|
|
||||||
|
type IFileOpenDialog struct {
|
||||||
|
_IFileOpenDialogBase
|
||||||
|
_ *_IFileOpenDialogVtbl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type _IFileOpenDialogBase struct{ _IFileDialogBase }
|
||||||
|
type _IFileOpenDialogVtbl struct {
|
||||||
|
_IFileDialogVtbl
|
||||||
|
GetResults uintptr
|
||||||
|
GetSelectedItems uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *_IFileOpenDialogBase) GetResults() (res *IShellItemArray, err error) {
|
||||||
|
vtbl := (*(**_IFileOpenDialogVtbl)(unsafe.Pointer(c)))
|
||||||
|
hr, _, _ := c.Call(vtbl.GetResults, uintptr(unsafe.Pointer(&res)))
|
||||||
|
if hr != 0 {
|
||||||
|
err = syscall.Errno(hr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type _IFileDialogBase struct{ _IModalWindowBase }
|
||||||
|
type _IFileDialogVtbl struct {
|
||||||
|
_IModalWindowVtbl
|
||||||
|
SetFileTypes uintptr
|
||||||
|
SetFileTypeIndex uintptr
|
||||||
|
GetFileTypeIndex uintptr
|
||||||
|
Advise uintptr
|
||||||
|
Unadvise uintptr
|
||||||
|
SetOptions uintptr
|
||||||
|
GetOptions uintptr
|
||||||
|
SetDefaultFolder uintptr
|
||||||
|
SetFolder uintptr
|
||||||
|
GetFolder uintptr
|
||||||
|
GetCurrentSelection uintptr
|
||||||
|
SetFileName uintptr
|
||||||
|
GetFileName uintptr
|
||||||
|
SetTitle uintptr
|
||||||
|
SetOkButtonLabel uintptr
|
||||||
|
SetFileNameLabel uintptr
|
||||||
|
GetResult uintptr
|
||||||
|
AddPlace uintptr
|
||||||
|
SetDefaultExtension uintptr
|
||||||
|
Close uintptr
|
||||||
|
SetClientGuid uintptr
|
||||||
|
ClearClientData uintptr
|
||||||
|
SetFilter uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *_IFileDialogBase) SetOptions(fos int) (err error) {
|
||||||
|
vtbl := (*(**_IFileDialogVtbl)(unsafe.Pointer(c)))
|
||||||
|
hr, _, _ := c.Call(vtbl.SetOptions, uintptr(fos))
|
||||||
|
if hr != 0 {
|
||||||
|
err = syscall.Errno(hr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *_IFileDialogBase) GetOptions() (fos int, err error) {
|
||||||
|
vtbl := (*(**_IFileDialogVtbl)(unsafe.Pointer(c)))
|
||||||
|
hr, _, _ := c.Call(vtbl.GetOptions, uintptr(unsafe.Pointer(&fos)))
|
||||||
|
if hr != 0 {
|
||||||
|
err = syscall.Errno(hr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *_IFileDialogBase) SetFolder(item *IShellItem) (err error) {
|
||||||
|
vtbl := (*(**_IFileDialogVtbl)(unsafe.Pointer(c)))
|
||||||
|
hr, _, _ := c.Call(vtbl.SetFolder, uintptr(unsafe.Pointer(item)))
|
||||||
|
if hr != 0 {
|
||||||
|
err = syscall.Errno(hr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *_IFileDialogBase) SetTitle(title *uint16) (err error) {
|
||||||
|
vtbl := (*(**_IFileDialogVtbl)(unsafe.Pointer(c)))
|
||||||
|
hr, _, _ := c.Call(vtbl.SetTitle, uintptr(unsafe.Pointer(title)))
|
||||||
|
if hr != 0 {
|
||||||
|
err = syscall.Errno(hr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *_IFileDialogBase) GetResult() (item *IShellItem, err error) {
|
||||||
|
vtbl := (*(**_IFileDialogVtbl)(unsafe.Pointer(c)))
|
||||||
|
hr, _, _ := c.Call(vtbl.GetResult, uintptr(unsafe.Pointer(&item)))
|
||||||
|
if hr != 0 {
|
||||||
|
err = syscall.Errno(hr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type _IModalWindowBase struct{ _IUnknownBase }
|
||||||
|
type _IModalWindowVtbl struct {
|
||||||
|
_IUnknownVtbl
|
||||||
|
Show uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *_IModalWindowBase) Show(wnd HWND) (err error) {
|
||||||
|
vtbl := (*(**_IModalWindowVtbl)(unsafe.Pointer(c)))
|
||||||
|
hr, _, _ := c.Call(vtbl.Show, uintptr(wnd))
|
||||||
|
if hr != 0 {
|
||||||
|
err = syscall.Errno(hr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type IShellItem struct {
|
||||||
|
_IShellItemBase
|
||||||
|
_ *_IShellItemVtbl
|
||||||
|
}
|
||||||
|
|
||||||
|
type _IShellItemBase struct{ _IUnknownBase }
|
||||||
type _IShellItemVtbl struct {
|
type _IShellItemVtbl struct {
|
||||||
IUnknownVtbl
|
_IUnknownVtbl
|
||||||
BindToHandler uintptr
|
BindToHandler uintptr
|
||||||
GetParent uintptr
|
GetParent uintptr
|
||||||
GetDisplayName uintptr
|
GetDisplayName uintptr
|
||||||
|
@ -57,6 +181,56 @@ type _IShellItemVtbl struct {
|
||||||
Compare uintptr
|
Compare uintptr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *_IShellItemBase) GetDisplayName(name int) (res string, err error) {
|
||||||
|
var ptr uintptr
|
||||||
|
vtbl := (*(**_IShellItemVtbl)(unsafe.Pointer(c)))
|
||||||
|
hr, _, _ := c.Call(vtbl.GetDisplayName, uintptr(name), uintptr(unsafe.Pointer(&ptr)))
|
||||||
|
if hr != 0 {
|
||||||
|
err = syscall.Errno(hr)
|
||||||
|
} else {
|
||||||
|
var buf []uint16
|
||||||
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
|
||||||
|
hdr.Data, hdr.Len, hdr.Cap = uintptr(ptr), 32768, 32768
|
||||||
|
res = syscall.UTF16ToString(buf)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type IShellItemArray struct {
|
||||||
|
_IShellItemArrayBase
|
||||||
|
_ *_IShellItemArrayVtbl
|
||||||
|
}
|
||||||
|
|
||||||
|
type _IShellItemArrayBase struct{ _IUnknownBase }
|
||||||
|
type _IShellItemArrayVtbl struct {
|
||||||
|
_IUnknownVtbl
|
||||||
|
BindToHandler uintptr
|
||||||
|
GetPropertyStore uintptr
|
||||||
|
GetPropertyDescriptionList uintptr
|
||||||
|
GetAttributes uintptr
|
||||||
|
GetCount uintptr
|
||||||
|
GetItemAt uintptr
|
||||||
|
EnumItems uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *_IShellItemArrayBase) GetCount() (numItems uint32, err error) {
|
||||||
|
vtbl := (*(**_IShellItemArrayVtbl)(unsafe.Pointer(c)))
|
||||||
|
hr, _, _ := c.Call(vtbl.GetCount, uintptr(unsafe.Pointer(&numItems)))
|
||||||
|
if hr != 0 {
|
||||||
|
err = syscall.Errno(hr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *_IShellItemArrayBase) GetItemAt(index uint32) (item *IShellItem, err error) {
|
||||||
|
vtbl := (*(**_IShellItemArrayVtbl)(unsafe.Pointer(c)))
|
||||||
|
hr, _, _ := c.Call(vtbl.GetItemAt, uintptr(index), uintptr(unsafe.Pointer(&item)))
|
||||||
|
if hr != 0 {
|
||||||
|
err = syscall.Errno(hr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
//sys SHBrowseForFolder(bi *BROWSEINFO) (ret Pointer) = shell32.SHBrowseForFolder
|
//sys SHBrowseForFolder(bi *BROWSEINFO) (ret Pointer) = shell32.SHBrowseForFolder
|
||||||
//sys SHCreateItemFromParsingName(path *uint16, bc *COMObject, iid uintptr, item **IShellItem) (res error) = shell32.SHCreateItemFromParsingName
|
//sys SHCreateItemFromParsingName(path *uint16, bc *COMObject, iid uintptr, item **IShellItem) (res error) = shell32.SHCreateItemFromParsingName
|
||||||
//sys ShellNotifyIcon(message uint32, data *NOTIFYICONDATA) (ret int, err error) = shell32.Shell_NotifyIconW
|
//sys ShellNotifyIcon(message uint32, data *NOTIFYICONDATA) (ret int, err error) = shell32.Shell_NotifyIconW
|
||||||
|
|
|
@ -353,6 +353,15 @@ type NONCLIENTMETRICS struct {
|
||||||
MessageFont LOGFONT
|
MessageFont LOGFONT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-cwpretstruct
|
||||||
|
type CWPRETSTRUCT struct {
|
||||||
|
Result uintptr
|
||||||
|
LParam uintptr
|
||||||
|
WParam uintptr
|
||||||
|
Message uint32
|
||||||
|
Wnd HWND
|
||||||
|
}
|
||||||
|
|
||||||
//sys CallNextHookEx(hk Handle, code int32, wparam uintptr, lparam unsafe.Pointer) (ret uintptr) = user32.CallNextHookEx
|
//sys CallNextHookEx(hk Handle, code int32, wparam uintptr, lparam unsafe.Pointer) (ret uintptr) = user32.CallNextHookEx
|
||||||
//sys CreateIconFromResource(resBits []byte, icon bool, ver uint32) (ret Handle, err error) = user32.CreateIconFromResource
|
//sys CreateIconFromResource(resBits []byte, icon bool, ver uint32) (ret Handle, err error) = user32.CreateIconFromResource
|
||||||
//sys CreateWindowEx(exStyle uint32, className *uint16, windowName *uint16, style uint32, x int, y int, width int, height int, parent HWND, menu Handle, instance Handle, param unsafe.Pointer) (ret HWND, err error) = user32.CreateWindowExW
|
//sys CreateWindowEx(exStyle uint32, className *uint16, windowName *uint16, style uint32, x int, y int, width int, height int, parent HWND, menu Handle, instance Handle, param unsafe.Pointer) (ret HWND, err error) = user32.CreateWindowExW
|
||||||
|
|
|
@ -9,6 +9,18 @@ type Handle = windows.Handle
|
||||||
type HWND = windows.HWND
|
type HWND = windows.HWND
|
||||||
type Pointer uintptr
|
type Pointer uintptr
|
||||||
|
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
|
||||||
|
type SYSTEMTIME struct {
|
||||||
|
Year uint16
|
||||||
|
Month uint16
|
||||||
|
DayOfWeek uint16
|
||||||
|
Day uint16
|
||||||
|
Hour uint16
|
||||||
|
Minute uint16
|
||||||
|
Second uint16
|
||||||
|
Milliseconds uint16
|
||||||
|
}
|
||||||
|
|
||||||
func RtlGetNtVersionNumbers() (majorVersion, minorVersion, buildNumber uint32) {
|
func RtlGetNtVersionNumbers() (majorVersion, minorVersion, buildNumber uint32) {
|
||||||
return windows.RtlGetNtVersionNumbers()
|
return windows.RtlGetNtVersionNumbers()
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ func newDialogHook(ctx context.Context, icon any, title *string, init func(wnd w
|
||||||
return &hook, nil
|
return &hook, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dialogHookProc(code int32, wparam uintptr, lparam *_CWPRETSTRUCT) uintptr {
|
func dialogHookProc(code int32, wparam uintptr, lparam *win.CWPRETSTRUCT) uintptr {
|
||||||
if lparam.Message == win.WM_INITDIALOG {
|
if lparam.Message == win.WM_INITDIALOG {
|
||||||
tid := win.GetCurrentThreadId()
|
tid := win.GetCurrentThreadId()
|
||||||
hook := (*dialogHook)(loadBackRef(uintptr(tid)))
|
hook := (*dialogHook)(loadBackRef(uintptr(tid)))
|
||||||
|
@ -360,36 +360,3 @@ func enableVisualStyles() (cookie uintptr) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-cwpretstruct
|
|
||||||
type _CWPRETSTRUCT struct {
|
|
||||||
Result uintptr
|
|
||||||
LParam uintptr
|
|
||||||
WParam uintptr
|
|
||||||
Message uint32
|
|
||||||
Wnd win.HWND
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
|
|
||||||
type _SYSTEMTIME struct {
|
|
||||||
year uint16
|
|
||||||
month uint16
|
|
||||||
dayOfWeek uint16
|
|
||||||
day uint16
|
|
||||||
hour uint16
|
|
||||||
minute uint16
|
|
||||||
second uint16
|
|
||||||
milliseconds uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://github.com/wine-mirror/wine/blob/master/include/unknwn.idl
|
|
||||||
|
|
||||||
type _IUnknownVtbl struct {
|
|
||||||
QueryInterface uintptr
|
|
||||||
AddRef uintptr
|
|
||||||
Release uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
func uuid(s string) uintptr {
|
|
||||||
return (*reflect.StringHeader)(unsafe.Pointer(&s)).Data
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue