Icon fixes (windows), see #35.
This commit is contained in:
parent
ab2a08c75a
commit
566fbb4e60
6 changed files with 36 additions and 34 deletions
|
@ -223,13 +223,11 @@ func pickFolders(opts options, multi bool) (string, []string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if opts.ctx != nil || opts.windowIcon != nil {
|
||||
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, nil)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
defer unhook()
|
||||
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, nil)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
defer unhook()
|
||||
|
||||
err = dialog.Show(owner)
|
||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||
|
@ -293,13 +291,11 @@ func browseForFolder(opts options) (string, []string, error) {
|
|||
args.CallbackFunc = syscall.NewCallback(browseForFolderCallback)
|
||||
}
|
||||
|
||||
if opts.ctx != nil || opts.windowIcon != nil {
|
||||
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, nil)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
defer unhook()
|
||||
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, nil)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
defer unhook()
|
||||
|
||||
ptr := win.SHBrowseForFolder(&args)
|
||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||
|
|
|
@ -380,7 +380,7 @@ type CWPRETSTRUCT struct {
|
|||
}
|
||||
|
||||
//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 CreateIconFromResourceEx(resBits []byte, icon bool, ver uint32, cx int, cy int, flags int) (ret Handle, err error) = user32.CreateIconFromResourceEx
|
||||
//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 DefWindowProc(wnd HWND, msg uint32, wparam uintptr, lparam unsafe.Pointer) (ret uintptr) = user32.DefWindowProcW
|
||||
//sys DestroyIcon(icon Handle) (err error) = user32.DestroyIcon
|
||||
|
|
|
@ -70,7 +70,7 @@ var (
|
|||
procSHGetPathFromIDListEx = modshell32.NewProc("SHGetPathFromIDListEx")
|
||||
procShell_NotifyIconW = modshell32.NewProc("Shell_NotifyIconW")
|
||||
procCallNextHookEx = moduser32.NewProc("CallNextHookEx")
|
||||
procCreateIconFromResource = moduser32.NewProc("CreateIconFromResource")
|
||||
procCreateIconFromResourceEx = moduser32.NewProc("CreateIconFromResourceEx")
|
||||
procCreateWindowExW = moduser32.NewProc("CreateWindowExW")
|
||||
procDefWindowProcW = moduser32.NewProc("DefWindowProcW")
|
||||
procDestroyIcon = moduser32.NewProc("DestroyIcon")
|
||||
|
@ -267,7 +267,7 @@ func CallNextHookEx(hk Handle, code int32, wparam uintptr, lparam unsafe.Pointer
|
|||
return
|
||||
}
|
||||
|
||||
func CreateIconFromResource(resBits []byte, icon bool, ver uint32) (ret Handle, err error) {
|
||||
func CreateIconFromResourceEx(resBits []byte, icon bool, ver uint32, cx int, cy int, flags int) (ret Handle, err error) {
|
||||
var _p0 *byte
|
||||
if len(resBits) > 0 {
|
||||
_p0 = &resBits[0]
|
||||
|
@ -276,7 +276,7 @@ func CreateIconFromResource(resBits []byte, icon bool, ver uint32) (ret Handle,
|
|||
if icon {
|
||||
_p1 = 1
|
||||
}
|
||||
r0, _, e1 := syscall.Syscall6(procCreateIconFromResource.Addr(), 4, uintptr(unsafe.Pointer(_p0)), uintptr(len(resBits)), uintptr(_p1), uintptr(ver), 0, 0)
|
||||
r0, _, e1 := syscall.Syscall9(procCreateIconFromResourceEx.Addr(), 7, uintptr(unsafe.Pointer(_p0)), uintptr(len(resBits)), uintptr(_p1), uintptr(ver), uintptr(cx), uintptr(cy), uintptr(flags), 0, 0)
|
||||
ret = Handle(r0)
|
||||
if ret == 0 {
|
||||
err = errnoErr(e1)
|
||||
|
|
|
@ -82,8 +82,9 @@ func message(kind messageKind, text string, opts options) error {
|
|||
}
|
||||
}
|
||||
|
||||
func hookMessageDialog(opts options) (unhook context.CancelFunc, err error) {
|
||||
func hookMessageDialog(opts options) (context.CancelFunc, error) {
|
||||
var init func(wnd win.HWND)
|
||||
var icon icon
|
||||
if opts.okLabel != nil || opts.cancelLabel != nil || opts.extraButton != nil || opts.icon != nil {
|
||||
init = func(wnd win.HWND) {
|
||||
if opts.okLabel != nil {
|
||||
|
@ -97,13 +98,19 @@ func hookMessageDialog(opts options) (unhook context.CancelFunc, err error) {
|
|||
win.SetDlgItemText(wnd, win.IDNO, strptr(*opts.extraButton))
|
||||
}
|
||||
|
||||
icon := getIcon(opts.icon)
|
||||
if icon.handle != 0 {
|
||||
defer icon.delete()
|
||||
ctl, _ := win.GetDlgItem(wnd, win.IDC_STATIC_OK)
|
||||
win.SendMessage(ctl, win.STM_SETICON, uintptr(icon.handle), 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
return hookDialog(opts.ctx, opts.windowIcon, nil, init)
|
||||
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, init)
|
||||
if err != nil || opts.icon == nil {
|
||||
return unhook, err
|
||||
}
|
||||
icon = getIcon(opts.icon)
|
||||
return func() {
|
||||
icon.delete()
|
||||
unhook()
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ func notify(text string, opts options) error {
|
|||
icon := getIcon(opts.icon)
|
||||
if icon.handle != 0 {
|
||||
defer icon.delete()
|
||||
args.Icon = win.Handle(icon.handle)
|
||||
args.Icon = icon.handle
|
||||
args.Flags |= win.NIF_ICON
|
||||
args.InfoFlags |= win.NIIF_USER
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ func setupEnumCallback(wnd win.HWND, lparam *win.HWND) uintptr {
|
|||
}
|
||||
|
||||
func hookDialog(ctx context.Context, icon any, title *string, init func(wnd win.HWND)) (unhook context.CancelFunc, err error) {
|
||||
if ctx == nil && icon == nil && init == nil {
|
||||
if ctx == nil && icon == nil && title == nil && init == nil {
|
||||
return func() {}, nil
|
||||
}
|
||||
if ctx != nil && ctx.Err() != nil {
|
||||
|
@ -94,7 +94,7 @@ type dialogHook struct {
|
|||
wnd uintptr
|
||||
hook win.Handle
|
||||
done chan struct{}
|
||||
icon any
|
||||
icon icon
|
||||
title *string
|
||||
init func(wnd win.HWND)
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ func newDialogHook(ctx context.Context, icon any, title *string, init func(wnd w
|
|||
ctx: ctx,
|
||||
tid: tid,
|
||||
hook: hk,
|
||||
icon: icon,
|
||||
icon: getIcon(icon),
|
||||
title: title,
|
||||
init: init,
|
||||
}
|
||||
|
@ -132,12 +132,8 @@ func dialogHookProc(code int32, wparam uintptr, lparam *win.CWPRETSTRUCT) uintpt
|
|||
if hook.ctx != nil && hook.ctx.Err() != nil {
|
||||
win.SendMessage(lparam.Wnd, win.WM_SYSCOMMAND, win.SC_CLOSE, 0)
|
||||
} else {
|
||||
if hook.icon != nil {
|
||||
icon := getIcon(hook.icon)
|
||||
if icon.handle != 0 {
|
||||
defer icon.delete()
|
||||
win.SendMessage(lparam.Wnd, win.WM_SETICON, 0, uintptr(icon.handle))
|
||||
}
|
||||
if hook.icon.handle != 0 {
|
||||
win.SendMessage(lparam.Wnd, win.WM_SETICON, 0, uintptr(hook.icon.handle))
|
||||
}
|
||||
if hook.title != nil {
|
||||
win.SetWindowText(lparam.Wnd, strptr(*hook.title))
|
||||
|
@ -155,6 +151,7 @@ func (h *dialogHook) unhook() {
|
|||
if h.done != nil {
|
||||
close(h.done)
|
||||
}
|
||||
h.icon.delete()
|
||||
win.UnhookWindowsHookEx(h.hook)
|
||||
}
|
||||
|
||||
|
@ -289,17 +286,19 @@ func getIcon(i any) icon {
|
|||
res.handle, _ = win.LoadImage(0,
|
||||
strptr(path),
|
||||
win.IMAGE_ICON, 0, 0,
|
||||
win.LR_LOADFROMFILE|win.LR_DEFAULTSIZE|win.LR_SHARED)
|
||||
win.LR_LOADFROMFILE|win.LR_DEFAULTSIZE)
|
||||
res.destroy = true
|
||||
case bytes.HasPrefix(data, []byte("\x89PNG\r\n\x1a\n")):
|
||||
res.handle, err = win.CreateIconFromResource(
|
||||
data, true, 0x00030000)
|
||||
res.handle, _ = win.CreateIconFromResourceEx(
|
||||
data, true, 0x00030000, 0, 0,
|
||||
win.LR_DEFAULTSIZE)
|
||||
res.destroy = true
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (i *icon) delete() {
|
||||
if i.handle != 0 {
|
||||
if i.destroy && i.handle != 0 {
|
||||
win.DestroyIcon(i.handle)
|
||||
i.handle = 0
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue