win32ss/user/ntuser/msgqueue.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/win32ss/user/ntuser/msgqueue.c b/win32ss/user/ntuser/msgqueue.c index a674f806e8a..10e3508e0ae 100644 --- a/win32ss/user/ntuser/msgqueue.c +++ b/win32ss/user/ntuser/msgqueue.c @@ -627,13 +627,50 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook /* Check if the mouse is captured */ Msg->hwnd = IntGetCaptureWindow(); + + pwnd = IntTopLevelWindowFromPoint(Msg->pt.x, Msg->pt.y); + if (Msg->hwnd != NULL) { - pwnd = UserGetWindowObject(Msg->hwnd); + /* Get captured window. */ + PWND pwndCap = UserGetWindowObject(Msg->hwnd); + + /* Redirect mouse move or cancel capture mode + if message queues are different. */ + if (pwnd && pwndCap->head.pti->MessageQueue != pwnd->head.pti->MessageQueue) + { + if (Msg->message == WM_MOUSEMOVE) + { + /* Button is not down. Redirect messeage. */ + if (Msg->wParam == 0) + Msg->hwnd = pwnd->head.h; + else + pwnd = pwndCap; + } + else + { + /* Cancel mouse capture on captured thread. */ + MSG msgMess = *Msg; + + /* (L/M/R/BUTTONDOWN) */ + MsqPostMessage(pwndCap->head.pti, &msgMess, TRUE, QS_MOUSEBUTTON, 0, dwExtraInfo); + + /* (L/M/R/BUTTONUP) */ + msgMess.message += 1; + msgMess.wParam = 0; + MsqPostMessage(pwndCap->head.pti, &msgMess, TRUE, QS_MOUSEBUTTON, 0, dwExtraInfo); + + /* Set new window for input. */ + Msg->hwnd = pwnd->head.h; + } + } + else + { + pwnd = pwndCap; + } } else { - pwnd = IntTopLevelWindowFromPoint(Msg->pt.x, Msg->pt.y); if (pwnd) Msg->hwnd = pwnd->head.h; }