summaryrefslogtreecommitdiff
path: root/container_windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'container_windows.c')
-rw-r--r--container_windows.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/container_windows.c b/container_windows.c
new file mode 100644
index 0000000..a95818d
--- /dev/null
+++ b/container_windows.c
@@ -0,0 +1,96 @@
+// 17 july 2014
+
+#include "winapi_windows.h"
+#include "_cgo_export.h"
+
+/*
+This could all just be part of Window, but doing so just makes things complex.
+In this case, I chose to waste a window handle rather than keep things super complex.
+If this is seriously an issue in the future, I can roll it back.
+*/
+
+#define containerclass L"gouicontainer"
+
+static LRESULT CALLBACK containerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ void *data;
+ RECT r;
+ LRESULT lResult;
+
+ data = getWindowData(hwnd, uMsg, wParam, lParam, &lResult, storeContainerHWND);
+ if (data == NULL)
+ return lResult;
+ if (sharedWndProc(hwnd, uMsg, wParam, lParam, &lResult))
+ return lResult;
+ switch (uMsg) {
+ case WM_SIZE:
+ if (GetClientRect(hwnd, &r) == 0)
+ xpanic("error getting client rect for Window in WM_SIZE", GetLastError());
+ containerResize(data, &r);
+ return 0;
+ default:
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+ }
+ xmissedmsg("container", "containerWndProc()", uMsg);
+ return 0; // unreached
+}
+
+DWORD makeContainerWindowClass(char **errmsg)
+{
+ WNDCLASSW wc;
+
+ ZeroMemory(&wc, sizeof (WNDCLASSW));
+ wc.lpfnWndProc = containerWndProc;
+ wc.hInstance = hInstance;
+ wc.hIcon = hDefaultIcon;
+ wc.hCursor = hArrowCursor;
+ wc.hbrBackground = NULL;//(HBRUSH) (COLOR_BTNFACE + 1);
+ wc.lpszClassName = containerclass;
+ if (RegisterClassW(&wc) == 0) {
+ *errmsg = "error registering container window class";
+ return GetLastError();
+ }
+ return 0;
+}
+
+HWND newContainer(void *data)
+{
+ HWND hwnd;
+
+ hwnd = CreateWindowExW(
+ WS_EX_CONTROLPARENT | WS_EX_TRANSPARENT,
+ containerclass, L"",
+ WS_CHILD | WS_VISIBLE,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 100, 100,
+ msgwin, NULL, hInstance, data);
+ if (hwnd == NULL)
+ xpanic("container creation failed", GetLastError());
+ return hwnd;
+}
+
+void calculateBaseUnits(HWND hwnd, int *baseX, int *baseY, LONG *internalLeading)
+{
+ HDC dc;
+ HFONT prevFont;
+ TEXTMETRICW tm;
+ SIZE size;
+
+ dc = GetDC(hwnd);
+ if (dc == NULL)
+ xpanic("error getting DC for preferred size calculations", GetLastError());
+ prevFont = (HFONT) SelectObject(dc, controlFont);
+ if (prevFont == NULL)
+ xpanic("error loading control font into device context for preferred size calculation", GetLastError());
+ if (GetTextMetricsW(dc, &tm) == 0)
+ xpanic("error getting text metrics for preferred size calculations", GetLastError());
+ if (GetTextExtentPoint32W(dc, L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &size) == 0)
+ xpanic("error getting text extent point for preferred size calculations", GetLastError());
+ *baseX = (int) ((size.cx / 26 + 1) / 2);
+ *baseY = (int) tm.tmHeight;
+ *internalLeading = tm.tmInternalLeading;
+ 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());
+}