Refactor (windows).
This commit is contained in:
parent
a16177f604
commit
1ca281d701
4 changed files with 73 additions and 86 deletions
|
@ -1,12 +1,10 @@
|
||||||
package zenity
|
package zenity
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func entry(text string, opts options) (string, bool, error) {
|
func entry(text string, opts options) (out string, ok bool, err error) {
|
||||||
var title string
|
var title string
|
||||||
if opts.title != nil {
|
if opts.title != nil {
|
||||||
title = *opts.title
|
title = *opts.title
|
||||||
|
@ -17,88 +15,14 @@ func entry(text string, opts options) (string, bool, error) {
|
||||||
if opts.cancelLabel == nil {
|
if opts.cancelLabel == nil {
|
||||||
opts.cancelLabel = stringPtr("Cancel")
|
opts.cancelLabel = stringPtr("Cancel")
|
||||||
}
|
}
|
||||||
return editBox(title, text, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func password(opts options) (string, string, bool, error) {
|
|
||||||
opts.hideText = true
|
|
||||||
pass, ok, err := entry("Password:", opts)
|
|
||||||
return "", pass, ok, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
registerClassEx = user32.NewProc("RegisterClassExW")
|
|
||||||
unregisterClass = user32.NewProc("UnregisterClassW")
|
|
||||||
createWindowEx = user32.NewProc("CreateWindowExW")
|
|
||||||
destroyWindow = user32.NewProc("DestroyWindow")
|
|
||||||
postQuitMessage = user32.NewProc("PostQuitMessage")
|
|
||||||
defWindowProc = user32.NewProc("DefWindowProcW")
|
|
||||||
getWindowRect = user32.NewProc("GetWindowRect")
|
|
||||||
setWindowPos = user32.NewProc("SetWindowPos")
|
|
||||||
setFocus = user32.NewProc("SetFocus")
|
|
||||||
showWindow = user32.NewProc("ShowWindow")
|
|
||||||
getSystemMetrics = user32.NewProc("GetSystemMetrics")
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
func getWindowString(wnd uintptr) string {
|
|
||||||
len, _, _ := getWindowTextLength.Call(wnd)
|
|
||||||
buf := make([]uint16, len+1)
|
|
||||||
getWindowText.Call(wnd, uintptr(unsafe.Pointer(&buf[0])), len+1)
|
|
||||||
return syscall.UTF16ToString(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func centerWindow(wnd uintptr) {
|
|
||||||
getMetric := func(i uintptr) int32 {
|
|
||||||
ret, _, _ := getSystemMetrics.Call(i)
|
|
||||||
return int32(ret)
|
|
||||||
}
|
|
||||||
|
|
||||||
var rect _RECT
|
|
||||||
getWindowRect.Call(wnd, uintptr(unsafe.Pointer(&rect)))
|
|
||||||
x := (getMetric(0 /* SM_CXSCREEN */) - (rect.right - rect.left)) / 2
|
|
||||||
y := (getMetric(1 /* SM_CYSCREEN */) - (rect.bottom - rect.top)) / 2
|
|
||||||
setWindowPos.Call(wnd, 0, uintptr(x), uintptr(y), 0, 0, 0x5) // SWP_NOZORDER|SWP_NOSIZE
|
|
||||||
}
|
|
||||||
|
|
||||||
func registerClass(instance, proc uintptr) (uintptr, error) {
|
|
||||||
name := "WC_" + strconv.FormatUint(uint64(proc), 16)
|
|
||||||
|
|
||||||
var wcx _WNDCLASSEX
|
|
||||||
wcx.Size = uint32(unsafe.Sizeof(wcx))
|
|
||||||
wcx.WndProc = proc
|
|
||||||
wcx.Instance = instance
|
|
||||||
wcx.Background = 5 // COLOR_WINDOW
|
|
||||||
wcx.ClassName = syscall.StringToUTF16Ptr(name)
|
|
||||||
|
|
||||||
ret, _, err := registerClassEx.Call(uintptr(unsafe.Pointer(&wcx)))
|
|
||||||
return ret, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func editBox(title, text string, opts options) (out string, ok bool, err error) {
|
|
||||||
var wnd, textCtl, editCtl uintptr
|
|
||||||
var okBtn, cancelBtn, extraBtn uintptr
|
|
||||||
defWindowProc := defWindowProc.Addr()
|
|
||||||
|
|
||||||
defer setup()()
|
defer setup()()
|
||||||
|
|
||||||
font := getFont()
|
font := getFont()
|
||||||
defer font.Delete()
|
defer font.Delete()
|
||||||
|
defWindowProc := defWindowProc.Addr()
|
||||||
|
|
||||||
|
var wnd, textCtl, editCtl uintptr
|
||||||
|
var okBtn, cancelBtn, extraBtn uintptr
|
||||||
|
|
||||||
layout := func(dpi dpi) {
|
layout := func(dpi dpi) {
|
||||||
hfont := font.ForDPI(dpi)
|
hfont := font.ForDPI(dpi)
|
||||||
|
@ -232,3 +156,9 @@ func editBox(title, text string, opts options) (out string, ok bool, err error)
|
||||||
}
|
}
|
||||||
return out, ok, err
|
return out, ok, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func password(opts options) (string, string, bool, error) {
|
||||||
|
opts.hideText = true
|
||||||
|
str, ok, err := entry("Password:", opts)
|
||||||
|
return "", str, ok, err
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strconv"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
@ -37,6 +38,7 @@ var (
|
||||||
|
|
||||||
getMessage = user32.NewProc("GetMessageW")
|
getMessage = user32.NewProc("GetMessageW")
|
||||||
sendMessage = user32.NewProc("SendMessageW")
|
sendMessage = user32.NewProc("SendMessageW")
|
||||||
|
postQuitMessage = user32.NewProc("PostQuitMessage")
|
||||||
isDialogMessage = user32.NewProc("IsDialogMessageW")
|
isDialogMessage = user32.NewProc("IsDialogMessageW")
|
||||||
dispatchMessage = user32.NewProc("DispatchMessageW")
|
dispatchMessage = user32.NewProc("DispatchMessageW")
|
||||||
translateMessage = user32.NewProc("TranslateMessage")
|
translateMessage = user32.NewProc("TranslateMessage")
|
||||||
|
@ -56,6 +58,16 @@ var (
|
||||||
releaseDC = user32.NewProc("ReleaseDC")
|
releaseDC = user32.NewProc("ReleaseDC")
|
||||||
getWindowDC = user32.NewProc("GetWindowDC")
|
getWindowDC = user32.NewProc("GetWindowDC")
|
||||||
systemParametersInfo = user32.NewProc("SystemParametersInfoW")
|
systemParametersInfo = user32.NewProc("SystemParametersInfoW")
|
||||||
|
setWindowPos = user32.NewProc("SetWindowPos")
|
||||||
|
getWindowRect = user32.NewProc("GetWindowRect")
|
||||||
|
getSystemMetrics = user32.NewProc("GetSystemMetrics")
|
||||||
|
unregisterClass = user32.NewProc("UnregisterClassW")
|
||||||
|
registerClassEx = user32.NewProc("RegisterClassExW")
|
||||||
|
destroyWindow = user32.NewProc("DestroyWindow")
|
||||||
|
createWindowEx = user32.NewProc("CreateWindowExW")
|
||||||
|
showWindow = user32.NewProc("ShowWindow")
|
||||||
|
setFocus = user32.NewProc("SetFocus")
|
||||||
|
defWindowProc = user32.NewProc("DefWindowProcW")
|
||||||
)
|
)
|
||||||
|
|
||||||
func intptr(i int64) uintptr {
|
func intptr(i int64) uintptr {
|
||||||
|
@ -238,6 +250,40 @@ func (f *font) Delete() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func centerWindow(wnd uintptr) {
|
||||||
|
getMetric := func(i uintptr) int32 {
|
||||||
|
ret, _, _ := getSystemMetrics.Call(i)
|
||||||
|
return int32(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
var rect _RECT
|
||||||
|
getWindowRect.Call(wnd, uintptr(unsafe.Pointer(&rect)))
|
||||||
|
x := (getMetric(0 /* SM_CXSCREEN */) - (rect.right - rect.left)) / 2
|
||||||
|
y := (getMetric(1 /* SM_CYSCREEN */) - (rect.bottom - rect.top)) / 2
|
||||||
|
setWindowPos.Call(wnd, 0, uintptr(x), uintptr(y), 0, 0, 0x5) // SWP_NOZORDER|SWP_NOSIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
func getWindowString(wnd uintptr) string {
|
||||||
|
len, _, _ := getWindowTextLength.Call(wnd)
|
||||||
|
buf := make([]uint16, len+1)
|
||||||
|
getWindowText.Call(wnd, uintptr(unsafe.Pointer(&buf[0])), len+1)
|
||||||
|
return syscall.UTF16ToString(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerClass(instance, proc uintptr) (uintptr, error) {
|
||||||
|
name := "WC_" + strconv.FormatUint(uint64(proc), 16)
|
||||||
|
|
||||||
|
var wcx _WNDCLASSEX
|
||||||
|
wcx.Size = uint32(unsafe.Sizeof(wcx))
|
||||||
|
wcx.WndProc = proc
|
||||||
|
wcx.Instance = instance
|
||||||
|
wcx.Background = 5 // COLOR_WINDOW
|
||||||
|
wcx.ClassName = syscall.StringToUTF16Ptr(name)
|
||||||
|
|
||||||
|
ret, _, err := registerClassEx.Call(uintptr(unsafe.Pointer(&wcx)))
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/winmsg/using-messages-and-message-queues
|
// https://docs.microsoft.com/en-us/windows/win32/winmsg/using-messages-and-message-queues
|
||||||
func messageLoop(wnd uintptr) error {
|
func messageLoop(wnd uintptr) error {
|
||||||
getMessage := getMessage.Addr()
|
getMessage := getMessage.Addr()
|
||||||
|
@ -332,6 +378,22 @@ type _RECT struct {
|
||||||
bottom int32
|
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://github.com/wine-mirror/wine/blob/master/include/unknwn.idl
|
// https://github.com/wine-mirror/wine/blob/master/include/unknwn.idl
|
||||||
|
|
||||||
type _IUnknownVtbl struct {
|
type _IUnknownVtbl struct {
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
package zenity
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
user32.NewProc("SetProcessDPIAware").Call()
|
|
||||||
}
|
|
Loading…
Reference in a new issue