| | |
| | | // } |
| | | // }; |
| | | // |
| | | // #define DWM_API_DECLARE(NAME) decltype(&::NAME) p##NAME = DefaultFunc<decltype(&::NAME)>::func |
| | | #define DWM_API_DECLARE(NAME) decltype(&::NAME) p##NAME = nullptr |
| | | // #define DYNAMIC_API_DECLARE(NAME) decltype(&::NAME) p##NAME = DefaultFunc<decltype(&::NAME)>::func |
| | | #define DYNAMIC_API_DECLARE(NAME) decltype(&::NAME) p##NAME = nullptr |
| | | |
| | | DWM_API_DECLARE(DwmFlush); |
| | | DWM_API_DECLARE(DwmIsCompositionEnabled); |
| | | DWM_API_DECLARE(DwmGetCompositionTimingInfo); |
| | | DWM_API_DECLARE(GetDpiForWindow); |
| | | DWM_API_DECLARE(GetSystemMetricsForDpi); |
| | | DWM_API_DECLARE(GetDpiForMonitor); |
| | | DWM_API_DECLARE(timeGetDevCaps); |
| | | DWM_API_DECLARE(timeBeginPeriod); |
| | | DWM_API_DECLARE(timeEndPeriod); |
| | | DYNAMIC_API_DECLARE(DwmFlush); |
| | | DYNAMIC_API_DECLARE(DwmIsCompositionEnabled); |
| | | DYNAMIC_API_DECLARE(DwmGetCompositionTimingInfo); |
| | | DYNAMIC_API_DECLARE(GetDpiForWindow); |
| | | DYNAMIC_API_DECLARE(GetSystemMetricsForDpi); |
| | | DYNAMIC_API_DECLARE(GetDpiForMonitor); |
| | | DYNAMIC_API_DECLARE(timeGetDevCaps); |
| | | DYNAMIC_API_DECLARE(timeBeginPeriod); |
| | | DYNAMIC_API_DECLARE(timeEndPeriod); |
| | | |
| | | #undef DWM_API_DECLARE |
| | | #undef DYNAMIC_API_DECLARE |
| | | |
| | | DynamicApis() { |
| | | #define DYNAMIC_API_RESOLVE(DLL, NAME) p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL##.resolve(#NAME)) |
| | | |
| | | QSystemLibrary user32(QStringLiteral("user32")); |
| | | pGetDpiForWindow = |
| | | reinterpret_cast<decltype(pGetDpiForWindow)>(user32.resolve("GetDpiForWindow")); |
| | | pGetSystemMetricsForDpi = reinterpret_cast<decltype(pGetSystemMetricsForDpi)>( |
| | | user32.resolve("GetSystemMetricsForDpi")); |
| | | DYNAMIC_API_RESOLVE(user32, GetDpiForWindow); |
| | | DYNAMIC_API_RESOLVE(user32, GetSystemMetricsForDpi); |
| | | |
| | | QSystemLibrary shcore(QStringLiteral("shcore")); |
| | | pGetDpiForMonitor = |
| | | reinterpret_cast<decltype(pGetDpiForMonitor)>(shcore.resolve("GetDpiForMonitor")); |
| | | DYNAMIC_API_RESOLVE(shcore, GetDpiForMonitor); |
| | | |
| | | QSystemLibrary dwmapi(QStringLiteral("dwmapi")); |
| | | pDwmFlush = reinterpret_cast<decltype(pDwmFlush)>(dwmapi.resolve("DwmFlush")); |
| | | pDwmIsCompositionEnabled = reinterpret_cast<decltype(pDwmIsCompositionEnabled)>( |
| | | dwmapi.resolve("DwmIsCompositionEnabled")); |
| | | pDwmGetCompositionTimingInfo = reinterpret_cast<decltype(pDwmGetCompositionTimingInfo)>( |
| | | dwmapi.resolve("DwmGetCompositionTimingInfo")); |
| | | DYNAMIC_API_RESOLVE(dwmapi, DwmFlush); |
| | | DYNAMIC_API_RESOLVE(dwmapi, DwmIsCompositionEnabled); |
| | | DYNAMIC_API_RESOLVE(dwmapi, DwmGetCompositionTimingInfo); |
| | | |
| | | QSystemLibrary winmm(QStringLiteral("winmm")); |
| | | ptimeGetDevCaps = |
| | | reinterpret_cast<decltype(ptimeGetDevCaps)>(winmm.resolve("timeGetDevCaps")); |
| | | ptimeBeginPeriod = |
| | | reinterpret_cast<decltype(ptimeBeginPeriod)>(winmm.resolve("timeBeginPeriod")); |
| | | ptimeEndPeriod = |
| | | reinterpret_cast<decltype(ptimeEndPeriod)>(winmm.resolve("timeEndPeriod")); |
| | | DYNAMIC_API_RESOLVE(winmm, timeGetDevCaps); |
| | | DYNAMIC_API_RESOLVE(winmm, timeBeginPeriod); |
| | | DYNAMIC_API_RESOLVE(winmm, timeEndPeriod); |
| | | |
| | | #undef DYNAMIC_API_RESOLVE |
| | | } |
| | | |
| | | ~DynamicApis() = default; |
| | |
| | | } |
| | | ::SetMenuDefaultItem(hMenu, defaultItemId.value_or(UINT_MAX), FALSE); |
| | | |
| | | ::DrawMenuBar(hWnd); |
| | | //::DrawMenuBar(hWnd); |
| | | |
| | | // Popup the system menu at the required position. |
| | | const auto result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), pos.x, pos.y, 0, hWnd, nullptr); |
| | |
| | | return false; |
| | | } |
| | | |
| | | if (systemMenuHandler(hWnd, message, wParam, lParam, result)) { |
| | | return true; |
| | | } |
| | | |
| | | // Test snap layout |
| | | if (snapLayoutHandler(hWnd, message, wParam, lParam, result)) { |
| | | return true; |
| | |
| | | |
| | | // Main implementation |
| | | if (customWindowHandler(hWnd, message, wParam, lParam, result)) { |
| | | return true; |
| | | } |
| | | |
| | | if (systemMenuHandler(hWnd, message, wParam, lParam, result)) { |
| | | return true; |
| | | } |
| | | |
| | |
| | | // this is also the normal behavior of a native Win32 window (but only when the |
| | | // window is not maximized/fullscreen/minimized, of course). |
| | | if (isWindowNoState(hWnd)) { |
| | | static constexpr const int kBorderSize = 2; |
| | | static constexpr const auto kBorderSize = quint8{2}; |
| | | bool isTop = (nativeLocalPos.y <= kBorderSize); |
| | | bool isLeft = nativeLocalPos.x <= kBorderSize; |
| | | bool isRight = (nativeLocalPos.x >= (clientWidth - kBorderSize)); |
| | | if (isTop || isRight) { |
| | | if (isTop || isLeft || isRight) { |
| | | if (dontOverrideCursor) { |
| | | // The user doesn't want the window to be resized, so we tell |
| | | // Windows we are in the client area so that the controls beneath |
| | | // the mouse cursor can still be hovered or clicked. |
| | | *result = (isTitleBar ? HTCAPTION : HTCLIENT); |
| | | } else { |
| | | if (isTop && isRight) { |
| | | *result = HTTOPRIGHT; |
| | | } else if (isTop) { |
| | | *result = HTTOP; |
| | | if (isTop) { |
| | | if (isLeft) { |
| | | *result = HTTOPLEFT; |
| | | } else if (isRight) { |
| | | *result = HTTOPRIGHT; |
| | | } else { |
| | | *result = HTTOP; |
| | | } |
| | | } else { |
| | | *result = HTRIGHT; |
| | | if (isLeft) { |
| | | *result = HTLEFT; |
| | | } else { |
| | | *result = HTRIGHT; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | const bool isBottom = (nativeLocalPos.y >= (clientHeight - frameSize)); |
| | | // Make the border a little wider to let the user easy to resize on corners. |
| | | const auto scaleFactor = ((isTop || isBottom) ? qreal(2) : qreal(1)); |
| | | const int scaledFrameSizeX = std::round(qreal(frameSize) * scaleFactor); |
| | | const bool isLeft = (nativeLocalPos.x < scaledFrameSizeX); |
| | | const bool isRight = (nativeLocalPos.x >= (clientWidth - scaledFrameSizeX)); |
| | | const int scaledFrameSize = std::round(qreal(frameSize) * scaleFactor); |
| | | const bool isLeft = (nativeLocalPos.x < scaledFrameSize); |
| | | const bool isRight = (nativeLocalPos.x >= (clientWidth - scaledFrameSize)); |
| | | if (dontOverrideCursor && (isTop || isBottom || isLeft || isRight)) { |
| | | // Return HTCLIENT instead of HTBORDER here, because the mouse is |
| | | // inside the window now, return HTCLIENT to let the controls |