Skip to content

Interact with Magpie programally

Blinue edited this page Jun 22, 2024 · 4 revisions

Magpie provides mechanisms for interaction with other programs. Through these mechanisms, your application can cooperate with Magpie.

MagpieWatcher demonstrates how to use these mechanisms.

How to Receive Notifications When Scaling State Changes

You should listen for the MagpieScalingChanged message.

UINT WM_MAGPIE_SCALINGCHANGED = RegisterWindowMessage(L"MagpieScalingChanged");

Parameters

wParam is the event ID. For different events, lParam has different meanings. Currently, two events are supported:

  • 0: Scaling has ended. lParam is not used.
  • 1: Scaling has started. lParam is the handle of the scaling window.

Notes

If your process has a higher integrity level than Magpie, you won't receive messages broadcasted by Magpie due to User Interface Privilege Isolation (UIPI). In such cases, call ChangeWindowMessageFilterEx to allow receiving the MagpieScalingChanged message.

ChangeWindowMessageFilterEx(hYourWindow, WM_MAGPIE_SCALINGCHANGED, MSGFLT_ADD, nullptr);

How to Get the Handle of the Scaling Window

You can listen for the MagpieScalingChanged message to obtain the handle of the scaling window. Additionally, while Magpie is scaling, you can also search for the window with the class name Window_Magpie_967EB565-6F73-4E94-AE53-00CC42592A22. Magpie ensures that this class name remains unchanged and that only one scaling window exists at a time.

HWND hwndScaling = FindWindow(L"Window_Magpie_967EB565-6F73-4E94-AE53-00CC42592A22", nullptr);

How to Place Your Window Above the Scaling Window

Your window must be topmost. You should also listen for the MagpieScalingChanged message; you will receive one after the scaling window is shown, and then you can use BringWindowToTop to place your window above it. The scaling window does not attempt to adjust its position on the Z-axis while it exists.

HWND hWnd = CreateWindowEx(WS_EX_TOPMOST, ...);
...
if (message == WM_MAGPIE_SCALINGCHANGED) {
    switch (wParam) {
        case 0:
            // Scaling has ended
            break;
        case 1:
            // Scaling has started
            // Place this window above the scaling window
            BringWindowToTop(hWnd);
            break;
        default:
            break;
    }
}

How to Obtain Scaling Information

Scaling information is stored in the window properties of the scaling window. Currently available properties include:

  • Magpie.SrcHWND: Handle of the source window
  • Magpie.SrcLeftMagpie.SrcTopMagpie.SrcRightMagpie.SrcBottom: Source region of scaling
  • Magpie.DestLeftMagpie.DestTopMagpie.DestRightMagpie.DestBottom: Destination region of scaling
HWND hwndSrc = (HWND)GetProp(hwndScaling, L"Magpie.SrcHWND");

RECT srcRect;
srcRect.left = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.SrcLeft");
srcRect.top = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.SrcTop");
srcRect.right = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.SrcRight");
srcRect.bottom = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.SrcBottom");

RECT destRect;
destRect.left = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.DestLeft");
destRect.top = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.DestTop");
destRect.right = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.DestRight");
destRect.bottom = (LONG)(INT_PTR)GetProp(hwndScaling, L"Magpie.DestBottom");

Notes

  1. These properties are only guaranteed to exist after the scaling window has completed its initialization. Therefore, it is advisable to check whether the scaling window is visible before retrieving these properties, especially when the window handle is obtained using the class name.
  2. The coordinates stored in these properties are not DPI-virtualized. To use them correctly, you need to set your application's DPI awareness level to Per-Monitor V2. For more details, please refer to High DPI Desktop Application Development on Windows.

How to Keep Magpie Scaling When Your Window Is in the Foreground

Magpie stops scaling when the foreground window changes, with some system windows being exceptions. By setting the Magpie.ToolWindow property, you can include your window and all its owned windows in the exceptions list.

SetProp(hYourWindow, L"Magpie.ToolWindow", (HANDLE)TRUE);

Notes

According to the documentation, you should use RemoveProp to clear this property before your window is destroyed. However, if you forget to do so, there's no need to worry: the system will automatically clean it up.