#include "Win32Utils.h" #include #include namespace Win32Utils { bool isMaximized(HWND hWnd) { WINDOWPLACEMENT wPos; BOOL windowPlacement = GetWindowPlacement(hWnd, &wPos); if (!windowPlacement) return false; return wPos.showCmd == SW_MAXIMIZE; } bool isFullScreen(HWND hWnd) { if (!hWnd) return false; RECT winRect; if (!GetWindowRect(hWnd, &winRect)) { return false; } MONITORINFO mi = { sizeof(mi) }; if (!getMonitorInfo(hWnd, MONITOR_DEFAULTTOPRIMARY, &mi)) { return false; } return (mi.rcMonitor.left == winRect.left) && (mi.rcMonitor.right == winRect.right) && (mi.rcMonitor.bottom == winRect.bottom) && (mi.rcMonitor.top == winRect.top); } /** * @brief getMonitorInfo * @param hWnd: window handle * @param dwFlags: Determines the return value if the window does not intersect any display monitor * @param lpmi * @return */ bool getMonitorInfo(HWND hWnd, DWORD dwFlags, LPMONITORINFO lpmi) { HMONITOR monitor = MonitorFromWindow(hWnd, dwFlags); if (!monitor) { return false; } return GetMonitorInfo(monitor, lpmi); } /** * @brief getResizeBorderThickness * @param hWnd: window handle * @param horizontal: (dpiScale) whether to use dpi scale * @return */ int getResizeBorderThickness(HWND hWnd, bool horizontal) { QWindow *window = findWindow(hWnd); if (!window) { return 0; } int frame = SM_CXSIZEFRAME; if (!horizontal) { frame = SM_CYSIZEFRAME; } #ifdef Q_CC_MSVC UINT dpi = GetDpiForWindow(hWnd); int result = GetSystemMetricsForDpi(frame, dpi) + GetSystemMetricsForDpi(92, dpi); if (result > 0) return result; #endif int thickness; if (QtWin::isCompositionEnabled()) { thickness = 8; } else { thickness = 4; } return qRound(thickness * window->devicePixelRatio()); } QWindow *findWindow(HWND hWnd) { if (!hWnd) { return nullptr; } QWindowList windows = QGuiApplication::topLevelWindows(); for (auto win : windows) { if (win && (SIZE_T(win->winId()) == SIZE_T(hWnd))) { return win; } } return nullptr; } bool isGreaterEqualVersion(QOperatingSystemVersion version) { return QOperatingSystemVersion::current() >= version; } bool isWin7() { return QOperatingSystemVersion::current().majorVersion() == QOperatingSystemVersion::Windows7.majorVersion(); } bool isGreaterEqualWin8_1() { return isGreaterEqualVersion(QOperatingSystemVersion::Windows8_1); } bool isGreaterEqualWin10() { return isGreaterEqualVersion(QOperatingSystemVersion::Windows10); } /** * @brief Win8以后GetVersionEx废弃,操作不正常,用黑魔法实现版本查询 * @param lpVersionInformation * @return */ BOOL GetVersionEx2(LPOSVERSIONINFOW lpVersionInformation) { HMODULE hNtDll = GetModuleHandle(L"NTDLL"); // 获取ntdll.dll的句柄 typedef NTSTATUS(NTAPI * tRtlGetVersion)(PRTL_OSVERSIONINFOW povi); // RtlGetVersion的原型 tRtlGetVersion pRtlGetVersion = NULL; if (hNtDll) { pRtlGetVersion = (tRtlGetVersion)GetProcAddress(hNtDll, "RtlGetVersion"); // 获取RtlGetVersion地址 } if (pRtlGetVersion) { return pRtlGetVersion((PRTL_OSVERSIONINFOW)lpVersionInformation) >= 0; // 调用RtlGetVersion } return FALSE; } bool isGreaterEqualWin11() { #if 0 OSVERSIONINFOW osi; osi.dwOSVersionInfoSize = sizeof(osi); if (!GetVersionEx2(&osi)) { return false; } if (osi.dwMajorVersion < 10) { return false; } if (osi.dwBuildNumber >= 22000) { return true; } return false; #endif QOperatingSystemVersion os = QOperatingSystemVersion::current(); if (os.majorVersion() >= 10 && os.microVersion() >= 22000) { return true; } return false; } /** * @brief detect whether the taskbar is hidden automatically * @return */ bool Taskbar::isAutoHide() { APPBARDATA appbarData; appbarData.cbSize = sizeof(APPBARDATA); appbarData.hWnd = 0; appbarData.uCallbackMessage = 0; appbarData.uEdge = 0; appbarData.rc = { 0, 0, 0, 0 }; appbarData.lParam = 0; UINT uState = (UINT)SHAppBarMessage(ABM_GETSTATE, &appbarData); return uState == ABS_AUTOHIDE; } /** * @brief get the position of auto-hide task bar` * @param hWnd * @return */ Taskbar::Position Taskbar::getPosition(HWND hWnd) { APPBARDATA appbarData; if (isGreaterEqualWin8_1()) { MONITORINFO mi = { sizeof(mi) }; if (!getMonitorInfo(hWnd, MONITOR_DEFAULTTONEAREST, &mi)) { return NO_POSITION; } RECT monitor = mi.rcMonitor; appbarData = APPBARDATA { sizeof(APPBARDATA), 0, 0, 0, monitor, 0 }; const QVector positions = { LEFT, TOP, RIGHT, BOTTOM }; for (auto positon : positions) { appbarData.uEdge = positon; // ABM_GETAUTOHIDEBAREX = 11 if (SHAppBarMessage(11, &appbarData)) { return positon; } } return NO_POSITION; } appbarData = APPBARDATA { sizeof(APPBARDATA), FindWindow(L"Shell_TrayWnd", NULL), 0, 0, RECT { 0, 0, 0, 0 }, 0 }; if (appbarData.hWnd) { HMONITOR windowMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); if (!windowMonitor) { return NO_POSITION; } HMONITOR taskbarMonitor = MonitorFromWindow(appbarData.hWnd, MONITOR_DEFAULTTOPRIMARY); if (!taskbarMonitor) { return NO_POSITION; } if (windowMonitor == taskbarMonitor) { SHAppBarMessage(ABM_GETTASKBARPOS, &appbarData); return (Position)appbarData.uEdge; } } return NO_POSITION; } void WindowsMoveResize::startSystemMove(QWidget *window, QPoint globalPos) { Q_UNUSED(globalPos) ReleaseCapture(); SendMessage((HWND)window->winId(), WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0); } void WindowsMoveResize::starSystemResize(QWidget *window, QPoint globalPos, Qt::Edges edges) { Q_UNUSED(window) Q_UNUSED(globalPos) Q_UNUSED(edges) } } // namespace Win32Utils