QWizard/Win: Handle hit testing correctly for Vista style

Clicking the area just below the close button when Aero is enabled
reveals duplicate caption buttons. DwmDefWindowProc returns hit results
for DWM caption buttons but DefWindowProc may also return hit results
for non-DWM caption buttons.

To resolve this issue, if DefWindowProc returns a window button hit
result then we just use HTCLIENT (the client area) as the hit result
instead.

Change-Id: Ia741ce4f9aa944109d8de54c2f84009f5ea1883f
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
This commit is contained in:
Jonathan Liu 2012-06-09 01:09:39 +10:00 committed by Qt by Nokia
parent 378e65c07a
commit 9ab445d264

View File

@ -378,25 +378,24 @@ void QVistaHelper::setTitleBarIconAndCaptionVisible(bool visible)
bool QVistaHelper::winEvent(MSG* msg, long* result) bool QVistaHelper::winEvent(MSG* msg, long* result)
{ {
bool retval = true;
switch (msg->message) { switch (msg->message) {
case WM_NCHITTEST: { case WM_NCHITTEST: {
LRESULT lResult; LRESULT lResult;
pDwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult); // Perform hit testing using DWM
if (lResult == HTCLOSE || lResult == HTMAXBUTTON || lResult == HTMINBUTTON || lResult == HTHELP) if (pDwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult)) {
// DWM returned a hit, no further processing necessary
*result = lResult; *result = lResult;
} else {
// DWM didn't return a hit, process using DefWindowProc
lResult = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
// If DefWindowProc returns a window caption button, just return HTCLIENT (client area).
// This avoid unnecessary hits to Windows NT style caption buttons which aren't visible but are
// located just under the Aero style window close button.
if (lResult == HTCLOSE || lResult == HTMAXBUTTON || lResult == HTMINBUTTON || lResult == HTHELP)
*result = HTCLIENT;
else else
*result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam); *result = lResult;
break;
} }
case WM_NCMOUSEMOVE:
case WM_NCLBUTTONDOWN:
case WM_NCLBUTTONUP:
case WIZ_WM_NCMOUSELEAVE: {
LRESULT lResult;
pDwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult);
*result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
break; break;
} }
// case WM_NCCALCSIZE: { #fixme: If the frame size is changed, it needs to be communicated to the QWindow. // case WM_NCCALCSIZE: { #fixme: If the frame size is changed, it needs to be communicated to the QWindow.
@ -407,10 +406,16 @@ bool QVistaHelper::winEvent(MSG* msg, long* result)
// break; // break;
// } // }
default: default:
retval = false; LRESULT lResult;
// Pass to DWM to handle
if (pDwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult))
*result = lResult;
// If the message wasn't handled by DWM, continue processing it as normal
else
return false;
} }
return retval; return true;
} }
void QVistaHelper::setMouseCursor(QPoint pos) void QVistaHelper::setMouseCursor(QPoint pos)
@ -597,6 +602,8 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event)
winEvent(&msg, &result); winEvent(&msg, &result);
} else if (event->type() == QEvent::MouseButtonPress) { } else if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::LeftButton) {
long result; long result;
MSG msg; MSG msg;
msg.message = WM_NCHITTEST; msg.message = WM_NCHITTEST;
@ -608,8 +615,11 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event)
msg.wParam = result; msg.wParam = result;
msg.message = WM_NCLBUTTONDOWN; msg.message = WM_NCLBUTTONDOWN;
winEvent(&msg, &result); winEvent(&msg, &result);
}
} else if (event->type() == QEvent::MouseButtonRelease) { } else if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::LeftButton) {
long result; long result;
MSG msg; MSG msg;
msg.message = WM_NCHITTEST; msg.message = WM_NCHITTEST;
@ -622,6 +632,7 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event)
msg.message = WM_NCLBUTTONUP; msg.message = WM_NCLBUTTONUP;
winEvent(&msg, &result); winEvent(&msg, &result);
} }
}
return false; return false;
} }