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()()
|
||||
dlg.font = getFont()
|
||||
defer dlg.font.delete()
|
||||
icon := getIcon(opts.windowIcon)
|
||||
defer icon.delete()
|
||||
|
||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||
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
|
||||
}
|
||||
|
||||
cls, err := registerClass(instance, syscall.NewCallback(calendarProc))
|
||||
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(calendarProc))
|
||||
if cls == 0 {
|
||||
return time.Time{}, err
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ func (dlg *entryDialog) setup(text string, opts options) (string, error) {
|
|||
defer setup()()
|
||||
dlg.font = getFont()
|
||||
defer dlg.font.delete()
|
||||
icon := getIcon(opts.windowIcon)
|
||||
defer icon.delete()
|
||||
|
||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||
return "", opts.ctx.Err()
|
||||
|
@ -47,7 +49,7 @@ func (dlg *entryDialog) setup(text string, opts options) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
cls, err := registerClass(instance, syscall.NewCallback(entryProc))
|
||||
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(entryProc))
|
||||
if cls == 0 {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) {
|
|||
defer setup()()
|
||||
dlg.font = getFont()
|
||||
defer dlg.font.delete()
|
||||
icon := getIcon(opts.windowIcon)
|
||||
defer icon.delete()
|
||||
|
||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||
return nil, opts.ctx.Err()
|
||||
|
@ -64,7 +66,7 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
cls, err := registerClass(instance, syscall.NewCallback(listProc))
|
||||
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(listProc))
|
||||
if cls == 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -42,6 +42,16 @@ func notify(text string, opts options) error {
|
|||
args.InfoFlags |= 0x2 // NIIF_WARNING
|
||||
case ErrorIcon:
|
||||
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()
|
||||
|
|
|
@ -111,16 +111,14 @@ func (d *progressDialog) Close() error {
|
|||
}
|
||||
|
||||
func (dlg *progressDialog) setup(opts options) error {
|
||||
done := false
|
||||
defer func() {
|
||||
if !done {
|
||||
dlg.init.Done()
|
||||
}
|
||||
}()
|
||||
var once sync.Once
|
||||
defer once.Do(dlg.init.Done)
|
||||
|
||||
defer setup()()
|
||||
dlg.font = getFont()
|
||||
defer dlg.font.delete()
|
||||
icon := getIcon(opts.windowIcon)
|
||||
defer icon.delete()
|
||||
|
||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||
return opts.ctx.Err()
|
||||
|
@ -131,7 +129,7 @@ func (dlg *progressDialog) setup(opts options) error {
|
|||
return err
|
||||
}
|
||||
|
||||
cls, err := registerClass(instance, syscall.NewCallback(progressProc))
|
||||
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(progressProc))
|
||||
if cls == 0 {
|
||||
return err
|
||||
}
|
||||
|
@ -182,8 +180,7 @@ func (dlg *progressDialog) setup(opts options) error {
|
|||
} else {
|
||||
sendMessage.Call(dlg.progCtl, _PBM_SETRANGE32, 0, uintptr(opts.maxValue))
|
||||
}
|
||||
dlg.init.Done()
|
||||
done = true
|
||||
once.Do(dlg.init.Done)
|
||||
|
||||
if opts.ctx != nil {
|
||||
wait := make(chan struct{})
|
||||
|
|
|
@ -47,6 +47,8 @@ func (dlg *passwordDialog) setup(opts options) (string, string, error) {
|
|||
defer setup()()
|
||||
dlg.font = getFont()
|
||||
defer dlg.font.delete()
|
||||
icon := getIcon(opts.windowIcon)
|
||||
defer icon.delete()
|
||||
|
||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||
return "", "", opts.ctx.Err()
|
||||
|
@ -57,7 +59,7 @@ func (dlg *passwordDialog) setup(opts options) (string, string, error) {
|
|||
return "", "", err
|
||||
}
|
||||
|
||||
cls, err := registerClass(instance, syscall.NewCallback(passwordProc))
|
||||
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(passwordProc))
|
||||
if cls == 0 {
|
||||
return "", "", err
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ type dialogHook struct {
|
|||
|
||||
func newDialogHook(ctx context.Context, icon any, title *string, init func(wnd uintptr)) (*dialogHook, error) {
|
||||
tid, _, _ := getCurrentThreadId.Call()
|
||||
hk, _, err := setWindowsHookEx.Call(5, // WH_CBT
|
||||
hk, _, err := setWindowsHookEx.Call(12, // WH_CALLWNDPROCRET
|
||||
syscall.NewCallback(dialogHookProc), 0, tid)
|
||||
if hk == 0 {
|
||||
return nil, err
|
||||
|
@ -203,31 +203,31 @@ func newDialogHook(ctx context.Context, icon any, title *string, init func(wnd u
|
|||
return &hook, nil
|
||||
}
|
||||
|
||||
func dialogHookProc(code int32, wparam, lparam uintptr) uintptr {
|
||||
if code == 5 { // HCBT_ACTIVATE
|
||||
func dialogHookProc(code int32, wparam uintptr, lparam *_CWPRETSTRUCT) uintptr {
|
||||
if lparam.Message == 0x0110 { // WM_INITDIALOG
|
||||
tid, _, _ := getCurrentThreadId.Call()
|
||||
hook := (*dialogHook)(loadBackRef(tid))
|
||||
atomic.StoreUintptr(&hook.wnd, wparam)
|
||||
atomic.StoreUintptr(&hook.wnd, lparam.Wnd)
|
||||
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 {
|
||||
if hook.icon != nil {
|
||||
icon := getIcon(hook.icon)
|
||||
if icon.handle != 0 {
|
||||
defer icon.delete()
|
||||
sendMessage.Call(wparam, _WM_SETICON, 0, icon.handle)
|
||||
sendMessage.Call(lparam.Wnd, _WM_SETICON, 0, icon.handle)
|
||||
}
|
||||
}
|
||||
if hook.title != nil {
|
||||
setWindowText.Call(wparam, strptr(*hook.title))
|
||||
setWindowText.Call(lparam.Wnd, strptr(*hook.title))
|
||||
}
|
||||
if hook.init != nil {
|
||||
hook.init(wparam)
|
||||
hook.init(lparam.Wnd)
|
||||
}
|
||||
}
|
||||
}
|
||||
next, _, _ := callNextHookEx.Call(
|
||||
0, uintptr(code), wparam, lparam)
|
||||
0, uintptr(code), wparam, uintptr(unsafe.Pointer(lparam)))
|
||||
return next
|
||||
}
|
||||
|
||||
|
@ -408,12 +408,13 @@ func getWindowString(wnd uintptr) string {
|
|||
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)
|
||||
|
||||
var wcx _WNDCLASSEX
|
||||
wcx.Size = uint32(unsafe.Sizeof(wcx))
|
||||
wcx.WndProc = proc
|
||||
wcx.Icon = icon
|
||||
wcx.Instance = instance
|
||||
wcx.Background = 5 // COLOR_WINDOW
|
||||
wcx.ClassName = syscall.StringToUTF16Ptr(name)
|
||||
|
@ -487,6 +488,15 @@ type _INITCOMMONCONTROLSEX struct {
|
|||
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
|
||||
type _LOGFONT struct {
|
||||
Height int32
|
||||
|
|
Loading…
Reference in a new issue