From 3aa09ad7bbe99c51e3e953fb396de49639cdf377 Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Mon, 20 Jun 2022 13:37:28 +0100 Subject: [PATCH] Refactor (windows). --- date_windows.go | 22 ++--- entry_windows.go | 22 ++--- internal/win/comdlg32.go | 6 +- internal/win/gdi32.go | 4 +- internal/win/kernel32.go | 27 ++++++ internal/win/shell32.go | 4 +- internal/win/user32.go | 49 ++++++++++ internal/win/zsyscall_windows.go | 143 ++++++++++++++++++++++++++--- list_windows.go | 22 ++--- msg_windows.go | 2 +- progress_windows.go | 22 ++--- pwd_windows.go | 26 +++--- util_windows.go | 148 +++++++++++-------------------- 13 files changed, 325 insertions(+), 172 deletions(-) diff --git a/date_windows.go b/date_windows.go index b0c286c..e8f3112 100644 --- a/date_windows.go +++ b/date_windows.go @@ -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 { diff --git a/entry_windows.go b/entry_windows.go index 22273f2..0ed06c7 100644 --- a/entry_windows.go +++ b/entry_windows.go @@ -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)) diff --git a/internal/win/comdlg32.go b/internal/win/comdlg32.go index 2c74c9b..60da766 100644 --- a/internal/win/comdlg32.go +++ b/internal/win/comdlg32.go @@ -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 diff --git a/internal/win/gdi32.go b/internal/win/gdi32.go index 933f6f1..735c874 100644 --- a/internal/win/gdi32.go +++ b/internal/win/gdi32.go @@ -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 diff --git a/internal/win/kernel32.go b/internal/win/kernel32.go index 8e3fd7b..0f87f2c 100644 --- a/internal/win/kernel32.go +++ b/internal/win/kernel32.go @@ -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 diff --git a/internal/win/shell32.go b/internal/win/shell32.go index 8f2bfca..a3ae27b 100644 --- a/internal/win/shell32.go +++ b/internal/win/shell32.go @@ -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 diff --git a/internal/win/user32.go b/internal/win/user32.go index 0e8adf2..b8c3d4a 100644 --- a/internal/win/user32.go +++ b/internal/win/user32.go @@ -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 diff --git a/internal/win/zsyscall_windows.go b/internal/win/zsyscall_windows.go index 1fa8b07..b69034b 100644 --- a/internal/win/zsyscall_windows.go +++ b/internal/win/zsyscall_windows.go @@ -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 { diff --git a/list_windows.go b/list_windows.go index df18879..ba1ecd3 100644 --- a/list_windows.go +++ b/list_windows.go @@ -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 { diff --git a/msg_windows.go b/msg_windows.go index 5e7c62f..de457c6 100644 --- a/msg_windows.go +++ b/msg_windows.go @@ -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 diff --git a/progress_windows.go b/progress_windows.go index fba9651..d2d2701 100644 --- a/progress_windows.go +++ b/progress_windows.go @@ -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)) diff --git a/pwd_windows.go b/pwd_windows.go index b96ee79..98ae7ff 100644 --- a/pwd_windows.go +++ b/pwd_windows.go @@ -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)) diff --git a/util_windows.go b/util_windows.go index 7c44672..8520470 100644 --- a/util_windows.go +++ b/util_windows.go @@ -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