diff --git a/src/common/common.cpp b/src/common/common.cpp index 5a781b756..5be74b36e 100644 --- a/src/common/common.cpp +++ b/src/common/common.cpp @@ -17,19 +17,6 @@ namespace localized_strings const wchar_t LAST_ERROR_TITLE_STRING[] = L"Error"; } -std::optional get_button_pos(HWND hwnd) -{ - RECT button; - if (DwmGetWindowAttribute(hwnd, DWMWA_CAPTION_BUTTON_BOUNDS, &button, sizeof(RECT)) == S_OK) - { - return button; - } - else - { - return {}; - } -} - std::optional get_window_pos(HWND hwnd) { RECT window; @@ -43,19 +30,6 @@ std::optional get_window_pos(HWND hwnd) } } -std::optional get_mouse_pos() -{ - POINT point; - if (GetCursorPos(&point) == 0) - { - return {}; - } - else - { - return point; - } -} - bool is_system_window(HWND hwnd, const char* class_name) { // We compare the HWND against HWND of the desktop and shell windows, @@ -79,74 +53,6 @@ bool is_system_window(HWND hwnd, const char* class_name) return false; } -int width(const RECT& rect) -{ - return rect.right - rect.left; -} - -int height(const RECT& rect) -{ - return rect.bottom - rect.top; -} - -bool operator<(const RECT& lhs, const RECT& rhs) -{ - auto lhs_tuple = std::make_tuple(lhs.left, lhs.right, lhs.top, lhs.bottom); - auto rhs_tuple = std::make_tuple(rhs.left, rhs.right, rhs.top, rhs.bottom); - return lhs_tuple < rhs_tuple; -} - -RECT keep_rect_inside_rect(const RECT& small_rect, const RECT& big_rect) -{ - RECT result = small_rect; - if ((result.right - result.left) > (big_rect.right - big_rect.left)) - { - // small_rect is too big horizontally. resize it. - result.right = big_rect.right; - result.left = big_rect.left; - } - else - { - if (result.right > big_rect.right) - { - // move the rect left. - result.left -= result.right - big_rect.right; - result.right -= result.right - big_rect.right; - } - - if (result.left < big_rect.left) - { - // move the rect right. - result.right += big_rect.left - result.left; - result.left += big_rect.left - result.left; - } - } - - if ((result.bottom - result.top) > (big_rect.bottom - big_rect.top)) - { - // small_rect is too big vertically. resize it. - result.bottom = big_rect.bottom; - result.top = big_rect.top; - } - else - { - if (result.bottom > big_rect.bottom) - { - // move the rect up. - result.top -= result.bottom - big_rect.bottom; - result.bottom -= result.bottom - big_rect.bottom; - } - - if (result.top < big_rect.top) - { - // move the rect down. - result.bottom += big_rect.top - result.top; - result.top += big_rect.top - result.top; - } - } - return result; -} - int run_message_loop(const bool until_idle, const std::optional timeout_seconds) { MSG msg; diff --git a/src/common/common.h b/src/common/common.h index 5044b1339..4d9c5f5fd 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -6,23 +6,12 @@ #include #include -// Returns RECT with positions of the minimize/maximize buttons of the given window. -// Does not always work, since some apps draw custom toolbars. -std::optional get_button_pos(HWND hwnd); // Gets position of given window. std::optional get_window_pos(HWND hwnd); -// Gets mouse position. -std::optional get_mouse_pos(); + // Check if window is part of the shell or the taskbar. bool is_system_window(HWND hwnd, const char* class_name); -// Calculate sizes -int width(const RECT& rect); -int height(const RECT& rect); -// Compare rects -bool operator<(const RECT& lhs, const RECT& rhs); -// Moves and/or resizes small_rect to fit inside big_rect. -RECT keep_rect_inside_rect(const RECT& small_rect, const RECT& big_rect); // Initializes and runs windows message loop int run_message_loop(const bool until_idle = false, const std::optional timeout_seconds = {}); @@ -107,5 +96,3 @@ struct overloaded : Ts... }; template overloaded(Ts...) -> overloaded; - -#define POWER_LAUNCHER_PID_SHARED_FILE L"Local\\3cbfbad4-199b-4e2c-9825-942d5d3d3c74" diff --git a/src/common/monitors.cpp b/src/common/monitors.cpp index 4acb0d048..1ad10aaff 100644 --- a/src/common/monitors.cpp +++ b/src/common/monitors.cpp @@ -4,6 +4,16 @@ #include "common.h" +namespace +{ + bool operator<(const RECT& lhs, const RECT& rhs) + { + auto lhs_tuple = std::make_tuple(lhs.left, lhs.right, lhs.top, lhs.bottom); + auto rhs_tuple = std::make_tuple(rhs.left, rhs.right, rhs.top, rhs.bottom); + return lhs_tuple < rhs_tuple; + } +} + bool operator==(const ScreenSize& lhs, const ScreenSize& rhs) { auto lhs_tuple = std::make_tuple(lhs.rect.left, lhs.rect.right, lhs.rect.top, lhs.rect.bottom); diff --git a/src/modules/fancyzones/lib/FancyZonesLib.vcxproj b/src/modules/fancyzones/lib/FancyZonesLib.vcxproj index 29c395eaa..4352317af 100644 --- a/src/modules/fancyzones/lib/FancyZonesLib.vcxproj +++ b/src/modules/fancyzones/lib/FancyZonesLib.vcxproj @@ -123,6 +123,7 @@ + @@ -143,6 +144,7 @@ + diff --git a/src/modules/fancyzones/lib/FancyZonesLib.vcxproj.filters b/src/modules/fancyzones/lib/FancyZonesLib.vcxproj.filters index 620e7c6e8..d0d30891c 100644 --- a/src/modules/fancyzones/lib/FancyZonesLib.vcxproj.filters +++ b/src/modules/fancyzones/lib/FancyZonesLib.vcxproj.filters @@ -74,6 +74,9 @@ Header Files + + Header Files + @@ -124,6 +127,9 @@ Source Files + + Source Files + diff --git a/src/modules/fancyzones/lib/ZoneWindow.cpp b/src/modules/fancyzones/lib/ZoneWindow.cpp index 24c4271eb..fc21e6de5 100644 --- a/src/modules/fancyzones/lib/ZoneWindow.cpp +++ b/src/modules/fancyzones/lib/ZoneWindow.cpp @@ -5,6 +5,7 @@ #include "FancyZonesData.h" #include "FancyZonesDataTypes.h" #include "ZoneWindow.h" +#include "ZoneWindowDrawing.h" #include "trace.h" #include "util.h" #include "Settings.h" @@ -18,7 +19,6 @@ // Non-Localizable strings namespace NonLocalizable { - const wchar_t SegoeUiFont[] = L"Segoe ui"; const wchar_t ToolWindowClassName[] = L"SuperFancyZones_ZoneWindow"; } @@ -60,135 +60,6 @@ namespace ZoneWindowUtils } } -namespace ZoneWindowDrawUtils -{ - struct ColorSetting - { - BYTE fillAlpha{}; - COLORREF fill{}; - BYTE borderAlpha{}; - COLORREF border{}; - int thickness{}; - }; - - void DrawBackdrop(wil::unique_hdc& hdc, RECT const& clientRect) noexcept - { - FillRectARGB(hdc, &clientRect, 0, RGB(0, 0, 0), false); - } - - void DrawIndex(wil::unique_hdc& hdc, Rect rect, size_t index) - { - Gdiplus::Graphics g(hdc.get()); - - Gdiplus::FontFamily fontFamily(NonLocalizable::SegoeUiFont); - Gdiplus::Font font(&fontFamily, 80, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); - Gdiplus::SolidBrush solidBrush(Gdiplus::Color(255, 0, 0, 0)); - - std::wstring text = std::to_wstring(index); - - g.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); - Gdiplus::StringFormat stringFormat = new Gdiplus::StringFormat(); - stringFormat.SetAlignment(Gdiplus::StringAlignmentCenter); - stringFormat.SetLineAlignment(Gdiplus::StringAlignmentCenter); - - Gdiplus::RectF gdiRect(static_cast(rect.left()), - static_cast(rect.top()), - static_cast(rect.width()), - static_cast(rect.height())); - - g.DrawString(text.c_str(), -1, &font, gdiRect, &stringFormat, &solidBrush); - } - - void DrawZone(wil::unique_hdc& hdc, ColorSetting const& colorSetting, winrt::com_ptr zone, const std::vector>& zones, bool flashMode) noexcept - { - RECT zoneRect = zone->GetZoneRect(); - - Gdiplus::Graphics g(hdc.get()); - Gdiplus::Color fillColor(colorSetting.fillAlpha, GetRValue(colorSetting.fill), GetGValue(colorSetting.fill), GetBValue(colorSetting.fill)); - Gdiplus::Color borderColor(colorSetting.borderAlpha, GetRValue(colorSetting.border), GetGValue(colorSetting.border), GetBValue(colorSetting.border)); - - Gdiplus::Rect rectangle(zoneRect.left, zoneRect.top, zoneRect.right - zoneRect.left - 1, zoneRect.bottom - zoneRect.top - 1); - - Gdiplus::Pen pen(borderColor, static_cast(colorSetting.thickness)); - g.FillRectangle(new Gdiplus::SolidBrush(fillColor), rectangle); - g.DrawRectangle(&pen, rectangle); - - if (!flashMode) - { - DrawIndex(hdc, zoneRect, zone->Id()); - } - } - - void DrawActiveZoneSet(wil::unique_hdc& hdc, - COLORREF zoneColor, - COLORREF zoneBorderColor, - COLORREF highlightColor, - int zoneOpacity, - const std::vector>& zones, - const std::vector& highlightZones, - bool flashMode, - bool drawHints) noexcept - { - // { fillAlpha, fill, borderAlpha, border, thickness } - ColorSetting const colorHints{ OpacitySettingToAlpha(zoneOpacity), RGB(81, 92, 107), 255, RGB(104, 118, 138), -2 }; - ColorSetting colorViewer{ OpacitySettingToAlpha(zoneOpacity), 0, 255, RGB(40, 50, 60), -2 }; - ColorSetting colorHighlight{ OpacitySettingToAlpha(zoneOpacity), 0, 255, 0, -2 }; - ColorSetting const colorFlash{ OpacitySettingToAlpha(zoneOpacity), RGB(81, 92, 107), 200, RGB(104, 118, 138), -2 }; - - std::vector isHighlighted(zones.size(), false); - for (size_t x : highlightZones) - { - isHighlighted[x] = true; - } - - // First draw the inactive zones - for (auto iter = zones.begin(); iter != zones.end(); iter++) - { - size_t zoneId = iter - zones.begin(); - winrt::com_ptr zone = iter->try_as(); - if (!zone) - { - continue; - } - - if (!isHighlighted[zoneId]) - { - if (flashMode) - { - DrawZone(hdc, colorFlash, zone, zones, flashMode); - } - else if (drawHints) - { - DrawZone(hdc, colorHints, zone, zones, flashMode); - } - { - colorViewer.fill = zoneColor; - colorViewer.border = zoneBorderColor; - DrawZone(hdc, colorViewer, zone, zones, flashMode); - } - } - } - - // Draw the active zones on top of the inactive zones - for (auto iter = zones.begin(); iter != zones.end(); iter++) - { - size_t zoneId = iter - zones.begin(); - winrt::com_ptr zone = iter->try_as(); - if (!zone) - { - continue; - } - - if (isHighlighted[zoneId]) - { - colorHighlight.fill = highlightColor; - colorHighlight.border = zoneBorderColor; - DrawZone(hdc, colorHighlight, zone, zones, flashMode); - } - } - } -} - struct ZoneWindow : public winrt::implements { public: @@ -718,11 +589,11 @@ void ZoneWindow::OnPaint(wil::unique_hdc& hdc) noexcept HPAINTBUFFER bufferedPaint = BeginBufferedPaint(hdc.get(), &clientRect, BPBF_TOPDOWNDIB, nullptr, &hdcMem); if (bufferedPaint) { - ZoneWindowDrawUtils::DrawBackdrop(hdcMem, clientRect); + ZoneWindowDrawing::DrawBackdrop(hdcMem, clientRect); if (m_activeZoneSet && m_host) { - ZoneWindowDrawUtils::DrawActiveZoneSet(hdcMem, + ZoneWindowDrawing::DrawActiveZoneSet(hdcMem, m_host->GetZoneColor(), m_host->GetZoneBorderColor(), m_host->GetZoneHighlightColor(), diff --git a/src/modules/fancyzones/lib/ZoneWindowDrawing.cpp b/src/modules/fancyzones/lib/ZoneWindowDrawing.cpp new file mode 100644 index 000000000..59b2c27f4 --- /dev/null +++ b/src/modules/fancyzones/lib/ZoneWindowDrawing.cpp @@ -0,0 +1,178 @@ +#include "pch.h" +#include "ZoneWindowDrawing.h" + +#include + +namespace NonLocalizable +{ + const wchar_t SegoeUiFont[] = L"Segoe ui"; +} + +namespace +{ + void InitRGB(_Out_ RGBQUAD* quad, BYTE alpha, COLORREF color) + { + 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; + } + + void FillRectARGB(wil::unique_hdc& hdc, RECT const* prcFill, BYTE alpha, COLORREF color, bool blendAlpha) + { + 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); + } + + BYTE OpacitySettingToAlpha(int opacity) + { + return static_cast(opacity * 2.55); + } + + void DrawIndex(wil::unique_hdc& hdc, FancyZonesUtils::Rect rect, size_t index) + { + Gdiplus::Graphics g(hdc.get()); + + Gdiplus::FontFamily fontFamily(NonLocalizable::SegoeUiFont); + Gdiplus::Font font(&fontFamily, 80, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); + Gdiplus::SolidBrush solidBrush(Gdiplus::Color(255, 0, 0, 0)); + + std::wstring text = std::to_wstring(index); + + g.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); + Gdiplus::StringFormat stringFormat = new Gdiplus::StringFormat(); + stringFormat.SetAlignment(Gdiplus::StringAlignmentCenter); + stringFormat.SetLineAlignment(Gdiplus::StringAlignmentCenter); + + Gdiplus::RectF gdiRect(static_cast(rect.left()), + static_cast(rect.top()), + static_cast(rect.width()), + static_cast(rect.height())); + + g.DrawString(text.c_str(), -1, &font, gdiRect, &stringFormat, &solidBrush); + } + + void DrawZone(wil::unique_hdc& hdc, ZoneWindowDrawing::ColorSetting const& colorSetting, winrt::com_ptr zone, const std::vector>& zones, bool flashMode) noexcept + { + RECT zoneRect = zone->GetZoneRect(); + + Gdiplus::Graphics g(hdc.get()); + Gdiplus::Color fillColor(colorSetting.fillAlpha, GetRValue(colorSetting.fill), GetGValue(colorSetting.fill), GetBValue(colorSetting.fill)); + Gdiplus::Color borderColor(colorSetting.borderAlpha, GetRValue(colorSetting.border), GetGValue(colorSetting.border), GetBValue(colorSetting.border)); + + Gdiplus::Rect rectangle(zoneRect.left, zoneRect.top, zoneRect.right - zoneRect.left - 1, zoneRect.bottom - zoneRect.top - 1); + + Gdiplus::Pen pen(borderColor, static_cast(colorSetting.thickness)); + g.FillRectangle(new Gdiplus::SolidBrush(fillColor), rectangle); + g.DrawRectangle(&pen, rectangle); + + if (!flashMode) + { + DrawIndex(hdc, zoneRect, zone->Id()); + } + } +} + +namespace ZoneWindowDrawing +{ + void DrawBackdrop(wil::unique_hdc& hdc, RECT const& clientRect) noexcept + { + FillRectARGB(hdc, &clientRect, 0, RGB(0, 0, 0), false); + } + + void DrawActiveZoneSet(wil::unique_hdc& hdc, + COLORREF zoneColor, + COLORREF zoneBorderColor, + COLORREF highlightColor, + int zoneOpacity, + const std::vector>& zones, + const std::vector& highlightZones, + bool flashMode, + bool drawHints) noexcept + { + // { fillAlpha, fill, borderAlpha, border, thickness } + ColorSetting const colorHints{ OpacitySettingToAlpha(zoneOpacity), RGB(81, 92, 107), 255, RGB(104, 118, 138), -2 }; + ColorSetting colorViewer{ OpacitySettingToAlpha(zoneOpacity), 0, 255, RGB(40, 50, 60), -2 }; + ColorSetting colorHighlight{ OpacitySettingToAlpha(zoneOpacity), 0, 255, 0, -2 }; + ColorSetting const colorFlash{ OpacitySettingToAlpha(zoneOpacity), RGB(81, 92, 107), 200, RGB(104, 118, 138), -2 }; + + std::vector isHighlighted(zones.size(), false); + for (int x : highlightZones) + { + isHighlighted[x] = true; + } + + // First draw the inactive zones + for (auto iter = zones.begin(); iter != zones.end(); iter++) + { + int zoneId = static_cast(iter - zones.begin()); + winrt::com_ptr zone = iter->try_as(); + if (!zone) + { + continue; + } + + if (!isHighlighted[zoneId]) + { + if (flashMode) + { + DrawZone(hdc, colorFlash, zone, zones, flashMode); + } + else if (drawHints) + { + DrawZone(hdc, colorHints, zone, zones, flashMode); + } + { + colorViewer.fill = zoneColor; + colorViewer.border = zoneBorderColor; + DrawZone(hdc, colorViewer, zone, zones, flashMode); + } + } + } + + // Draw the active zones on top of the inactive zones + for (auto iter = zones.begin(); iter != zones.end(); iter++) + { + int zoneId = static_cast(iter - zones.begin()); + winrt::com_ptr zone = iter->try_as(); + if (!zone) + { + continue; + } + + if (isHighlighted[zoneId]) + { + colorHighlight.fill = highlightColor; + colorHighlight.border = zoneBorderColor; + DrawZone(hdc, colorHighlight, zone, zones, flashMode); + } + } + } +} diff --git a/src/modules/fancyzones/lib/ZoneWindowDrawing.h b/src/modules/fancyzones/lib/ZoneWindowDrawing.h new file mode 100644 index 000000000..14bb0f581 --- /dev/null +++ b/src/modules/fancyzones/lib/ZoneWindowDrawing.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include + +#include "util.h" +#include "Zone.h" + +namespace ZoneWindowDrawing +{ + struct ColorSetting + { + BYTE fillAlpha{}; + COLORREF fill{}; + BYTE borderAlpha{}; + COLORREF border{}; + int thickness{}; + }; + + void DrawBackdrop(wil::unique_hdc& hdc, RECT const& clientRect) noexcept; + void DrawActiveZoneSet(wil::unique_hdc& hdc, + COLORREF zoneColor, + COLORREF zoneBorderColor, + COLORREF highlightColor, + int zoneOpacity, + const std::vector>& zones, + const std::vector& highlightZones, + bool flashMode, + bool drawHints) noexcept; +} diff --git a/src/modules/fancyzones/lib/util.cpp b/src/modules/fancyzones/lib/util.cpp index cdb612a65..c10c56266 100644 --- a/src/modules/fancyzones/lib/util.cpp +++ b/src/modules/fancyzones/lib/util.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include diff --git a/src/modules/launcher/Microsoft.Launcher/dllmain.cpp b/src/modules/launcher/Microsoft.Launcher/dllmain.cpp index feade6e69..b61bfcd8f 100644 --- a/src/modules/launcher/Microsoft.Launcher/dllmain.cpp +++ b/src/modules/launcher/Microsoft.Launcher/dllmain.cpp @@ -8,6 +8,11 @@ extern "C" IMAGE_DOS_HEADER __ImageBase; +namespace +{ + #define POWER_LAUNCHER_PID_SHARED_FILE L"Local\\3cbfbad4-199b-4e2c-9825-942d5d3d3c74" +} + BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call)