Mostly added Checkbox to the Windows backend; it doesn't show up right away and it crashes in WM_NCDESTROY...

This commit is contained in:
Pietro Gagliardi 2014-07-21 21:34:52 -04:00
parent d57d2aa2de
commit 451536f6a5
3 changed files with 97 additions and 3 deletions

View File

@ -75,3 +75,53 @@ void setButtonSubclass(HWND hwnd, void *data)
if ((*fv_SetWindowSubclass)(hwnd, buttonSubProc, 0, (DWORD_PTR) data) == FALSE) if ((*fv_SetWindowSubclass)(hwnd, buttonSubProc, 0, (DWORD_PTR) data) == FALSE)
xpanic("error subclassing Button to give it its own event handler", GetLastError()); 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);
}

View File

@ -46,9 +46,9 @@ type button struct {
var buttonclass = toUTF16("BUTTON") var buttonclass = toUTF16("BUTTON")
func newButton(text string) *button { func startNewButton(text string, style C.DWORD) *button {
w := newWidget(buttonclass, w := newWidget(buttonclass,
C.BS_PUSHBUTTON | C.WS_TABSTOP, style | C.WS_TABSTOP,
0) 0)
C.setWindowText(w.hwnd, toUTF16(text)) C.setWindowText(w.hwnd, toUTF16(text))
C.controlSetControlFont(w.hwnd) C.controlSetControlFont(w.hwnd)
@ -56,7 +56,12 @@ func newButton(text string) *button {
widgetbase: w, widgetbase: w,
clicked: newEvent(), 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 return b
} }
@ -78,3 +83,39 @@ func buttonClicked(data unsafe.Pointer) {
b.clicked.fire() b.clicked.fire()
println("button clicked") 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")
}

View File

@ -43,6 +43,9 @@ extern void controlSetParent(HWND, HWND);
extern void controlSetControlFont(HWND); extern void controlSetControlFont(HWND);
extern LRESULT forwardCommand(HWND, UINT, WPARAM, LPARAM); extern LRESULT forwardCommand(HWND, UINT, WPARAM, LPARAM);
extern void setButtonSubclass(HWND, void *); extern void setButtonSubclass(HWND, void *);
extern void setCheckboxSubclass(HWND, void *);
extern BOOL checkboxChecked(HWND);
extern void checkboxSetChecked(HWND, BOOL);
/* init_windows.c */ /* init_windows.c */
extern HINSTANCE hInstance; extern HINSTANCE hInstance;