| | |
| | | // Try hooked procedure and save result |
| | | LRESULT result; |
| | | if (ctx->windowProc(hWnd, message, wParam, lParam, &result)) { |
| | | // https://github.com/stdware/qwindowkit/issues/45 |
| | | // Forward the event to user-defined native event filters, there may be some messages |
| | | // that need to be processed by the user. |
| | | std::ignore = |
| | |
| | | auto hWnd = reinterpret_cast<HWND>(m_windowId); |
| | | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) |
| | | const QPoint nativeGlobalPos = |
| | | QHighDpi::toNativeGlobalPosition(pos, m_windowHandle); |
| | | QHighDpi::toNativeGlobalPosition(pos, m_windowHandle.data()); |
| | | #else |
| | | const QPoint nativeGlobalPos = QHighDpi::toNativePixels(pos, m_windowHandle); |
| | | const QPoint nativeGlobalPos = QHighDpi::toNativePixels(pos, m_windowHandle.data()); |
| | | #endif |
| | | std::ignore = showSystemMenu_sys(hWnd, qpoint2point(nativeGlobalPos), false, |
| | | m_delegate->isHostSizeFixed(m_host)); |
| | | isHostSizeFixed()); |
| | | return; |
| | | } |
| | | |
| | |
| | | POINT screenPoint{GET_X_LPARAM(dwScreenPos), GET_Y_LPARAM(dwScreenPos)}; |
| | | ::ScreenToClient(hWnd, &screenPoint); |
| | | QPoint qtScenePos = QHighDpi::fromNativeLocalPosition(point2qpoint(screenPoint), |
| | | m_windowHandle); |
| | | m_windowHandle.data()); |
| | | auto dummy = WindowAgentBase::Unknown; |
| | | if (isInSystemButtons(qtScenePos, &dummy)) { |
| | | // We must record whether the last WM_MOUSELEAVE was filtered, because if |
| | |
| | | // menu while Windows will create and execute a new event loop |
| | | // until the menu returns |
| | | iconButtonClickTime = ::GetTickCount64(); |
| | | *result = |
| | | ::DefWindowProcW(hWnd, WM_NCLBUTTONDOWN, wParam, lParam); |
| | | *result = ::DefWindowProcW(hWnd, message, wParam, lParam); |
| | | iconButtonClickTime = 0; |
| | | if (iconButtonClickLevel & IconButtonTriggersClose) { |
| | | ::PostMessageW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0); |
| | | } |
| | |
| | | auto clientWidth = RECT_WIDTH(clientRect); |
| | | auto clientHeight = RECT_HEIGHT(clientRect); |
| | | |
| | | QPoint qtScenePos = |
| | | QHighDpi::fromNativeLocalPosition(point2qpoint(nativeLocalPos), m_windowHandle); |
| | | QPoint qtScenePos = QHighDpi::fromNativeLocalPosition(point2qpoint(nativeLocalPos), |
| | | m_windowHandle.data()); |
| | | |
| | | bool isFixedSize = m_delegate->isHostSizeFixed(m_host); |
| | | bool isFixedSize = isHostSizeFixed(); |
| | | bool isTitleBar = isInTitleBarDraggableArea(qtScenePos); |
| | | bool dontOverrideCursor = false; // ### TODO |
| | | |
| | |
| | | switch (message) { |
| | | case WM_RBUTTONUP: { |
| | | const POINT nativeLocalPos = getNativePosFromMouse(); |
| | | const QPoint qtScenePos = |
| | | QHighDpi::fromNativeLocalPosition(point2qpoint(nativeLocalPos), m_windowHandle); |
| | | if (isInTitleBarDraggableArea(qtScenePos)) { |
| | | const QPoint qtScenePos = QHighDpi::fromNativeLocalPosition( |
| | | point2qpoint(nativeLocalPos), m_windowHandle.data()); |
| | | WindowAgentBase::SystemButton sysButtonType = WindowAgentBase::Unknown; |
| | | if (isInTitleBarDraggableArea(qtScenePos) || |
| | | (isInSystemButtons(qtScenePos, &sysButtonType) && |
| | | sysButtonType == WindowAgentBase::WindowIcon)) { |
| | | shouldShowSystemMenu = true; |
| | | nativeGlobalPos = nativeLocalPos; |
| | | ::ClientToScreen(hWnd, &nativeGlobalPos); |
| | |
| | | WH_MOUSE, |
| | | [](int nCode, WPARAM wParam, LPARAM lParam) { |
| | | if (nCode >= 0) { |
| | | if (wParam == WM_LBUTTONDOWN || wParam == WM_LBUTTONDBLCLK) { |
| | | if (wParam == WM_LBUTTONDBLCLK) { |
| | | switch (wParam) { |
| | | case WM_LBUTTONDBLCLK: |
| | | mouseDoubleClicked = true; |
| | | Q_FALLTHROUGH(); |
| | | |
| | | // case WM_POINTERDOWN: |
| | | |
| | | case WM_LBUTTONDOWN: { |
| | | auto pMouseStruct = |
| | | reinterpret_cast<MOUSEHOOKSTRUCT *>(lParam); |
| | | if (pMouseStruct) { |
| | | mouseClickPos = pMouseStruct->pt; |
| | | } |
| | | break; |
| | | } |
| | | auto pMouseStruct = reinterpret_cast<MOUSEHOOKSTRUCT *>(lParam); |
| | | if (pMouseStruct) { |
| | | mouseClickPos = pMouseStruct->pt; |
| | | } |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | return ::CallNextHookEx(nullptr, nCode, wParam, lParam); |
| | |
| | | } |
| | | } |
| | | |
| | | bool res = showSystemMenu_sys(hWnd, nativeGlobalPos, broughtByKeyboard, |
| | | m_delegate->isHostSizeFixed(m_host)); |
| | | bool res = |
| | | showSystemMenu_sys(hWnd, nativeGlobalPos, broughtByKeyboard, isHostSizeFixed()); |
| | | |
| | | // Uninstall mouse hook and check if it's a double-click |
| | | if (mouseHookedLocal) { |
| | | ::UnhookWindowsHookEx(mouseHook); |
| | | |
| | | // Emulate the Windows icon button's behavior |
| | | static uint32_t doubleClickTime = ::GetDoubleClickTime(); |
| | | if (!res && mouseClickPos.has_value()) { |
| | | POINT nativeLocalPos = mouseClickPos.value(); |
| | | ::ScreenToClient(hWnd, &nativeLocalPos); |
| | | QPoint qtScenePos = QHighDpi::fromNativeLocalPosition( |
| | | point2qpoint(nativeLocalPos), m_windowHandle); |
| | | point2qpoint(nativeLocalPos), m_windowHandle.data()); |
| | | WindowAgentBase::SystemButton sysButtonType = WindowAgentBase::Unknown; |
| | | if (isInSystemButtons(qtScenePos, &sysButtonType) && |
| | | sysButtonType == WindowAgentBase::WindowIcon) { |
| | | iconButtonClickLevel |= IconButtonClicked; |
| | | if (::GetTickCount64() - iconButtonClickTime <= doubleClickTime) { |
| | | if (::GetTickCount64() - iconButtonClickTime <= ::GetDoubleClickTime()) { |
| | | iconButtonClickLevel |= IconButtonTriggersClose; |
| | | } |
| | | } |