diff --git a/src/modules/fancyzones/dll/dllmain.cpp b/src/modules/fancyzones/dll/dllmain.cpp index a5d1a63158..19dd123748 100644 --- a/src/modules/fancyzones/dll/dllmain.cpp +++ b/src/modules/fancyzones/dll/dllmain.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include +#include #include #include #include @@ -27,29 +28,18 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser return TRUE; } -// TODO: multimon support, need to pass the HMONITOR from the editor to here instead -// of using MonitorFromPoint // This function is exported and called from FancyZonesEditor.exe to save a layout from the editor. STDAPI PersistZoneSet( PCWSTR activeKey, // Registry key holding ActiveZoneSet + PCWSTR resolutionKey, // Registry key to persist ZoneSet to HMONITOR monitor, WORD layoutId, // LayoutModel Id int zoneCount, // Number of zones in zones int zones[]) // Array of zones serialized in left/top/right/bottom chunks { // See if we have already persisted this layout we can update. - std::wstringstream stream; - MONITORINFOEX mi; - mi.cbSize = sizeof(mi); - if (GetMonitorInfo(monitor, &mi)) - { - stream << (mi.rcMonitor.right - mi.rcMonitor.left) << "_"; - stream << (mi.rcMonitor.bottom - mi.rcMonitor.top); - } - - std::wstring resolutionKey(stream.str()); UUID id{GUID_NULL}; - if (wil::unique_hkey key{ RegistryHelpers::OpenKey(resolutionKey.c_str()) }) + if (wil::unique_hkey key{ RegistryHelpers::OpenKey(resolutionKey) }) { ZoneSetPersistedData data{}; DWORD dataSize = sizeof(data); @@ -84,7 +74,7 @@ STDAPI PersistZoneSet( id, layoutId, reinterpret_cast(monitor), - resolutionKey.c_str(), + resolutionKey, ZoneSetLayout::Custom, 0, 0, 0)); diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs index ddc1f94bef..f86f47439d 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs @@ -155,6 +155,7 @@ namespace FancyZonesEditor.Models internal delegate int PersistZoneSet( [MarshalAs(UnmanagedType.LPWStr)] string activeKey, + [MarshalAs(UnmanagedType.LPWStr)] string resolutionKey, uint monitor, ushort layoutId, int zoneCount, @@ -201,7 +202,7 @@ namespace FancyZonesEditor.Models } var persistZoneSet = Marshal.GetDelegateForFunctionPointer(pfn); - persistZoneSet(Settings.UniqueKey, Settings.Monitor, _id, zoneCount, zoneArray); + persistZoneSet(Settings.UniqueKey, Settings.WorkAreaKey, Settings.Monitor, _id, zoneCount, zoneArray); } private static readonly string c_registryPath = Settings.RegistryPath + "\\Layouts"; diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/Settings.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/Settings.cs index f5098f04ed..0f19c51703 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/Settings.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/Settings.cs @@ -153,6 +153,12 @@ namespace FancyZonesEditor private static String _uniqueKey; private String _uniqueRegistryPath; + public static String WorkAreaKey + { + get { return _workAreaKey; } + } + private static String _workAreaKey; + public static float Dpi { get { return _dpi; } @@ -267,26 +273,27 @@ namespace FancyZonesEditor _dpi = 1; string[] args = Environment.GetCommandLineArgs(); - if (args.Length == 6) + if (args.Length == 7) { // 1 = unique key for per-monitor settings - // 2 = layoutid used to generate current layout - // 3 = handle to foreground window (used to figure out which monitor to show on) - // 4 = handle to monitor (passed back to engine to persist data) - // 5 = monitor DPI (float) + // 2 = layoutid used to generate current layout (used to pick the default layout to show) + // 3 = handle to monitor (passed back to engine to persist data) + // 4 = X_Y_Width_Height (where EditorOverlay shows up) + // 5 = resolution key (passed back to engine to persist data) + // 6 = monitor DPI (float) _uniqueKey = args[1]; _uniqueRegistryPath += "\\" + _uniqueKey; - var foregroundWindow = new IntPtr(uint.Parse(args[3])); - var screen = System.Windows.Forms.Screen.FromHandle(foregroundWindow); + var parsedLocation = args[4].Split('_'); + var x = int.Parse(parsedLocation[0]); + var y = int.Parse(parsedLocation[1]); + var width = int.Parse(parsedLocation[2]); + var height = int.Parse(parsedLocation[3]); - _dpi = float.Parse(args[5]); - _workArea = new Rect( - screen.WorkingArea.X / _dpi, - screen.WorkingArea.Y / _dpi, - screen.WorkingArea.Width / _dpi, - screen.WorkingArea.Height / _dpi); + _workAreaKey = args[5]; + _dpi = float.Parse(args[6]); + _workArea = new Rect(x, y, width, height); uint monitor = 0; if (uint.TryParse(args[4], out monitor)) diff --git a/src/modules/fancyzones/lib/FancyZones.cpp b/src/modules/fancyzones/lib/FancyZones.cpp index 00f0a8449b..0b578add72 100644 --- a/src/modules/fancyzones/lib/FancyZones.cpp +++ b/src/modules/fancyzones/lib/FancyZones.cpp @@ -249,11 +249,23 @@ void FancyZones::ToggleEditor() noexcept UINT dpi_y = 96; DPIAware::GetScreenDPIForWindow(foregroundWindow, dpi_x, dpi_y); + MONITORINFOEX mi; + mi.cbSize = sizeof(mi); + GetMonitorInfo(monitor, &mi); + + // Location that the editor should occupy, scaled by DPI + std::wstring editorLocation = + std::to_wstring(MulDiv(mi.rcWork.left, 96, dpi_x)) + L"_" + + std::to_wstring(MulDiv(mi.rcWork.top, 96, dpi_y)) + L"_" + + std::to_wstring(MulDiv(mi.rcWork.right - mi.rcWork.left, 96, dpi_x)) + L"_" + + std::to_wstring(MulDiv(mi.rcWork.bottom - mi.rcWork.top, 96, dpi_y)); + const std::wstring params = iter->second->UniqueId() + L" " + std::to_wstring(iter->second->ActiveZoneSet()->LayoutId()) + L" " + - std::to_wstring(reinterpret_cast(foregroundWindow)) + L" " + std::to_wstring(reinterpret_cast(monitor)) + L" " + + editorLocation + L" " + + iter->second->WorkAreaKey() + L" " + std::to_wstring(static_cast(dpi_x) / 96.0f); SHELLEXECUTEINFO sei{ sizeof(sei) }; diff --git a/src/modules/fancyzones/lib/ZoneWindow.cpp b/src/modules/fancyzones/lib/ZoneWindow.cpp index 8b2aaf76b6..d7b1666c7e 100644 --- a/src/modules/fancyzones/lib/ZoneWindow.cpp +++ b/src/modules/fancyzones/lib/ZoneWindow.cpp @@ -18,6 +18,7 @@ public: IFACEMETHODIMP_(void) CycleActiveZoneSet(DWORD vkCode) noexcept; IFACEMETHODIMP_(std::wstring) DeviceId() noexcept { return { m_deviceId.get() }; } IFACEMETHODIMP_(std::wstring) UniqueId() noexcept { return { m_uniqueId }; } + IFACEMETHODIMP_(std::wstring) WorkAreaKey() noexcept { return { m_workArea }; } IFACEMETHODIMP_(void) SaveWindowProcessToZoneIndex(HWND window) noexcept; IFACEMETHODIMP_(IZoneSet*) ActiveZoneSet() noexcept { return m_activeZoneSet.get(); } diff --git a/src/modules/fancyzones/lib/ZoneWindow.h b/src/modules/fancyzones/lib/ZoneWindow.h index 7979ee9216..566a520ee5 100644 --- a/src/modules/fancyzones/lib/ZoneWindow.h +++ b/src/modules/fancyzones/lib/ZoneWindow.h @@ -16,6 +16,7 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow IFACEMETHOD_(void, SaveWindowProcessToZoneIndex)(HWND window) = 0; IFACEMETHOD_(std::wstring, DeviceId)() = 0; IFACEMETHOD_(std::wstring, UniqueId)() = 0; + IFACEMETHOD_(std::wstring, WorkAreaKey)() = 0; IFACEMETHOD_(IZoneSet*, ActiveZoneSet)() = 0; };