|
-
Feb 19th, 2018, 07:09 AM
#1
Thread Starter
Frenzied Member
Forcing DPI Manifest to 96DPI AWARE
Hello,
Is it possible to FORCE the app via a manifest to run as 96DPI no matter what the DPI are on the OS environment?
_____________________________________________________________________
----If this post has helped you. Please take time to Rate it.
----If you've solved your problem, then please mark it as RESOLVED from Thread Tools.

-
Feb 19th, 2018, 08:01 AM
#2
Re: Forcing DPI Manifest to 96DPI AWARE
No, it doesn't work that way.
The easiest path is to move to Windows 10 1703 or later and use a manifest to opt in to “System (enhanced)” DPI scaling, i.e. GDI Scaling. This is not perfect and doesn't handle scaling for GDI+, DirectX, etc. but for most normal VB6 programs you just "Set it... and forget it" as Ron Popeil used to say.
This means abandoning down-level support back into history unless those machines run at 96 DPI. Not much of a burden since Win8.x has minimal presence in the world, Win7 losing market share day by day, and everything older is officially dead.
That is as close as you are going to get to what you want. See Improving the high-DPI experience in GDI based Desktop Apps and High-DPI Scaling Improvements for Desktop Applications in the Windows 10 Creators Update.
If you want to keep those contrarians dug in on Win7 going then you have more work ahead.
Anything better than GDI Scaling requires at least old-style "System" DPI Awareness if not "Per-Monitor" or "Per-Monitor V2" DPI Awareness and a lot of careful code to manage scaling. This is helped a lot by avoiding ScaleMode set at pixel or user modes and sticking to absolute measures such as the native and default twips. You still have to correct for fractional twips per pixel here and there as outlined in [VB6] Tutorial: Being DPI Aware.
Last edited by dilettante; Feb 19th, 2018 at 08:05 AM.
-
Feb 19th, 2018, 09:08 AM
#3
Re: Forcing DPI Manifest to 96DPI AWARE
thats another reason to not use windows 10. the "enhanced" scaling is ****. (i do have 10 in a laptop to try my app on it)
they force you to upgrade to 10 because of directx12 support but they still use GDI to scale? and the scaling is just bad.
here an article about that https://blogs.windows.com/buildingap...-desktop-apps/
-
Feb 19th, 2018, 10:28 AM
#4
Re: Forcing DPI Manifest to 96DPI AWARE
I already posted a link to that article above.
And if you think that's any reason to huddle back on the dying Windows 7 you just aren't paying attention.
They don't "use GDI to scale" your VB6 programs use GDI and they offer you a GDI Scaling High DPI appcompat so you have little work to do if it gives you acceptable results.
You are probably forcing your creaky old Win7 machine to run at 96dpi and your newer laptop probably has a gratuitously high resolution display so Windows selected some higher DPI for you so that you can read text on the screen.
gratuitously
adverb, definitions:
1. without good reason; unjustifiably.
2. free of charge.
Well it sure ain't "free of charge" and is only done to keep hardware profits high by preying on conspicuous consumers.
-
Feb 19th, 2018, 12:10 PM
#5
Re: Forcing DPI Manifest to 96DPI AWARE
they could have added more scaling options, such as client-area capture upscaling mode using hardware acceleration with a few different algorithm options.
that would help tons of old applications. now we need to use 3rd party tools because microsoft is not creative enough.
-
Feb 19th, 2018, 01:36 PM
#6
Re: Forcing DPI Manifest to 96DPI AWARE
What do you want for nothing? Rubber biscuit?
You can always just handle it properly yourself. I think they've been very helpful.
-
Feb 19th, 2018, 02:23 PM
#7
Re: Forcing DPI Manifest to 96DPI AWARE
I just took a random recent program and added a manifest with <gdiScaling>True</gdiScaling> and it does a perfectly good job considering it required zero effort to be DPI Aware:

Is it pixel-perfect? No, some positioning is off a pixel or two. But pretty usable considering I didn't add a line of code.
Last edited by dilettante; Feb 19th, 2018 at 02:34 PM.
-
Feb 19th, 2018, 03:22 PM
#8
Re: Forcing DPI Manifest to 96DPI AWARE
 Originally Posted by some1uk03
Is it possible to FORCE the app via a manifest to run as 96DPI no matter what the DPI are on the OS environment?
What so far (in all the previous answers) was not considered - is the possibility,
that you meant the above "as you wrote it" - meaning that the OS:
- "shall not scale anything on its own, no matter what the System-DPI-settings are"
(with the effect, that you can work Pixel-Perfect at least in the Client-Area of a given hWnd -
e.g. a "blitted Bitmap" with PixelDimensions of 100x100 Pixels will be rendered at exactly those dimensions, no matter
if you run on a "4K-display", or only the "normal 1920x1080-resolution" which is the common one on todays Desktop-Monitors)
And that you can accomplish by declaring to the OS, that your App "is DPI-aware":
- on Vista this means, declaring "System-DPI-awareness"
- on Win8.1 this means, declaring "per Monitor-DPI-awareness" (V1)
- and on Win10 this means, declaring "per Monitor-DPI-awareness" (V2)
If you do that, then "the system will leave you alone" (will not try to assist you with any "well meant scaling") -
the only exception with that is, that on Win10 (and declared "per Monitor-DPI-awareness V2", will scale
the "non-client-areas" of a Form for you (but it will leave the Client-Area you draw things to, alone again - and in your responsibility).
So yes, it is possible to tell Windows, that you want to run at "100%" (in "non-scaled, 96dpi mode").
But then, you are of course responsible yourself, to offer your own "Zoomed modes" (e.g. for users which run a NoteBook with 4K-resolution).
Olaf
-
Feb 19th, 2018, 09:52 PM
#9
Re: Forcing DPI Manifest to 96DPI AWARE
And that you can accomplish by declaring to the OS, that your App "is DPI-aware":
- on Vista this means, declaring "System-DPI-awareness"
- on Win8.1 this means, declaring "per Monitor-DPI-awareness" (V1)
- and on Win10 this means, declaring "per Monitor-DPI-awareness" (V2) ...
So yes, it is possible to tell Windows, that you want to run at "100%" (in "non-scaled, 96dpi mode")
VB will still scale itself to the system DPI initially because it is twip-based. Its form dimensions and most controls will scale. I'm thinking this was the real question: how to keep the project's forms at a fixed size, no matter what the DPI. So if at 150% DPI, the form and controls are larger -- to scale it back to dimensions at 100% DPI would be some effort. Without a manifest, VB thinks it's at 100% DPI all the time, but the system will generate the scaling/stretching as is probably the case here.
-
Feb 19th, 2018, 10:07 PM
#10
Re: Forcing DPI Manifest to 96DPI AWARE
I ran an earlier version of that same program with no manifest at all on a machine at 120% DPI.
It works but it is blurry:
-
Feb 20th, 2018, 12:50 AM
#11
Re: Forcing DPI Manifest to 96DPI AWARE
 Originally Posted by LaVolpe
VB will still scale itself to the system DPI initially because it is twip-based. Its form dimensions and most controls will scale.
No, the VB6-Form- and -Control-Engine will do no such scaling (then behaving according to the specs), if you do two things:
- declare your App DPIAware per Flat-API (being the first call in Sub Main)
- don't specify a dpi-awareness-section in your manifest (or don't include one into your Exe in the first place)
 Originally Posted by LaVolpe
I'm thinking this was the real question: how to keep the project's forms at a fixed size, no matter what the DPI.
I think so too - and as said - one can achieve that the Form and Controls "remain as they are at 96-DPI and keeping their original Pixel-Size",
when the App was declared DPI-aware per Flat-API.
In that case, the VB6-App will behave *exactly* as written in the specs.
- no attempt of scaling of the Forms-Client-area is made
- "pixel-exact" dimensions will apply in your BitBlt-calls and other GDI-related Ops
- the system-dpi which the App "sees", will remain at 96
- and Screen.TwipsPerPxel will still report 15
With the effect of:
- no blurring
- *but* also no scaling (of Controls, Fonts or anything else) of course
With "no manifest" and "no Flat-API-ensured DPI-awareness", the behaviour is basically the same
- "pixel-exact" dimensions will apply in your BitBlt-calls and other GDI-related Ops (but going into an OffScreen-Bitmap)
- the system-dpi which the App "sees", will remain at 96
- and Screen.TwipsPerPxel will still report 15
But in this case - everything is rendered into a temporary OffScreen-Bitmap with the old Pixel-Dimensions,
which is then "scaled up" (blurry) to an automatically resized Form (Form-Client-area).
What we currently experience when applying "DPI-awareness" per manifest, is not according to the specs IMO (just another, additional "fumbling" from MS).
My guess is, that in this case a "new Flag in the newer msvbvm60.dlls is set" (kinda like: "a dpi-awareness-wish was detected in the Exe-manifest") -
and that this flag will then change things (msvbvm60.dll-internally) with the effect of:
- no blurring
- but now "VB6-runtime-managed auto-scaling"
In my opinion they should have left all this alone - only supporting the "quite clear" effect we have when applying DPI-awareness per API-call
(also in the case of declared DPI-awareness per manifest). As it is currently, there's only a whole lot of confusion, what "DPI-awareness" really means.
And the intent was (when we go by the documentation), that with declared DPI-awareness:
- "the App is left alone" (the system will not make any scaling-attempts in that App)
- the developers of the App having sole responsibility for Zooming things, because it was them who declared "I'm aware of different outside-DPI to my internal 96).
Olaf
-
Feb 20th, 2018, 06:27 AM
#12
Re: Forcing DPI Manifest to 96DPI AWARE
You do know that the 1st definition of "per" in English is "for each" rather than "by means of" right? And that the second usage is considered archaic?
Saying "applying DPI-awareness per API-call" means "applying DPI-awareness for each API-call" which I'm sure is not what you meant.
I think you are talking about setting "System DPI Awareness" by way of an API call, specifically a call to the strongly deprecated SetProcessDPIAware function:
Note
SetProcessDPIAware is subject to a possible race condition if a DLL caches dpi settings during initialization. For this reason, it is recommended that dpi-aware be set through the application (.exe) manifest rather than by calling SetProcessDPIAware.
Your other contention sounds like a conspiracy theory with no foundation. I have seen no mention of (and no evidence of) any manifest detection process within the VB6 runtime that then produces changes in behavior with regard to scaling.
You may have things exactly backwards. Twiddling after the process starts running as you are, you could be seeing symptoms caused by precisely the pathological race condition mentioned in the MSDN quote above.
Don't use that API call. At all. Full Stop.
Last edited by dilettante; Feb 20th, 2018 at 06:48 AM.
-
Feb 20th, 2018, 09:38 AM
#13
Re: Forcing DPI Manifest to 96DPI AWARE
 Originally Posted by dilettante
You do know that the 1st definition of "per" in English is "for each" rather than "by means of" right? And that the second usage is considered archaic?
Saying "applying DPI-awareness per API-call" means "applying DPI-awareness for each API-call" which I'm sure is not what you meant.
Obviously I meant the "archaic form" (as you found out already).
That "latinism" is quite common as a preposition in german, whilst "via" (having basically the same meaning: "by way of")
is not used that often here (but seems more common in english)... will try to remind myself of that (but no guarantees... )
 Originally Posted by dilettante
I think you are talking about setting "System DPI Awareness" by way of an API call,
Yes.
 Originally Posted by dilettante
...specifically a call to the strongly deprecated SetProcessDPIAware function:
No, I'm talking about the "non-deprecated" call here: https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx
 Originally Posted by dilettante
Your other contention sounds like a conspiracy theory with no foundation.
I wonder why it sounds like that to you, because the MSDN clearly states:
Unlike the other awareness values, PROCESS_PER_MONITOR_DPI_AWARE should adapt to the display that it is on. This means that it is always rendered natively and is never scaled by the system. The responsibility is on the app to adjust the scale factor...
And in my tests (when applying this API with the Enum-Value: PROCESS_PER_MONITOR_DPI_AWARE = 2),
the behaviour of the VB6-App was exactly as described in the MSDN... (no scaling was applied, and pixel-exact 100% 96dpi mode assumed).
So, what's your explanation for the fact, that a VB6-App behaves "not according to what was written in the MSDN",
when the same "per monitor-dpi-awareness-value" is applied "per manifest"?
Though independent from what your own guessing-game might be ...
from the OPs point of view there is apparently a simple and clean solution (which - again - is neither "discouraged" nor "deprecated" by MS).
Olaf
-
Feb 20th, 2018, 03:50 PM
#14
Re: Forcing DPI Manifest to 96DPI AWARE
SetProcessDpiAwareness function
Important
For older applications, it is strongly recommended to not use SetProcessDpiAwareness to set the DPI awareness for your application. Instead, you should declare the DPI awareness for your application in the application manifest. See PROCESS_DPI_AWARENESS for more information about the DPI awareness values and how to set them in the manifest.
So yes, that's another strongly deprecated hack and for the same reasons. Do not use it.
-
Feb 20th, 2018, 05:33 PM
#15
Re: Forcing DPI Manifest to 96DPI AWARE
That says "for older applications" which doesn't imply it is deprecated at all.
-
Feb 21st, 2018, 06:32 PM
#16
Re: Forcing DPI Manifest to 96DPI AWARE
 Originally Posted by jpbro
That says "for older applications" which doesn't imply it is deprecated at all.
Yep - and "new VB6-compiled Applications" can't be considered "older applications", when they behave
exactly in the same way as e.g. a "new VC-compiled Appliction" (when per-monitor-dpi-awareness was applied per Flat-API).
The Flat-API-applied awareness is not "the hack" (its behaviour is conform to what is documented) -
instead the effect which is caused by applying awareness via manifest is "the hack" (as far as VB6-Apps are concerned).
I've just played that through with a simple VC-compiled (C-based) Window-example which was drawing per GDI.
And here the behaviour is identical (no matter if I apply per-monitor-awareness via API or via manifest).
All these "page-long explanations and tutorials, how to ensure 'proper DPI-awareness' in VB6"
are that complicated (need to address a ton of "exceptions to the rule"), because of that discrepancy
(that manifest-applied awareness is behaving differently to what is documented).
If that discrepancy would not exist (VB6 compiled Apps behaving conform to documentation, which the Flat-API-applied awareness can ensure),
a "VB6-tutorial for "per-monitor-awareness" would be quite short and easy to understand:
- you can rely on, that 96dpi "rules" throughout (inside) your whole App
- you can rely on, that "TwipsPerPixel" is *always* reported with a Value of 15
- since you can rely on the above, your App is always rendered in the same "original Pixel-Size" as on your Dev-Machine
- since you can rely on the above, writing a "Resizer" for your Forms and Controls on that Form (which accepts a simple Zoom-Factor) becomes super-easy
- such a Resizer (along with differently applied ZoomFactors) could be tested on your Dev-machine without having to switch the Systems Screen-DPIs
- just be aware, that on the outside of your App, a different (Monitor-)DPI might apply, but all you have to do is, to apply a ZoomFactor which is "current Monitor-dpi divided by 96"
That easy it could have been (with regards to an easy to understand "tutorial") - but currently is not.
Olaf
Last edited by Schmidt; Feb 21st, 2018 at 06:41 PM.
-
Feb 21st, 2018, 09:55 PM
#17
Re: Forcing DPI Manifest to 96DPI AWARE
Would the idea behind "forcing" 96 DPI be similar to the concept of the CSS "pixel" https://juiceboxinteractive.com/idea...obile-devices/...Let the host decide what a physical pixel is vs. a software reference pixel?
It does seem much easier to achieve rational/reasonable layouts across various devices on the web compared to the desktop (various Windows OS desktops at least). Not sure if it helps with multiple monitors of varying DPIs (that seems like a path to hell programming wise, so the more help you get from downstream the better I think).
Speaking of which - is this something that could be helped/handled by RC5 form/widget library? Always having a 96 DPI "window" to work against, and it can also handle the multiple monitor DPI variations?
-
Feb 22nd, 2018, 10:38 PM
#18
Re: Forcing DPI Manifest to 96DPI AWARE
 Originally Posted by jpbro
Would the idea behind "forcing" 96 DPI be similar to the concept of the CSS "pixel"...
Yes, especially when the graphics-lib (or graphics-environment) you are using, supports such an approach more directly.
For "device-independent Pixels" to work "on common ground", the "real, physical DIB-memory allocations" (the PixelSurfaces you later render to)
have to be based on an always constant "dpi-value at ZoomFactor=1" - and that is (in most modern graphics-libs 96dpi).
E.g. Cairo-ImageSurfaces (when their "Contexts" are "unzoomed" (Scalefactor = 1) assume 96dpi-resolution (with regards to Fonts and the appropriate Text-Outputs).
 Originally Posted by jpbro
Speaking of which - is this something that could be helped/handled by RC5 form/widget library? Always having a 96 DPI "window" to work against, and it can also handle the multiple monitor DPI variations?
Yes, of course - the concept of a "Zoom-independent-Pixel" is already built-in (when you use the RC5-WidgetForm- and Widget-Engine).
An RC5-WidgetForm (or -Panel) is working (and needs to be resized) with "true, physical Pixel-Dimensions" (working directly against the Win32-System-API).
But for Widget-Renderings or WidgetPlacements on such a Form or Panel, you have a "WidgetRoot", which offers a Zoom-Factor,
which you can change at any time (e.g. similar to Browser-Engines, by using <Ctrl>+MouseWheel) - and thus (since it reacts
immediately) reacting to Monitor-dpi-change-events can be handled in two lines of code, by just changing:
- the physical dimensions of your Form (a Form.Move, in cases where this is needed at all)
- and by just setting that "current WidgetRoot.Zoom" to the new appropriate value (currentMonitorDPI / 96), to enlarge or reduce the size of the whole Widget-Hierarchy on that Form in one go
So the Widgets on such a WidgetRoot (e.g. when you set a Zoom-Factor = 2) - are then rendered automatically:
- twice as large
- and will have "twice their physical Left/Top-Offsets"
But despite of that new Zoom-Factor, all Widgets will still report the very same Widget.Left, Widget.Top, .Width/Height Pixel-coords to you, as with ZoomFactor = 1.
Also all your "MouseEvents" will report still the same "incoming Mouse-Movement-Coords" - independent of the fact, that your "outside ZoomFactor" and their physical size is now changed.
e.g. when you placed a Button-Widget at 10,10 - with a size of 150, 30:
- this will match with physical Screen-pixels when ZoomFactor=1
And when you set the WidgetRoot.Zoom = 2, the same widgets physical coords will then be:
- 20,20, 300x60 (and all the renderings "on that Widget" scaling properly along)
- but the Widget will report (in W.Left, W.Top, W.Width and W.Height) still 10,10, 150, 30
- and when you move the mouse on top of this widget, it will still report incoming x,y Params in the range [0-150] and [0-30]
That concept saves a whole lot of efforts on your end, when you consider "Widget-Movements or -placments, relative to each other" - as well as "Renderings in a given Widget",
since you will not have to incorporate the outside Zoom-Factors into your "Widget-internal Offsets or -calculations"...
Olaf
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|