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
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"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
|
||||
if opts.title != nil {
|
||||
title = *opts.title
|
||||
|
@ -17,88 +15,14 @@ func entry(text string, opts options) (string, bool, error) {
|
|||
if opts.cancelLabel == nil {
|
||||
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()()
|
||||
|
||||
font := getFont()
|
||||
defer font.Delete()
|
||||
defWindowProc := defWindowProc.Addr()
|
||||
|
||||
var wnd, textCtl, editCtl uintptr
|
||||
var okBtn, cancelBtn, extraBtn uintptr
|
||||
|
||||
layout := func(dpi 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
|
||||
}
|
||||
|
||||
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"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
@ -37,6 +38,7 @@ var (
|
|||
|
||||
getMessage = user32.NewProc("GetMessageW")
|
||||
sendMessage = user32.NewProc("SendMessageW")
|
||||
postQuitMessage = user32.NewProc("PostQuitMessage")
|
||||
isDialogMessage = user32.NewProc("IsDialogMessageW")
|
||||
dispatchMessage = user32.NewProc("DispatchMessageW")
|
||||
translateMessage = user32.NewProc("TranslateMessage")
|
||||
|
@ -56,6 +58,16 @@ var (
|
|||
releaseDC = user32.NewProc("ReleaseDC")
|
||||
getWindowDC = user32.NewProc("GetWindowDC")
|
||||
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 {
|
||||
|
@ -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
|
||||
func messageLoop(wnd uintptr) error {
|
||||
getMessage := getMessage.Addr()
|
||||
|
@ -332,6 +378,22 @@ 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://github.com/wine-mirror/wine/blob/master/include/unknwn.idl
|
||||
|
||||
type _IUnknownVtbl struct {
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
package zenity
|
||||
|
||||
func init() {
|
||||
user32.NewProc("SetProcessDPIAware").Call()
|
||||
}
|
Loading…
Reference in a new issue