Refactor (windows).

This commit is contained in:
Nuno Cruces 2022-06-20 13:37:28 +01:00
parent b273c0992b
commit 3aa09ad7bb
13 changed files with 325 additions and 172 deletions

View file

@ -47,48 +47,48 @@ func (dlg *calendarDialog) setup(text string, opts options) (time.Time, error) {
return time.Time{}, opts.ctx.Err()
}
instance, _, err := getModuleHandle.Call(0)
if instance == 0 {
instance, err := win.GetModuleHandle(nil)
if err != nil {
return time.Time{}, err
}
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(calendarProc))
if cls == 0 {
if err != nil {
return time.Time{}, err
}
defer unregisterClass.Call(cls, instance)
defer win.UnregisterClass(cls, instance)
owner, _ := opts.attach.(win.HWND)
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
cls, strptr(*opts.title),
uintptr(cls), strptr(*opts.title),
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
_CW_USEDEFAULT, _CW_USEDEFAULT,
281, 281, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
281, 281, uintptr(owner), 0, uintptr(instance), uintptr(unsafe.Pointer(dlg)))
dlg.textCtl, _, _ = createWindowEx.Call(0,
strptr("STATIC"), strptr(text),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_SS_WORDELLIPSIS|_SS_EDITCONTROL|_SS_NOPREFIX,
12, 10, 241, 16, dlg.wnd, 0, instance, 0)
12, 10, 241, 16, dlg.wnd, 0, uintptr(instance), 0)
var flags uintptr = _WS_CHILD | _WS_VISIBLE | _WS_GROUP | _WS_TABSTOP | _MCS_NOTODAY
dlg.dateCtl, _, _ = createWindowEx.Call(0,
strptr(_MONTHCAL_CLASS),
0, flags,
12, 30, 241, 164, dlg.wnd, 0, instance, 0)
12, 30, 241, 164, dlg.wnd, 0, uintptr(instance), 0)
dlg.okBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.okLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
12, 206, 75, 24, dlg.wnd, win.IDOK, instance, 0)
12, 206, 75, 24, dlg.wnd, win.IDOK, uintptr(instance), 0)
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.cancelLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 206, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
12, 206, 75, 24, dlg.wnd, win.IDCANCEL, uintptr(instance), 0)
if opts.extraButton != nil {
dlg.extraBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.extraButton),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 206, 75, 24, dlg.wnd, win.IDNO, instance, 0)
12, 206, 75, 24, dlg.wnd, win.IDNO, uintptr(instance), 0)
}
if opts.time != nil {

View file

@ -46,28 +46,28 @@ func (dlg *entryDialog) setup(text string, opts options) (string, error) {
return "", opts.ctx.Err()
}
instance, _, err := getModuleHandle.Call(0)
if instance == 0 {
instance, err := win.GetModuleHandle(nil)
if err != nil {
return "", err
}
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(entryProc))
if cls == 0 {
if err != nil {
return "", err
}
defer unregisterClass.Call(cls, instance)
defer win.UnregisterClass(cls, instance)
owner, _ := opts.attach.(win.HWND)
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
cls, strptr(*opts.title),
uintptr(cls), strptr(*opts.title),
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
_CW_USEDEFAULT, _CW_USEDEFAULT,
281, 141, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
281, 141, uintptr(owner), 0, uintptr(instance), uintptr(unsafe.Pointer(dlg)))
dlg.textCtl, _, _ = createWindowEx.Call(0,
strptr("STATIC"), strptr(text),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_SS_WORDELLIPSIS|_SS_EDITCONTROL|_SS_NOPREFIX,
12, 10, 241, 16, dlg.wnd, 0, instance, 0)
12, 10, 241, 16, dlg.wnd, 0, uintptr(instance), 0)
var flags uintptr = _WS_CHILD | _WS_VISIBLE | _WS_GROUP | _WS_TABSTOP | _ES_AUTOHSCROLL
if opts.hideText {
@ -76,21 +76,21 @@ func (dlg *entryDialog) setup(text string, opts options) (string, error) {
dlg.editCtl, _, _ = createWindowEx.Call(_WS_EX_CLIENTEDGE,
strptr("EDIT"), strptr(opts.entryText),
flags,
12, 30, 241, 24, dlg.wnd, 0, instance, 0)
12, 30, 241, 24, dlg.wnd, 0, uintptr(instance), 0)
dlg.okBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.okLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
12, 66, 75, 24, dlg.wnd, win.IDOK, instance, 0)
12, 66, 75, 24, dlg.wnd, win.IDOK, uintptr(instance), 0)
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.cancelLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 66, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
12, 66, 75, 24, dlg.wnd, win.IDCANCEL, uintptr(instance), 0)
if opts.extraButton != nil {
dlg.extraBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.extraButton),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 66, 75, 24, dlg.wnd, win.IDNO, instance, 0)
12, 66, 75, 24, dlg.wnd, win.IDNO, uintptr(instance), 0)
}
dlg.layout(getDPI(dlg.wnd))

View file

@ -61,8 +61,8 @@ type OPENFILENAME struct {
CustData Pointer
FnHook uintptr
TemplateName *uint16
PvReserved uintptr
DwReserved uint32
pvReserved uintptr
dwReserved uint32
FlagsEx uint32
}
@ -74,7 +74,7 @@ func CommDlgError() error {
}
}
//sys commDlgExtendedError() (code int) = comdlg32.CommDlgExtendedError
//sys ChooseColor(cc *CHOOSECOLOR) (ok bool) = comdlg32.ChooseColorW
//sys commDlgExtendedError() (code int) = comdlg32.CommDlgExtendedError
//sys GetOpenFileName(ofn *OPENFILENAME) (ok bool) = comdlg32.GetOpenFileNameW
//sys GetSaveFileName(ofn *OPENFILENAME) (ok bool) = comdlg32.GetSaveFileNameW

View file

@ -25,6 +25,6 @@ type LOGFONT struct {
FaceName [32]uint16
}
//sys CreateFontIndirect(lf *LOGFONT) (font Handle) = gdi32.CreateFontIndirectW
//sys CreateFontIndirect(lf *LOGFONT) (ret Handle) = gdi32.CreateFontIndirectW
//sys DeleteObject(o Handle) (ok bool) = gdi32.DeleteObject
//sys GetDeviceCaps(dc Handle, index int) (cap int) = gdi32.GetDeviceCaps
//sys GetDeviceCaps(dc Handle, index int) (ret int) = gdi32.GetDeviceCaps

View file

@ -4,8 +4,35 @@ package win
import "golang.org/x/sys/windows"
const (
ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID = 0x001
ACTCTX_FLAG_LANGID_VALID = 0x002
ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x004
ACTCTX_FLAG_RESOURCE_NAME_VALID = 0x008
ACTCTX_FLAG_SET_PROCESS_DEFAULT = 0x010
ACTCTX_FLAG_APPLICATION_NAME_VALID = 0x020
ACTCTX_FLAG_HMODULE_VALID = 0x080
)
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-actctxw
type ACTCTX struct {
Size uint32
Flags uint32
Source *uint16
ProcessorArchitecture uint16
LangId uint16
AssemblyDirectory *uint16
ResourceName uintptr
ApplicationName *uint16
Module Handle
}
func GetCurrentThreadId() (id uint32) { return windows.GetCurrentThreadId() }
func GetSystemDirectory() (string, error) { return windows.GetSystemDirectory() }
//sys ActivateActCtx(actCtx Handle, cookie *uintptr) (err error) = kernel32.ActivateActCtx
//sys CreateActCtx(actCtx *ACTCTX) (ret Handle, err error) = kernel32.CreateActCtxW
//sys DeactivateActCtx(flags uint32, cookie uintptr) (err error) = kernel32.DeactivateActCtx
//sys GetConsoleWindow() (ret HWND) = kernel32.GetConsoleWindow
//sys GetModuleHandle(moduleName *uint16) (ret Handle, err error) = kernel32.GetModuleHandleW
//sys ReleaseActCtx(actCtx Handle) = kernel32.ReleaseActCtx

View file

@ -57,7 +57,7 @@ type _IShellItemVtbl struct {
Compare uintptr
}
//sys SHBrowseForFolder(bi *BROWSEINFO) (ptr unsafe.Pointer) = shell32.SHBrowseForFolder
//sys SHBrowseForFolder(bi *BROWSEINFO) (ret unsafe.Pointer) = shell32.SHBrowseForFolder
//sys SHCreateItemFromParsingName(path *uint16, bc unsafe.Pointer, iid uintptr, item **IShellItem) (res error) = shell32.SHCreateItemFromParsingName
//sys SHGetPathFromIDListEx(ptr unsafe.Pointer, path *uint16, pathLen int, opts int) (ok bool) = shell32.SHGetPathFromIDListEx
//sys ShellNotifyIcon(message uint32, data *NOTIFYICONDATA) (ret int, err error) = shell32.Shell_NotifyIconW
//sys SHGetPathFromIDListEx(ptr unsafe.Pointer, path *uint16, pathLen int, opts int) (ok bool) = shell32.SHGetPathFromIDListEx

View file

@ -55,11 +55,27 @@ const (
PBM_SETMARQUEE = WM_USER + 10
STM_SETICON = 0x0170
USER_DEFAULT_SCREEN_DPI = 96
DPI_AWARENESS_CONTEXT_UNAWARE = ^uintptr(1) + 1
DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = ^uintptr(2) + 1
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = ^uintptr(3) + 1
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = ^uintptr(4) + 1
DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = ^uintptr(5) + 1
IMAGE_BITMAP = 0
IMAGE_ICON = 1
IMAGE_CURSOR = 2
LR_DEFAULTCOLOR = 0x00000000
LR_MONOCHROME = 0x00000001
LR_LOADFROMFILE = 0x00000010
LR_LOADTRANSPARENT = 0x00000020
LR_DEFAULTSIZE = 0x00000040
LR_VGACOLOR = 0x00000080
LR_LOADMAP3DCOLORS = 0x00001000
LR_CREATEDIBSECTION = 0x00002000
LR_SHARED = 0x00008000
)
func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
@ -70,6 +86,13 @@ func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) {
return windows.GetWindowThreadProcessId(hwnd, pid)
}
func GetDpiForWindow(wnd HWND) (ret int, err error) {
if err := procGetDpiForWindow.Find(); err != nil {
return 0, err
}
return getDpiForWindow(wnd), nil
}
func SetThreadDpiAwarenessContext(dpiContext uintptr) (ret uintptr, err error) {
if err := procSetThreadDpiAwarenessContext.Find(); err != nil {
return 0, err
@ -110,6 +133,7 @@ type MSG struct {
LParam uintptr
Time uint32
Pt POINT
private uint32
}
// https://docs.microsoft.com/en-us/windows/win32/api/windef/ns-windef-point
@ -117,14 +141,39 @@ type POINT struct {
x, y int32
}
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-wndclassexw
type WNDCLASSEX struct {
Size uint32
Style uint32
WndProc uintptr
ClsExtra int32
WndExtra int32
Instance Handle
Icon Handle
Cursor Handle
Background Handle
MenuName *uint16
ClassName *uint16
IconSm Handle
}
//sys DestroyIcon(icon Handle) (err error) = user32.DestroyIcon
//sys DispatchMessage(msg *MSG) (ret uintptr) = user32.DispatchMessageW
//sys EnumChildWindows(parent HWND, enumFunc uintptr, lparam unsafe.Pointer) = user32.EnumChildWindows
//sys EnumWindows(enumFunc uintptr, lparam unsafe.Pointer) (err error) = user32.EnumChildWindows
//sys GetDlgCtrlID(wnd HWND) (ret int) = user32.GetDlgCtrlID
//sys getDpiForWindow(wnd HWND) (ret int) = user32.GetDpiForWindow
//sys GetMessage(msg *MSG, wnd HWND, msgFilterMin uint32, msgFilterMax uint32) (ret uintptr) = user32.GetMessageW
//sys GetWindowDC(wnd HWND) (ret Handle) = user32.GetWindowDC
//sys IsDialogMessage(wnd HWND, msg *MSG) (ok bool) = user32.IsDialogMessageW
//sys LoadIcon(instance Handle, resource uintptr) (ret Handle, err error) = user32.LoadIconW
//sys LoadImage(instance Handle, name *uint16, typ int, cx int, cy int, load int) (ret Handle, err error) = user32.LoadImageW
//sys RegisterClassEx(cls *WNDCLASSEX) (ret uint16, err error) = user32.RegisterClassExW
//sys ReleaseDC(wnd HWND, dc Handle) (ok bool) = user32.ReleaseDC
//sys SendMessage(wnd HWND, msg uint32, wparam uintptr, lparam uintptr) (ret uintptr) = user32.SendMessageW
//sys SetForegroundWindow(wnd HWND) (ok bool) = user32.SetForegroundWindow
//sys setThreadDpiAwarenessContext(dpiContext uintptr) (ret uintptr) = user32.SetThreadDpiAwarenessContext
//sys SetWindowText(wnd HWND, text *uint16) (err error) = user32.SetWindowTextW
//sys TranslateMessage(msg *MSG) (ok bool) = user32.TranslateMessage
//sys UnregisterClass(atom uint16, instance Handle) (err error) = user32.UnregisterClassW
//sys CreateIconFromResource(resBits []byte, resSize int, icon bool, ver uint32) (ret Handle, err error) = user32.CreateIconFromResource

View file

@ -56,24 +56,37 @@ var (
procCreateFontIndirectW = modgdi32.NewProc("CreateFontIndirectW")
procDeleteObject = modgdi32.NewProc("DeleteObject")
procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps")
procActivateActCtx = modkernel32.NewProc("ActivateActCtx")
procCreateActCtxW = modkernel32.NewProc("CreateActCtxW")
procDeactivateActCtx = modkernel32.NewProc("DeactivateActCtx")
procGetConsoleWindow = modkernel32.NewProc("GetConsoleWindow")
procGetModuleHandleW = modkernel32.NewProc("GetModuleHandleW")
procReleaseActCtx = modkernel32.NewProc("ReleaseActCtx")
procRtlGetNtVersionNumbers = modntdll.NewProc("RtlGetNtVersionNumbers")
procCoCreateInstance = modole32.NewProc("CoCreateInstance")
procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolder")
procSHCreateItemFromParsingName = modshell32.NewProc("SHCreateItemFromParsingName")
procSHGetPathFromIDListEx = modshell32.NewProc("SHGetPathFromIDListEx")
procShell_NotifyIconW = modshell32.NewProc("Shell_NotifyIconW")
procCreateIconFromResource = moduser32.NewProc("CreateIconFromResource")
procDestroyIcon = moduser32.NewProc("DestroyIcon")
procDispatchMessageW = moduser32.NewProc("DispatchMessageW")
procEnumChildWindows = moduser32.NewProc("EnumChildWindows")
procGetDlgCtrlID = moduser32.NewProc("GetDlgCtrlID")
procGetDpiForWindow = moduser32.NewProc("GetDpiForWindow")
procGetMessageW = moduser32.NewProc("GetMessageW")
procGetWindowDC = moduser32.NewProc("GetWindowDC")
procIsDialogMessageW = moduser32.NewProc("IsDialogMessageW")
procLoadIconW = moduser32.NewProc("LoadIconW")
procLoadImageW = moduser32.NewProc("LoadImageW")
procRegisterClassExW = moduser32.NewProc("RegisterClassExW")
procReleaseDC = moduser32.NewProc("ReleaseDC")
procSendMessageW = moduser32.NewProc("SendMessageW")
procSetForegroundWindow = moduser32.NewProc("SetForegroundWindow")
procSetThreadDpiAwarenessContext = moduser32.NewProc("SetThreadDpiAwarenessContext")
procSetWindowTextW = moduser32.NewProc("SetWindowTextW")
procTranslateMessage = moduser32.NewProc("TranslateMessage")
procUnregisterClassW = moduser32.NewProc("UnregisterClassW")
procWTSSendMessageW = modwtsapi32.NewProc("WTSSendMessageW")
)
@ -107,9 +120,9 @@ func GetSaveFileName(ofn *OPENFILENAME) (ok bool) {
return
}
func CreateFontIndirect(lf *LOGFONT) (font Handle) {
func CreateFontIndirect(lf *LOGFONT) (ret Handle) {
r0, _, _ := syscall.Syscall(procCreateFontIndirectW.Addr(), 1, uintptr(unsafe.Pointer(lf)), 0, 0)
font = Handle(r0)
ret = Handle(r0)
return
}
@ -119,9 +132,34 @@ func DeleteObject(o Handle) (ok bool) {
return
}
func GetDeviceCaps(dc Handle, index int) (cap int) {
func GetDeviceCaps(dc Handle, index int) (ret int) {
r0, _, _ := syscall.Syscall(procGetDeviceCaps.Addr(), 2, uintptr(dc), uintptr(index), 0)
cap = int(r0)
ret = int(r0)
return
}
func ActivateActCtx(actCtx Handle, cookie *uintptr) (err error) {
r1, _, e1 := syscall.Syscall(procActivateActCtx.Addr(), 2, uintptr(actCtx), uintptr(unsafe.Pointer(cookie)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func CreateActCtx(actCtx *ACTCTX) (ret Handle, err error) {
r0, _, e1 := syscall.Syscall(procCreateActCtxW.Addr(), 1, uintptr(unsafe.Pointer(actCtx)), 0, 0)
ret = Handle(r0)
if ret == 0 {
err = errnoErr(e1)
}
return
}
func DeactivateActCtx(flags uint32, cookie uintptr) (err error) {
r1, _, e1 := syscall.Syscall(procDeactivateActCtx.Addr(), 2, uintptr(flags), uintptr(cookie), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
@ -140,6 +178,11 @@ func GetModuleHandle(moduleName *uint16) (ret Handle, err error) {
return
}
func ReleaseActCtx(actCtx Handle) {
syscall.Syscall(procReleaseActCtx.Addr(), 1, uintptr(actCtx), 0, 0)
return
}
func RtlGetNtVersionNumbers(major *uint32, minor *uint32, build *uint32) {
syscall.Syscall(procRtlGetNtVersionNumbers.Addr(), 3, uintptr(unsafe.Pointer(major)), uintptr(unsafe.Pointer(minor)), uintptr(unsafe.Pointer(build)))
return
@ -153,9 +196,9 @@ func CoCreateInstance(clsid uintptr, unkOuter unsafe.Pointer, clsContext int32,
return
}
func SHBrowseForFolder(bi *BROWSEINFO) (ptr unsafe.Pointer) {
func SHBrowseForFolder(bi *BROWSEINFO) (ret unsafe.Pointer) {
r0, _, _ := syscall.Syscall(procSHBrowseForFolder.Addr(), 1, uintptr(unsafe.Pointer(bi)), 0, 0)
ptr = unsafe.Pointer(r0)
ret = unsafe.Pointer(r0)
return
}
@ -182,14 +225,34 @@ func ShellNotifyIcon(message uint32, data *NOTIFYICONDATA) (ret int, err error)
return
}
func DispatchMessage(msg *MSG) (ret uintptr) {
r0, _, _ := syscall.Syscall(procDispatchMessageW.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0)
ret = uintptr(r0)
func CreateIconFromResource(resBits []byte, resSize int, icon bool, ver uint32) (ret Handle, err error) {
var _p0 *byte
if len(resBits) > 0 {
_p0 = &resBits[0]
}
var _p1 uint32
if icon {
_p1 = 1
}
r0, _, e1 := syscall.Syscall6(procCreateIconFromResource.Addr(), 5, uintptr(unsafe.Pointer(_p0)), uintptr(len(resBits)), uintptr(resSize), uintptr(_p1), uintptr(ver), 0)
ret = Handle(r0)
if ret == 0 {
err = errnoErr(e1)
}
return
}
func EnumChildWindows(parent HWND, enumFunc uintptr, lparam unsafe.Pointer) {
syscall.Syscall(procEnumChildWindows.Addr(), 3, uintptr(parent), uintptr(enumFunc), uintptr(lparam))
func DestroyIcon(icon Handle) (err error) {
r1, _, e1 := syscall.Syscall(procDestroyIcon.Addr(), 1, uintptr(icon), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func DispatchMessage(msg *MSG) (ret uintptr) {
r0, _, _ := syscall.Syscall(procDispatchMessageW.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0)
ret = uintptr(r0)
return
}
@ -201,24 +264,74 @@ func EnumWindows(enumFunc uintptr, lparam unsafe.Pointer) (err error) {
return
}
func EnumChildWindows(parent HWND, enumFunc uintptr, lparam unsafe.Pointer) {
syscall.Syscall(procEnumChildWindows.Addr(), 3, uintptr(parent), uintptr(enumFunc), uintptr(lparam))
return
}
func GetDlgCtrlID(wnd HWND) (ret int) {
r0, _, _ := syscall.Syscall(procGetDlgCtrlID.Addr(), 1, uintptr(wnd), 0, 0)
ret = int(r0)
return
}
func getDpiForWindow(wnd HWND) (ret int) {
r0, _, _ := syscall.Syscall(procGetDpiForWindow.Addr(), 1, uintptr(wnd), 0, 0)
ret = int(r0)
return
}
func GetMessage(msg *MSG, wnd HWND, msgFilterMin uint32, msgFilterMax uint32) (ret uintptr) {
r0, _, _ := syscall.Syscall6(procGetMessageW.Addr(), 4, uintptr(unsafe.Pointer(msg)), uintptr(wnd), uintptr(msgFilterMin), uintptr(msgFilterMax), 0, 0)
ret = uintptr(r0)
return
}
func GetWindowDC(wnd HWND) (ret Handle) {
r0, _, _ := syscall.Syscall(procGetWindowDC.Addr(), 1, uintptr(wnd), 0, 0)
ret = Handle(r0)
return
}
func IsDialogMessage(wnd HWND, msg *MSG) (ok bool) {
r0, _, _ := syscall.Syscall(procIsDialogMessageW.Addr(), 2, uintptr(wnd), uintptr(unsafe.Pointer(msg)), 0)
ok = r0 != 0
return
}
func LoadIcon(instance Handle, resource uintptr) (ret Handle, err error) {
r0, _, e1 := syscall.Syscall(procLoadIconW.Addr(), 2, uintptr(instance), uintptr(resource), 0)
ret = Handle(r0)
if ret == 0 {
err = errnoErr(e1)
}
return
}
func LoadImage(instance Handle, name *uint16, typ int, cx int, cy int, load int) (ret Handle, err error) {
r0, _, e1 := syscall.Syscall6(procLoadImageW.Addr(), 6, uintptr(instance), uintptr(unsafe.Pointer(name)), uintptr(typ), uintptr(cx), uintptr(cy), uintptr(load))
ret = Handle(r0)
if ret == 0 {
err = errnoErr(e1)
}
return
}
func RegisterClassEx(cls *WNDCLASSEX) (ret uint16, err error) {
r0, _, e1 := syscall.Syscall(procRegisterClassExW.Addr(), 1, uintptr(unsafe.Pointer(cls)), 0, 0)
ret = uint16(r0)
if ret == 0 {
err = errnoErr(e1)
}
return
}
func ReleaseDC(wnd HWND, dc Handle) (ok bool) {
r0, _, _ := syscall.Syscall(procReleaseDC.Addr(), 2, uintptr(wnd), uintptr(dc), 0)
ok = r0 != 0
return
}
func SendMessage(wnd HWND, msg uint32, wparam uintptr, lparam uintptr) (ret uintptr) {
r0, _, _ := syscall.Syscall6(procSendMessageW.Addr(), 4, uintptr(wnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0)
ret = uintptr(r0)
@ -251,6 +364,14 @@ func TranslateMessage(msg *MSG) (ok bool) {
return
}
func UnregisterClass(atom uint16, instance Handle) (err error) {
r1, _, e1 := syscall.Syscall(procUnregisterClassW.Addr(), 2, uintptr(atom), uintptr(instance), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func WTSSendMessage(server Handle, sessionID uint32, title *uint16, titleLength int, message *uint16, messageLength int, style uint32, timeout int, response *uint32, wait bool) (err error) {
var _p0 uint32
if wait {

View file

@ -63,28 +63,28 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) {
return nil, opts.ctx.Err()
}
instance, _, err := getModuleHandle.Call(0)
if instance == 0 {
instance, err := win.GetModuleHandle(nil)
if err != nil {
return nil, err
}
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(listProc))
if cls == 0 {
if err != nil {
return nil, err
}
defer unregisterClass.Call(cls, instance)
defer win.UnregisterClass(cls, instance)
owner, _ := opts.attach.(win.HWND)
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
cls, strptr(*opts.title),
uintptr(cls), strptr(*opts.title),
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
_CW_USEDEFAULT, _CW_USEDEFAULT,
281, 281, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
281, 281, uintptr(owner), 0, uintptr(instance), uintptr(unsafe.Pointer(dlg)))
dlg.textCtl, _, _ = createWindowEx.Call(0,
strptr("STATIC"), strptr(text),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_SS_WORDELLIPSIS|_SS_EDITCONTROL|_SS_NOPREFIX,
12, 10, 241, 16, dlg.wnd, 0, instance, 0)
12, 10, 241, 16, dlg.wnd, 0, uintptr(instance), 0)
var flags uintptr = _WS_CHILD | _WS_VISIBLE | _WS_GROUP | _WS_TABSTOP | _WS_VSCROLL
if dlg.multiple {
@ -93,21 +93,21 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) {
dlg.listCtl, _, _ = createWindowEx.Call(_WS_EX_CLIENTEDGE,
strptr("LISTBOX"), strptr(opts.entryText),
flags,
12, 30, 241, 164, dlg.wnd, 0, instance, 0)
12, 30, 241, 164, dlg.wnd, 0, uintptr(instance), 0)
dlg.okBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.okLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
12, 206, 75, 24, dlg.wnd, win.IDOK, instance, 0)
12, 206, 75, 24, dlg.wnd, win.IDOK, uintptr(instance), 0)
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.cancelLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 206, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
12, 206, 75, 24, dlg.wnd, win.IDCANCEL, uintptr(instance), 0)
if opts.extraButton != nil {
dlg.extraBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.extraButton),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 206, 75, 24, dlg.wnd, win.IDNO, instance, 0)
12, 206, 75, 24, dlg.wnd, win.IDNO, uintptr(instance), 0)
}
for _, item := range dlg.items {

View file

@ -114,7 +114,7 @@ func hookMessageDialogCallback(wnd win.HWND, lparam *options) uintptr {
icon := getIcon(lparam.icon)
if icon.handle != 0 {
defer icon.delete()
win.SendMessage(wnd, win.STM_SETICON, icon.handle, 0)
win.SendMessage(wnd, win.STM_SETICON, uintptr(icon.handle), 0)
}
}
return 1

View file

@ -126,28 +126,28 @@ func (dlg *progressDialog) setup(opts options) error {
return opts.ctx.Err()
}
instance, _, err := getModuleHandle.Call(0)
if instance == 0 {
instance, err := win.GetModuleHandle(nil)
if err != nil {
return err
}
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(progressProc))
if cls == 0 {
if err != nil {
return err
}
defer unregisterClass.Call(cls, instance)
defer win.UnregisterClass(cls, instance)
owner, _ := opts.attach.(win.HWND)
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
cls, strptr(*opts.title),
uintptr(cls), strptr(*opts.title),
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
_CW_USEDEFAULT, _CW_USEDEFAULT,
281, 133, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
281, 133, uintptr(owner), 0, uintptr(instance), uintptr(unsafe.Pointer(dlg)))
dlg.textCtl, _, _ = createWindowEx.Call(0,
strptr("STATIC"), 0,
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_SS_WORDELLIPSIS|_SS_EDITCONTROL|_SS_NOPREFIX,
12, 10, 241, 16, dlg.wnd, 0, instance, 0)
12, 10, 241, 16, dlg.wnd, 0, uintptr(instance), 0)
var flags uintptr = _WS_CHILD | _WS_VISIBLE | _PBS_SMOOTH
if opts.maxValue < 0 {
@ -156,23 +156,23 @@ func (dlg *progressDialog) setup(opts options) error {
dlg.progCtl, _, _ = createWindowEx.Call(0,
strptr(_PROGRESS_CLASS),
0, flags,
12, 30, 241, 16, dlg.wnd, 0, instance, 0)
12, 30, 241, 16, dlg.wnd, 0, uintptr(instance), 0)
dlg.okBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.okLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON|_WS_DISABLED,
12, 58, 75, 24, dlg.wnd, win.IDOK, instance, 0)
12, 58, 75, 24, dlg.wnd, win.IDOK, uintptr(instance), 0)
if !opts.noCancel {
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.cancelLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 58, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
12, 58, 75, 24, dlg.wnd, win.IDCANCEL, uintptr(instance), 0)
}
if opts.extraButton != nil {
dlg.extraBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.extraButton),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 58, 75, 24, dlg.wnd, win.IDNO, instance, 0)
12, 58, 75, 24, dlg.wnd, win.IDNO, uintptr(instance), 0)
}
dlg.layout(getDPI(dlg.wnd))

View file

@ -56,58 +56,58 @@ func (dlg *passwordDialog) setup(opts options) (string, string, error) {
return "", "", opts.ctx.Err()
}
instance, _, err := getModuleHandle.Call(0)
if instance == 0 {
instance, err := win.GetModuleHandle(nil)
if err != nil {
return "", "", err
}
cls, err := registerClass(instance, icon.handle, syscall.NewCallback(passwordProc))
if cls == 0 {
if err != nil {
return "", "", err
}
defer unregisterClass.Call(cls, instance)
defer win.UnregisterClass(cls, instance)
owner, _ := opts.attach.(win.HWND)
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
cls, strptr(*opts.title),
uintptr(cls), strptr(*opts.title),
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
_CW_USEDEFAULT, _CW_USEDEFAULT,
281, 191, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
281, 191, uintptr(owner), 0, uintptr(instance), uintptr(unsafe.Pointer(dlg)))
dlg.uTextCtl, _, _ = createWindowEx.Call(0,
strptr("STATIC"), strptr("Username:"),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_SS_WORDELLIPSIS|_SS_EDITCONTROL|_SS_NOPREFIX,
12, 10, 241, 16, dlg.wnd, 0, instance, 0)
12, 10, 241, 16, dlg.wnd, 0, uintptr(instance), 0)
var flags uintptr = _WS_CHILD | _WS_VISIBLE | _WS_GROUP | _WS_TABSTOP | _ES_AUTOHSCROLL
dlg.uEditCtl, _, _ = createWindowEx.Call(_WS_EX_CLIENTEDGE,
strptr("EDIT"), 0,
flags,
12, 30, 241, 24, dlg.wnd, 0, instance, 0)
12, 30, 241, 24, dlg.wnd, 0, uintptr(instance), 0)
dlg.pTextCtl, _, _ = createWindowEx.Call(0,
strptr("STATIC"), strptr("Password:"),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_SS_WORDELLIPSIS|_SS_EDITCONTROL|_SS_NOPREFIX,
12, 60, 241, 16, dlg.wnd, 0, instance, 0)
12, 60, 241, 16, dlg.wnd, 0, uintptr(instance), 0)
dlg.pEditCtl, _, _ = createWindowEx.Call(_WS_EX_CLIENTEDGE,
strptr("EDIT"), 0,
flags|_ES_PASSWORD,
12, 80, 241, 24, dlg.wnd, 0, instance, 0)
12, 80, 241, 24, dlg.wnd, 0, uintptr(instance), 0)
dlg.okBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.okLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
12, 116, 75, 24, dlg.wnd, win.IDOK, instance, 0)
12, 116, 75, 24, dlg.wnd, win.IDOK, uintptr(instance), 0)
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.cancelLabel),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 116, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
12, 116, 75, 24, dlg.wnd, win.IDCANCEL, uintptr(instance), 0)
if opts.extraButton != nil {
dlg.extraBtn, _, _ = createWindowEx.Call(0,
strptr("BUTTON"), strptr(*opts.extraButton),
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
12, 116, 75, 24, dlg.wnd, win.IDNO, instance, 0)
12, 116, 75, 24, dlg.wnd, win.IDNO, uintptr(instance), 0)
}
dlg.layout(getDPI(dlg.wnd))

View file

@ -17,42 +17,27 @@ import (
)
var (
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
user32 = windows.NewLazySystemDLL("user32.dll")
user32 = windows.NewLazySystemDLL("user32.dll")
activateActCtx = kernel32.NewProc("ActivateActCtx")
createActCtx = kernel32.NewProc("CreateActCtxW")
deactivateActCtx = kernel32.NewProc("DeactivateActCtx")
getModuleHandle = kernel32.NewProc("GetModuleHandleW")
callNextHookEx = user32.NewProc("CallNextHookEx")
createIconFromResource = user32.NewProc("CreateIconFromResource")
createWindowEx = user32.NewProc("CreateWindowExW")
defWindowProc = user32.NewProc("DefWindowProcW")
destroyIcon = user32.NewProc("DestroyIcon")
destroyWindow = user32.NewProc("DestroyWindow")
enableWindow = user32.NewProc("EnableWindow")
getDpiForWindow = user32.NewProc("GetDpiForWindow")
getSystemMetrics = user32.NewProc("GetSystemMetrics")
getWindowDC = user32.NewProc("GetWindowDC")
getWindowRect = user32.NewProc("GetWindowRect")
getWindowText = user32.NewProc("GetWindowTextW")
getWindowTextLength = user32.NewProc("GetWindowTextLengthW")
loadIcon = user32.NewProc("LoadIconW")
loadImage = user32.NewProc("LoadImageW")
postQuitMessage = user32.NewProc("PostQuitMessage")
registerClassEx = user32.NewProc("RegisterClassExW")
releaseDC = user32.NewProc("ReleaseDC")
sendMessage = user32.NewProc("SendMessageW")
setFocus = user32.NewProc("SetFocus")
setWindowLong = user32.NewProc("SetWindowLongW")
setWindowPos = user32.NewProc("SetWindowPos")
setWindowsHookEx = user32.NewProc("SetWindowsHookExW")
setWindowText = user32.NewProc("SetWindowTextW")
showWindow = user32.NewProc("ShowWindow")
systemParametersInfo = user32.NewProc("SystemParametersInfoW")
unhookWindowsHookEx = user32.NewProc("UnhookWindowsHookEx")
unregisterClass = user32.NewProc("UnregisterClassW")
callNextHookEx = user32.NewProc("CallNextHookEx")
createWindowEx = user32.NewProc("CreateWindowExW")
defWindowProc = user32.NewProc("DefWindowProcW")
destroyWindow = user32.NewProc("DestroyWindow")
enableWindow = user32.NewProc("EnableWindow")
getSystemMetrics = user32.NewProc("GetSystemMetrics")
getWindowRect = user32.NewProc("GetWindowRect")
getWindowText = user32.NewProc("GetWindowTextW")
getWindowTextLength = user32.NewProc("GetWindowTextLengthW")
postQuitMessage = user32.NewProc("PostQuitMessage")
sendMessage = user32.NewProc("SendMessageW")
setFocus = user32.NewProc("SetFocus")
setWindowLong = user32.NewProc("SetWindowLongW")
setWindowPos = user32.NewProc("SetWindowPos")
setWindowsHookEx = user32.NewProc("SetWindowsHookExW")
setWindowText = user32.NewProc("SetWindowTextW")
showWindow = user32.NewProc("ShowWindow")
systemParametersInfo = user32.NewProc("SystemParametersInfoW")
unhookWindowsHookEx = user32.NewProc("UnhookWindowsHookEx")
)
func intptr(i int64) uintptr {
@ -97,7 +82,7 @@ func setup() context.CancelFunc {
win.SetThreadDpiAwarenessContext(restore)
}
if cookie != 0 {
deactivateActCtx.Call(0, cookie)
win.DeactivateActCtx(0, cookie)
}
runtime.UnlockOSThread()
}
@ -172,7 +157,7 @@ func dialogHookProc(code int32, wparam uintptr, lparam *_CWPRETSTRUCT) uintptr {
icon := getIcon(hook.icon)
if icon.handle != 0 {
defer icon.delete()
win.SendMessage(lparam.Wnd, win.WM_SETICON, 0, icon.handle)
win.SendMessage(lparam.Wnd, win.WM_SETICON, 0, uintptr(icon.handle))
}
}
if hook.title != nil {
@ -234,20 +219,23 @@ func deleteBackRef(id uintptr) {
delete(backRefs.m, id)
}
type dpi uintptr
type dpi int
func getDPI(wnd uintptr) dpi {
var res uintptr
func getDPI(_wnd uintptr) dpi {
wnd := win.HWND(_wnd)
if wnd != 0 && getDpiForWindow.Find() == nil {
res, _, _ = getDpiForWindow.Call(wnd)
} else if dc, _, _ := getWindowDC.Call(wnd); dc != 0 {
res = uintptr(win.GetDeviceCaps(win.Handle(dc), win.LOGPIXELSY))
releaseDC.Call(0, dc)
res, _ := win.GetDpiForWindow(wnd)
if res != 0 {
return dpi(res)
}
if dc := win.GetWindowDC(wnd); dc != 0 {
res = win.GetDeviceCaps(dc, win.LOGPIXELSY)
win.ReleaseDC(wnd, dc)
}
if res == 0 {
return 96 // USER_DEFAULT_SCREEN_DPI
return win.USER_DEFAULT_SCREEN_DPI
}
return dpi(res)
}
@ -256,7 +244,7 @@ func (d dpi) scale(dim uintptr) uintptr {
if d == 0 {
return dim
}
return dim * uintptr(d) / 96 // USER_DEFAULT_SCREEN_DPI
return dim * uintptr(d) / win.USER_DEFAULT_SCREEN_DPI
}
type font struct {
@ -289,7 +277,7 @@ func (f *font) delete() {
}
type icon struct {
handle uintptr
handle win.Handle
destroy bool
}
@ -307,7 +295,7 @@ func getIcon(i any) icon {
resource = 32516 // IDI_INFORMATION
}
if resource != 0 {
res.handle, _, _ = loadIcon.Call(0, resource)
res.handle, _ = win.LoadIcon(0, resource)
return res
}
@ -323,16 +311,13 @@ func getIcon(i any) icon {
switch {
case bytes.HasPrefix(data, []byte("\x00\x00\x01\x00")):
res.handle, _, _ = loadImage.Call(0,
strptr(path),
1, /*IMAGE_ICON*/
0, 0,
0x00008050 /*LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_SHARED*/)
res.handle, _ = win.LoadImage(0,
syscall.StringToUTF16Ptr(path),
win.IMAGE_ICON, 0, 0,
win.LR_LOADFROMFILE|win.LR_DEFAULTSIZE|win.LR_SHARED)
case bytes.HasPrefix(data, []byte("\x89PNG\r\n\x1a\n")):
res.handle, _, _ = createIconFromResource.Call(
uintptr(unsafe.Pointer(&data[0])),
uintptr(len(data)),
1, 0x00030000)
res.handle, _ = win.CreateIconFromResource(
data, len(data), true, 0x00030000)
res.destroy = true
}
return res
@ -340,7 +325,7 @@ func getIcon(i any) icon {
func (i *icon) delete() {
if i.handle != 0 {
destroyIcon.Call(i.handle)
win.DestroyIcon(i.handle)
i.handle = 0
}
}
@ -365,10 +350,10 @@ func getWindowString(wnd uintptr) string {
return syscall.UTF16ToString(buf)
}
func registerClass(instance, icon, proc uintptr) (uintptr, error) {
func registerClass(instance, icon win.Handle, proc uintptr) (uint16, error) {
name := "WC_" + strconv.FormatUint(uint64(proc), 16)
var wcx _WNDCLASSEX
var wcx win.WNDCLASSEX
wcx.Size = uint32(unsafe.Sizeof(wcx))
wcx.WndProc = proc
wcx.Icon = icon
@ -376,8 +361,7 @@ func registerClass(instance, icon, proc uintptr) (uintptr, error) {
wcx.Background = 5 // COLOR_WINDOW
wcx.ClassName = syscall.StringToUTF16Ptr(name)
atom, _, err := registerClassEx.Call(uintptr(unsafe.Pointer(&wcx)))
return atom, err
return win.RegisterClassEx(&wcx)
}
// https://stackoverflow.com/questions/4308503/how-to-enable-visual-styles-without-a-manifest
@ -387,32 +371,20 @@ func enableVisualStyles() (cookie uintptr) {
return
}
var ctx _ACTCTX
var ctx win.ACTCTX
ctx.Size = uint32(unsafe.Sizeof(ctx))
ctx.Flags = 0x01c // ACTCTX_FLAG_RESOURCE_NAME_VALID|ACTCTX_FLAG_SET_PROCESS_DEFAULT|ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID
ctx.Flags = win.ACTCTX_FLAG_RESOURCE_NAME_VALID | win.ACTCTX_FLAG_SET_PROCESS_DEFAULT | win.ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID
ctx.Source = syscall.StringToUTF16Ptr("shell32.dll")
ctx.AssemblyDirectory = syscall.StringToUTF16Ptr(dir)
ctx.ResourceName = 124
if h, _, _ := createActCtx.Call(uintptr(unsafe.Pointer(&ctx))); h != 0 {
activateActCtx.Call(h, uintptr(unsafe.Pointer(&cookie)))
if hnd, err := win.CreateActCtx(&ctx); err == nil {
win.ActivateActCtx(hnd, &cookie)
win.ReleaseActCtx(hnd)
}
return
}
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-actctxw
type _ACTCTX struct {
Size uint32
Flags uint32
Source *uint16
ProcessorArchitecture uint16
LangId uint16
AssemblyDirectory *uint16
ResourceName uintptr
ApplicationName *uint16
Module uintptr
}
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-cwpretstruct
type _CWPRETSTRUCT struct {
Result uintptr
@ -449,22 +421,6 @@ type _RECT struct {
bottom int32
}
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-wndclassexw
type _WNDCLASSEX struct {
Size uint32
Style uint32
WndProc uintptr
ClsExtra int32
WndExtra int32
Instance uintptr
Icon uintptr
Cursor uintptr
Background uintptr
MenuName *uint16
ClassName *uint16
IconSm uintptr
}
// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
type _SYSTEMTIME struct {
year uint16