Refactor (windows).

This commit is contained in:
Nuno Cruces 2022-06-18 12:37:39 +01:00
parent d33a18d05a
commit d47150a866
24 changed files with 222 additions and 145 deletions

View file

@ -27,7 +27,7 @@ func selectColor(opts options) (color.Color, error) {
var args win.CHOOSECOLOR var args win.CHOOSECOLOR
args.StructSize = uint32(unsafe.Sizeof(args)) args.StructSize = uint32(unsafe.Sizeof(args))
args.Owner, _ = opts.attach.(uintptr) args.Owner, _ = opts.attach.(win.HWND)
args.CustColors = &customColors args.CustColors = &customColors
if opts.color != nil { if opts.color != nil {

View file

@ -37,22 +37,6 @@ const (
_SWP_NOMOVE = 0x0002 _SWP_NOMOVE = 0x0002
_SWP_NOZORDER = 0x0004 _SWP_NOZORDER = 0x0004
_MB_OKCANCEL = 0x00000001
_MB_YESNOCANCEL = 0x00000003
_MB_YESNO = 0x00000004
_MB_ICONERROR = 0x00000010
_MB_ICONQUESTION = 0x00000020
_MB_ICONWARNING = 0x00000030
_MB_ICONINFORMATION = 0x00000040
_MB_DEFBUTTON1 = 0x00000000
_MB_DEFBUTTON2 = 0x00000100
_MB_DEFBUTTON3 = 0x00000200
_IDOK = 1
_IDCANCEL = 2
_IDYES = 6
_IDNO = 7
_SC_CLOSE = 0xf060 _SC_CLOSE = 0xf060
_WM_DESTROY = 0x0002 _WM_DESTROY = 0x0002

View file

@ -4,6 +4,8 @@ import (
"syscall" "syscall"
"time" "time"
"unsafe" "unsafe"
"github.com/ncruces/zenity/internal/win"
) )
func calendar(text string, opts options) (time.Time, error) { func calendar(text string, opts options) (time.Time, error) {
@ -56,12 +58,12 @@ func (dlg *calendarDialog) setup(text string, opts options) (time.Time, error) {
} }
defer unregisterClass.Call(cls, instance) defer unregisterClass.Call(cls, instance)
owner, _ := opts.attach.(uintptr) owner, _ := opts.attach.(win.HWND)
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME, dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
cls, strptr(*opts.title), cls, strptr(*opts.title),
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME, _WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
_CW_USEDEFAULT, _CW_USEDEFAULT, _CW_USEDEFAULT, _CW_USEDEFAULT,
281, 281, owner, 0, instance, uintptr(unsafe.Pointer(dlg))) 281, 281, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
dlg.textCtl, _, _ = createWindowEx.Call(0, dlg.textCtl, _, _ = createWindowEx.Call(0,
strptr("STATIC"), strptr(text), strptr("STATIC"), strptr(text),
@ -77,16 +79,16 @@ func (dlg *calendarDialog) setup(text string, opts options) (time.Time, error) {
dlg.okBtn, _, _ = createWindowEx.Call(0, dlg.okBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.okLabel), strptr("BUTTON"), strptr(*opts.okLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
12, 206, 75, 24, dlg.wnd, _IDOK, instance, 0) 12, 206, 75, 24, dlg.wnd, win.IDOK, instance, 0)
dlg.cancelBtn, _, _ = createWindowEx.Call(0, dlg.cancelBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.cancelLabel), strptr("BUTTON"), strptr(*opts.cancelLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 206, 75, 24, dlg.wnd, _IDCANCEL, instance, 0) 12, 206, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
if opts.extraButton != nil { if opts.extraButton != nil {
dlg.extraBtn, _, _ = createWindowEx.Call(0, dlg.extraBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.extraButton), strptr("BUTTON"), strptr(*opts.extraButton),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 206, 75, 24, dlg.wnd, _IDNO, instance, 0) 12, 206, 75, 24, dlg.wnd, win.IDNO, instance, 0)
} }
if opts.time != nil { if opts.time != nil {
@ -168,13 +170,13 @@ func calendarProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointe
switch wparam { switch wparam {
default: default:
return 1 return 1
case _IDOK, _IDYES: case win.IDOK, win.IDYES:
var date _SYSTEMTIME var date _SYSTEMTIME
sendMessage.Call(dlg.dateCtl, _MCM_GETCURSEL, 0, uintptr(unsafe.Pointer(&date))) sendMessage.Call(dlg.dateCtl, _MCM_GETCURSEL, 0, uintptr(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 _IDCANCEL: case win.IDCANCEL:
dlg.err = ErrCanceled dlg.err = ErrCanceled
case _IDNO: case win.IDNO:
dlg.err = ErrExtraButton dlg.err = ErrExtraButton
} }
destroyWindow.Call(wnd) destroyWindow.Call(wnd)

View file

@ -3,6 +3,8 @@ package zenity
import ( import (
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/ncruces/zenity/internal/win"
) )
func entry(text string, opts options) (string, error) { func entry(text string, opts options) (string, error) {
@ -55,12 +57,12 @@ func (dlg *entryDialog) setup(text string, opts options) (string, error) {
} }
defer unregisterClass.Call(cls, instance) defer unregisterClass.Call(cls, instance)
owner, _ := opts.attach.(uintptr) owner, _ := opts.attach.(win.HWND)
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME, dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
cls, strptr(*opts.title), cls, strptr(*opts.title),
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME, _WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
_CW_USEDEFAULT, _CW_USEDEFAULT, _CW_USEDEFAULT, _CW_USEDEFAULT,
281, 141, owner, 0, instance, uintptr(unsafe.Pointer(dlg))) 281, 141, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
dlg.textCtl, _, _ = createWindowEx.Call(0, dlg.textCtl, _, _ = createWindowEx.Call(0,
strptr("STATIC"), strptr(text), strptr("STATIC"), strptr(text),
@ -79,16 +81,16 @@ func (dlg *entryDialog) setup(text string, opts options) (string, error) {
dlg.okBtn, _, _ = createWindowEx.Call(0, dlg.okBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.okLabel), strptr("BUTTON"), strptr(*opts.okLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
12, 66, 75, 24, dlg.wnd, _IDOK, instance, 0) 12, 66, 75, 24, dlg.wnd, win.IDOK, instance, 0)
dlg.cancelBtn, _, _ = createWindowEx.Call(0, dlg.cancelBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.cancelLabel), strptr("BUTTON"), strptr(*opts.cancelLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 66, 75, 24, dlg.wnd, _IDCANCEL, instance, 0) 12, 66, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
if opts.extraButton != nil { if opts.extraButton != nil {
dlg.extraBtn, _, _ = createWindowEx.Call(0, dlg.extraBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.extraButton), strptr("BUTTON"), strptr(*opts.extraButton),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 66, 75, 24, dlg.wnd, _IDNO, instance, 0) 12, 66, 75, 24, dlg.wnd, win.IDNO, instance, 0)
} }
dlg.layout(getDPI(dlg.wnd)) dlg.layout(getDPI(dlg.wnd))
@ -162,11 +164,11 @@ func entryProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointer)
switch wparam { switch wparam {
default: default:
return 1 return 1
case _IDOK, _IDYES: case win.IDOK, win.IDYES:
dlg.out = getWindowString(dlg.editCtl) dlg.out = getWindowString(dlg.editCtl)
case _IDCANCEL: case win.IDCANCEL:
dlg.err = ErrCanceled dlg.err = ErrCanceled
case _IDNO: case win.IDNO:
dlg.err = ErrExtraButton dlg.err = ErrExtraButton
} }
destroyWindow.Call(wnd) destroyWindow.Call(wnd)

View file

@ -27,7 +27,7 @@ func selectFile(opts options) (string, error) {
var args win.OPENFILENAME var args win.OPENFILENAME
args.StructSize = uint32(unsafe.Sizeof(args)) args.StructSize = uint32(unsafe.Sizeof(args))
args.Owner, _ = opts.attach.(uintptr) args.Owner, _ = opts.attach.(win.HWND)
args.Flags = win.OFN_NOCHANGEDIR | win.OFN_FILEMUSTEXIST | win.OFN_EXPLORER args.Flags = win.OFN_NOCHANGEDIR | win.OFN_FILEMUSTEXIST | win.OFN_EXPLORER
if opts.title != nil { if opts.title != nil {
@ -73,7 +73,7 @@ func selectFileMultiple(opts options) ([]string, error) {
var args win.OPENFILENAME var args win.OPENFILENAME
args.StructSize = uint32(unsafe.Sizeof(args)) args.StructSize = uint32(unsafe.Sizeof(args))
args.Owner, _ = opts.attach.(uintptr) args.Owner, _ = opts.attach.(win.HWND)
args.Flags = win.OFN_NOCHANGEDIR | win.OFN_ALLOWMULTISELECT | win.OFN_FILEMUSTEXIST | win.OFN_EXPLORER args.Flags = win.OFN_NOCHANGEDIR | win.OFN_ALLOWMULTISELECT | win.OFN_FILEMUSTEXIST | win.OFN_EXPLORER
if opts.title != nil { if opts.title != nil {
@ -144,7 +144,7 @@ func selectFileSave(opts options) (string, error) {
var args win.OPENFILENAME var args win.OPENFILENAME
args.StructSize = uint32(unsafe.Sizeof(args)) args.StructSize = uint32(unsafe.Sizeof(args))
args.Owner, _ = opts.attach.(uintptr) args.Owner, _ = opts.attach.(win.HWND)
args.Flags = win.OFN_NOCHANGEDIR | win.OFN_PATHMUSTEXIST | win.OFN_NOREADONLYRETURN | win.OFN_EXPLORER args.Flags = win.OFN_NOCHANGEDIR | win.OFN_PATHMUSTEXIST | win.OFN_NOREADONLYRETURN | win.OFN_EXPLORER
if opts.title != nil { if opts.title != nil {
@ -252,8 +252,8 @@ func pickFolders(opts options, multi bool) (str string, lst []string, err error)
defer unhook() defer unhook()
} }
owner, _ := opts.attach.(uintptr) owner, _ := opts.attach.(win.HWND)
hr, _, _ = dialog.Call(dialog.Show, owner) hr, _, _ = dialog.Call(dialog.Show, uintptr(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()
} }
@ -313,7 +313,7 @@ func pickFolders(opts options, multi bool) (str string, lst []string, err error)
func browseForFolder(opts options) (string, []string, error) { func browseForFolder(opts options) (string, []string, error) {
var args win.BROWSEINFO var args win.BROWSEINFO
args.Owner, _ = opts.attach.(uintptr) args.Owner, _ = opts.attach.(win.HWND)
args.Flags = 0x1 // BIF_RETURNONLYFSDIRS args.Flags = 0x1 // BIF_RETURNONLYFSDIRS
if opts.title != nil { if opts.title != nil {

View file

@ -17,8 +17,8 @@ const (
// https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-choosecolorw-r1 // https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-choosecolorw-r1
type CHOOSECOLOR struct { type CHOOSECOLOR struct {
StructSize uint32 StructSize uint32
Owner uintptr Owner HWND
Instance uintptr Instance HWND
RgbResult uint32 RgbResult uint32
CustColors *[16]uint32 CustColors *[16]uint32
Flags uint32 Flags uint32
@ -42,8 +42,8 @@ const (
// https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-openfilenamew // https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-openfilenamew
type OPENFILENAME struct { type OPENFILENAME struct {
StructSize uint32 StructSize uint32
Owner uintptr Owner HWND
Instance uintptr Instance Handle
Filter *uint16 Filter *uint16
CustomFilter *uint16 CustomFilter *uint16
MaxCustomFilter uint32 MaxCustomFilter uint32

30
internal/win/gdi32.go Normal file
View file

@ -0,0 +1,30 @@
//go:build windows
package win
const (
LOGPIXELSX = 88
LOGPIXELSY = 90
)
// https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logfontw
type LOGFONT struct {
Height int32
Width int32
Escapement int32
Orientation int32
Weight int32
Italic byte
Underline byte
StrikeOut byte
CharSet byte
OutPrecision byte
ClipPrecision byte
Quality byte
PitchAndFamily byte
FaceName [32]uint16
}
//sys CreateFontIndirect(lf *LOGFONT) (font Handle) = gdi32.CreateFontIndirectW
//sys DeleteObject(o Handle) (ok bool) = gdi32.DeleteObject
//sys GetDeviceCaps(dc Handle, index int) (cap uintptr) = gdi32.GetDeviceCaps

View file

@ -1,5 +1,6 @@
// Package win is internal. DO NOT USE. //go:build generate
package win
//go:generate -command mkwinsyscall go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go //go:generate -command mkwinsyscall go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go
//go:generate mkwinsyscall comctl32.go comdlg32.go ole32.go shell32.go //go:generate mkwinsyscall comctl32.go comdlg32.go gdi32.go ole32.go shell32.go user32.go
package win

View file

@ -9,7 +9,7 @@ const (
// https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/ns-shlobj_core-browseinfow // https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/ns-shlobj_core-browseinfow
type BROWSEINFO struct { type BROWSEINFO struct {
Owner uintptr Owner HWND
Root uintptr Root uintptr
DisplayName *uint16 DisplayName *uint16
Title *uint16 Title *uint16
@ -22,11 +22,11 @@ type BROWSEINFO struct {
// https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataw // https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataw
type NOTIFYICONDATA struct { type NOTIFYICONDATA struct {
StructSize uint32 StructSize uint32
Wnd uintptr Wnd HWND
ID uint32 ID uint32
Flags uint32 Flags uint32
CallbackMessage uint32 CallbackMessage uint32
Icon uintptr Icon Handle
Tip [128]uint16 // NOTIFYICONDATAA_V1_SIZE Tip [128]uint16 // NOTIFYICONDATAA_V1_SIZE
State uint32 State uint32
StateMask uint32 StateMask uint32
@ -35,7 +35,7 @@ type NOTIFYICONDATA struct {
InfoTitle [64]uint16 InfoTitle [64]uint16
InfoFlags uint32 InfoFlags uint32
// GuidItem [16]byte // NOTIFYICONDATAA_V2_SIZE // GuidItem [16]byte // NOTIFYICONDATAA_V2_SIZE
// BalloonIcon syscall.Handle // NOTIFYICONDATAA_V3_SIZE // BalloonIcon Handle // NOTIFYICONDATAA_V3_SIZE
} }
type IShellItem struct { type IShellItem struct {

34
internal/win/user32.go Normal file
View file

@ -0,0 +1,34 @@
//go:build windows
package win
import "golang.org/x/sys/windows"
const (
IDOK = 1
IDCANCEL = 2
IDABORT = 3
IDRETRY = 4
IDIGNORE = 5
IDYES = 6
IDNO = 7
MB_OK = windows.MB_OK
MB_OKCANCEL = windows.MB_OKCANCEL
MB_ABORTRETRYIGNORE = windows.MB_ABORTRETRYIGNORE
MB_YESNOCANCEL = windows.MB_YESNOCANCEL
MB_YESNO = windows.MB_YESNO
MB_RETRYCANCEL = windows.MB_RETRYCANCEL
MB_CANCELTRYCONTINUE = windows.MB_CANCELTRYCONTINUE
MB_ICONERROR = windows.MB_ICONERROR
MB_ICONQUESTION = windows.MB_ICONQUESTION
MB_ICONWARNING = windows.MB_ICONWARNING
MB_ICONINFORMATION = windows.MB_ICONINFORMATION
MB_DEFBUTTON1 = windows.MB_DEFBUTTON1
MB_DEFBUTTON2 = windows.MB_DEFBUTTON2
MB_DEFBUTTON3 = windows.MB_DEFBUTTON3
)
func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
return windows.MessageBox(hwnd, text, caption, boxtype)
}

9
internal/win/win32.go Normal file
View file

@ -0,0 +1,9 @@
//go:build windows
// Package win is internal. DO NOT USE.
package win
import "golang.org/x/sys/windows"
type Handle = windows.Handle
type HWND = windows.HWND

View file

@ -40,6 +40,7 @@ func errnoErr(e syscall.Errno) error {
var ( var (
modcomctl32 = windows.NewLazySystemDLL("comctl32.dll") modcomctl32 = windows.NewLazySystemDLL("comctl32.dll")
modcomdlg32 = windows.NewLazySystemDLL("comdlg32.dll") modcomdlg32 = windows.NewLazySystemDLL("comdlg32.dll")
modgdi32 = windows.NewLazySystemDLL("gdi32.dll")
modole32 = windows.NewLazySystemDLL("ole32.dll") modole32 = windows.NewLazySystemDLL("ole32.dll")
modshell32 = windows.NewLazySystemDLL("shell32.dll") modshell32 = windows.NewLazySystemDLL("shell32.dll")
@ -48,6 +49,9 @@ var (
procCommDlgExtendedError = modcomdlg32.NewProc("CommDlgExtendedError") procCommDlgExtendedError = modcomdlg32.NewProc("CommDlgExtendedError")
procGetOpenFileNameW = modcomdlg32.NewProc("GetOpenFileNameW") procGetOpenFileNameW = modcomdlg32.NewProc("GetOpenFileNameW")
procGetSaveFileNameW = modcomdlg32.NewProc("GetSaveFileNameW") procGetSaveFileNameW = modcomdlg32.NewProc("GetSaveFileNameW")
procCreateFontIndirectW = modgdi32.NewProc("CreateFontIndirectW")
procDeleteObject = modgdi32.NewProc("DeleteObject")
procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps")
procCoCreateInstance = modole32.NewProc("CoCreateInstance") procCoCreateInstance = modole32.NewProc("CoCreateInstance")
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree") procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolder") procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolder")
@ -86,6 +90,24 @@ func GetSaveFileName(ofn *OPENFILENAME) (ok bool) {
return return
} }
func CreateFontIndirect(lf *LOGFONT) (font Handle) {
r0, _, _ := syscall.Syscall(procCreateFontIndirectW.Addr(), 1, uintptr(unsafe.Pointer(lf)), 0, 0)
font = Handle(r0)
return
}
func DeleteObject(o Handle) (ok bool) {
r0, _, _ := syscall.Syscall(procDeleteObject.Addr(), 1, uintptr(o), 0, 0)
ok = r0 != 0
return
}
func GetDeviceCaps(dc Handle, index int) (cap uintptr) {
r0, _, _ := syscall.Syscall(procGetDeviceCaps.Addr(), 2, uintptr(dc), uintptr(index), 0)
cap = uintptr(r0)
return
}
func CoCreateInstance(clsid uintptr, unkOuter unsafe.Pointer, clsContext int32, iid uintptr, address unsafe.Pointer) (ret error) { func CoCreateInstance(clsid uintptr, unkOuter unsafe.Pointer, clsContext int32, iid uintptr, address unsafe.Pointer) (ret error) {
r0, _, _ := syscall.Syscall6(procCoCreateInstance.Addr(), 5, uintptr(clsid), uintptr(unkOuter), uintptr(clsContext), uintptr(iid), uintptr(address), 0) r0, _, _ := syscall.Syscall6(procCoCreateInstance.Addr(), 5, uintptr(clsid), uintptr(unkOuter), uintptr(clsContext), uintptr(iid), uintptr(address), 0)
if r0 != 0 { if r0 != 0 {

View file

@ -1,3 +0,0 @@
package zenutil
//go:generate go run osa_generator.go osascripts/

View file

@ -1,4 +1,5 @@
// Code generated by zenity; DO NOT EDIT. // Code generated by zenity; DO NOT EDIT.
//go:build darwin //go:build darwin
package zenutil package zenutil

View file

@ -1,4 +1,6 @@
//go:build tools //go:build generate
//go:generate go run osa_generator.go osascripts/
package main package main
@ -102,6 +104,7 @@ func minify(data []byte) ([]byte, error) {
} }
var generator = template.Must(template.New("").Parse(`// Code generated by zenity; DO NOT EDIT. var generator = template.Must(template.New("").Parse(`// Code generated by zenity; DO NOT EDIT.
//go:build darwin //go:build darwin
package zenutil package zenutil

View file

@ -1,11 +1,15 @@
package zenutil package zenutil
import "strconv" import (
"strconv"
"golang.org/x/sys/windows"
)
// ParseWindowId is internal. // ParseWindowId is internal.
func ParseWindowId(id string) uintptr { func ParseWindowId(id string) windows.HWND {
hwnd, _ := strconv.ParseUint(id, 0, 64) hwnd, _ := strconv.ParseUint(id, 0, 64)
return uintptr(hwnd) return windows.HWND(uintptr(hwnd))
} }
// GetParentWindowId is internal. // GetParentWindowId is internal.

View file

@ -3,6 +3,8 @@ package zenity
import ( import (
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/ncruces/zenity/internal/win"
) )
func list(text string, items []string, opts options) (string, error) { func list(text string, items []string, opts options) (string, error) {
@ -72,12 +74,12 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) {
} }
defer unregisterClass.Call(cls, instance) defer unregisterClass.Call(cls, instance)
owner, _ := opts.attach.(uintptr) owner, _ := opts.attach.(win.HWND)
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME, dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
cls, strptr(*opts.title), cls, strptr(*opts.title),
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME, _WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
_CW_USEDEFAULT, _CW_USEDEFAULT, _CW_USEDEFAULT, _CW_USEDEFAULT,
281, 281, owner, 0, instance, uintptr(unsafe.Pointer(dlg))) 281, 281, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
dlg.textCtl, _, _ = createWindowEx.Call(0, dlg.textCtl, _, _ = createWindowEx.Call(0,
strptr("STATIC"), strptr(text), strptr("STATIC"), strptr(text),
@ -96,16 +98,16 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) {
dlg.okBtn, _, _ = createWindowEx.Call(0, dlg.okBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.okLabel), strptr("BUTTON"), strptr(*opts.okLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
12, 206, 75, 24, dlg.wnd, _IDOK, instance, 0) 12, 206, 75, 24, dlg.wnd, win.IDOK, instance, 0)
dlg.cancelBtn, _, _ = createWindowEx.Call(0, dlg.cancelBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.cancelLabel), strptr("BUTTON"), strptr(*opts.cancelLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 206, 75, 24, dlg.wnd, _IDCANCEL, instance, 0) 12, 206, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
if opts.extraButton != nil { if opts.extraButton != nil {
dlg.extraBtn, _, _ = createWindowEx.Call(0, dlg.extraBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.extraButton), strptr("BUTTON"), strptr(*opts.extraButton),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 206, 75, 24, dlg.wnd, _IDNO, instance, 0) 12, 206, 75, 24, dlg.wnd, win.IDNO, instance, 0)
} }
for _, item := range dlg.items { for _, item := range dlg.items {
@ -182,7 +184,7 @@ func listProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointer) u
switch wparam { switch wparam {
default: default:
return 1 return 1
case _IDOK, _IDYES: case win.IDOK, win.IDYES:
if dlg.multiple { if dlg.multiple {
if len, _, _ := sendMessage.Call(dlg.listCtl, _LB_GETSELCOUNT, 0, 0); int32(len) >= 0 { if len, _, _ := sendMessage.Call(dlg.listCtl, _LB_GETSELCOUNT, 0, 0); int32(len) >= 0 {
dlg.out = make([]string, len) dlg.out = make([]string, len)
@ -201,9 +203,9 @@ func listProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointer) u
dlg.out = []string{} dlg.out = []string{}
} }
} }
case _IDCANCEL: case win.IDCANCEL:
dlg.err = ErrCanceled dlg.err = ErrCanceled
case _IDNO: case win.IDNO:
dlg.err = ErrExtraButton dlg.err = ErrExtraButton
} }
destroyWindow.Call(wnd) destroyWindow.Call(wnd)

View file

@ -4,54 +4,55 @@ import (
"context" "context"
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/ncruces/zenity/internal/win"
) )
var ( var (
getDlgCtrlID = user32.NewProc("GetDlgCtrlID") getDlgCtrlID = user32.NewProc("GetDlgCtrlID")
messageBox = user32.NewProc("MessageBoxW")
) )
func message(kind messageKind, text string, opts options) error { func message(kind messageKind, text string, opts options) error {
var flags uintptr var flags uint32
switch { switch {
case kind == questionKind && opts.extraButton != nil: case kind == questionKind && opts.extraButton != nil:
flags |= _MB_YESNOCANCEL flags |= win.MB_YESNOCANCEL
case kind == questionKind: case kind == questionKind:
flags |= _MB_OKCANCEL flags |= win.MB_OKCANCEL
case opts.extraButton != nil: case opts.extraButton != nil:
flags |= _MB_YESNO flags |= win.MB_YESNO
} }
switch opts.icon { switch opts.icon {
case ErrorIcon: case ErrorIcon:
flags |= _MB_ICONERROR flags |= win.MB_ICONERROR
case QuestionIcon: case QuestionIcon:
flags |= _MB_ICONQUESTION flags |= win.MB_ICONQUESTION
case WarningIcon: case WarningIcon:
flags |= _MB_ICONWARNING flags |= win.MB_ICONWARNING
case InfoIcon: case InfoIcon:
flags |= _MB_ICONINFORMATION flags |= win.MB_ICONINFORMATION
case NoIcon: case NoIcon:
// //
default: default:
switch kind { switch kind {
case errorKind: case errorKind:
flags |= _MB_ICONERROR flags |= win.MB_ICONERROR
case questionKind: case questionKind:
flags |= _MB_ICONQUESTION flags |= win.MB_ICONQUESTION
case warningKind: case warningKind:
flags |= _MB_ICONWARNING flags |= win.MB_ICONWARNING
case infoKind: case infoKind:
flags |= _MB_ICONINFORMATION flags |= win.MB_ICONINFORMATION
} }
} }
if kind == questionKind && opts.defaultCancel { if kind == questionKind && opts.defaultCancel {
if opts.extraButton == nil { if opts.extraButton == nil {
flags |= _MB_DEFBUTTON2 flags |= win.MB_DEFBUTTON2
} else { } else {
flags |= _MB_DEFBUTTON3 flags |= win.MB_DEFBUTTON3
} }
} }
@ -70,18 +71,18 @@ func message(kind messageKind, text string, opts options) error {
title = syscall.StringToUTF16Ptr(*opts.title) title = syscall.StringToUTF16Ptr(*opts.title)
} }
owner, _ := opts.attach.(uintptr) owner, _ := opts.attach.(win.HWND)
s, _, err := messageBox.Call(owner, strptr(text), uintptr(unsafe.Pointer(title)), flags) s, err := win.MessageBox(owner, syscall.StringToUTF16Ptr(text), title, flags)
if opts.ctx != nil && opts.ctx.Err() != nil { if opts.ctx != nil && opts.ctx.Err() != nil {
return opts.ctx.Err() return opts.ctx.Err()
} }
switch s { switch s {
case _IDOK, _IDYES: case win.IDOK, win.IDYES:
return nil return nil
case _IDCANCEL: case win.IDCANCEL:
return ErrCanceled return ErrCanceled
case _IDNO: case win.IDNO:
return ErrExtraButton return ErrExtraButton
default: default:
return err return err
@ -101,11 +102,11 @@ func hookMessageDialogCallback(wnd uintptr, lparam *options) uintptr {
var text *string var text *string
switch ctl { switch ctl {
case _IDOK, _IDYES: case win.IDOK, win.IDYES:
text = lparam.okLabel text = lparam.okLabel
case _IDCANCEL: case win.IDCANCEL:
text = lparam.cancelLabel text = lparam.cancelLabel
case _IDNO: case win.IDNO:
text = lparam.extraButton text = lparam.extraButton
} }
if text != nil { if text != nil {

View file

@ -46,7 +46,7 @@ func notify(text string, opts options) error {
icon := getIcon(opts.icon) icon := getIcon(opts.icon)
if icon.handle != 0 { if icon.handle != 0 {
defer icon.delete() defer icon.delete()
args.Icon = icon.handle args.Icon = win.Handle(icon.handle)
args.Flags |= 0x00000002 // NIF_ICON args.Flags |= 0x00000002 // NIF_ICON
args.InfoFlags |= 0x4 // NIIF_USER args.InfoFlags |= 0x4 // NIIF_USER
} }
@ -90,13 +90,13 @@ func wtsMessage(text string, opts options) error {
switch opts.icon { switch opts.icon {
case ErrorIcon: case ErrorIcon:
flags |= _MB_ICONERROR flags |= win.MB_ICONERROR
case QuestionIcon: case QuestionIcon:
flags |= _MB_ICONQUESTION flags |= win.MB_ICONQUESTION
case WarningIcon: case WarningIcon:
flags |= _MB_ICONWARNING flags |= win.MB_ICONWARNING
case InfoIcon: case InfoIcon:
flags |= _MB_ICONINFORMATION flags |= win.MB_ICONINFORMATION
} }
title := opts.title title := opts.title

View file

@ -5,6 +5,8 @@ import (
"sync" "sync"
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/ncruces/zenity/internal/win"
) )
func progress(opts options) (ProgressDialog, error) { func progress(opts options) (ProgressDialog, error) {
@ -135,12 +137,12 @@ func (dlg *progressDialog) setup(opts options) error {
} }
defer unregisterClass.Call(cls, instance) defer unregisterClass.Call(cls, instance)
owner, _ := opts.attach.(uintptr) owner, _ := opts.attach.(win.HWND)
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME, dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
cls, strptr(*opts.title), cls, strptr(*opts.title),
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME, _WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
_CW_USEDEFAULT, _CW_USEDEFAULT, _CW_USEDEFAULT, _CW_USEDEFAULT,
281, 133, owner, 0, instance, uintptr(unsafe.Pointer(dlg))) 281, 133, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
dlg.textCtl, _, _ = createWindowEx.Call(0, dlg.textCtl, _, _ = createWindowEx.Call(0,
strptr("STATIC"), 0, strptr("STATIC"), 0,
@ -159,18 +161,18 @@ func (dlg *progressDialog) setup(opts options) error {
dlg.okBtn, _, _ = createWindowEx.Call(0, dlg.okBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.okLabel), strptr("BUTTON"), strptr(*opts.okLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON|_WS_DISABLED, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON|_WS_DISABLED,
12, 58, 75, 24, dlg.wnd, _IDOK, instance, 0) 12, 58, 75, 24, dlg.wnd, win.IDOK, instance, 0)
if !opts.noCancel { if !opts.noCancel {
dlg.cancelBtn, _, _ = createWindowEx.Call(0, dlg.cancelBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.cancelLabel), strptr("BUTTON"), strptr(*opts.cancelLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 58, 75, 24, dlg.wnd, _IDCANCEL, instance, 0) 12, 58, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
} }
if opts.extraButton != nil { if opts.extraButton != nil {
dlg.extraBtn, _, _ = createWindowEx.Call(0, dlg.extraBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.extraButton), strptr("BUTTON"), strptr(*opts.extraButton),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 58, 75, 24, dlg.wnd, _IDNO, instance, 0) 12, 58, 75, 24, dlg.wnd, win.IDNO, instance, 0)
} }
dlg.layout(getDPI(dlg.wnd)) dlg.layout(getDPI(dlg.wnd))
@ -256,11 +258,11 @@ func progressProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointe
switch wparam { switch wparam {
default: default:
return 1 return 1
case _IDOK, _IDYES: case win.IDOK, win.IDYES:
// //
case _IDCANCEL: case win.IDCANCEL:
dlg.err = ErrCanceled dlg.err = ErrCanceled
case _IDNO: case win.IDNO:
dlg.err = ErrExtraButton dlg.err = ErrExtraButton
} }
destroyWindow.Call(wnd) destroyWindow.Call(wnd)

View file

@ -3,6 +3,8 @@ package zenity
import ( import (
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/ncruces/zenity/internal/win"
) )
func password(opts options) (string, string, error) { func password(opts options) (string, string, error) {
@ -65,12 +67,12 @@ func (dlg *passwordDialog) setup(opts options) (string, string, error) {
} }
defer unregisterClass.Call(cls, instance) defer unregisterClass.Call(cls, instance)
owner, _ := opts.attach.(uintptr) owner, _ := opts.attach.(win.HWND)
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME, dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
cls, strptr(*opts.title), cls, strptr(*opts.title),
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME, _WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
_CW_USEDEFAULT, _CW_USEDEFAULT, _CW_USEDEFAULT, _CW_USEDEFAULT,
281, 191, owner, 0, instance, uintptr(unsafe.Pointer(dlg))) 281, 191, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
dlg.uTextCtl, _, _ = createWindowEx.Call(0, dlg.uTextCtl, _, _ = createWindowEx.Call(0,
strptr("STATIC"), strptr("Username:"), strptr("STATIC"), strptr("Username:"),
@ -96,16 +98,16 @@ func (dlg *passwordDialog) setup(opts options) (string, string, error) {
dlg.okBtn, _, _ = createWindowEx.Call(0, dlg.okBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.okLabel), strptr("BUTTON"), strptr(*opts.okLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
12, 116, 75, 24, dlg.wnd, _IDOK, instance, 0) 12, 116, 75, 24, dlg.wnd, win.IDOK, instance, 0)
dlg.cancelBtn, _, _ = createWindowEx.Call(0, dlg.cancelBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.cancelLabel), strptr("BUTTON"), strptr(*opts.cancelLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 116, 75, 24, dlg.wnd, _IDCANCEL, instance, 0) 12, 116, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
if opts.extraButton != nil { if opts.extraButton != nil {
dlg.extraBtn, _, _ = createWindowEx.Call(0, dlg.extraBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.extraButton), strptr("BUTTON"), strptr(*opts.extraButton),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP, _WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 116, 75, 24, dlg.wnd, _IDNO, instance, 0) 12, 116, 75, 24, dlg.wnd, win.IDNO, instance, 0)
} }
dlg.layout(getDPI(dlg.wnd)) dlg.layout(getDPI(dlg.wnd))
@ -183,12 +185,12 @@ func passwordProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointe
switch wparam { switch wparam {
default: default:
return 1 return 1
case _IDOK, _IDYES: case win.IDOK, win.IDYES:
dlg.usr = getWindowString(dlg.uEditCtl) dlg.usr = getWindowString(dlg.uEditCtl)
dlg.pwd = getWindowString(dlg.pEditCtl) dlg.pwd = getWindowString(dlg.pEditCtl)
case _IDCANCEL: case win.IDCANCEL:
dlg.err = ErrCanceled dlg.err = ErrCanceled
case _IDNO: case win.IDNO:
dlg.err = ErrExtraButton dlg.err = ErrExtraButton
} }
destroyWindow.Call(wnd) destroyWindow.Call(wnd)

View file

@ -98,6 +98,8 @@ func pwdResult(sep string, opts options, out []byte, err error) (string, string,
return "", str, err return "", str, err
} }
func hwnd(i uint64) uintptr { return uintptr(i) }
// Replace with strings.Cut after 1.18. // Replace with strings.Cut after 1.18.
func cut(s, sep string) (before, after string, found bool) { func cut(s, sep string) (before, after string, found bool) {
if i := strings.Index(s, sep); i >= 0 { if i := strings.Index(s, sep); i >= 0 {

View file

@ -17,16 +17,11 @@ import (
) )
var ( var (
gdi32 = windows.NewLazySystemDLL("gdi32.dll")
kernel32 = windows.NewLazySystemDLL("kernel32.dll") kernel32 = windows.NewLazySystemDLL("kernel32.dll")
ntdll = windows.NewLazySystemDLL("ntdll.dll") ntdll = windows.NewLazySystemDLL("ntdll.dll")
user32 = windows.NewLazySystemDLL("user32.dll") user32 = windows.NewLazySystemDLL("user32.dll")
wtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll") wtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll")
createFontIndirect = gdi32.NewProc("CreateFontIndirectW")
deleteObject = gdi32.NewProc("DeleteObject")
getDeviceCaps = gdi32.NewProc("GetDeviceCaps")
activateActCtx = kernel32.NewProc("ActivateActCtx") activateActCtx = kernel32.NewProc("ActivateActCtx")
createActCtx = kernel32.NewProc("CreateActCtxW") createActCtx = kernel32.NewProc("CreateActCtxW")
deactivateActCtx = kernel32.NewProc("DeactivateActCtx") deactivateActCtx = kernel32.NewProc("DeactivateActCtx")
@ -82,6 +77,8 @@ func strptr(s string) uintptr {
return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s))) return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s)))
} }
func hwnd(i uint64) win.HWND { return win.HWND(uintptr(i)) }
func setup() context.CancelFunc { func setup() context.CancelFunc {
var wnd uintptr var wnd uintptr
enumWindows.Call(syscall.NewCallback(setupEnumCallback), uintptr(unsafe.Pointer(&wnd))) enumWindows.Call(syscall.NewCallback(setupEnumCallback), uintptr(unsafe.Pointer(&wnd)))
@ -264,7 +261,7 @@ func getDPI(wnd uintptr) dpi {
if wnd != 0 && getDpiForWindow.Find() == nil { if wnd != 0 && getDpiForWindow.Find() == nil {
res, _, _ = getDpiForWindow.Call(wnd) res, _, _ = getDpiForWindow.Call(wnd)
} else if dc, _, _ := getWindowDC.Call(wnd); dc != 0 { } else if dc, _, _ := getWindowDC.Call(wnd); dc != 0 {
res, _, _ = getDeviceCaps.Call(dc, 90) // LOGPIXELSY res = win.GetDeviceCaps(win.Handle(dc), win.LOGPIXELSY)
releaseDC.Call(0, dc) releaseDC.Call(0, dc)
} }
@ -282,8 +279,8 @@ func (d dpi) scale(dim uintptr) uintptr {
} }
type font struct { type font struct {
handle uintptr handle win.Handle
logical _LOGFONT logical win.LOGFONT
} }
func getFont() font { func getFont() font {
@ -298,14 +295,14 @@ func (f *font) forDPI(dpi dpi) uintptr {
if h := -int32(dpi.scale(12)); f.handle == 0 || f.logical.Height != h { if h := -int32(dpi.scale(12)); f.handle == 0 || f.logical.Height != h {
f.delete() f.delete()
f.logical.Height = h f.logical.Height = h
f.handle, _, _ = createFontIndirect.Call(uintptr(unsafe.Pointer(&f.logical))) f.handle = win.CreateFontIndirect(&f.logical)
} }
return f.handle return uintptr(f.handle)
} }
func (f *font) delete() { func (f *font) delete() {
if f.handle != 0 { if f.handle != 0 {
deleteObject.Call(f.handle) win.DeleteObject(f.handle)
f.handle = 0 f.handle = 0
} }
} }
@ -470,24 +467,6 @@ type _CWPRETSTRUCT struct {
Wnd uintptr Wnd uintptr
} }
// https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logfontw
type _LOGFONT struct {
Height int32
Width int32
Escapement int32
Orientation int32
Weight int32
Italic byte
Underline byte
StrikeOut byte
CharSet byte
OutPrecision byte
ClipPrecision byte
Quality byte
PitchAndFamily byte
FaceName [32]uint16
}
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-nonclientmetricsw // https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-nonclientmetricsw
type _NONCLIENTMETRICS struct { type _NONCLIENTMETRICS struct {
Size uint32 Size uint32
@ -496,15 +475,15 @@ type _NONCLIENTMETRICS struct {
ScrollHeight int32 ScrollHeight int32
CaptionWidth int32 CaptionWidth int32
CaptionHeight int32 CaptionHeight int32
CaptionFont _LOGFONT CaptionFont win.LOGFONT
SmCaptionWidth int32 SmCaptionWidth int32
SmCaptionHeight int32 SmCaptionHeight int32
SmCaptionFont _LOGFONT SmCaptionFont win.LOGFONT
MenuWidth int32 MenuWidth int32
MenuHeight int32 MenuHeight int32
MenuFont _LOGFONT MenuFont win.LOGFONT
StatusFont _LOGFONT StatusFont win.LOGFONT
MessageFont _LOGFONT MessageFont win.LOGFONT
} }
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msg // https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msg

View file

@ -201,7 +201,7 @@ func Attach(id any) Option {
switch runtime.GOOS { switch runtime.GOOS {
case "windows": case "windows":
if v := reflect.ValueOf(id); v.Kind() == reflect.Uintptr { if v := reflect.ValueOf(id); v.Kind() == reflect.Uintptr {
id = uintptr(v.Uint()) id = hwnd(v.Uint())
} else { } else {
panic("interface conversion: expected uintptr") panic("interface conversion: expected uintptr")
} }