summaryrefslogtreecommitdiff
path: root/redo/basicctrls_windows.c
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-07-30 00:54:50 -0400
committerPietro Gagliardi <[email protected]>2014-07-30 00:54:50 -0400
commit5a51263adc6d2e8ee7ea0dac4d92a66755c07cb1 (patch)
tree0ee46724c8518419cce73cc2fdeda0ed3399357e /redo/basicctrls_windows.c
parent8b1756e95236202c3baccb4a4c56c40abb12b446 (diff)
Renamed the controls* and containers* files to basicctrls* and containerctrls*, respectively, in preparation for the widget hierarchy redo.
Diffstat (limited to 'redo/basicctrls_windows.c')
-rw-r--r--redo/basicctrls_windows.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/redo/basicctrls_windows.c b/redo/basicctrls_windows.c
new file mode 100644
index 0000000..8974bdb
--- /dev/null
+++ b/redo/basicctrls_windows.c
@@ -0,0 +1,138 @@
+/* 17 july 2014 */
+
+#include "winapi_windows.h"
+#include "_cgo_export.h"
+
+HWND newWidget(LPCWSTR class, DWORD style, DWORD extstyle)
+{
+ HWND hwnd;
+
+ hwnd = CreateWindowExW(
+ extstyle,
+ class, L"",
+ style | WS_CHILD | WS_VISIBLE,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ /*
+ the following has the consequence of making the control message-only at first
+ this shouldn't cause any problems... hopefully not
+ but see the msgwndproc() for caveat info
+ also don't use low control IDs as they will conflict with dialog boxes (IDCANCEL, etc.)
+ */
+ msgwin, (HMENU) 100, hInstance, NULL);
+ if (hwnd == NULL)
+ xpanic("error creating control", GetLastError());
+ return hwnd;
+}
+
+void controlSetParent(HWND control, HWND parent)
+{
+ if (SetParent(control, parent) == NULL)
+ xpanic("error changing control parent", GetLastError());
+}
+
+void controlSetControlFont(HWND which)
+{
+ SendMessageW(which, WM_SETFONT, (WPARAM) controlFont, TRUE);
+}
+
+/*
+all controls that have events receive the events themselves through subclasses
+to do this, all windows (including the message-only window; see http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q104069) forward WM_COMMAND to each control with this function
+*/
+LRESULT forwardCommand(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ HWND control = (HWND) lParam;
+
+ /* don't generate an event if the control (if there is one) is unparented (a child of the message-only window) */
+ if (control != NULL && IsChild(msgwin, control) == 0)
+ return SendMessageW(control, msgCOMMAND, wParam, lParam);
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+}
+
+LRESULT forwardNotify(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ NMHDR *nmhdr = (NMHDR *) lParam;
+ HWND control = nmhdr->hwndFrom;
+
+ /* don't generate an event if the control (if there is one) is unparented (a child of the message-only window) */
+ if (control != NULL && IsChild(msgwin, control) == 0)
+ return SendMessageW(control, msgNOTIFY, wParam, lParam);
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+}
+
+static LRESULT CALLBACK buttonSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR data)
+{
+ switch (uMsg) {
+ case msgCOMMAND:
+ if (HIWORD(wParam) == BN_CLICKED) {
+ buttonClicked((void *) data);
+ return 0;
+ }
+ return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
+ case WM_NCDESTROY:
+ if ((*fv_RemoveWindowSubclass)(hwnd, buttonSubProc, id) == FALSE)
+ xpanic("error removing Button subclass (which was for its own event handler)", GetLastError());
+ return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
+ default:
+ return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
+ }
+ xmissedmsg("Button", "buttonSubProc()", uMsg);
+ return 0; /* unreached */
+}
+
+void setButtonSubclass(HWND hwnd, void *data)
+{
+ if ((*fv_SetWindowSubclass)(hwnd, buttonSubProc, 0, (DWORD_PTR) data) == FALSE)
+ xpanic("error subclassing Button to give it its own event handler", GetLastError());
+}
+
+static LRESULT CALLBACK checkboxSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR data)
+{
+ switch (uMsg) {
+ case msgCOMMAND:
+ if (HIWORD(wParam) == BN_CLICKED) {
+ WPARAM check;
+
+ /* we didn't use BS_AUTOCHECKBOX (see controls_windows.go) so we have to manage the check state ourselves */
+ check = BST_CHECKED;
+ if (SendMessage(hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ check = BST_UNCHECKED;
+ SendMessage(hwnd, BM_SETCHECK, check, 0);
+ checkboxToggled((void *) data);
+ return 0;
+ }
+ return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
+ case WM_NCDESTROY:
+ if ((*fv_RemoveWindowSubclass)(hwnd, checkboxSubProc, id) == FALSE)
+ xpanic("error removing Checkbox subclass (which was for its own event handler)", GetLastError());
+ return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
+ default:
+ return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
+ }
+ xmissedmsg("Checkbox", "checkboxSubProc()", uMsg);
+ return 0; /* unreached */
+}
+
+void setCheckboxSubclass(HWND hwnd, void *data)
+{
+ if ((*fv_SetWindowSubclass)(hwnd, checkboxSubProc, 0, (DWORD_PTR) data) == FALSE)
+ xpanic("error subclassing Checkbox to give it its own event handler", GetLastError());
+}
+
+BOOL checkboxChecked(HWND hwnd)
+{
+ if (SendMessage(hwnd, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
+ return FALSE;
+ return TRUE;
+}
+
+void checkboxSetChecked(HWND hwnd, BOOL c)
+{
+ WPARAM check;
+
+ check = BST_CHECKED;
+ if (c == FALSE)
+ check = BST_UNCHECKED;
+ SendMessage(hwnd, BM_SETCHECK, check, 0);
+}