WindowUtils.h
1 #pragma once 2 3 #include <common/Display/dpi_aware.h> 4 #include <common/utils/excluded_apps.h> 5 #include <common/utils/window.h> 6 7 namespace WindowUtils 8 { 9 // Non-Localizable strings 10 namespace NonLocalizable 11 { 12 const char SplashClassName[] = "MsoSplash"; 13 14 const wchar_t SystemAppsFolder[] = L"SYSTEMAPPS"; 15 16 const wchar_t CoreWindow[] = L"WINDOWS.UI.CORE.COREWINDOW"; 17 const wchar_t SearchUI[] = L"SEARCHUI.EXE"; 18 const wchar_t HelpWindow[] = L"WINDOWS\\HH.EXE"; 19 const wchar_t ApplicationFrameHost[] = L"WINDOWS\\SYSTEM32\\APPLICATIONFRAMEHOST.EXE"; 20 21 const wchar_t WorkspacesSnapshotTool[] = L"POWERTOYS.WORKSPACESSNAPSHOTTOOL"; 22 const wchar_t WorkspacesEditor[] = L"POWERTOYS.WORKSPACESEDITOR"; 23 const wchar_t WorkspacesLauncher[] = L"POWERTOYS.WORKSPACESLAUNCHER"; 24 const wchar_t WorkspacesWindowArranger[] = L"POWERTOYS.WORKSPACESWINDOWARRANGER"; 25 } 26 27 inline bool IsRoot(HWND window) noexcept 28 { 29 return GetAncestor(window, GA_ROOT) == window; 30 } 31 32 inline bool IsMinimized(HWND window) 33 { 34 return IsIconic(window); 35 } 36 37 inline bool IsMaximized(HWND window) noexcept 38 { 39 WINDOWPLACEMENT placement{}; 40 if (GetWindowPlacement(window, &placement) && 41 placement.showCmd == SW_SHOWMAXIMIZED) 42 { 43 return true; 44 } 45 return false; 46 } 47 48 constexpr bool HasStyle(LONG style, LONG styleToCheck) noexcept 49 { 50 return ((style & styleToCheck) == styleToCheck); 51 } 52 53 inline bool IsExcludedByDefault(HWND window, const std::wstring& processPath) 54 { 55 std::wstring processPathUpper = processPath; 56 CharUpperBuffW(processPathUpper.data(), static_cast<DWORD>(processPathUpper.length())); 57 58 static std::vector<std::wstring> defaultExcludedFolders = { 59 NonLocalizable::SystemAppsFolder, 60 }; 61 if (find_folder_in_path(processPathUpper, defaultExcludedFolders)) 62 { 63 return true; 64 } 65 66 std::array<char, 256> className; 67 GetClassNameA(window, className.data(), static_cast<int>(className.size())); 68 if (is_system_window(window, className.data())) 69 { 70 return true; 71 } 72 73 if (strcmp(NonLocalizable::SplashClassName, className.data()) == 0) 74 { 75 return true; 76 } 77 78 static std::vector<std::wstring> defaultExcludedApps = { 79 NonLocalizable::CoreWindow, 80 NonLocalizable::SearchUI, 81 NonLocalizable::HelpWindow, 82 NonLocalizable::WorkspacesEditor, 83 NonLocalizable::WorkspacesLauncher, 84 NonLocalizable::WorkspacesWindowArranger, 85 NonLocalizable::WorkspacesSnapshotTool, 86 }; 87 return (check_excluded_app(window, processPathUpper, defaultExcludedApps)); 88 } 89 90 inline RECT GetWindowRect(HWND window) 91 { 92 RECT rect; 93 if (GetWindowRect(window, &rect)) 94 { 95 float width = static_cast<float>(rect.right - rect.left); 96 float height = static_cast<float>(rect.bottom - rect.top); 97 float originX = static_cast<float>(rect.left); 98 float originY = static_cast<float>(rect.top); 99 100 DPIAware::InverseConvert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), width, height); 101 DPIAware::InverseConvert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), originX, originY); 102 103 return RECT(static_cast<LONG>(std::roundf(originX)), 104 static_cast<LONG>(std::roundf(originY)), 105 static_cast<LONG>(std::roundf(originX + width)), 106 static_cast<LONG>(std::roundf(originY + height))); 107 } 108 109 return rect; 110 } 111 112 #define MAX_TITLE_LENGTH 255 113 inline std::wstring GetWindowTitle(HWND window) 114 { 115 WCHAR title[MAX_TITLE_LENGTH]; 116 int len = GetWindowTextW(window, title, MAX_TITLE_LENGTH); 117 if (len <= 0) 118 { 119 return {}; 120 } 121 122 return std::wstring(title); 123 } 124 125 126 inline bool HasThickFrame(HWND window) 127 { 128 auto style = GetWindowLong(window, GWL_STYLE); 129 return WindowUtils::HasStyle(style, WS_THICKFRAME); 130 } 131 }