common: refactor common library pt2 (#8588)

- remove common lib
- split settings, remove common-md
- move ipc interop/kb_layout to interop
- rename core -> settings, settings -> old_settings
- os-detect header-only; interop -> PowerToysInterop
- split notifications, move single-use headers where they're used
- winstore lib
- rename com utils
- rename Updating and Telemetry projects
- rename core -> settings-ui and remove examples folder
- rename settings-ui folder + consisent common/version include
This commit is contained in:
Andrey Nekrasov
2020-12-15 15:16:09 +03:00
committed by GitHub
parent cddf48547d
commit 212ea2de30
588 changed files with 3304 additions and 3328 deletions

View File

@@ -1,10 +1,9 @@
#include "pch.h"
#include <common/common.h>
#include <common/dpi_aware.h>
#include <common/monitor_utils.h>
#include <common/on_thread_executor.h>
#include <common/window_helpers.h>
#include <common/display/dpi_aware.h>
#include <common/logger/logger.h>
#include <common/utils/resources.h>
#include <common/utils/window.h>
#include "FancyZones.h"
#include "lib/Settings.h"
@@ -14,14 +13,14 @@
#include "lib/WindowMoveHandler.h"
#include "lib/FancyZonesWinHookEventIDs.h"
#include "lib/util.h"
#include "on_thread_executor.h"
#include "trace.h"
#include "VirtualDesktopUtils.h"
#include "MonitorWorkAreaHandler.h"
#include "util.h"
#include <lib/SecondaryMouseButtonsHook.h>
extern "C" IMAGE_DOS_HEADER __ImageBase;
enum class DisplayChangeType
{
WorkArea,
@@ -637,9 +636,9 @@ void FancyZones::ToggleEditor() noexcept
params += std::to_wstring(spanZonesAcrossMonitors) + divider; /* Span zones */
std::vector<std::pair<HMONITOR, MONITORINFOEX>> allMonitors;
allMonitors = GetAllMonitorInfo<&MONITORINFOEX::rcWork>();
// device id map
allMonitors = FancyZonesUtils::GetAllMonitorInfo<&MONITORINFOEX::rcWork>();
// device id map
std::unordered_map<std::wstring, DWORD> displayDeviceIdxMap;
bool showDpiWarning = false;
@@ -649,7 +648,7 @@ void FancyZones::ToggleEditor() noexcept
{
HMONITOR monitor = monitorData.first;
auto monitorInfo = monitorData.second;
std::wstring monitorId;
std::wstring deviceId = FancyZonesUtils::GetDisplayDeviceId(monitorInfo.szDevice, displayDeviceIdxMap);
wil::unique_cotaskmem_string virtualDesktopId;
@@ -1117,7 +1116,7 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
current = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
}
auto allMonitors = GetAllMonitorRects<&MONITORINFOEX::rcWork>();
auto allMonitors = FancyZonesUtils::GetAllMonitorRects<&MONITORINFOEX::rcWork>();
if (current && allMonitors.size() > 1 && m_settings->GetSettings()->moveWindowAcrossMonitors)
{

View File

@@ -1,6 +1,6 @@
#pragma once
#include <common/WinHookEvent.h>
#include <common/hooks/WinHookEvent.h>
#include <functional>

View File

@@ -5,8 +5,7 @@
#include "ZoneSet.h"
#include "Settings.h"
#include <common/common.h>
#include <common/json.h>
#include <common/utils/json.h>
#include <shlwapi.h>
#include <filesystem>
@@ -15,6 +14,7 @@
#include <regex>
#include <sstream>
#include <unordered_set>
#include <common/utils/process_path.h>
// Non-localizable strings
namespace NonLocalizable

View File

@@ -2,8 +2,8 @@
#include "JsonHelpers.h"
#include <common/settings_helpers.h>
#include <common/json.h>
#include <common/SettingsAPI/settings_helpers.h>
#include <common/utils/json.h>
#include <mutex>
#include <string>

View File

@@ -1,6 +1,6 @@
#pragma once
#include <common/json.h>
#include <common/utils/json.h>
#include <string>
#include <vector>

View File

@@ -15,7 +15,6 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@@ -28,18 +27,15 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="FancyZones.h" />
<ClInclude Include="FancyZonesDataTypes.h" />
@@ -70,6 +66,7 @@
<ClCompile Include="FancyZonesData.cpp" />
<ClCompile Include="JsonHelpers.cpp" />
<ClCompile Include="MonitorWorkAreaHandler.cpp" />
<ClCompile Include="OnThreadExecutor.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
</ClCompile>
@@ -84,9 +81,11 @@
<ClCompile Include="ZoneWindow.cpp" />
<ClCompile Include="ZoneWindowDrawing.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="fancyzones.base.rc" />
<ProjectReference Include="..\..\..\common\notifications\notifications.vcxproj">
<Project>{1d5be09d-78c0-4fd7-af00-ae7c1af7c525}</Project>
</ProjectReference>
<ResourceCompile Include="Generated Files/fancyzones.rc" />
<None Include="packages.config" />
<None Include="Resources.resx" />

View File

@@ -131,6 +131,9 @@
<ClCompile Include="ZoneWindowDrawing.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OnThreadExecutor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View File

@@ -2,7 +2,7 @@
#include "FancyZonesDataTypes.h"
#include <common/json.h>
#include <common/utils/json.h>
#include <string>
#include <vector>

View File

@@ -0,0 +1,51 @@
#include "pch.h"
#include "on_thread_executor.h"
OnThreadExecutor::OnThreadExecutor() :
_shutdown_request{ false }, _worker_thread{ [this] { worker_thread(); } }
{
}
std::future<void> OnThreadExecutor::submit(task_t task)
{
auto future = task.get_future();
std::lock_guard lock{ _task_mutex };
_task_queue.emplace(std::move(task));
_task_cv.notify_one();
return future;
}
void OnThreadExecutor::cancel()
{
std::lock_guard lock{ _task_mutex };
_task_queue = {};
_task_cv.notify_one();
}
void OnThreadExecutor::worker_thread()
{
while (!_shutdown_request)
{
task_t task;
{
std::unique_lock task_lock{ _task_mutex };
_task_cv.wait(task_lock, [this] { return !_task_queue.empty() || _shutdown_request; });
if (_shutdown_request)
{
return;
}
task = std::move(_task_queue.front());
_task_queue.pop();
}
task();
}
}
OnThreadExecutor::~OnThreadExecutor()
{
_shutdown_request = true;
_task_cv.notify_one();
_worker_thread.join();
}

View File

@@ -1,12 +1,11 @@
#include "pch.h"
#include <common/settings_objects.h>
#include <common/common.h>
#include <common/SettingsAPI/settings_objects.h>
#include <common/utils/resources.h>
#include "lib/Settings.h"
#include "lib/FancyZones.h"
#include "trace.h"
extern "C" IMAGE_DOS_HEADER __ImageBase;
// Non-Localizable strings
namespace NonLocalizable
{
@@ -43,20 +42,26 @@ namespace NonLocalizable
struct FancyZonesSettings : winrt::implements<FancyZonesSettings, IFancyZonesSettings>
{
public:
FancyZonesSettings(HINSTANCE hinstance, PCWSTR name, PCWSTR key)
: m_hinstance(hinstance),
FancyZonesSettings(HINSTANCE hinstance, PCWSTR name, PCWSTR key) :
m_hinstance(hinstance),
m_moduleName(name),
m_moduleKey(key)
{
LoadSettings(name, true);
}
IFACEMETHODIMP_(void) SetCallback(IFancyZonesCallback* callback) { m_callback = callback; }
IFACEMETHODIMP_(void) ResetCallback() { m_callback = nullptr; }
IFACEMETHODIMP_(bool) GetConfig(_Out_ PWSTR buffer, _Out_ int *buffer_sizeg) noexcept;
IFACEMETHODIMP_(void) SetConfig(PCWSTR config) noexcept;
IFACEMETHODIMP_(void) CallCustomAction(PCWSTR action) noexcept;
IFACEMETHODIMP_(const Settings*) GetSettings() const noexcept { return &m_settings; }
IFACEMETHODIMP_(void)
SetCallback(IFancyZonesCallback* callback) { m_callback = callback; }
IFACEMETHODIMP_(void)
ResetCallback() { m_callback = nullptr; }
IFACEMETHODIMP_(bool)
GetConfig(_Out_ PWSTR buffer, _Out_ int* buffer_sizeg) noexcept;
IFACEMETHODIMP_(void)
SetConfig(PCWSTR config) noexcept;
IFACEMETHODIMP_(void)
CallCustomAction(PCWSTR action) noexcept;
IFACEMETHODIMP_(const Settings*)
GetSettings() const noexcept { return &m_settings; }
private:
void LoadSettings(PCWSTR config, bool fromFile) noexcept;
@@ -74,7 +79,8 @@ private:
PCWSTR name;
bool* value;
int resourceId;
} m_configBools[14 /* 15 */] = { // "Turning FLASHING_ZONE option off"
} m_configBools[14 /* 15 */] = {
// "Turning FLASHING_ZONE option off"
{ NonLocalizable::ShiftDragID, &m_settings.shiftDrag, IDS_SETTING_DESCRIPTION_SHIFTDRAG },
{ NonLocalizable::MouseSwitchID, &m_settings.mouseSwitch, IDS_SETTING_DESCRIPTION_MOUSESWITCH },
{ NonLocalizable::OverrideSnapHotKeysID, &m_settings.overrideSnapHotkeys, IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS },
@@ -89,14 +95,14 @@ private:
{ NonLocalizable::OpenWindowOnActiveMonitorID, &m_settings.openWindowOnActiveMonitor, IDS_SETTING_DESCRIPTION_OPEN_WINDOW_ON_ACTIVE_MONITOR },
{ NonLocalizable::RestoreSizeID, &m_settings.restoreSize, IDS_SETTING_DESCRIPTION_RESTORESIZE },
{ NonLocalizable::UseCursorPosEditorStartupScreenID, &m_settings.use_cursorpos_editor_startupscreen, IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN },
{ NonLocalizable::ShowOnAllMonitorsID, &m_settings.showZonesOnAllMonitors, IDS_SETTING_DESCRIPTION_SHOW_FANCY_ZONES_ON_ALL_MONITORS},
{ NonLocalizable::ShowOnAllMonitorsID, &m_settings.showZonesOnAllMonitors, IDS_SETTING_DESCRIPTION_SHOW_FANCY_ZONES_ON_ALL_MONITORS },
{ NonLocalizable::SpanZonesAcrossMonitorsID, &m_settings.spanZonesAcrossMonitors, IDS_SETTING_DESCRIPTION_SPAN_ZONES_ACROSS_MONITORS },
{ NonLocalizable::MakeDraggedWindowTransparentID, &m_settings.makeDraggedWindowTransparent, IDS_SETTING_DESCRIPTION_MAKE_DRAGGED_WINDOW_TRANSPARENT},
{ NonLocalizable::MakeDraggedWindowTransparentID, &m_settings.makeDraggedWindowTransparent, IDS_SETTING_DESCRIPTION_MAKE_DRAGGED_WINDOW_TRANSPARENT },
};
};
IFACEMETHODIMP_(bool) FancyZonesSettings::GetConfig(_Out_ PWSTR buffer, _Out_ int *buffer_size) noexcept
IFACEMETHODIMP_(bool)
FancyZonesSettings::GetConfig(_Out_ PWSTR buffer, _Out_ int* buffer_size) noexcept
{
PowerToysSettings::Settings settings(m_hinstance, m_moduleName);
@@ -112,8 +118,7 @@ IFACEMETHODIMP_(bool) FancyZonesSettings::GetConfig(_Out_ PWSTR buffer, _Out_ in
NonLocalizable::ToggleEditorActionID, // action name.
IDS_SETTING_LAUNCH_EDITOR_LABEL,
IDS_SETTING_LAUNCH_EDITOR_BUTTON,
IDS_SETTING_LAUNCH_EDITOR_DESCRIPTION
);
IDS_SETTING_LAUNCH_EDITOR_DESCRIPTION);
settings.add_hotkey(NonLocalizable::EditorHotkeyID, IDS_SETTING_LAUNCH_EDITOR_HOTKEY_LABEL, m_settings.editorHotkey);
for (auto const& setting : m_configBools)
@@ -132,7 +137,8 @@ IFACEMETHODIMP_(bool) FancyZonesSettings::GetConfig(_Out_ PWSTR buffer, _Out_ in
return settings.serialize_to_buffer(buffer, buffer_size);
}
IFACEMETHODIMP_(void) FancyZonesSettings::SetConfig(PCWSTR serializedPowerToysSettingsJson) noexcept
IFACEMETHODIMP_(void)
FancyZonesSettings::SetConfig(PCWSTR serializedPowerToysSettingsJson) noexcept
{
LoadSettings(serializedPowerToysSettingsJson, false /*fromFile*/);
SaveSettings();
@@ -143,7 +149,8 @@ IFACEMETHODIMP_(void) FancyZonesSettings::SetConfig(PCWSTR serializedPowerToysSe
Trace::SettingsChanged(m_settings);
}
IFACEMETHODIMP_(void) FancyZonesSettings::CallCustomAction(PCWSTR action) noexcept
IFACEMETHODIMP_(void)
FancyZonesSettings::CallCustomAction(PCWSTR action) noexcept
{
try
{
@@ -173,8 +180,8 @@ void FancyZonesSettings::LoadSettings(PCWSTR config, bool fromFile) noexcept
try
{
PowerToysSettings::PowerToyValues values = fromFile ?
PowerToysSettings::PowerToyValues::load_from_settings_file(m_moduleKey) :
PowerToysSettings::PowerToyValues::from_json_string(config, m_moduleKey);
PowerToysSettings::PowerToyValues::load_from_settings_file(m_moduleKey) :
PowerToysSettings::PowerToyValues::from_json_string(config, m_moduleKey);
for (auto const& setting : m_configBools)
{

View File

@@ -1,6 +1,6 @@
#pragma once
#include <common/settings_objects.h>
#include <common/SettingsAPI/settings_objects.h>
// Zoned window properties are not localized.
namespace ZonedWindowProperties
@@ -49,4 +49,4 @@ interface __declspec(uuid("{BA4E77C4-6F44-4C5D-93D3-CBDE880495C2}")) IFancyZones
IFACEMETHOD_(const Settings*, GetSettings)() const = 0;
};
winrt::com_ptr<IFancyZonesSettings> MakeFancyZonesSettings(HINSTANCE hinstance, PCWSTR name, PCWSTR key) noexcept;
winrt::com_ptr<IFancyZonesSettings> MakeFancyZonesSettings(HINSTANCE hinstance, PCWSTR name, PCWSTR key) noexcept;

View File

@@ -1,18 +1,17 @@
#include "pch.h"
#include "WindowMoveHandler.h"
#include <common/dpi_aware.h>
#include <common/notifications.h>
#include <common/toast_dont_show_again.h>
#include <common/window_helpers.h>
#include <common/display/dpi_aware.h>
#include <common/notifications/notifications.h>
#include <common/notifications/dont_show_again.h>
#include <common/utils/elevation.h>
#include <common/utils/resources.h>
#include "FancyZonesData.h"
#include "Settings.h"
#include "ZoneWindow.h"
#include "util.h"
extern "C" IMAGE_DOS_HEADER __ImageBase;
// Non-Localizable strings
namespace NonLocalizable
{
@@ -301,6 +300,7 @@ void WindowMoveHandler::WarnIfElevationIsRequired(HWND window) noexcept
{
using namespace notifications;
using namespace NonLocalizable;
using namespace FancyZonesUtils;
static bool warning_shown = false;
if (!is_process_elevated() && IsProcessOfWindowElevated(window))

View File

@@ -3,8 +3,8 @@
#include <Shellscalingapi.h>
#include <common/dpi_aware.h>
#include <common/monitors.h>
#include <common/display/dpi_aware.h>
#include <common/display/monitors.h>
#include "Zone.h"
#include "Settings.h"
#include "util.h"

View File

@@ -8,7 +8,7 @@
#include "Zone.h"
#include "util.h"
#include <common/dpi_aware.h>
#include <common/display/dpi_aware.h>
#include <limits>
#include <map>

View File

@@ -171,4 +171,4 @@ struct ZoneSetConfig
int SensitivityRadius;
};
winrt::com_ptr<IZoneSet> MakeZoneSet(ZoneSetConfig const& config) noexcept;
winrt::com_ptr<IZoneSet> MakeZoneSet(ZoneSetConfig const& config) noexcept;

View File

@@ -1,7 +1,6 @@
#include "pch.h"
#include <common/common.h>
#include <common/on_thread_executor.h>
#include <common/logger/logger.h>
#include "FancyZonesData.h"
#include "FancyZonesDataTypes.h"
@@ -9,6 +8,7 @@
#include "ZoneWindowDrawing.h"
#include "trace.h"
#include "util.h"
#include "on_thread_executor.h"
#include "Settings.h"
#include <ShellScalingApi.h>
@@ -195,7 +195,7 @@ IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnable
{
m_zoneWindowDrawing->DrawActiveZoneSet(m_activeZoneSet->GetZones(), m_highlightZone, m_host);
}
return S_OK;
}

View File

@@ -1,6 +1,6 @@
#include <windows.h>
#include "resource.h"
#include "../../../../common/version.h"
#include "../../../../common/version/version.h"
#define APSTUDIO_READONLY_SYMBOLS
#include "winres.h"

View File

@@ -0,0 +1,31 @@
#pragma once
#include <future>
#include <thread>
#include <functional>
#include <queue>
#include <atomic>
// OnThreadExecutor allows its caller to off-load some work to a persistently running background thread.
// This might come in handy if you use the API which sets thread-wide global state and the state needs
// to be isolated.
class OnThreadExecutor final
{
public:
using task_t = std::packaged_task<void()>;
OnThreadExecutor();
~OnThreadExecutor();
std::future<void> submit(task_t task);
void cancel();
private:
void worker_thread();
std::mutex _task_mutex;
std::condition_variable _task_cv;
std::atomic_bool _shutdown_request;
std::queue<std::packaged_task<void()>> _task_queue;
std::thread _worker_thread;
};

View File

@@ -2,12 +2,14 @@
#include "util.h"
#include "Settings.h"
#include <common/common.h>
#include <common/dpi_aware.h>
#include <common/display/dpi_aware.h>
#include <common/utils/process_path.h>
#include <common/utils/window.h>
#include <array>
#include <sstream>
#include <complex>
#include <wil/Resource.h>
#include <fancyzones/lib/FancyZonesDataTypes.h>
@@ -18,6 +20,20 @@ namespace NonLocalizable
const wchar_t PowerToysAppFZEditor[] = L"FANCYZONESEDITOR.EXE";
}
bool find_app_name_in_path(const std::wstring& where, const std::vector<std::wstring>& what)
{
for (const auto& row : what)
{
const auto pos = where.rfind(row);
const auto last_slash = where.rfind('\\');
//Check that row occurs in where, and its last occurrence contains in itself the first character after the last backslash.
if (pos != std::wstring::npos && pos <= last_slash + 1 && pos + row.length() > last_slash)
{
return true;
}
}
return false;
}
namespace
{
bool IsZonableByProcessPath(const std::wstring& processPath, const std::vector<std::wstring>& excludedApps)
@@ -65,7 +81,7 @@ namespace FancyZonesUtils
return defaultDeviceId;
}
}
std::optional<FancyZonesDataTypes::DeviceIdData> ParseDeviceId(const std::wstring& str)
{
FancyZonesDataTypes::DeviceIdData data;
@@ -93,7 +109,7 @@ namespace FancyZonesUtils
data.deviceName += L"#" + temp;
}
else if(std::getline(wss, temp, L'_') && !temp.empty())
else if (std::getline(wss, temp, L'_') && !temp.empty())
{
data.deviceName = temp;
}
@@ -153,7 +169,7 @@ namespace FancyZonesUtils
return data;
}
typedef BOOL(WINAPI* GetDpiForMonitorInternalFunc)(HMONITOR, UINT, UINT*, UINT*);
std::wstring GetDisplayDeviceId(const std::wstring& device, std::unordered_map<std::wstring, DWORD>& displayDeviceIdxMap)
{
@@ -618,7 +634,7 @@ namespace FancyZonesUtils
const double eccentricity = 2.0;
auto rectCenter = [](RECT rect) {
return complex {
return complex{
0.5 * rect.left + 0.5 * rect.right,
0.5 * rect.top + 0.5 * rect.bottom
};
@@ -732,4 +748,33 @@ namespace FancyZonesUtils
return windowRect;
}
bool IsProcessOfWindowElevated(HWND window)
{
DWORD pid = 0;
GetWindowThreadProcessId(window, &pid);
if (!pid)
{
return false;
}
wil::unique_handle hProcess{ OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,
FALSE,
pid) };
wil::unique_handle token;
bool elevated = false;
if (OpenProcessToken(hProcess.get(), TOKEN_QUERY, &token))
{
TOKEN_ELEVATION elevation;
DWORD size;
if (GetTokenInformation(token.get(), TokenElevation, &elevation, sizeof(elevation), &size))
{
return elevation.TokenIsElevated != 0;
}
}
return false;
}
}

View File

@@ -1,8 +1,7 @@
#pragma once
#include "gdiplus.h"
#include <common/monitor_utils.h>
#include <common/string_utils.h>
#include <common/utils/string_utils.h>
namespace FancyZonesDataTypes
{
@@ -95,7 +94,7 @@ namespace FancyZonesUtils
inline COLORREF HexToRGB(std::wstring_view hex, const COLORREF fallbackColor = RGB(255, 255, 255))
{
hex = left_trim<wchar_t>(trim<wchar_t>(hex), L"#");
try
{
const long long tmp = std::stoll(hex.data(), nullptr, 16);
@@ -115,6 +114,50 @@ namespace FancyZonesUtils
return static_cast<BYTE>(opacity * 2.55);
}
template<RECT MONITORINFO::*member>
std::vector<std::pair<HMONITOR, RECT>> GetAllMonitorRects()
{
using result_t = std::vector<std::pair<HMONITOR, RECT>>;
result_t result;
auto enumMonitors = [](HMONITOR monitor, HDC hdc, LPRECT pRect, LPARAM param) -> BOOL {
MONITORINFOEX mi;
mi.cbSize = sizeof(mi);
result_t& result = *reinterpret_cast<result_t*>(param);
if (GetMonitorInfo(monitor, &mi))
{
result.push_back({ monitor, mi.*member });
}
return TRUE;
};
EnumDisplayMonitors(NULL, NULL, enumMonitors, reinterpret_cast<LPARAM>(&result));
return result;
}
template<RECT MONITORINFO::*member>
std::vector<std::pair<HMONITOR, MONITORINFOEX>> GetAllMonitorInfo()
{
using result_t = std::vector<std::pair<HMONITOR, MONITORINFOEX>>;
result_t result;
auto enumMonitors = [](HMONITOR monitor, HDC hdc, LPRECT pRect, LPARAM param) -> BOOL {
MONITORINFOEX mi;
mi.cbSize = sizeof(mi);
result_t& result = *reinterpret_cast<result_t*>(param);
if (GetMonitorInfo(monitor, &mi))
{
result.push_back({ monitor, mi });
}
return TRUE;
};
EnumDisplayMonitors(NULL, NULL, enumMonitors, reinterpret_cast<LPARAM>(&result));
return result;
}
template<RECT MONITORINFO::*member>
RECT GetAllMonitorsCombinedRect()
{
@@ -168,4 +211,7 @@ namespace FancyZonesUtils
RECT PrepareRectForCycling(RECT windowRect, RECT zoneWindowRect, DWORD vkCode) noexcept;
size_t ChooseNextZoneByPosition(DWORD vkCode, RECT windowRect, const std::vector<RECT>& zoneRects) noexcept;
// If HWND is already dead, we assume it wasn't elevated
bool IsProcessOfWindowElevated(HWND window);
}