2019-09-05 00:26:26 +08:00
|
|
|
#pragma once
|
|
|
|
|
2020-03-25 22:38:44 +08:00
|
|
|
#include "gdiplus.h"
|
2020-12-10 23:28:44 +08:00
|
|
|
#include <common/monitor_utils.h>
|
2020-09-02 23:34:17 +08:00
|
|
|
#include <common/string_utils.h>
|
2020-03-25 22:38:44 +08:00
|
|
|
|
2020-11-17 16:38:19 +08:00
|
|
|
namespace FancyZonesDataTypes
|
|
|
|
{
|
|
|
|
struct DeviceIdData;
|
|
|
|
}
|
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
namespace FancyZonesUtils
|
2019-09-05 00:26:26 +08:00
|
|
|
{
|
2020-08-25 01:38:15 +08:00
|
|
|
struct Rect
|
2019-09-05 00:26:26 +08:00
|
|
|
{
|
2020-08-25 01:38:15 +08:00
|
|
|
Rect() {}
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
Rect(RECT rect) :
|
|
|
|
m_rect(rect)
|
|
|
|
{
|
|
|
|
}
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
Rect(RECT rect, UINT dpi) :
|
|
|
|
m_rect(rect)
|
|
|
|
{
|
|
|
|
m_rect.right = m_rect.left + MulDiv(m_rect.right - m_rect.left, dpi, 96);
|
|
|
|
m_rect.bottom = m_rect.top + MulDiv(m_rect.bottom - m_rect.top, dpi, 96);
|
|
|
|
}
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
int x() const { return m_rect.left; }
|
|
|
|
int y() const { return m_rect.top; }
|
|
|
|
int width() const { return m_rect.right - m_rect.left; }
|
|
|
|
int height() const { return m_rect.bottom - m_rect.top; }
|
|
|
|
int left() const { return m_rect.left; }
|
|
|
|
int top() const { return m_rect.top; }
|
|
|
|
int right() const { return m_rect.right; }
|
|
|
|
int bottom() const { return m_rect.bottom; }
|
|
|
|
int aspectRatio() const { return MulDiv(m_rect.bottom - m_rect.top, 100, m_rect.right - m_rect.left); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
RECT m_rect{};
|
|
|
|
};
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
inline void MakeWindowTransparent(HWND window)
|
2020-02-10 21:59:51 +08:00
|
|
|
{
|
2020-08-25 01:38:15 +08:00
|
|
|
int const pos = -GetSystemMetrics(SM_CXVIRTUALSCREEN) - 8;
|
|
|
|
if (wil::unique_hrgn hrgn{ CreateRectRgn(pos, 0, (pos + 1), 1) })
|
|
|
|
{
|
|
|
|
DWM_BLURBEHIND bh = { DWM_BB_ENABLE | DWM_BB_BLURREGION, TRUE, hrgn.get(), FALSE };
|
|
|
|
DwmEnableBlurBehindWindow(window, &bh);
|
|
|
|
}
|
2020-02-10 21:59:51 +08:00
|
|
|
}
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
inline void InitRGB(_Out_ RGBQUAD* quad, BYTE alpha, COLORREF color)
|
2019-09-05 00:26:26 +08:00
|
|
|
{
|
2020-08-25 01:38:15 +08:00
|
|
|
ZeroMemory(quad, sizeof(*quad));
|
|
|
|
quad->rgbReserved = alpha;
|
|
|
|
quad->rgbRed = GetRValue(color) * alpha / 255;
|
|
|
|
quad->rgbGreen = GetGValue(color) * alpha / 255;
|
|
|
|
quad->rgbBlue = GetBValue(color) * alpha / 255;
|
2019-09-05 00:26:26 +08:00
|
|
|
}
|
2020-08-25 01:38:15 +08:00
|
|
|
|
|
|
|
inline void FillRectARGB(wil::unique_hdc& hdc, RECT const* prcFill, BYTE alpha, COLORREF color, bool blendAlpha)
|
2019-09-05 00:26:26 +08:00
|
|
|
{
|
2020-08-25 01:38:15 +08:00
|
|
|
BITMAPINFO bi;
|
|
|
|
ZeroMemory(&bi, sizeof(bi));
|
|
|
|
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
|
bi.bmiHeader.biWidth = 1;
|
|
|
|
bi.bmiHeader.biHeight = 1;
|
|
|
|
bi.bmiHeader.biPlanes = 1;
|
|
|
|
bi.bmiHeader.biBitCount = 32;
|
|
|
|
bi.bmiHeader.biCompression = BI_RGB;
|
|
|
|
|
|
|
|
RECT fillRect;
|
|
|
|
CopyRect(&fillRect, prcFill);
|
|
|
|
|
|
|
|
RGBQUAD bitmapBits;
|
|
|
|
InitRGB(&bitmapBits, alpha, color);
|
|
|
|
StretchDIBits(
|
|
|
|
hdc.get(),
|
|
|
|
fillRect.left,
|
|
|
|
fillRect.top,
|
|
|
|
fillRect.right - fillRect.left,
|
|
|
|
fillRect.bottom - fillRect.top,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
1,
|
|
|
|
1,
|
|
|
|
&bitmapBits,
|
|
|
|
&bi,
|
|
|
|
DIB_RGB_COLORS,
|
|
|
|
SRCCOPY);
|
2019-09-05 00:26:26 +08:00
|
|
|
}
|
2020-01-07 01:59:18 +08:00
|
|
|
|
2020-09-02 23:34:17 +08:00
|
|
|
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);
|
2020-09-03 22:50:49 +08:00
|
|
|
const BYTE nR = static_cast<BYTE>((tmp & 0xFF0000) >> 16);
|
|
|
|
const BYTE nG = static_cast<BYTE>((tmp & 0xFF00) >> 8);
|
|
|
|
const BYTE nB = static_cast<BYTE>((tmp & 0xFF));
|
2020-09-02 23:34:17 +08:00
|
|
|
return RGB(nR, nG, nB);
|
|
|
|
}
|
|
|
|
catch (const std::exception&)
|
|
|
|
{
|
|
|
|
return fallbackColor;
|
|
|
|
}
|
|
|
|
}
|
2020-08-07 16:06:25 +08:00
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
inline BYTE OpacitySettingToAlpha(int opacity)
|
|
|
|
{
|
|
|
|
return static_cast<BYTE>(opacity * 2.55);
|
|
|
|
}
|
2020-08-07 16:06:25 +08:00
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
template<RECT MONITORINFO::*member>
|
|
|
|
RECT GetAllMonitorsCombinedRect()
|
2020-08-07 16:06:25 +08:00
|
|
|
{
|
2020-08-25 01:38:15 +08:00
|
|
|
auto allMonitors = GetAllMonitorRects<member>();
|
|
|
|
bool empty = true;
|
|
|
|
RECT result{ 0, 0, 0, 0 };
|
|
|
|
|
|
|
|
for (auto& [monitor, rect] : allMonitors)
|
2020-08-07 16:06:25 +08:00
|
|
|
{
|
2020-08-25 01:38:15 +08:00
|
|
|
if (empty)
|
|
|
|
{
|
|
|
|
empty = false;
|
|
|
|
result = rect;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result.left = min(result.left, rect.left);
|
|
|
|
result.top = min(result.top, rect.top);
|
|
|
|
result.right = max(result.right, rect.right);
|
|
|
|
result.bottom = max(result.bottom, rect.bottom);
|
|
|
|
}
|
2020-08-07 16:06:25 +08:00
|
|
|
}
|
2020-08-25 01:38:15 +08:00
|
|
|
|
|
|
|
return result;
|
2020-08-07 16:06:25 +08:00
|
|
|
}
|
|
|
|
|
2020-12-07 22:57:53 +08:00
|
|
|
std::wstring GetDisplayDeviceId(const std::wstring& device, std::unordered_map<std::wstring, DWORD>& displayDeviceIdxMap);
|
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
UINT GetDpiForMonitor(HMONITOR monitor) noexcept;
|
|
|
|
void OrderMonitors(std::vector<std::pair<HMONITOR, RECT>>& monitorInfo);
|
|
|
|
void SizeWindowToRect(HWND window, RECT rect) noexcept;
|
2020-08-07 16:06:25 +08:00
|
|
|
|
2020-09-15 19:03:17 +08:00
|
|
|
bool HasNoVisibleOwner(HWND window) noexcept;
|
|
|
|
bool IsStandardWindow(HWND window);
|
2020-08-28 21:00:21 +08:00
|
|
|
bool IsCandidateForLastKnownZone(HWND window, const std::vector<std::wstring>& excludedApps) noexcept;
|
|
|
|
bool IsCandidateForZoning(HWND window, const std::vector<std::wstring>& excludedApps) noexcept;
|
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
bool IsWindowMaximized(HWND window) noexcept;
|
|
|
|
void SaveWindowSizeAndOrigin(HWND window) noexcept;
|
|
|
|
void RestoreWindowSize(HWND window) noexcept;
|
|
|
|
void RestoreWindowOrigin(HWND window) noexcept;
|
2020-04-30 18:16:08 +08:00
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
bool IsValidGuid(const std::wstring& str);
|
2020-11-17 16:38:19 +08:00
|
|
|
|
|
|
|
std::wstring GenerateUniqueId(HMONITOR monitor, const std::wstring& devideId, const std::wstring& virtualDesktopId);
|
|
|
|
std::wstring GenerateUniqueIdAllMonitorsArea(const std::wstring& virtualDesktopId);
|
|
|
|
|
|
|
|
std::wstring TrimDeviceId(const std::wstring& deviceId);
|
|
|
|
std::optional<FancyZonesDataTypes::DeviceIdData> ParseDeviceId(const std::wstring& deviceId);
|
2020-08-25 01:38:15 +08:00
|
|
|
bool IsValidDeviceId(const std::wstring& str);
|
2020-07-22 16:39:13 +08:00
|
|
|
|
2020-08-25 01:38:15 +08:00
|
|
|
RECT PrepareRectForCycling(RECT windowRect, RECT zoneWindowRect, DWORD vkCode) noexcept;
|
|
|
|
size_t ChooseNextZoneByPosition(DWORD vkCode, RECT windowRect, const std::vector<RECT>& zoneRects) noexcept;
|
|
|
|
}
|