@@ -13061,6 +13061,82 @@ static void test_shell_tray(void)
1306113061 DestroyWindow(hwnd);
1306213062}
1306313063
13064+ static int wm_mousemove_count;
13065+ static BOOL do_release_capture;
13066+
13067+ static LRESULT WINAPI test_ReleaseCapture_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
13068+ {
13069+ if (msg == WM_MOUSEMOVE)
13070+ {
13071+ wm_mousemove_count++;
13072+ if (wm_mousemove_count >= 100)
13073+ return 1;
13074+
13075+ if (do_release_capture)
13076+ ReleaseCapture();
13077+ return 0;
13078+ }
13079+ return DefWindowProcA(hwnd, msg, wp, lp);
13080+ }
13081+
13082+ static void test_ReleaseCapture(void)
13083+ {
13084+ WNDCLASSA cls = {0};
13085+ ATOM atom;
13086+ HWND hwnd;
13087+ POINT pt;
13088+ BOOL ret;
13089+
13090+ cls.lpfnWndProc = test_ReleaseCapture_proc;
13091+ cls.hInstance = GetModuleHandleA(0);
13092+ cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
13093+ cls.hbrBackground = GetStockObject(BLACK_BRUSH);
13094+ cls.lpszClassName = "test_ReleaseCapture_class";
13095+ atom = RegisterClassA(&cls);
13096+ ok(!!atom, "RegisterClassA failed, error %#lx.\n", GetLastError());
13097+
13098+ hwnd = CreateWindowExA(WS_EX_TOPMOST, cls.lpszClassName, "", WS_POPUP | WS_VISIBLE, 100, 100,
13099+ 100, 100, NULL, NULL, 0, NULL);
13100+ ok(!!hwnd, "CreateWindowA failed, error %#lx.\n", GetLastError());
13101+ ret = SetForegroundWindow(hwnd);
13102+ ok(ret, "SetForegroundWindow failed, error %#lx.\n", GetLastError());
13103+ GetCursorPos(&pt);
13104+ ret = SetCursorPos(150, 150);
13105+ ok(ret, "SetCursorPos failed, error %#lx.\n", GetLastError());
13106+ flush_events(TRUE);
13107+
13108+ /* Test a Wine bug that WM_MOUSEMOVE is post too many times when calling ReleaseCapture() during
13109+ * handling WM_MOUSEMOVE and the cursor is on the window */
13110+ do_release_capture = TRUE;
13111+ ret = ReleaseCapture();
13112+ ok(ret, "ReleaseCapture failed, error %#lx.\n", GetLastError());
13113+ flush_events(TRUE);
13114+ do_release_capture = FALSE;
13115+ todo_wine
13116+ ok(wm_mousemove_count < 10, "Got too many WM_MOUSEMOVE.\n");
13117+
13118+ /* Test that ReleaseCapture() should send a WM_MOUSEMOVE if a window is captured */
13119+ SetCapture(hwnd);
13120+ wm_mousemove_count = 0;
13121+ ret = ReleaseCapture();
13122+ ok(ret, "ReleaseCapture failed, error %#lx.\n", GetLastError());
13123+ flush_events(TRUE);
13124+ ok(wm_mousemove_count == 1, "Got no WM_MOUSEMOVE.\n");
13125+
13126+ /* Test that ReleaseCapture() shouldn't send WM_MOUSEMOVE if no window is captured */
13127+ wm_mousemove_count = 0;
13128+ ret = ReleaseCapture();
13129+ ok(ret, "ReleaseCapture failed, error %#lx.\n", GetLastError());
13130+ flush_events(TRUE);
13131+ todo_wine
13132+ ok(wm_mousemove_count == 0, "Got WM_MOUSEMOVE.\n");
13133+
13134+ ret = SetCursorPos(pt.x, pt.y);
13135+ ok(ret, "SetCursorPos failed, error %#lx.\n", GetLastError());
13136+ DestroyWindow(hwnd);
13137+ UnregisterClassA(cls.lpszClassName, GetModuleHandleA(0));
13138+ }
13139+
1306413140START_TEST(win)
1306513141{
1306613142 char **argv;
@@ -13243,6 +13319,7 @@ START_TEST(win)
1324313319 test_cancel_mode();
1324413320 test_DragDetect();
1324513321 test_WM_NCCALCSIZE();
13322+ test_ReleaseCapture();
1324613323
1324713324 /* add the tests above this line */
1324813325 if (hhook) UnhookWindowsHookEx(hhook);
0 commit comments