Search code examples
winformsgraphicsscreenshotdpibitblt

PrintScreen contents are larger than what I see


I would happily provide a screenshot of this, however the problem is the captured image, is much larger than my actual desktop.

I am completely frustrated with this as I have tried using BitBlt with the desktop hdc AND the new "Graphics" commands.

My actual desktop resolution is 1920x1080 - 1080p .

BitBlt and "Graphics" both return that my resolution is 1536x864 @ 96 DPI.

A form (WinForm), Maximized, borderless, and irrelevant of scaling mode the form is set to, also shows 1536x864 @ 96 DPI.

Now the image that is captured, is like it is being done from 1920x1080, but clipping the region 1536x864 as the screenshot.

If I do PrintScreen directly using Prtscn button, I get the entire image, but still it is about 1.5-2x larger than what I actually see.

What I am looking for -- is a resolution for how I can take a picture of what is on my screen in the scale/dpi/whatever is going on here that it visually looks like. I have written a screen capture program, and using a few different examples for the RubberBand form (overlay form to select a region of the screen by drawing a box), and as you can imagine, this scaling crap is causing those box captures to be offset, and the contents are zoomed.

This is very annoying -- even to explain, however I am positive that most of you are familiar with the terms I use, and also know what to expect from taking a screenshot, so my explanation above should be pretty clear as to what my problem is.

Example/Consideration

Imagine, taking a picture of a window that is 300x300, and getting the top left 150x150 of that zoomed to 300x300 completely skipping the remainder of the window. Resulting image is still 300x300, but it's not what you selected.

Now imagine, you grab a picture of your screen by the only dimensions you can get programmatically, and then put the image into a picturebox. Even though both your screen and the picturebox claim to be the same dimensions and dpi, the image in the picturebox requires scrolling even if the picturebox is maximized to fullscreen on a borderless with no borders / etc. -- again, the picture is zoomed, but how is it still reporting that it's the same size as the form XD (comparing Graphics or BitBlt dimensions with the actual form. also tried comparing picturebox contents, and still same effect)

This, is EXACTLY what the effect is that is happening. When I try to capture a region or segment of the screen. I am not sure why windows api/crl is lying about this seemingly trivial stuff, however there must be a way to accurately obtain screenshots/capture regions without this faux zoom effect -- across all resolutions.


Solution

  • Thank you Hans Passant for pointing me in the right direction.

    To add "true" dpi scaling support to a winforms application, you can make it so by adding the following block to your manifest :

    Project > Add New Item > Visual C# Items > Application Manifest File

    One the file has been added, open it up and look for a line like

    </asmv1:assembly>
    

    Whatever the "asmv" number is, (in the example above it is 1), use that to format the code:

    <asmv1:application>
        <asmv1:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
            <dpiAware>true</dpiAware>
        </asmv1:windowsSettings>
    </asmv1:application>
    

    Paste the above code (changing the asmv1 to whatever version the manifest is), just above the final closing line for the ""

    Also, make sure your forms are set to AutoScale to dpi (and all sub-elements).