237 lines
6.2 KiB
Go
237 lines
6.2 KiB
Go
//go:build windows
|
|
|
|
package win
|
|
|
|
import (
|
|
"reflect"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
const (
|
|
BIF_RETURNONLYFSDIRS = 0x00000001
|
|
|
|
BFFM_INITIALIZED = 1
|
|
BFFM_SETSELECTION = WM_USER + 103
|
|
|
|
NIM_ADD = 0
|
|
NIM_DELETE = 2
|
|
)
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/ns-shlobj_core-browseinfow
|
|
type BROWSEINFO struct {
|
|
Owner HWND
|
|
Root Pointer
|
|
DisplayName *uint16
|
|
Title *uint16
|
|
Flags uint32
|
|
CallbackFunc uintptr
|
|
LParam *uint16
|
|
Image int32
|
|
}
|
|
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataw
|
|
type NOTIFYICONDATA struct {
|
|
StructSize uint32
|
|
Wnd HWND
|
|
ID uint32
|
|
Flags uint32
|
|
CallbackMessage uint32
|
|
Icon Handle
|
|
Tip [128]uint16 // NOTIFYICONDATAA_V1_SIZE
|
|
State uint32
|
|
StateMask uint32
|
|
Info [256]uint16
|
|
Version uint32
|
|
InfoTitle [64]uint16
|
|
InfoFlags uint32
|
|
// GuidItem [16]byte // NOTIFYICONDATAA_V2_SIZE
|
|
// BalloonIcon Handle // NOTIFYICONDATAA_V3_SIZE
|
|
}
|
|
|
|
// 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 {
|
|
_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 {
|
|
_IUnknownVtbl
|
|
BindToHandler uintptr
|
|
GetParent uintptr
|
|
GetDisplayName uintptr
|
|
GetAttributes 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 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 SHGetPathFromIDListEx(ptr Pointer, path *uint16, pathLen int, opts int) (ok bool) = shell32.SHGetPathFromIDListEx
|