summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-07-21 21:34:52 -0400
committerPietro Gagliardi <[email protected]>2014-07-21 21:34:52 -0400
commit451536f6a59656f8695220be87f6de487d1b2ae6 (patch)
tree6134a3f7d33b5d3b2d519442300a6be0087b6d38
parentd57d2aa2de674039938080d78d9addf53dd6f3e0 (diff)
Mostly added Checkbox to the Windows backend; it doesn't show up right away and it crashes in WM_NCDESTROY...
-rw-r--r--redo/controls_windows.c50
-rw-r--r--redo/controls_windows.go47
-rw-r--r--redo/winapi_windows.h3
3 files changed, 97 insertions, 3 deletions
diff --git a/redo/controls_windows.c b/redo/controls_windows.c
index c660bd7..2c5934d 100644
--- a/redo/controls_windows.c
+++ b/redo/controls_windows.c
@@ -75,3 +75,53 @@ 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, buttonSubProc, 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);
+}
diff --git a/redo/controls_windows.go b/redo/controls_windows.go
index 84b5625..a4eae27 100644
--- a/redo/controls_windows.go
+++ b/redo/controls_windows.go
@@ -46,9 +46,9 @@ type button struct {
var buttonclass = toUTF16("BUTTON")
-func newButton(text string) *button {
+func startNewButton(text string, style C.DWORD) *button {
w := newWidget(buttonclass,
- C.BS_PUSHBUTTON | C.WS_TABSTOP,
+ style | C.WS_TABSTOP,
0)
C.setWindowText(w.hwnd, toUTF16(text))
C.controlSetControlFont(w.hwnd)
@@ -56,7 +56,12 @@ func newButton(text string) *button {
widgetbase: w,
clicked: newEvent(),
}
- C.setButtonSubclass(w.hwnd, unsafe.Pointer(b))
+ return b
+}
+
+func newButton(text string) *button {
+ b := startNewButton(text, C.BS_PUSHBUTTON)
+ C.setButtonSubclass(b.hwnd, unsafe.Pointer(b))
return b
}
@@ -78,3 +83,39 @@ func buttonClicked(data unsafe.Pointer) {
b.clicked.fire()
println("button clicked")
}
+
+type checkbox struct {
+ *button
+}
+
+func newCheckbox(text string) *checkbox {
+ c := &checkbox{
+ // don't use BS_AUTOCHECKBOX here because it creates problems when refocusing (see http://blogs.msdn.com/b/oldnewthing/archive/2014/05/22/10527522.aspx)
+ // we'll handle actually toggling the check state ourselves (see controls_windows.c)
+ button: startNewButton(text, C.BS_CHECKBOX),
+ }
+ C.setCheckboxSubclass(c.hwnd, unsafe.Pointer(c))
+ return c
+}
+
+func (c *checkbox) Checked() bool {
+ if C.checkboxChecked(c.hwnd) == C.FALSE {
+ return false
+ }
+ return true
+}
+
+func (c *checkbox) SetChecked(checked bool) {
+ if checked {
+ C.checkboxSetChecked(c.hwnd, C.TRUE)
+ return
+ }
+ C.checkboxSetChecked(c.hwnd, C.FALSE)
+}
+
+//export checkboxToggled
+func checkboxToggled(data unsafe.Pointer) {
+ c := (*checkbox)(data)
+ c.clicked.fire()
+ println("checkbox toggled")
+}
diff --git a/redo/winapi_windows.h b/redo/winapi_windows.h
index 6d7f548..d620879 100644
--- a/redo/winapi_windows.h
+++ b/redo/winapi_windows.h
@@ -43,6 +43,9 @@ extern void controlSetParent(HWND, HWND);
extern void controlSetControlFont(HWND);
extern LRESULT forwardCommand(HWND, UINT, WPARAM, LPARAM);
extern void setButtonSubclass(HWND, void *);
+extern void setCheckboxSubclass(HWND, void *);
+extern BOOL checkboxChecked(HWND);
+extern void checkboxSetChecked(HWND, BOOL);
/* init_windows.c */
extern HINSTANCE hInstance;