Search code examples
winapidpidirect2d

ID2D1RenderTarget::GetSize returing physical pixels instead of DIP


I'm currently getting started with Win32 and Direct2D and reached the chapter on DPI and DIP. At the very bottom it says ID2D1RenderTarget::GetSize returns size as DIP and ID2D1RenderTarget::GetPixelSize as physical pixels. Their individual documentation confirms that. However I cannot observe that ID2D1RenderTarget::GetSize actually returns DIP.

I tested it by

  1. setting the scale of one of my two otherwise identical displays to 175%,
  2. adding <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness> to my application manifest,
  3. obtaining

    D2D1_SIZE_U sizeP = pRenderTarget->GetPixelSize();
    D2D1_SIZE_F size = pRenderTarget->GetSize();
    

    in method MainWindow::CalculateLayout from this example (and printing the values),

  4. and moving the window from one screen to the other, and arbitrarily resizing it.

I can see the window-border changing size when moving from one display to another. However, the values in both sizeP and size (besides being int and float) are always identical and correspond to the physical size of the ID2D1HwndRenderTarget.

Since I do not expect the documentation to be flawed, I wonder what I am missing to actually get the DIP of the window of the ID2D1HwndRenderTarget pRenderTarget.


Solution

  • The size is only relative to the DPI of the render target, set using ID2D1RenderTarget::SetDpi. This value is not automatically connected to the value provided by the display system, which can be queried using ID2D1Factory::GetDesktopDpi or GetDpiForMonitor.