/ src / modules / Workspaces / workspaces-common / WindowUtils.h
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  }