Button should send BM_SETSTATE message after it has changed its internal state
Dmitry Timoshkov
dmitry at baikal.ru
Thu Aug 26 08:43:25 CDT 2004
Hello,
this is a result of my bug hunting for a not existing capture bug.
An app I'm working on subclasses a button and relies on the fact
that on WM_LBUTTONDOWN message button sends BM_SETSTATE message *after*
it has changed its internal state.
I've written a test case for WM_LBUTTONDOWN/WM_LBUTTONUP messages
just in case.
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
Button should send BM_SETSTATE message after it has changed
its internal state.
diff -u cvs/hq/wine/controls/button.c wine/controls/button.c
--- cvs/hq/wine/controls/button.c 2004-08-23 13:33:05.000000000 +0900
+++ wine/controls/button.c 2004-08-26 22:02:00.000000000 +0900
@@ -256,8 +256,8 @@ static LRESULT WINAPI ButtonWndProc_comm
case WM_LBUTTONDOWN:
SetCapture( hWnd );
SetFocus( hWnd );
- SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 );
set_button_state( hWnd, get_button_state( hWnd ) | BUTTON_BTNPRESSED );
+ SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 );
break;
case WM_KEYUP:
diff -u cvs/hq/wine/dlls/user/tests/msg.c wine/dlls/user/tests/msg.c
--- cvs/hq/wine/dlls/user/tests/msg.c 2004-08-26 14:46:31.000000000 +0900
+++ wine/dlls/user/tests/msg.c 2004-08-26 21:58:11.000000000 +0900
@@ -1670,6 +1670,25 @@ static const struct message WmKillFocusS
{ WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
{ 0 }
};
+static const struct message WmLButtonDownSeq[] =
+{
+ { WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 },
+ { HCBT_SETFOCUS, hook },
+ { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
+ { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
+ { WM_CTLCOLORBTN, sent|defwinproc },
+ { BM_SETSTATE, sent|wparam|defwinproc, TRUE },
+ { WM_CTLCOLORBTN, sent|defwinproc },
+ { 0 }
+};
+static const struct message WmLButtonUpSeq[] =
+{
+ { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
+ { BM_SETSTATE, sent|wparam|defwinproc, FALSE },
+ { WM_CTLCOLORBTN, sent|defwinproc },
+ { WM_CAPTURECHANGED, sent|wparam|defwinproc, 0 },
+ { 0 }
+};
static WNDPROC old_button_proc;
@@ -1679,7 +1698,7 @@ static LRESULT CALLBACK button_hook_proc
LRESULT ret;
struct message msg;
- trace("%p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
+ trace("button: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
msg.message = message;
msg.flags = sent|wparam|lparam;
@@ -1688,6 +1707,9 @@ static LRESULT CALLBACK button_hook_proc
msg.lParam = lParam;
add_message(&msg);
+ if (message == BM_SETSTATE)
+ ok(GetCapture() == hwnd, "GetCapture() = %p\n", GetCapture());
+
defwndproc_counter++;
ret = CallWindowProcA(old_button_proc, hwnd, message, wParam, lParam);
defwndproc_counter--;
@@ -1754,6 +1776,20 @@ static void test_button_messages(void)
DestroyWindow(hwnd);
}
+
+ hwnd = CreateWindowExA(0, "my_button_class", "test", button[i].style | WS_POPUP | WS_VISIBLE,
+ 0, 0, 50, 14, 0, 0, 0, NULL);
+ ok(hwnd != 0, "Failed to create button window\n");
+
+ SetFocus(0);
+ flush_sequence();
+
+ SendMessageA(hwnd, WM_LBUTTONDOWN, 0, 0);
+ ok_sequence(WmLButtonDownSeq, "WM_LBUTTONDOWN on a button", FALSE);
+
+ SendMessageA(hwnd, WM_LBUTTONUP, 0, 0);
+ ok_sequence(WmLButtonUpSeq, "WM_LBUTTONDOWN on a button", FALSE);
+ DestroyWindow(hwnd);
}
/************* painting message test ********************/
More information about the wine-patches
mailing list