Refactor (windows).
This commit is contained in:
parent
b273c0992b
commit
3aa09ad7bb
13 changed files with 325 additions and 172 deletions
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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))
|
||||
|
|
108
util_windows.go
108
util_windows.go
|
@ -17,32 +17,18 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
kernel32 = windows.NewLazySystemDLL("kernel32.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")
|
||||
|
@ -52,7 +38,6 @@ var (
|
|||
showWindow = user32.NewProc("ShowWindow")
|
||||
systemParametersInfo = user32.NewProc("SystemParametersInfoW")
|
||||
unhookWindowsHookEx = user32.NewProc("UnhookWindowsHookEx")
|
||||
unregisterClass = user32.NewProc("UnregisterClassW")
|
||||
)
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue