From 07c791331c507334f33fececbfeb68b97c89a44d Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Mon, 10 Feb 2014 20:48:08 -0500 Subject: [PATCH] Improved program appearance by setting the correct font, colors, and other styles. --- common.go | 3 +++ main.go | 22 ++++++++++++++-- stdfont.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ windows.go | 22 ++++++++++++++++ 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 stdfont.go diff --git a/common.go b/common.go index 51ebf6f..79d6fc9 100644 --- a/common.go +++ b/common.go @@ -12,6 +12,7 @@ import ( var ( user32 = syscall.NewLazyDLL("user32.dll") kernel32 = syscall.NewLazyDLL("kernel32.dll") + gdi32 = syscall.NewLazyDLL("gdi32.dll") ) type HANDLE uintptr @@ -21,6 +22,8 @@ type HMENU HANDLE const ( NULL = 0 + FALSE = 0 // from windef.h + TRUE = 1 // from windef.h ) type ATOM uint16 diff --git a/main.go b/main.go index 9a425b6..7129a7e 100644 --- a/main.go +++ b/main.go @@ -106,6 +106,14 @@ func wndProc(hwnd HWND, msg uint32, wParam WPARAM, lParam LPARAM) LRESULT { panic("unreachable") } +func setFontAll(hwnd HWND, lParam LPARAM) (cont bool) { + _, err := SendMessage(hwnd, WM_SETFONT, WPARAM(lParam), LPARAM(TRUE)) + if err != nil { + fatalf("error setting window font: %v", err) + } + return true +} + const className = "mainwin" func main() { @@ -119,6 +127,10 @@ func main() { if err != nil { fatalf("error getting WinMain nCmdShow: %v", err) } + font, err := getStandardWindowFont() + if err != nil { + fatalf("error getting standard window font: %v", err) + } icon, err := LoadIcon_ResourceID(NULL, IDI_APPLICATION) if err != nil { @@ -135,7 +147,7 @@ func main() { HInstance: hInstance, HIcon: icon, HCursor: cursor, - HbrBackground: HBRUSH(COLOR_WINDOW + 1), + HbrBackground: HBRUSH(COLOR_BTNFACE + 1), } _, err = RegisterClass(wc) if err != nil { @@ -143,7 +155,7 @@ func main() { } hwnd, err := CreateWindowEx( - WS_EX_OVERLAPPEDWINDOW, + 0, className, "Main Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, @@ -249,6 +261,12 @@ func main() { fatalf("error creating checkbox: %v", err) } + setFontAll(hwnd, LPARAM(font)) + err = EnumChildWindows(hwnd, setFontAll, LPARAM(font)) + if err != nil { + fatalf("error setting font on controls: %v", err) + } + _, err = ShowWindow(hwnd, nCmdShow) if err != nil { fatalf("error showing window: %v", err) diff --git a/stdfont.go b/stdfont.go new file mode 100644 index 0000000..276b0ed --- /dev/null +++ b/stdfont.go @@ -0,0 +1,73 @@ +// 10 february 2014 +package main + +import ( +// "syscall" + "unsafe" +) + +const ( + SPI_GETNONCLIENTMETRICS = 0x0029 + LF_FACESIZE = 32 // from wingdi.h +) + +type LOGFONT struct { + lfHeight int32 + lfWidth int32 + lfEscapement int32 + lfOrientation int32 + lfWeight int32 + lfItalic byte + lfUnderline byte + lfStrikeOut byte + lfCharSet byte + lfOutPrecision byte + lfClipPrecision byte + lfQuality byte + lfPitchAndFamily byte + lfFaceName [LF_FACESIZE]uint16 +} + +type NONCLIENTMETRICS struct { + cbSize uint32 + iBorderWidth int + iScrollWidth int + iScrollHeight int + iCaptionWidth int + iCaptionHeight int + lfCaptionFont LOGFONT + iSmCaptionWidth int + iSmCaptionHeight int + lfSmCaptionFont LOGFONT + iMenuWidth int + iMenuHeight int + lfMenuFont LOGFONT + lfStatusFont LOGFONT + lfMessageFont LOGFONT +} + +var ( + systemParametersInfo = user32.NewProc("SystemParametersInfoW") + createFontIndirect = gdi32.NewProc("CreateFontIndirectW") +) + +// TODO adorn errors with which step failed? +func getStandardWindowFont() (hfont HANDLE, err error) { + var ncm NONCLIENTMETRICS + + ncm.cbSize = uint32(unsafe.Sizeof(ncm)) + r1, _, err := systemParametersInfo.Call( + uintptr(SPI_GETNONCLIENTMETRICS), + uintptr(unsafe.Sizeof(ncm)), + uintptr(unsafe.Pointer(&ncm)), + 0) + if r1 == 0 { // failure + return NULL, err + } + // TODO does this specify an error? + r1, _, err = createFontIndirect.Call(uintptr(unsafe.Pointer(&ncm.lfMessageFont))) + if r1 == 0 { // failure + return NULL, err + } + return HANDLE(r1), nil +} diff --git a/windows.go b/windows.go index 6f0f4c1..de6fd6f 100644 --- a/windows.go +++ b/windows.go @@ -134,6 +134,7 @@ const ( var ( createWindowEx = user32.NewProc("CreateWindowExW") destroyWindow = user32.NewProc("DestroyWindow") + enumChildWindows = user32.NewProc("EnumChildWindows") showWindow = user32.NewProc("ShowWindow") ) @@ -166,6 +167,27 @@ func DestroyWindow(hWnd HWND) (err error) { return nil } +type WNDENUMPROC func(hwnd HWND, lParam LPARAM) (cont bool) +type _WNDENUMPROC func(hwnd HWND, lParam LPARAM) int + +func enumChildProc(p WNDENUMPROC) _WNDENUMPROC { + return func(hwnd HWND, lParam LPARAM) int { + if p(hwnd, lParam) { + return TRUE + } + return FALSE + } +} + +// TODO figure out how to handle errors +func EnumChildWindows(hWndParent HWND, lpEnumFunc WNDENUMPROC, lParam LPARAM) (err error) { + enumChildWindows.Call( + uintptr(hWndParent), + syscall.NewCallback(enumChildProc(lpEnumFunc)), + uintptr(lParam)) + return nil +} + // TODO figure out how to handle errors func ShowWindow(hWnd HWND, nCmdShow int) (previouslyVisible bool, err error) { r1, _, _ := showWindow.Call(