mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +01:00
moved display utils
This commit is contained in:
@@ -596,7 +596,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "projects-common", "projects
|
|||||||
src\modules\Projects\projects-common\AppUtils.h = src\modules\Projects\projects-common\AppUtils.h
|
src\modules\Projects\projects-common\AppUtils.h = src\modules\Projects\projects-common\AppUtils.h
|
||||||
src\modules\Projects\projects-common\Data.h = src\modules\Projects\projects-common\Data.h
|
src\modules\Projects\projects-common\Data.h = src\modules\Projects\projects-common\Data.h
|
||||||
src\modules\Projects\projects-common\GuidUtils.h = src\modules\Projects\projects-common\GuidUtils.h
|
src\modules\Projects\projects-common\GuidUtils.h = src\modules\Projects\projects-common\GuidUtils.h
|
||||||
src\modules\Projects\projects-common\MonitorEnumerator.h = src\modules\Projects\projects-common\MonitorEnumerator.h
|
src\modules\Projects\projects-common\MonitorUtils.h = src\modules\Projects\projects-common\MonitorUtils.h
|
||||||
src\modules\Projects\projects-common\VirtualDesktop.h = src\modules\Projects\projects-common\VirtualDesktop.h
|
src\modules\Projects\projects-common\VirtualDesktop.h = src\modules\Projects\projects-common\VirtualDesktop.h
|
||||||
src\modules\Projects\projects-common\WindowEnumerator.h = src\modules\Projects\projects-common\WindowEnumerator.h
|
src\modules\Projects\projects-common\WindowEnumerator.h = src\modules\Projects\projects-common\WindowEnumerator.h
|
||||||
src\modules\Projects\projects-common\WindowFilter.h = src\modules\Projects\projects-common\WindowFilter.h
|
src\modules\Projects\projects-common\WindowFilter.h = src\modules\Projects\projects-common\WindowFilter.h
|
||||||
|
|||||||
@@ -24,15 +24,18 @@
|
|||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
<AdditionalIncludeDirectories>..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..\..\;..\..\common;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="DisplayUtils.h" />
|
||||||
|
<ClInclude Include="MonitorEnumerator.h" />
|
||||||
<ClInclude Include="monitors.h" />
|
<ClInclude Include="monitors.h" />
|
||||||
<ClInclude Include="dpi_aware.h" />
|
<ClInclude Include="dpi_aware.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="DisplayUtils.cpp" />
|
||||||
<ClCompile Include="monitors.cpp" />
|
<ClCompile Include="monitors.cpp" />
|
||||||
<ClCompile Include="dpi_aware.cpp" />
|
<ClCompile Include="dpi_aware.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
147
src/common/Display/DisplayUtils.cpp
Normal file
147
src/common/Display/DisplayUtils.cpp
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
#include "DisplayUtils.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#include <dpi_aware.h>
|
||||||
|
#include <MonitorEnumerator.h>
|
||||||
|
|
||||||
|
#include <utils/OnThreadExecutor.h>
|
||||||
|
|
||||||
|
namespace DisplayUtils
|
||||||
|
{
|
||||||
|
constexpr bool not_digit(wchar_t ch)
|
||||||
|
{
|
||||||
|
return '0' <= ch && ch <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring remove_non_digits(const std::wstring& input)
|
||||||
|
{
|
||||||
|
std::wstring result;
|
||||||
|
std::copy_if(input.begin(), input.end(), std::back_inserter(result), not_digit);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::wstring, std::wstring> SplitDisplayDeviceId(const std::wstring& str) noexcept
|
||||||
|
{
|
||||||
|
// format: \\?\DISPLAY#{device id}#{instance id}#{some other id}
|
||||||
|
// example: \\?\DISPLAY#GSM1388#4&125707d6&0&UID8388688#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
|
||||||
|
// output: { GSM1388, 4&125707d6&0&UID8388688 }
|
||||||
|
|
||||||
|
size_t nameStartPos = str.find_first_of('#');
|
||||||
|
size_t uidStartPos = str.find('#', nameStartPos + 1);
|
||||||
|
size_t uidEndPos = str.find('#', uidStartPos + 1);
|
||||||
|
|
||||||
|
if (nameStartPos == std::string::npos || uidStartPos == std::string::npos || uidEndPos == std::string::npos)
|
||||||
|
{
|
||||||
|
return { str, L"" };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { str.substr(nameStartPos + 1, uidStartPos - nameStartPos - 1), str.substr(uidStartPos + 1, uidEndPos - uidStartPos - 1) };
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<bool, std::vector<DisplayUtils::DisplayData>> GetDisplays()
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
std::vector<DisplayUtils::DisplayData> result{};
|
||||||
|
auto allMonitors = MonitorEnumerator::Enumerate();
|
||||||
|
|
||||||
|
OnThreadExecutor dpiUnawareThread;
|
||||||
|
dpiUnawareThread.submit(OnThreadExecutor::task_t{ [&] {
|
||||||
|
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
|
||||||
|
SetThreadDpiHostingBehavior(DPI_HOSTING_BEHAVIOR_MIXED);
|
||||||
|
} }).wait();
|
||||||
|
|
||||||
|
for (auto& monitorData : allMonitors)
|
||||||
|
{
|
||||||
|
MONITORINFOEX monitorInfo = monitorData.second;
|
||||||
|
MONITORINFOEX dpiUnawareMonitorInfo{};
|
||||||
|
|
||||||
|
dpiUnawareThread.submit(OnThreadExecutor::task_t{ [&] {
|
||||||
|
dpiUnawareMonitorInfo.cbSize = sizeof(dpiUnawareMonitorInfo);
|
||||||
|
if (!GetMonitorInfo(monitorData.first, &dpiUnawareMonitorInfo))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} }).wait();
|
||||||
|
|
||||||
|
UINT dpi = 0;
|
||||||
|
if (DPIAware::GetScreenDPIForMonitor(monitorData.first, dpi) != S_OK)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayUtils::DisplayData data{
|
||||||
|
.monitor = monitorData.first,
|
||||||
|
.dpi = dpi,
|
||||||
|
.monitorRectDpiAware = monitorInfo.rcMonitor,
|
||||||
|
.monitorRectDpiUnaware = dpiUnawareMonitorInfo.rcMonitor,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool foundActiveMonitor = false;
|
||||||
|
DISPLAY_DEVICE displayDevice{ .cb = sizeof(displayDevice) };
|
||||||
|
DWORD displayDeviceIndex = 0;
|
||||||
|
while (EnumDisplayDevicesW(monitorInfo.szDevice, displayDeviceIndex, &displayDevice, EDD_GET_DEVICE_INTERFACE_NAME))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* if (WI_IsFlagSet(displayDevice.StateFlags, DISPLAY_DEVICE_ACTIVE) &&
|
||||||
|
WI_IsFlagClear(displayDevice.StateFlags, DISPLAY_DEVICE_MIRRORING_DRIVER))
|
||||||
|
*/
|
||||||
|
if (((displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE) == DISPLAY_DEVICE_ACTIVE) &&
|
||||||
|
(displayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) == 0)
|
||||||
|
{
|
||||||
|
// Find display devices associated with the display.
|
||||||
|
foundActiveMonitor = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
displayDeviceIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundActiveMonitor)
|
||||||
|
{
|
||||||
|
auto deviceId = SplitDisplayDeviceId(displayDevice.DeviceID);
|
||||||
|
data.id = deviceId.first;
|
||||||
|
data.instanceId = deviceId.second;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::wstring numberStr = displayDevice.DeviceName; // \\.\DISPLAY1\Monitor0
|
||||||
|
numberStr = numberStr.substr(0, numberStr.find_last_of('\\')); // \\.\DISPLAY1
|
||||||
|
numberStr = remove_non_digits(numberStr);
|
||||||
|
data.number = std::stoi(numberStr);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
|
||||||
|
// Use the display name as a fallback value when no proper device was found.
|
||||||
|
data.id = monitorInfo.szDevice;
|
||||||
|
data.instanceId = L"";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::wstring numberStr = monitorInfo.szDevice; // \\.\DISPLAY1
|
||||||
|
numberStr = remove_non_digits(numberStr);
|
||||||
|
data.number = std::stoi(numberStr);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push_back(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { success, result };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
21
src/common/Display/DisplayUtils.h
Normal file
21
src/common/Display/DisplayUtils.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace DisplayUtils
|
||||||
|
{
|
||||||
|
struct DisplayData
|
||||||
|
{
|
||||||
|
HMONITOR monitor{};
|
||||||
|
std::wstring id;
|
||||||
|
std::wstring instanceId;
|
||||||
|
unsigned int number{};
|
||||||
|
unsigned int dpi{};
|
||||||
|
RECT monitorRectDpiAware{};
|
||||||
|
RECT monitorRectDpiUnaware{};
|
||||||
|
};
|
||||||
|
|
||||||
|
std::pair<bool, std::vector<DisplayData>> GetDisplays();
|
||||||
|
};
|
||||||
35
src/common/Display/MonitorEnumerator.h
Normal file
35
src/common/Display/MonitorEnumerator.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
class MonitorEnumerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::vector<std::pair<HMONITOR, MONITORINFOEX>> Enumerate()
|
||||||
|
{
|
||||||
|
MonitorEnumerator inst;
|
||||||
|
EnumDisplayMonitors(NULL, NULL, Callback, reinterpret_cast<LPARAM>(&inst));
|
||||||
|
return inst.m_monitors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MonitorEnumerator() = default;
|
||||||
|
~MonitorEnumerator() = default;
|
||||||
|
|
||||||
|
static BOOL CALLBACK Callback(HMONITOR monitor, HDC /*hdc*/, LPRECT /*pRect*/, LPARAM param)
|
||||||
|
{
|
||||||
|
MonitorEnumerator* inst = reinterpret_cast<MonitorEnumerator*>(param);
|
||||||
|
MONITORINFOEX mi;
|
||||||
|
mi.cbSize = sizeof(mi);
|
||||||
|
if (GetMonitorInfo(monitor, &mi))
|
||||||
|
{
|
||||||
|
inst->m_monitors.push_back({monitor, mi});
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<HMONITOR, MONITORINFOEX>> m_monitors;
|
||||||
|
};
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
#include "pch.h"
|
|
||||||
#include "MonitorUtils.h"
|
|
||||||
|
|
||||||
#include <ShellScalingApi.h>
|
|
||||||
|
|
||||||
#include <projects-common/MonitorEnumerator.h>
|
|
||||||
#include <OnThreadExecutor.h>
|
|
||||||
|
|
||||||
#include <common/Display/dpi_aware.h>
|
|
||||||
|
|
||||||
namespace MonitorUtils
|
|
||||||
{
|
|
||||||
namespace Display
|
|
||||||
{
|
|
||||||
constexpr inline bool not_digit(wchar_t ch)
|
|
||||||
{
|
|
||||||
return '0' <= ch && ch <= '9';
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring remove_non_digits(const std::wstring& input)
|
|
||||||
{
|
|
||||||
std::wstring result;
|
|
||||||
std::copy_if(input.begin(), input.end(), std::back_inserter(result), not_digit);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<bool, std::vector<Project::Monitor>> GetDisplays()
|
|
||||||
{
|
|
||||||
bool success = true;
|
|
||||||
std::vector<Project::Monitor> result{};
|
|
||||||
|
|
||||||
auto allMonitors = MonitorEnumerator::Enumerate();
|
|
||||||
for (auto& monitorData : allMonitors)
|
|
||||||
{
|
|
||||||
MONITORINFOEX monitorInfo = monitorData.second;
|
|
||||||
MONITORINFOEX dpiUnawareMonitorInfo{};
|
|
||||||
|
|
||||||
OnThreadExecutor dpiUnawareThread;
|
|
||||||
dpiUnawareThread.submit(OnThreadExecutor::task_t{ [&] {
|
|
||||||
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
|
|
||||||
SetThreadDpiHostingBehavior(DPI_HOSTING_BEHAVIOR_MIXED);
|
|
||||||
|
|
||||||
dpiUnawareMonitorInfo.cbSize = sizeof(dpiUnawareMonitorInfo);
|
|
||||||
if (!GetMonitorInfo(monitorData.first, &dpiUnawareMonitorInfo))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} }).wait();
|
|
||||||
|
|
||||||
float width = static_cast<float>(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left);
|
|
||||||
float height = static_cast<float>(monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top);
|
|
||||||
|
|
||||||
float dpiUnawareWidth = static_cast<float>(dpiUnawareMonitorInfo.rcMonitor.right - dpiUnawareMonitorInfo.rcMonitor.left);
|
|
||||||
float dpiUnawareHeight = static_cast<float>(dpiUnawareMonitorInfo.rcMonitor.bottom - dpiUnawareMonitorInfo.rcMonitor.top);
|
|
||||||
|
|
||||||
UINT dpi = 0;
|
|
||||||
if (DPIAware::GetScreenDPIForMonitor(monitorData.first, dpi) != S_OK)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Project::Monitor monitorId{
|
|
||||||
.monitor = monitorData.first,
|
|
||||||
.dpi = dpi,
|
|
||||||
.monitorRectDpiAware = Project::Monitor::MonitorRect {
|
|
||||||
.top = monitorInfo.rcMonitor.top,
|
|
||||||
.left = monitorInfo.rcMonitor.left,
|
|
||||||
.width = static_cast<int>(std::roundf(width)),
|
|
||||||
.height = static_cast<int>(std::roundf(height)),
|
|
||||||
},
|
|
||||||
.monitorRectDpiUnaware = Project::Monitor::MonitorRect {
|
|
||||||
.top = dpiUnawareMonitorInfo.rcMonitor.top,
|
|
||||||
.left = dpiUnawareMonitorInfo.rcMonitor.left,
|
|
||||||
.width = static_cast<int>(std::roundf(dpiUnawareWidth)),
|
|
||||||
.height = static_cast<int>(std::roundf(dpiUnawareHeight)),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
bool foundActiveMonitor = false;
|
|
||||||
DISPLAY_DEVICE displayDevice{ .cb = sizeof(displayDevice) };
|
|
||||||
DWORD displayDeviceIndex = 0;
|
|
||||||
while (EnumDisplayDevicesW(monitorInfo.szDevice, displayDeviceIndex, &displayDevice, EDD_GET_DEVICE_INTERFACE_NAME))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* if (WI_IsFlagSet(displayDevice.StateFlags, DISPLAY_DEVICE_ACTIVE) &&
|
|
||||||
WI_IsFlagClear(displayDevice.StateFlags, DISPLAY_DEVICE_MIRRORING_DRIVER))
|
|
||||||
*/
|
|
||||||
if (((displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE) == DISPLAY_DEVICE_ACTIVE) &&
|
|
||||||
(displayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) == 0)
|
|
||||||
{
|
|
||||||
// Find display devices associated with the display.
|
|
||||||
foundActiveMonitor = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayDeviceIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (foundActiveMonitor)
|
|
||||||
{
|
|
||||||
auto deviceId = SplitDisplayDeviceId(displayDevice.DeviceID);
|
|
||||||
monitorId.id = deviceId.first;
|
|
||||||
monitorId.instanceId = deviceId.second;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::wstring numberStr = displayDevice.DeviceName; // \\.\DISPLAY1\Monitor0
|
|
||||||
numberStr = numberStr.substr(0, numberStr.find_last_of('\\')); // \\.\DISPLAY1
|
|
||||||
numberStr = remove_non_digits(numberStr);
|
|
||||||
monitorId.number = std::stoi(numberStr);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
monitorId.number = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
success = false;
|
|
||||||
|
|
||||||
// Use the display name as a fallback value when no proper device was found.
|
|
||||||
monitorId.id = monitorInfo.szDevice;
|
|
||||||
monitorId.instanceId = L"";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::wstring numberStr = monitorInfo.szDevice; // \\.\DISPLAY1
|
|
||||||
numberStr = remove_non_digits(numberStr);
|
|
||||||
monitorId.number = std::stoi(numberStr);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
monitorId.number = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.push_back(std::move(monitorId));
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success, result };
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<std::wstring, std::wstring> SplitDisplayDeviceId(const std::wstring& str) noexcept
|
|
||||||
{
|
|
||||||
// format: \\?\DISPLAY#{device id}#{instance id}#{some other id}
|
|
||||||
// example: \\?\DISPLAY#GSM1388#4&125707d6&0&UID8388688#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
|
|
||||||
// output: { GSM1388, 4&125707d6&0&UID8388688 }
|
|
||||||
|
|
||||||
size_t nameStartPos = str.find_first_of('#');
|
|
||||||
size_t uidStartPos = str.find('#', nameStartPos + 1);
|
|
||||||
size_t uidEndPos = str.find('#', uidStartPos + 1);
|
|
||||||
|
|
||||||
if (nameStartPos == std::string::npos || uidStartPos == std::string::npos || uidEndPos == std::string::npos)
|
|
||||||
{
|
|
||||||
return { str, L"" };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { str.substr(nameStartPos + 1, uidStartPos - nameStartPos - 1), str.substr(uidStartPos + 1, uidEndPos - uidStartPos - 1) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Project::Monitor> IdentifyMonitors() noexcept
|
|
||||||
{
|
|
||||||
auto displaysResult = Display::GetDisplays();
|
|
||||||
|
|
||||||
// retry
|
|
||||||
int retryCounter = 0;
|
|
||||||
while (!displaysResult.first && retryCounter < 100)
|
|
||||||
{
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
|
||||||
displaysResult = Display::GetDisplays();
|
|
||||||
retryCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return displaysResult.second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <projects-common/Data.h>
|
|
||||||
|
|
||||||
// FancyZones: MonitorUtils.h
|
|
||||||
namespace MonitorUtils
|
|
||||||
{
|
|
||||||
namespace Display
|
|
||||||
{
|
|
||||||
std::pair<bool, std::vector<Project::Monitor>> GetDisplays();
|
|
||||||
std::pair<std::wstring, std::wstring> SplitDisplayDeviceId(const std::wstring& str) noexcept;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Project::Monitor> IdentifyMonitors() noexcept;
|
|
||||||
}
|
|
||||||
@@ -123,14 +123,12 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="MonitorUtils.cpp" />
|
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<PrecompiledHeader Condition="'$(UsePrecompiledHeaders)' != 'false'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(UsePrecompiledHeaders)' != 'false'">Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="MonitorUtils.h" />
|
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -18,9 +18,6 @@
|
|||||||
<ClInclude Include="pch.h">
|
<ClInclude Include="pch.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="MonitorUtils.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="resource.h">
|
<ClInclude Include="resource.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -32,9 +29,6 @@
|
|||||||
<ClCompile Include="main.cpp">
|
<ClCompile Include="main.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="MonitorUtils.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
|||||||
@@ -6,11 +6,10 @@
|
|||||||
#include <projects-common/AppUtils.h>
|
#include <projects-common/AppUtils.h>
|
||||||
#include <projects-common/Data.h>
|
#include <projects-common/Data.h>
|
||||||
#include <projects-common/GuidUtils.h>
|
#include <projects-common/GuidUtils.h>
|
||||||
|
#include <projects-common/MonitorUtils.h>
|
||||||
#include <projects-common/WindowEnumerator.h>
|
#include <projects-common/WindowEnumerator.h>
|
||||||
#include <projects-common/WindowFilter.h>
|
#include <projects-common/WindowFilter.h>
|
||||||
|
|
||||||
#include <MonitorUtils.h>
|
|
||||||
|
|
||||||
#include <common/utils/gpo.h>
|
#include <common/utils/gpo.h>
|
||||||
#include <common/utils/logger_helper.h>
|
#include <common/utils/logger_helper.h>
|
||||||
#include <common/utils/UnhandledExceptionHandler.h>
|
#include <common/utils/UnhandledExceptionHandler.h>
|
||||||
|
|||||||
46
src/modules/Projects/projects-common/MonitorUtils.h
Normal file
46
src/modules/Projects/projects-common/MonitorUtils.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <projects-common/Data.h>
|
||||||
|
#include <common/Display/DisplayUtils.h>
|
||||||
|
|
||||||
|
namespace MonitorUtils
|
||||||
|
{
|
||||||
|
inline std::vector<Project::Monitor> IdentifyMonitors() noexcept
|
||||||
|
{
|
||||||
|
auto displaysResult = DisplayUtils::GetDisplays();
|
||||||
|
|
||||||
|
int retryCounter = 0;
|
||||||
|
while (!displaysResult.first && retryCounter < 100)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
||||||
|
displaysResult = DisplayUtils::GetDisplays();
|
||||||
|
retryCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Project::Monitor> result{};
|
||||||
|
for (const auto& data : displaysResult.second)
|
||||||
|
{
|
||||||
|
result.emplace_back(Project::Monitor{
|
||||||
|
.monitor = data.monitor,
|
||||||
|
.id = data.id,
|
||||||
|
.instanceId = data.instanceId,
|
||||||
|
.number = data.number,
|
||||||
|
.dpi = data.dpi,
|
||||||
|
.monitorRectDpiAware = Project::Monitor::MonitorRect{
|
||||||
|
.top = data.monitorRectDpiAware.top,
|
||||||
|
.left = data.monitorRectDpiAware.left,
|
||||||
|
.width = data.monitorRectDpiAware.right - data.monitorRectDpiAware.left,
|
||||||
|
.height = data.monitorRectDpiAware.bottom - data.monitorRectDpiAware.top,
|
||||||
|
},
|
||||||
|
.monitorRectDpiUnaware = Project::Monitor::MonitorRect{
|
||||||
|
.top = data.monitorRectDpiUnaware.top,
|
||||||
|
.left = data.monitorRectDpiUnaware.left,
|
||||||
|
.width = data.monitorRectDpiUnaware.right - data.monitorRectDpiUnaware.left,
|
||||||
|
.height = data.monitorRectDpiUnaware.bottom - data.monitorRectDpiUnaware.top,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user