Yngve Hammersland
Yngve Hammersland

Reputation: 1674

Is it possible to set the DPI of an application programatically?

Is it possible to set the DPI of an application programmatically or the DPI only possible to set through the system preference?

Note: My application's GUI is coded in MFC and .NET forms.

Update: After some research I have found no way of doing this so I have to agree with the only answer here; it cannot be done.

Upvotes: 1

Views: 2052

Answers (2)

Heinzi
Heinzi

Reputation: 172200

Yes, there is a way, but it's not easy or pretty.

Story time: A few years ago I had a customer who needed two run two legacy applications on their system: One that would only work with "100%" Windows DPI settings, and another one that used a very small font and would really benefit from a higher Windows DPI setting.

Thus, I wrote a small tool that starts the second application and makes it believe that the Windows DPI setting is different than what it actually is.

This is how I did it:

  • Get a library that allows you to hook into Windows system calls. I used easyhook.

  • Hook into the gdi32 GetDeviceCaps call.

  • If the application requests the screen DPI, return a different value than the real one. The hook code looked something like this:

    int WINAPI myGetDeviceCapsHook(HDC hdc, int nIndex)
    {
        bool isDisplay = (GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY);
    
        if (isDisplay && (nIndex == LOGPIXELSX || nIndex == LOGPIXELSY))
        {
            return fakeDpiValue; // 96 for 100%, 120 for 125%, ...
        }
        else
        {
            return GetDeviceCaps(hdc, nIndex); // pass through to the "real" WinAPI function
        }
    }
    

Some icons and Windows system dialogs were messed up, but, apart from that, it worked surprisingly well -- at least for System-DPI-aware applications (MS Office and most .NET applications back in the day. The legacy application this was targeted at was written with MS Access).

A similar technique might work for Per-Monitor-DPI-aware applications, but since this was not needed, I never looked into it.

Upvotes: 0

tijmenvdk
tijmenvdk

Reputation: 1758

Assuming that you are talking about the Windows system-wide setting that determines the ratio between the physical DPI setting (that depends on the physical screen + resolution), the simple answer is "you can't", at least, not on at the application level in a WinForms app.

What you can do, is add scaling code to your form, see this StackOverflow entry. Basically, set the AutoScaleMode to ScaleMode.Dpi. See the other entry for more info.

Upvotes: 1

Related Questions