Window icons (windows).
This commit is contained in:
parent
b988db5bd2
commit
205db7d4be
7 changed files with 48 additions and 23 deletions
|
@ -38,6 +38,8 @@ func (dlg *calendarDialog) setup(text string, opts options) (time.Time, error) {
|
||||||
defer setup()()
|
defer setup()()
|
||||||
dlg.font = getFont()
|
dlg.font = getFont()
|
||||||
defer dlg.font.delete()
|
defer dlg.font.delete()
|
||||||
|
icon := getIcon(opts.windowIcon)
|
||||||
|
defer icon.delete()
|
||||||
|
|
||||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||||
return time.Time{}, opts.ctx.Err()
|
return time.Time{}, opts.ctx.Err()
|
||||||
|
@ -48,7 +50,7 @@ func (dlg *calendarDialog) setup(text string, opts options) (time.Time, error) {
|
||||||
return time.Time{}, err
|
return time.Time{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cls, err := registerClass(instance, syscall.NewCallback(calendarProc))
|
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(calendarProc))
|
||||||
if cls == 0 {
|
if cls == 0 {
|
||||||
return time.Time{}, err
|
return time.Time{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@ func (dlg *entryDialog) setup(text string, opts options) (string, error) {
|
||||||
defer setup()()
|
defer setup()()
|
||||||
dlg.font = getFont()
|
dlg.font = getFont()
|
||||||
defer dlg.font.delete()
|
defer dlg.font.delete()
|
||||||
|
icon := getIcon(opts.windowIcon)
|
||||||
|
defer icon.delete()
|
||||||
|
|
||||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||||
return "", opts.ctx.Err()
|
return "", opts.ctx.Err()
|
||||||
|
@ -47,7 +49,7 @@ func (dlg *entryDialog) setup(text string, opts options) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
cls, err := registerClass(instance, syscall.NewCallback(entryProc))
|
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(entryProc))
|
||||||
if cls == 0 {
|
if cls == 0 {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,8 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) {
|
||||||
defer setup()()
|
defer setup()()
|
||||||
dlg.font = getFont()
|
dlg.font = getFont()
|
||||||
defer dlg.font.delete()
|
defer dlg.font.delete()
|
||||||
|
icon := getIcon(opts.windowIcon)
|
||||||
|
defer icon.delete()
|
||||||
|
|
||||||
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()
|
||||||
|
@ -64,7 +66,7 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cls, err := registerClass(instance, syscall.NewCallback(listProc))
|
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(listProc))
|
||||||
if cls == 0 {
|
if cls == 0 {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,16 @@ func notify(text string, opts options) error {
|
||||||
args.InfoFlags |= 0x2 // NIIF_WARNING
|
args.InfoFlags |= 0x2 // NIIF_WARNING
|
||||||
case ErrorIcon:
|
case ErrorIcon:
|
||||||
args.InfoFlags |= 0x3 // NIIF_ERROR
|
args.InfoFlags |= 0x3 // NIIF_ERROR
|
||||||
|
case NoIcon:
|
||||||
|
//
|
||||||
|
default:
|
||||||
|
icon := getIcon(opts.icon)
|
||||||
|
if icon.handle != 0 {
|
||||||
|
defer icon.delete()
|
||||||
|
args.Icon = icon.handle
|
||||||
|
args.Flags |= 0x00000002 // NIF_ICON
|
||||||
|
args.InfoFlags |= 0x4 // NIIF_USER
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
|
|
@ -111,16 +111,14 @@ func (d *progressDialog) Close() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dlg *progressDialog) setup(opts options) error {
|
func (dlg *progressDialog) setup(opts options) error {
|
||||||
done := false
|
var once sync.Once
|
||||||
defer func() {
|
defer once.Do(dlg.init.Done)
|
||||||
if !done {
|
|
||||||
dlg.init.Done()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
defer setup()()
|
defer setup()()
|
||||||
dlg.font = getFont()
|
dlg.font = getFont()
|
||||||
defer dlg.font.delete()
|
defer dlg.font.delete()
|
||||||
|
icon := getIcon(opts.windowIcon)
|
||||||
|
defer icon.delete()
|
||||||
|
|
||||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||||
return opts.ctx.Err()
|
return opts.ctx.Err()
|
||||||
|
@ -131,7 +129,7 @@ func (dlg *progressDialog) setup(opts options) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cls, err := registerClass(instance, syscall.NewCallback(progressProc))
|
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(progressProc))
|
||||||
if cls == 0 {
|
if cls == 0 {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -182,8 +180,7 @@ func (dlg *progressDialog) setup(opts options) error {
|
||||||
} else {
|
} else {
|
||||||
sendMessage.Call(dlg.progCtl, _PBM_SETRANGE32, 0, uintptr(opts.maxValue))
|
sendMessage.Call(dlg.progCtl, _PBM_SETRANGE32, 0, uintptr(opts.maxValue))
|
||||||
}
|
}
|
||||||
dlg.init.Done()
|
once.Do(dlg.init.Done)
|
||||||
done = true
|
|
||||||
|
|
||||||
if opts.ctx != nil {
|
if opts.ctx != nil {
|
||||||
wait := make(chan struct{})
|
wait := make(chan struct{})
|
||||||
|
|
|
@ -47,6 +47,8 @@ func (dlg *passwordDialog) setup(opts options) (string, string, error) {
|
||||||
defer setup()()
|
defer setup()()
|
||||||
dlg.font = getFont()
|
dlg.font = getFont()
|
||||||
defer dlg.font.delete()
|
defer dlg.font.delete()
|
||||||
|
icon := getIcon(opts.windowIcon)
|
||||||
|
defer icon.delete()
|
||||||
|
|
||||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||||
return "", "", opts.ctx.Err()
|
return "", "", opts.ctx.Err()
|
||||||
|
@ -57,7 +59,7 @@ func (dlg *passwordDialog) setup(opts options) (string, string, error) {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
cls, err := registerClass(instance, syscall.NewCallback(passwordProc))
|
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(passwordProc))
|
||||||
if cls == 0 {
|
if cls == 0 {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ type dialogHook struct {
|
||||||
|
|
||||||
func newDialogHook(ctx context.Context, icon any, title *string, init func(wnd uintptr)) (*dialogHook, error) {
|
func newDialogHook(ctx context.Context, icon any, title *string, init func(wnd uintptr)) (*dialogHook, error) {
|
||||||
tid, _, _ := getCurrentThreadId.Call()
|
tid, _, _ := getCurrentThreadId.Call()
|
||||||
hk, _, err := setWindowsHookEx.Call(5, // WH_CBT
|
hk, _, err := setWindowsHookEx.Call(12, // WH_CALLWNDPROCRET
|
||||||
syscall.NewCallback(dialogHookProc), 0, tid)
|
syscall.NewCallback(dialogHookProc), 0, tid)
|
||||||
if hk == 0 {
|
if hk == 0 {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -203,31 +203,31 @@ func newDialogHook(ctx context.Context, icon any, title *string, init func(wnd u
|
||||||
return &hook, nil
|
return &hook, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dialogHookProc(code int32, wparam, lparam uintptr) uintptr {
|
func dialogHookProc(code int32, wparam uintptr, lparam *_CWPRETSTRUCT) uintptr {
|
||||||
if code == 5 { // HCBT_ACTIVATE
|
if lparam.Message == 0x0110 { // WM_INITDIALOG
|
||||||
tid, _, _ := getCurrentThreadId.Call()
|
tid, _, _ := getCurrentThreadId.Call()
|
||||||
hook := (*dialogHook)(loadBackRef(tid))
|
hook := (*dialogHook)(loadBackRef(tid))
|
||||||
atomic.StoreUintptr(&hook.wnd, wparam)
|
atomic.StoreUintptr(&hook.wnd, lparam.Wnd)
|
||||||
if hook.ctx != nil && hook.ctx.Err() != nil {
|
if hook.ctx != nil && hook.ctx.Err() != nil {
|
||||||
sendMessage.Call(wparam, _WM_SYSCOMMAND, _SC_CLOSE, 0)
|
sendMessage.Call(lparam.Wnd, _WM_SYSCOMMAND, _SC_CLOSE, 0)
|
||||||
} else {
|
} else {
|
||||||
if hook.icon != nil {
|
if hook.icon != nil {
|
||||||
icon := getIcon(hook.icon)
|
icon := getIcon(hook.icon)
|
||||||
if icon.handle != 0 {
|
if icon.handle != 0 {
|
||||||
defer icon.delete()
|
defer icon.delete()
|
||||||
sendMessage.Call(wparam, _WM_SETICON, 0, icon.handle)
|
sendMessage.Call(lparam.Wnd, _WM_SETICON, 0, icon.handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if hook.title != nil {
|
if hook.title != nil {
|
||||||
setWindowText.Call(wparam, strptr(*hook.title))
|
setWindowText.Call(lparam.Wnd, strptr(*hook.title))
|
||||||
}
|
}
|
||||||
if hook.init != nil {
|
if hook.init != nil {
|
||||||
hook.init(wparam)
|
hook.init(lparam.Wnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next, _, _ := callNextHookEx.Call(
|
next, _, _ := callNextHookEx.Call(
|
||||||
0, uintptr(code), wparam, lparam)
|
0, uintptr(code), wparam, uintptr(unsafe.Pointer(lparam)))
|
||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,12 +408,13 @@ func getWindowString(wnd uintptr) string {
|
||||||
return syscall.UTF16ToString(buf)
|
return syscall.UTF16ToString(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerClass(instance, proc uintptr) (uintptr, error) {
|
func registerClass(instance, icon, proc uintptr) (uintptr, error) {
|
||||||
name := "WC_" + strconv.FormatUint(uint64(proc), 16)
|
name := "WC_" + strconv.FormatUint(uint64(proc), 16)
|
||||||
|
|
||||||
var wcx _WNDCLASSEX
|
var wcx _WNDCLASSEX
|
||||||
wcx.Size = uint32(unsafe.Sizeof(wcx))
|
wcx.Size = uint32(unsafe.Sizeof(wcx))
|
||||||
wcx.WndProc = proc
|
wcx.WndProc = proc
|
||||||
|
wcx.Icon = icon
|
||||||
wcx.Instance = instance
|
wcx.Instance = instance
|
||||||
wcx.Background = 5 // COLOR_WINDOW
|
wcx.Background = 5 // COLOR_WINDOW
|
||||||
wcx.ClassName = syscall.StringToUTF16Ptr(name)
|
wcx.ClassName = syscall.StringToUTF16Ptr(name)
|
||||||
|
@ -487,6 +488,15 @@ type _INITCOMMONCONTROLSEX struct {
|
||||||
ICC uint32
|
ICC uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 uintptr
|
||||||
|
}
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logfontw
|
// https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logfontw
|
||||||
type _LOGFONT struct {
|
type _LOGFONT struct {
|
||||||
Height int32
|
Height int32
|
||||||
|
|
Loading…
Reference in a new issue