Refactor (windows).
This commit is contained in:
parent
d47150a866
commit
561f2b8b32
11 changed files with 74 additions and 52 deletions
|
@ -27,4 +27,4 @@ type LOGFONT struct {
|
||||||
|
|
||||||
//sys CreateFontIndirect(lf *LOGFONT) (font Handle) = gdi32.CreateFontIndirectW
|
//sys CreateFontIndirect(lf *LOGFONT) (font Handle) = gdi32.CreateFontIndirectW
|
||||||
//sys DeleteObject(o Handle) (ok bool) = gdi32.DeleteObject
|
//sys DeleteObject(o Handle) (ok bool) = gdi32.DeleteObject
|
||||||
//sys GetDeviceCaps(dc Handle, index int) (cap uintptr) = gdi32.GetDeviceCaps
|
//sys GetDeviceCaps(dc Handle, index int) (cap int) = gdi32.GetDeviceCaps
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//go:build generate
|
//go:build generate
|
||||||
|
|
||||||
//go:generate -command mkwinsyscall go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go
|
//go:generate -command mkwinsyscall go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go
|
||||||
//go:generate mkwinsyscall comctl32.go comdlg32.go gdi32.go ole32.go shell32.go user32.go
|
//go:generate mkwinsyscall comctl32.go comdlg32.go gdi32.go ole32.go shell32.go user32.go win32.go wtsapi32.go
|
||||||
|
|
||||||
package win
|
package win
|
||||||
|
|
|
@ -44,4 +44,4 @@ func (o *COMObject) Call(trap uintptr, a ...uintptr) (r1, r2 uintptr, lastErr er
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys CoTaskMemFree(address uintptr) = ole32.CoTaskMemFree
|
//sys CoTaskMemFree(address uintptr) = ole32.CoTaskMemFree
|
||||||
//sys CoCreateInstance(clsid uintptr, unkOuter unsafe.Pointer, clsContext int32, iid uintptr, address unsafe.Pointer) (ret error) = ole32.CoCreateInstance
|
//sys CoCreateInstance(clsid uintptr, unkOuter unsafe.Pointer, clsContext int32, iid uintptr, address unsafe.Pointer) (res error) = ole32.CoCreateInstance
|
||||||
|
|
|
@ -53,6 +53,6 @@ type _IShellItemVtbl struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys SHBrowseForFolder(bi *BROWSEINFO) (ptr uintptr) = shell32.SHBrowseForFolder
|
//sys SHBrowseForFolder(bi *BROWSEINFO) (ptr uintptr) = shell32.SHBrowseForFolder
|
||||||
//sys SHCreateItemFromParsingName(path *uint16, bc unsafe.Pointer, iid uintptr, item **IShellItem) (err error) = shell32.SHCreateItemFromParsingName
|
//sys SHCreateItemFromParsingName(path *uint16, bc unsafe.Pointer, iid uintptr, item **IShellItem) (res error) = shell32.SHCreateItemFromParsingName
|
||||||
//sys SHGetPathFromIDListEx(ptr uintptr, path *uint16, pathLen int, opts int) (err error) = shell32.SHGetPathFromIDListEx
|
//sys SHGetPathFromIDListEx(ptr uintptr, path *uint16, pathLen int, opts int) (ok bool) = shell32.SHGetPathFromIDListEx
|
||||||
//sys ShellNotifyIcon(message uint32, data *NOTIFYICONDATA) (ret int, err error) = shell32.Shell_NotifyIconW
|
//sys ShellNotifyIcon(message uint32, data *NOTIFYICONDATA) (ret int, err error) = shell32.Shell_NotifyIconW
|
||||||
|
|
|
@ -32,3 +32,5 @@ const (
|
||||||
func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
|
func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
|
||||||
return windows.MessageBox(hwnd, text, caption, boxtype)
|
return windows.MessageBox(hwnd, text, caption, boxtype)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//sys GetDlgCtrlID(wnd HWND) (ret int) = user32.GetDlgCtrlID
|
||||||
|
|
|
@ -7,3 +7,5 @@ import "golang.org/x/sys/windows"
|
||||||
|
|
||||||
type Handle = windows.Handle
|
type Handle = windows.Handle
|
||||||
type HWND = windows.HWND
|
type HWND = windows.HWND
|
||||||
|
|
||||||
|
//sys RtlGetNtVersionNumbers(major *uint32, minor *uint32, build *uint32) = ntdll.RtlGetNtVersionNumbers
|
||||||
|
|
10
internal/win/wtsapi32.go
Normal file
10
internal/win/wtsapi32.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package win
|
||||||
|
|
||||||
|
const (
|
||||||
|
WTS_CURRENT_SERVER_HANDLE = 0
|
||||||
|
WTS_CURRENT_SESSION = 0xffffffff
|
||||||
|
)
|
||||||
|
|
||||||
|
//sys WTSSendMessage(server Handle, sessionID uint32, title *uint16, titleLength int, message *uint16, messageLength int, style uint32, timeout int, response *uint32, wait bool) (err error) = wtsapi32.WTSSendMessageW
|
|
@ -41,8 +41,11 @@ var (
|
||||||
modcomctl32 = windows.NewLazySystemDLL("comctl32.dll")
|
modcomctl32 = windows.NewLazySystemDLL("comctl32.dll")
|
||||||
modcomdlg32 = windows.NewLazySystemDLL("comdlg32.dll")
|
modcomdlg32 = windows.NewLazySystemDLL("comdlg32.dll")
|
||||||
modgdi32 = windows.NewLazySystemDLL("gdi32.dll")
|
modgdi32 = windows.NewLazySystemDLL("gdi32.dll")
|
||||||
|
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||||
modole32 = windows.NewLazySystemDLL("ole32.dll")
|
modole32 = windows.NewLazySystemDLL("ole32.dll")
|
||||||
modshell32 = windows.NewLazySystemDLL("shell32.dll")
|
modshell32 = windows.NewLazySystemDLL("shell32.dll")
|
||||||
|
moduser32 = windows.NewLazySystemDLL("user32.dll")
|
||||||
|
modwtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll")
|
||||||
|
|
||||||
procInitCommonControlsEx = modcomctl32.NewProc("InitCommonControlsEx")
|
procInitCommonControlsEx = modcomctl32.NewProc("InitCommonControlsEx")
|
||||||
procChooseColorW = modcomdlg32.NewProc("ChooseColorW")
|
procChooseColorW = modcomdlg32.NewProc("ChooseColorW")
|
||||||
|
@ -52,12 +55,15 @@ var (
|
||||||
procCreateFontIndirectW = modgdi32.NewProc("CreateFontIndirectW")
|
procCreateFontIndirectW = modgdi32.NewProc("CreateFontIndirectW")
|
||||||
procDeleteObject = modgdi32.NewProc("DeleteObject")
|
procDeleteObject = modgdi32.NewProc("DeleteObject")
|
||||||
procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps")
|
procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps")
|
||||||
|
procRtlGetNtVersionNumbers = modntdll.NewProc("RtlGetNtVersionNumbers")
|
||||||
procCoCreateInstance = modole32.NewProc("CoCreateInstance")
|
procCoCreateInstance = modole32.NewProc("CoCreateInstance")
|
||||||
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
|
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
|
||||||
procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolder")
|
procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolder")
|
||||||
procSHCreateItemFromParsingName = modshell32.NewProc("SHCreateItemFromParsingName")
|
procSHCreateItemFromParsingName = modshell32.NewProc("SHCreateItemFromParsingName")
|
||||||
procSHGetPathFromIDListEx = modshell32.NewProc("SHGetPathFromIDListEx")
|
procSHGetPathFromIDListEx = modshell32.NewProc("SHGetPathFromIDListEx")
|
||||||
procShell_NotifyIconW = modshell32.NewProc("Shell_NotifyIconW")
|
procShell_NotifyIconW = modshell32.NewProc("Shell_NotifyIconW")
|
||||||
|
procGetDlgCtrlID = moduser32.NewProc("GetDlgCtrlID")
|
||||||
|
procWTSSendMessageW = modwtsapi32.NewProc("WTSSendMessageW")
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitCommonControlsEx(icc *INITCOMMONCONTROLSEX) (ok bool) {
|
func InitCommonControlsEx(icc *INITCOMMONCONTROLSEX) (ok bool) {
|
||||||
|
@ -102,16 +108,21 @@ func DeleteObject(o Handle) (ok bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDeviceCaps(dc Handle, index int) (cap uintptr) {
|
func GetDeviceCaps(dc Handle, index int) (cap int) {
|
||||||
r0, _, _ := syscall.Syscall(procGetDeviceCaps.Addr(), 2, uintptr(dc), uintptr(index), 0)
|
r0, _, _ := syscall.Syscall(procGetDeviceCaps.Addr(), 2, uintptr(dc), uintptr(index), 0)
|
||||||
cap = uintptr(r0)
|
cap = int(r0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func CoCreateInstance(clsid uintptr, unkOuter unsafe.Pointer, clsContext int32, iid uintptr, address unsafe.Pointer) (ret error) {
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func CoCreateInstance(clsid uintptr, unkOuter unsafe.Pointer, clsContext int32, iid uintptr, address unsafe.Pointer) (res error) {
|
||||||
r0, _, _ := syscall.Syscall6(procCoCreateInstance.Addr(), 5, uintptr(clsid), uintptr(unkOuter), uintptr(clsContext), uintptr(iid), uintptr(address), 0)
|
r0, _, _ := syscall.Syscall6(procCoCreateInstance.Addr(), 5, uintptr(clsid), uintptr(unkOuter), uintptr(clsContext), uintptr(iid), uintptr(address), 0)
|
||||||
if r0 != 0 {
|
if r0 != 0 {
|
||||||
ret = syscall.Errno(r0)
|
res = syscall.Errno(r0)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -127,19 +138,17 @@ func SHBrowseForFolder(bi *BROWSEINFO) (ptr uintptr) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func SHCreateItemFromParsingName(path *uint16, bc unsafe.Pointer, iid uintptr, item **IShellItem) (err error) {
|
func SHCreateItemFromParsingName(path *uint16, bc unsafe.Pointer, iid uintptr, item **IShellItem) (res error) {
|
||||||
r1, _, e1 := syscall.Syscall6(procSHCreateItemFromParsingName.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(bc), uintptr(iid), uintptr(unsafe.Pointer(item)), 0, 0)
|
r0, _, _ := syscall.Syscall6(procSHCreateItemFromParsingName.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(bc), uintptr(iid), uintptr(unsafe.Pointer(item)), 0, 0)
|
||||||
if r1 == 0 {
|
if r0 != 0 {
|
||||||
err = errnoErr(e1)
|
res = syscall.Errno(r0)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func SHGetPathFromIDListEx(ptr uintptr, path *uint16, pathLen int, opts int) (err error) {
|
func SHGetPathFromIDListEx(ptr uintptr, path *uint16, pathLen int, opts int) (ok bool) {
|
||||||
r1, _, e1 := syscall.Syscall6(procSHGetPathFromIDListEx.Addr(), 4, uintptr(ptr), uintptr(unsafe.Pointer(path)), uintptr(pathLen), uintptr(opts), 0, 0)
|
r0, _, _ := syscall.Syscall6(procSHGetPathFromIDListEx.Addr(), 4, uintptr(ptr), uintptr(unsafe.Pointer(path)), uintptr(pathLen), uintptr(opts), 0, 0)
|
||||||
if r1 == 0 {
|
ok = r0 != 0
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,3 +160,21 @@ func ShellNotifyIcon(message uint32, data *NOTIFYICONDATA) (ret int, err error)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetDlgCtrlID(wnd HWND) (ret int) {
|
||||||
|
r0, _, _ := syscall.Syscall(procGetDlgCtrlID.Addr(), 1, uintptr(wnd), 0, 0)
|
||||||
|
ret = int(r0)
|
||||||
|
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 {
|
||||||
|
_p0 = 1
|
||||||
|
}
|
||||||
|
r1, _, e1 := syscall.Syscall12(procWTSSendMessageW.Addr(), 10, uintptr(server), uintptr(sessionID), uintptr(unsafe.Pointer(title)), uintptr(titleLength), uintptr(unsafe.Pointer(message)), uintptr(messageLength), uintptr(style), uintptr(timeout), uintptr(unsafe.Pointer(response)), uintptr(_p0), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -8,10 +8,6 @@ import (
|
||||||
"github.com/ncruces/zenity/internal/win"
|
"github.com/ncruces/zenity/internal/win"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
getDlgCtrlID = user32.NewProc("GetDlgCtrlID")
|
|
||||||
)
|
|
||||||
|
|
||||||
func message(kind messageKind, text string, opts options) error {
|
func message(kind messageKind, text string, opts options) error {
|
||||||
var flags uint32
|
var flags uint32
|
||||||
|
|
||||||
|
@ -22,6 +18,8 @@ func message(kind messageKind, text string, opts options) error {
|
||||||
flags |= win.MB_OKCANCEL
|
flags |= win.MB_OKCANCEL
|
||||||
case opts.extraButton != nil:
|
case opts.extraButton != nil:
|
||||||
flags |= win.MB_YESNO
|
flags |= win.MB_YESNO
|
||||||
|
default:
|
||||||
|
opts.cancelLabel = opts.okLabel
|
||||||
}
|
}
|
||||||
|
|
||||||
switch opts.icon {
|
switch opts.icon {
|
||||||
|
@ -59,7 +57,7 @@ func message(kind messageKind, text string, opts options) error {
|
||||||
defer setup()()
|
defer setup()()
|
||||||
|
|
||||||
if opts.ctx != nil || opts.okLabel != nil || opts.cancelLabel != nil || opts.extraButton != nil || opts.icon != nil {
|
if opts.ctx != nil || opts.okLabel != nil || opts.cancelLabel != nil || opts.extraButton != nil || opts.icon != nil {
|
||||||
unhook, err := hookMessageDialog(kind, opts)
|
unhook, err := hookMessageDialog(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -89,7 +87,7 @@ func message(kind messageKind, text string, opts options) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func hookMessageDialog(kind messageKind, opts options) (unhook context.CancelFunc, err error) {
|
func hookMessageDialog(opts options) (unhook context.CancelFunc, err error) {
|
||||||
return hookDialog(opts.ctx, opts.windowIcon, nil, func(wnd uintptr) {
|
return hookDialog(opts.ctx, opts.windowIcon, nil, func(wnd uintptr) {
|
||||||
enumChildWindows.Call(wnd,
|
enumChildWindows.Call(wnd,
|
||||||
syscall.NewCallback(hookMessageDialogCallback),
|
syscall.NewCallback(hookMessageDialogCallback),
|
||||||
|
@ -97,8 +95,8 @@ func hookMessageDialog(kind messageKind, opts options) (unhook context.CancelFun
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func hookMessageDialogCallback(wnd uintptr, lparam *options) uintptr {
|
func hookMessageDialogCallback(wnd win.HWND, lparam *options) uintptr {
|
||||||
ctl, _, _ := getDlgCtrlID.Call(wnd)
|
ctl := win.GetDlgCtrlID(wnd)
|
||||||
|
|
||||||
var text *string
|
var text *string
|
||||||
switch ctl {
|
switch ctl {
|
||||||
|
@ -110,14 +108,14 @@ func hookMessageDialogCallback(wnd uintptr, lparam *options) uintptr {
|
||||||
text = lparam.extraButton
|
text = lparam.extraButton
|
||||||
}
|
}
|
||||||
if text != nil {
|
if text != nil {
|
||||||
setWindowText.Call(wnd, strptr(*text))
|
setWindowText.Call(uintptr(wnd), strptr(*text))
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctl == 20 /*IDC_STATIC_OK*/ {
|
if ctl == 20 /*IDC_STATIC_OK*/ {
|
||||||
icon := getIcon(lparam.icon)
|
icon := getIcon(lparam.icon)
|
||||||
if icon.handle != 0 {
|
if icon.handle != 0 {
|
||||||
defer icon.delete()
|
defer icon.delete()
|
||||||
sendMessage.Call(wnd, _STM_SETICON, icon.handle, 0)
|
sendMessage.Call(uintptr(wnd), _STM_SETICON, icon.handle, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1
|
return 1
|
||||||
|
|
|
@ -11,11 +11,6 @@ import (
|
||||||
"github.com/ncruces/zenity/internal/zenutil"
|
"github.com/ncruces/zenity/internal/zenutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
rtlGetNtVersionNumbers = ntdll.NewProc("RtlGetNtVersionNumbers")
|
|
||||||
wtsSendMessage = wtsapi32.NewProc("WTSSendMessageW")
|
|
||||||
)
|
|
||||||
|
|
||||||
func notify(text string, opts options) error {
|
func notify(text string, opts options) error {
|
||||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||||
return opts.ctx.Err()
|
return opts.ctx.Err()
|
||||||
|
@ -64,10 +59,7 @@ func notify(text string, opts options) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var major, minor, build uint32
|
var major, minor, build uint32
|
||||||
rtlGetNtVersionNumbers.Call(
|
win.RtlGetNtVersionNumbers(&major, &minor, &build)
|
||||||
uintptr(unsafe.Pointer(&major)),
|
|
||||||
uintptr(unsafe.Pointer(&minor)),
|
|
||||||
uintptr(unsafe.Pointer(&build)))
|
|
||||||
|
|
||||||
// On Windows 7 (6.1) and lower, wait up to 10 seconds to clean up.
|
// On Windows 7 (6.1) and lower, wait up to 10 seconds to clean up.
|
||||||
if major < 6 || major == 6 && minor < 2 {
|
if major < 6 || major == 6 && minor < 2 {
|
||||||
|
@ -86,7 +78,7 @@ func notify(text string, opts options) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func wtsMessage(text string, opts options) error {
|
func wtsMessage(text string, opts options) error {
|
||||||
var flags uintptr
|
var flags uint32
|
||||||
|
|
||||||
switch opts.icon {
|
switch opts.icon {
|
||||||
case ErrorIcon:
|
case ErrorIcon:
|
||||||
|
@ -113,15 +105,8 @@ func wtsMessage(text string, opts options) error {
|
||||||
ptitle := syscall.StringToUTF16(*title)
|
ptitle := syscall.StringToUTF16(*title)
|
||||||
|
|
||||||
var res uint32
|
var res uint32
|
||||||
s, _, err := wtsSendMessage.Call(
|
return win.WTSSendMessage(
|
||||||
0, // WTS_CURRENT_SERVER_HANDLE
|
win.WTS_CURRENT_SERVER_HANDLE, win.WTS_CURRENT_SESSION,
|
||||||
0xffffffff, // WTS_CURRENT_SESSION
|
&ptitle[0], 2*len(ptitle), &ptext[0], 2*len(ptext),
|
||||||
uintptr(unsafe.Pointer(&ptitle[0])), uintptr(2*len(ptitle)),
|
flags, timeout, &res, false)
|
||||||
uintptr(unsafe.Pointer(&ptext[0])), uintptr(2*len(ptext)),
|
|
||||||
flags, uintptr(timeout), uintptr(unsafe.Pointer(&res)), 0)
|
|
||||||
|
|
||||||
if s == 0 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||||
ntdll = windows.NewLazySystemDLL("ntdll.dll")
|
|
||||||
user32 = windows.NewLazySystemDLL("user32.dll")
|
user32 = windows.NewLazySystemDLL("user32.dll")
|
||||||
wtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll")
|
|
||||||
|
|
||||||
activateActCtx = kernel32.NewProc("ActivateActCtx")
|
activateActCtx = kernel32.NewProc("ActivateActCtx")
|
||||||
createActCtx = kernel32.NewProc("CreateActCtxW")
|
createActCtx = kernel32.NewProc("CreateActCtxW")
|
||||||
|
@ -261,7 +259,7 @@ func getDPI(wnd uintptr) dpi {
|
||||||
if wnd != 0 && getDpiForWindow.Find() == nil {
|
if wnd != 0 && getDpiForWindow.Find() == nil {
|
||||||
res, _, _ = getDpiForWindow.Call(wnd)
|
res, _, _ = getDpiForWindow.Call(wnd)
|
||||||
} else if dc, _, _ := getWindowDC.Call(wnd); dc != 0 {
|
} else if dc, _, _ := getWindowDC.Call(wnd); dc != 0 {
|
||||||
res = win.GetDeviceCaps(win.Handle(dc), win.LOGPIXELSY)
|
res = uintptr(win.GetDeviceCaps(win.Handle(dc), win.LOGPIXELSY))
|
||||||
releaseDC.Call(0, dc)
|
releaseDC.Call(0, dc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue