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 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: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
|
||||
|
|
|
@ -44,4 +44,4 @@ func (o *COMObject) Call(trap uintptr, a ...uintptr) (r1, r2 uintptr, lastErr er
|
|||
}
|
||||
|
||||
//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 SHCreateItemFromParsingName(path *uint16, bc unsafe.Pointer, iid uintptr, item **IShellItem) (err error) = shell32.SHCreateItemFromParsingName
|
||||
//sys SHGetPathFromIDListEx(ptr uintptr, path *uint16, pathLen int, opts int) (err error) = shell32.SHGetPathFromIDListEx
|
||||
//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) (ok bool) = shell32.SHGetPathFromIDListEx
|
||||
//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) {
|
||||
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 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")
|
||||
modcomdlg32 = windows.NewLazySystemDLL("comdlg32.dll")
|
||||
modgdi32 = windows.NewLazySystemDLL("gdi32.dll")
|
||||
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||
modole32 = windows.NewLazySystemDLL("ole32.dll")
|
||||
modshell32 = windows.NewLazySystemDLL("shell32.dll")
|
||||
moduser32 = windows.NewLazySystemDLL("user32.dll")
|
||||
modwtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll")
|
||||
|
||||
procInitCommonControlsEx = modcomctl32.NewProc("InitCommonControlsEx")
|
||||
procChooseColorW = modcomdlg32.NewProc("ChooseColorW")
|
||||
|
@ -52,12 +55,15 @@ var (
|
|||
procCreateFontIndirectW = modgdi32.NewProc("CreateFontIndirectW")
|
||||
procDeleteObject = modgdi32.NewProc("DeleteObject")
|
||||
procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps")
|
||||
procRtlGetNtVersionNumbers = modntdll.NewProc("RtlGetNtVersionNumbers")
|
||||
procCoCreateInstance = modole32.NewProc("CoCreateInstance")
|
||||
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
|
||||
procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolder")
|
||||
procSHCreateItemFromParsingName = modshell32.NewProc("SHCreateItemFromParsingName")
|
||||
procSHGetPathFromIDListEx = modshell32.NewProc("SHGetPathFromIDListEx")
|
||||
procShell_NotifyIconW = modshell32.NewProc("Shell_NotifyIconW")
|
||||
procGetDlgCtrlID = moduser32.NewProc("GetDlgCtrlID")
|
||||
procWTSSendMessageW = modwtsapi32.NewProc("WTSSendMessageW")
|
||||
)
|
||||
|
||||
func InitCommonControlsEx(icc *INITCOMMONCONTROLSEX) (ok bool) {
|
||||
|
@ -102,16 +108,21 @@ func DeleteObject(o Handle) (ok bool) {
|
|||
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)
|
||||
cap = uintptr(r0)
|
||||
cap = int(r0)
|
||||
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)
|
||||
if r0 != 0 {
|
||||
ret = syscall.Errno(r0)
|
||||
res = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -127,19 +138,17 @@ func SHBrowseForFolder(bi *BROWSEINFO) (ptr uintptr) {
|
|||
return
|
||||
}
|
||||
|
||||
func SHCreateItemFromParsingName(path *uint16, bc unsafe.Pointer, iid uintptr, item **IShellItem) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procSHCreateItemFromParsingName.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(bc), uintptr(iid), uintptr(unsafe.Pointer(item)), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
func SHCreateItemFromParsingName(path *uint16, bc unsafe.Pointer, iid uintptr, item **IShellItem) (res error) {
|
||||
r0, _, _ := syscall.Syscall6(procSHCreateItemFromParsingName.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(bc), uintptr(iid), uintptr(unsafe.Pointer(item)), 0, 0)
|
||||
if r0 != 0 {
|
||||
res = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SHGetPathFromIDListEx(ptr uintptr, path *uint16, pathLen int, opts int) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procSHGetPathFromIDListEx.Addr(), 4, uintptr(ptr), uintptr(unsafe.Pointer(path)), uintptr(pathLen), uintptr(opts), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
func SHGetPathFromIDListEx(ptr uintptr, path *uint16, pathLen int, opts int) (ok bool) {
|
||||
r0, _, _ := syscall.Syscall6(procSHGetPathFromIDListEx.Addr(), 4, uintptr(ptr), uintptr(unsafe.Pointer(path)), uintptr(pathLen), uintptr(opts), 0, 0)
|
||||
ok = r0 != 0
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -151,3 +160,21 @@ func ShellNotifyIcon(message uint32, data *NOTIFYICONDATA) (ret int, err error)
|
|||
}
|
||||
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"
|
||||
)
|
||||
|
||||
var (
|
||||
getDlgCtrlID = user32.NewProc("GetDlgCtrlID")
|
||||
)
|
||||
|
||||
func message(kind messageKind, text string, opts options) error {
|
||||
var flags uint32
|
||||
|
||||
|
@ -22,6 +18,8 @@ func message(kind messageKind, text string, opts options) error {
|
|||
flags |= win.MB_OKCANCEL
|
||||
case opts.extraButton != nil:
|
||||
flags |= win.MB_YESNO
|
||||
default:
|
||||
opts.cancelLabel = opts.okLabel
|
||||
}
|
||||
|
||||
switch opts.icon {
|
||||
|
@ -59,7 +57,7 @@ func message(kind messageKind, text string, opts options) error {
|
|||
defer setup()()
|
||||
|
||||
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 {
|
||||
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) {
|
||||
enumChildWindows.Call(wnd,
|
||||
syscall.NewCallback(hookMessageDialogCallback),
|
||||
|
@ -97,8 +95,8 @@ func hookMessageDialog(kind messageKind, opts options) (unhook context.CancelFun
|
|||
})
|
||||
}
|
||||
|
||||
func hookMessageDialogCallback(wnd uintptr, lparam *options) uintptr {
|
||||
ctl, _, _ := getDlgCtrlID.Call(wnd)
|
||||
func hookMessageDialogCallback(wnd win.HWND, lparam *options) uintptr {
|
||||
ctl := win.GetDlgCtrlID(wnd)
|
||||
|
||||
var text *string
|
||||
switch ctl {
|
||||
|
@ -110,14 +108,14 @@ func hookMessageDialogCallback(wnd uintptr, lparam *options) uintptr {
|
|||
text = lparam.extraButton
|
||||
}
|
||||
if text != nil {
|
||||
setWindowText.Call(wnd, strptr(*text))
|
||||
setWindowText.Call(uintptr(wnd), strptr(*text))
|
||||
}
|
||||
|
||||
if ctl == 20 /*IDC_STATIC_OK*/ {
|
||||
icon := getIcon(lparam.icon)
|
||||
if icon.handle != 0 {
|
||||
defer icon.delete()
|
||||
sendMessage.Call(wnd, _STM_SETICON, icon.handle, 0)
|
||||
sendMessage.Call(uintptr(wnd), _STM_SETICON, icon.handle, 0)
|
||||
}
|
||||
}
|
||||
return 1
|
||||
|
|
|
@ -11,11 +11,6 @@ import (
|
|||
"github.com/ncruces/zenity/internal/zenutil"
|
||||
)
|
||||
|
||||
var (
|
||||
rtlGetNtVersionNumbers = ntdll.NewProc("RtlGetNtVersionNumbers")
|
||||
wtsSendMessage = wtsapi32.NewProc("WTSSendMessageW")
|
||||
)
|
||||
|
||||
func notify(text string, opts options) error {
|
||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||
return opts.ctx.Err()
|
||||
|
@ -64,10 +59,7 @@ func notify(text string, opts options) error {
|
|||
}
|
||||
|
||||
var major, minor, build uint32
|
||||
rtlGetNtVersionNumbers.Call(
|
||||
uintptr(unsafe.Pointer(&major)),
|
||||
uintptr(unsafe.Pointer(&minor)),
|
||||
uintptr(unsafe.Pointer(&build)))
|
||||
win.RtlGetNtVersionNumbers(&major, &minor, &build)
|
||||
|
||||
// On Windows 7 (6.1) and lower, wait up to 10 seconds to clean up.
|
||||
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 {
|
||||
var flags uintptr
|
||||
var flags uint32
|
||||
|
||||
switch opts.icon {
|
||||
case ErrorIcon:
|
||||
|
@ -113,15 +105,8 @@ func wtsMessage(text string, opts options) error {
|
|||
ptitle := syscall.StringToUTF16(*title)
|
||||
|
||||
var res uint32
|
||||
s, _, err := wtsSendMessage.Call(
|
||||
0, // WTS_CURRENT_SERVER_HANDLE
|
||||
0xffffffff, // WTS_CURRENT_SESSION
|
||||
uintptr(unsafe.Pointer(&ptitle[0])), uintptr(2*len(ptitle)),
|
||||
uintptr(unsafe.Pointer(&ptext[0])), uintptr(2*len(ptext)),
|
||||
flags, uintptr(timeout), uintptr(unsafe.Pointer(&res)), 0)
|
||||
|
||||
if s == 0 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return win.WTSSendMessage(
|
||||
win.WTS_CURRENT_SERVER_HANDLE, win.WTS_CURRENT_SESSION,
|
||||
&ptitle[0], 2*len(ptitle), &ptext[0], 2*len(ptext),
|
||||
flags, timeout, &res, false)
|
||||
}
|
||||
|
|
|
@ -18,9 +18,7 @@ import (
|
|||
|
||||
var (
|
||||
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
ntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||
user32 = windows.NewLazySystemDLL("user32.dll")
|
||||
wtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll")
|
||||
|
||||
activateActCtx = kernel32.NewProc("ActivateActCtx")
|
||||
createActCtx = kernel32.NewProc("CreateActCtxW")
|
||||
|
@ -261,7 +259,7 @@ func getDPI(wnd uintptr) dpi {
|
|||
if wnd != 0 && getDpiForWindow.Find() == nil {
|
||||
res, _, _ = getDpiForWindow.Call(wnd)
|
||||
} 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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue