DPI awareness.
This commit is contained in:
parent
14ebdecd22
commit
bde480b495
1 changed files with 45 additions and 14 deletions
|
@ -48,7 +48,11 @@ var (
|
||||||
isDialogMessage = user32.NewProc("IsDialogMessageW")
|
isDialogMessage = user32.NewProc("IsDialogMessageW")
|
||||||
getSystemMetricsW = user32.NewProc("GetSystemMetrics")
|
getSystemMetricsW = user32.NewProc("GetSystemMetrics")
|
||||||
systemParametersInfoW = user32.NewProc("SystemParametersInfoW")
|
systemParametersInfoW = user32.NewProc("SystemParametersInfoW")
|
||||||
|
getWindowDC = user32.NewProc("GetWindowDC")
|
||||||
|
releaseDC = user32.NewProc("ReleaseDC")
|
||||||
|
getDpiForWindow = user32.NewProc("GetDpiForWindow")
|
||||||
|
|
||||||
|
getDeviceCaps = gdi32.NewProc("GetDeviceCaps")
|
||||||
createFontIndirectW = gdi32.NewProc("CreateFontIndirectW")
|
createFontIndirectW = gdi32.NewProc("CreateFontIndirectW")
|
||||||
|
|
||||||
getModuleHandleW = kernel32.NewProc("GetModuleHandleW")
|
getModuleHandleW = kernel32.NewProc("GetModuleHandleW")
|
||||||
|
@ -188,11 +192,35 @@ func getModuleHandle() (syscall.Handle, error) {
|
||||||
return syscall.Handle(ret), nil
|
return syscall.Handle(ret), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createWindow(exStyle uint64, className, windowName string, style uint64, x, y, width, height int64,
|
type dpi uintptr
|
||||||
|
|
||||||
|
func (d dpi) Scale(dim uintptr) uintptr {
|
||||||
|
return dim * uintptr(d) / 96 // USER_DEFAULT_SCREEN_DPI
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDPI(wnd uintptr) (dpi, error) {
|
||||||
|
var res uintptr = 96
|
||||||
|
|
||||||
|
if wnd != 0 && getDpiForWindow.Find() == nil {
|
||||||
|
res, _, _ = getDpiForWindow.Call(wnd)
|
||||||
|
} else {
|
||||||
|
dc, _, err := getWindowDC.Call(wnd)
|
||||||
|
if dc == 0 {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer releaseDC.Call(0, dc)
|
||||||
|
|
||||||
|
res, _, _ = getDeviceCaps.Call(dc, 90) // LOGPIXELSY
|
||||||
|
}
|
||||||
|
|
||||||
|
return dpi(res), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createWindow(exStyle uint64, className, windowName string, style, x, y, width, height uintptr,
|
||||||
parent, menu, instance syscall.Handle) (syscall.Handle, error) {
|
parent, menu, instance syscall.Handle) (syscall.Handle, error) {
|
||||||
ret, _, err := createWindowEx.Call(uintptr(exStyle), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(className))),
|
ret, _, err := createWindowEx.Call(uintptr(exStyle), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(className))),
|
||||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(windowName))), uintptr(style), uintptr(x), uintptr(y),
|
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(windowName))), uintptr(style), x, y,
|
||||||
uintptr(width), uintptr(height), uintptr(parent), uintptr(menu), uintptr(instance), uintptr(0))
|
width, height, uintptr(parent), uintptr(menu), uintptr(instance), uintptr(0))
|
||||||
|
|
||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -329,10 +357,9 @@ func messageLoop(hwnd uintptr) error {
|
||||||
translateMessage := translateMessage.Addr()
|
translateMessage := translateMessage.Addr()
|
||||||
dispatchMessage := dispatchMessage.Addr()
|
dispatchMessage := dispatchMessage.Addr()
|
||||||
|
|
||||||
var msg _MSG
|
|
||||||
var ptr = uintptr(unsafe.Pointer(&msg))
|
|
||||||
for {
|
for {
|
||||||
ret, _, err := syscall.Syscall6(getMessage, 4, ptr, 0, 0, 0, 0, 0)
|
var msg _MSG
|
||||||
|
ret, _, err := syscall.Syscall6(getMessage, 4, uintptr(unsafe.Pointer(&msg)), 0, 0, 0, 0, 0)
|
||||||
if int32(ret) == -1 {
|
if int32(ret) == -1 {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -340,10 +367,10 @@ func messageLoop(hwnd uintptr) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, _, _ = syscall.Syscall(isDialogMessage, 2, hwnd, ptr, 0)
|
ret, _, _ = syscall.Syscall(isDialogMessage, 2, hwnd, uintptr(unsafe.Pointer(&msg)), 0)
|
||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
syscall.Syscall(translateMessage, 1, ptr, 0, 0)
|
syscall.Syscall(translateMessage, 1, uintptr(unsafe.Pointer(&msg)), 0, 0)
|
||||||
syscall.Syscall(dispatchMessage, 1, ptr, 0, 0)
|
syscall.Syscall(dispatchMessage, 1, uintptr(unsafe.Pointer(&msg)), 0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,6 +407,7 @@ func editBox(title, text, defaultText, className string, password bool) (string,
|
||||||
notCancledOrClosed = false
|
notCancledOrClosed = false
|
||||||
destroyWindow(hwnd)
|
destroyWindow(hwnd)
|
||||||
}
|
}
|
||||||
|
case 0x2e0: // WM_DPICHANGED
|
||||||
default:
|
default:
|
||||||
ret := defWindowProc(hwnd, msg, wparam, lparam)
|
ret := defWindowProc(hwnd, msg, wparam, lparam)
|
||||||
return ret
|
return ret
|
||||||
|
@ -388,23 +416,26 @@ func editBox(title, text, defaultText, className string, password bool) (string,
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer setup()()
|
||||||
|
|
||||||
err = registerClass(className, instance, fn)
|
err = registerClass(className, instance, fn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return out, false, err
|
return out, false, err
|
||||||
}
|
}
|
||||||
defer unregisterClass(className, instance)
|
defer unregisterClass(className, instance)
|
||||||
|
|
||||||
hwnd, _ := createWindow(0, className, title, wsOverlappedWindow, swUseDefault, swUseDefault, 235, 140, 0, 0, instance)
|
dpi, err := getDPI(0)
|
||||||
hwndText, _ := createWindow(0, "STATIC", text, wsChild|wsVisible, 10, 10, 200, 16, hwnd, 0, instance)
|
hwnd, _ := createWindow(0, className, title, wsOverlappedWindow, swUseDefault, swUseDefault, dpi.Scale(235), dpi.Scale(140), 0, 0, instance)
|
||||||
|
hwndText, _ := createWindow(0, "STATIC", text, wsChild|wsVisible, dpi.Scale(10), dpi.Scale(10), dpi.Scale(200), dpi.Scale(16), hwnd, 0, instance)
|
||||||
|
|
||||||
flags := wsBorder | wsChild | wsVisible | wsGroup | wsTabStop | esAutoHScroll
|
flags := wsBorder | wsChild | wsVisible | wsGroup | wsTabStop | esAutoHScroll
|
||||||
if password {
|
if password {
|
||||||
flags |= esPassword
|
flags |= esPassword
|
||||||
}
|
}
|
||||||
hwndEdit, _ = createWindow(wsExClientEdge, "EDIT", defaultText, uint64(flags), 10, 30, 200, 24, hwnd, 0, instance)
|
hwndEdit, _ = createWindow(wsExClientEdge, "EDIT", defaultText, uintptr(flags), dpi.Scale(10), dpi.Scale(30), dpi.Scale(200), dpi.Scale(24), hwnd, 0, instance)
|
||||||
|
|
||||||
hwndOK, _ := createWindow(wsExClientEdge, "BUTTON", "OK", wsChild|wsVisible|bsPushButton|wsGroup|wsTabStop, 10, 65, 90, 24, hwnd, 100, instance)
|
hwndOK, _ := createWindow(wsExClientEdge, "BUTTON", "OK", wsChild|wsVisible|bsPushButton|wsGroup|wsTabStop, dpi.Scale(10), dpi.Scale(65), dpi.Scale(90), dpi.Scale(24), hwnd, 100, instance)
|
||||||
hwndCancel, _ := createWindow(wsExClientEdge, "BUTTON", "Cancel", wsChild|wsVisible|bsPushButton|wsGroup|wsTabStop, 120, 65, 90, 24, hwnd, 110, instance)
|
hwndCancel, _ := createWindow(wsExClientEdge, "BUTTON", "Cancel", wsChild|wsVisible|bsPushButton|wsGroup|wsTabStop, dpi.Scale(120), dpi.Scale(65), dpi.Scale(90), dpi.Scale(24), hwnd, 110, instance)
|
||||||
|
|
||||||
setWindowLong(hwnd, gwlStyle, getWindowLong(hwnd, gwlStyle)^wsMinimizeBox)
|
setWindowLong(hwnd, gwlStyle, getWindowLong(hwnd, gwlStyle)^wsMinimizeBox)
|
||||||
setWindowLong(hwnd, gwlStyle, getWindowLong(hwnd, gwlStyle)^wsMaximizeBox)
|
setWindowLong(hwnd, gwlStyle, getWindowLong(hwnd, gwlStyle)^wsMaximizeBox)
|
||||||
|
|
Loading…
Reference in a new issue