diff --git a/redo/sizing_windows.c b/redo/sizing_windows.c index 5589ddd..133cbcc 100644 --- a/redo/sizing_windows.c +++ b/redo/sizing_windows.c @@ -3,29 +3,34 @@ #include "winapi_windows.h" #include "_cgo_export.h" -HDC getDC(HWND hwnd) +BOOL baseUnitsCalculated = FALSE; +int baseX; +int baseY; + +/* called by newWindow() so we can calculate base units when we have a window */ +void calculateBaseUnits(HWND hwnd) { HDC dc; + HFONT prevFont; + TEXTMETRICW tm; + if (baseUnitsCalculated) + return; dc = GetDC(hwnd); if (dc == NULL) xpanic("error getting DC for preferred size calculations", GetLastError()); - /* TODO save for restoring later */ - if (SelectObject(dc, controlFont) == NULL) + prevFont = (HFONT) SelectObject(dc, controlFont); + if (prevFont == NULL) xpanic("error loading control font into device context for preferred size calculation", GetLastError()); - return dc; -} - -void releaseDC(HWND hwnd, HDC dc) -{ + if (GetTextMetricsW(dc, &tm) == 0) + xpanic("error getting text metrics for preferred size calculations", GetLastError()); + baseX = (int) tm.tmAveCharWidth; /* TODO not optimal; third reference below has better way */ + baseY = (int) tm.tmHeight; + if (SelectObject(dc, prevFont) != controlFont) + xpanic("error restoring previous font into device context after preferred size calculations", GetLastError()); if (ReleaseDC(hwnd, dc) == 0) xpanic("error releasing DC for preferred size calculations", GetLastError()); -} - -void getTextMetricsW(HDC dc, TEXTMETRICW *tm) -{ - if (GetTextMetricsW(dc, tm) == 0) - xpanic("error getting text metrics for preferred size calculations", GetLastError()); + baseUnitsCalculated = TRUE; } void moveWindow(HWND hwnd, int x, int y, int width, int height) diff --git a/redo/sizing_windows.go b/redo/sizing_windows.go index 429475b..d8f3246 100644 --- a/redo/sizing_windows.go +++ b/redo/sizing_windows.go @@ -21,20 +21,13 @@ const ( paddingDialogUnits = 4 ) -// only windows are containers, so only windows get beginResize() -func (w *window) beginResize() (d *sizing) { +func (c *container) beginResize() (d *sizing) { d = new(sizing) - dc := C.getDC(w.hwnd) - defer C.releaseDC(w.hwnd, dc) + d.baseX = int(C.baseX) + d.baseY = int(C.baseY) - var tm C.TEXTMETRICW - - C.getTextMetricsW(dc, &tm) - d.baseX = int(tm.tmAveCharWidth) // TODO not optimal; third reference below has better way - d.baseY = int(tm.tmHeight) - - if w.spaced { + if spaced { d.xmargin = int(C.MulDiv(marginDialogUnits, C.int(d.baseX), 4)) d.ymargin = int(C.MulDiv(marginDialogUnits, C.int(d.baseY), 8)) d.xpadding = int(C.MulDiv(paddingDialogUnits, C.int(d.baseX), 4)) diff --git a/redo/winapi_windows.h b/redo/winapi_windows.h index dcfd1fe..0129d37 100644 --- a/redo/winapi_windows.h +++ b/redo/winapi_windows.h @@ -63,9 +63,10 @@ extern HFONT statusbarFont; extern DWORD initWindows(char **); /* sizing_windows.c */ -extern HDC getDC(HWND); -extern void releaseDC(HWND, HDC); -extern void getTextMetricsW(HDC, TEXTMETRICW *); +extern BOOL baseUnitsCalculated; +extern int baseX; +extern int baseY; +extern void calculateBaseUnits(HWND); extern void moveWindow(HWND, int, int, int, int); /* window_windows.c */ diff --git a/redo/window_windows.c b/redo/window_windows.c index 2b1b12d..e848a89 100644 --- a/redo/window_windows.c +++ b/redo/window_windows.c @@ -73,6 +73,7 @@ HWND newWindow(LPCWSTR title, int width, int height, void *data) NULL, NULL, hInstance, data); if (hwnd == NULL) xpanic("Window creation failed", GetLastError()); + calculateBaseUnits(hwnd); return hwnd; } diff --git a/redo/window_windows.go b/redo/window_windows.go index 90b3e5e..2287039 100644 --- a/redo/window_windows.go +++ b/redo/window_windows.go @@ -96,7 +96,6 @@ func storeWindowHWND(data unsafe.Pointer, hwnd C.HWND) { //export windowResize func windowResize(data unsafe.Pointer, r *C.RECT) { w := (*window)(data) - w.container.d = w.beginResize() w.resize(int(r.right - r.left), int(r.bottom - r.top)) }