Is possible to let VB6 to autmatically care about PDI
I saw that, when somebody selects "magnified or reduce the size of text and others objects", lets said 125%.... It expands the actual area in pixels of all my forms. But by example the .PICTURE now don't cover all the form area, or de objects inside are not moved proportionally.
so, it is show the normal size of the app, plus an area uncover /unused of the form bottom/right corner.
So, is a way to force window to not let my forms to be expanded?. Is to say, if the user want to expand the icons at the desktop, no problem, but not my program..., because I can't afford to do a given skin for each zoom size, plus monitor resolution in the world.
If you have been ignoring this you have a lot of work to do.
No, there is no way to opt out of DPI Virtualization without rewriting to be DPI-Aware and marking your program as such. But at least Virtualization is better beginning in Windows 10 1703. See:
If you have been ignoring this you have a lot of work to do.
No, there is no way to opt out of DPI Virtualization without rewriting to be DPI-Aware and marking your program as such. But at least Virtualization is better beginning in Windows 10 1703. See:
No, what I did is to define the interface visual outside the EXE, so the EXE has a script engine and runs external code to define its visuals properties, graphics.
But, to contract to a graphical artist to make the skins is expensive, so we contract just enough, is to say, a skin for 1366x768, other for 1920 x 1080 and in the future one for 4K.
So, don't matter the resolution, we can resize it by skin.
But now, there is a ZOOM setting in the resolution form, which has options 100% 125% 150%.... like for ppl with visual problems? improve accesibility?.....
way no!, we don't want to multiply the artist tasks,
So, if Windows resizes the FORMs, why it don't resize/positioning also everything inside automatically?.
If all our forms are autoredraw=true, so there is a image buffer which can be MAX / MIN.... but I assume Windows don't works with that for this purpose.
flagging it as dpi aware will it change something? like, let the app alone?
Last edited by flyguille; Dec 14th, 2017 at 06:49 PM.
Re: Is possible to let VB6 to autmatically care about PDI
Windows offers basically 3 types of DPI settings for any applications:
1. Not aware. This means Windows will take your form and paint it to the appropriate size, stretching nearly everything. Some items like TrueType fonts will scale pretty well in newer O/S. This is probably the worst graphical results. Without a manifest declaring your app DPI aware, this is the option you get.
2. System Aware. This means the app knows what DPI the current O/S session booted in, not necessarily, what DPI the user may have changed it to sometime afterwards or can change it later, without restarting. When your app is declared System DPI aware, your form can auto-scale, auto-position most things if you pay attention to many details. In order to get this option, you need to declare your app as System DPI-Aware with a manifest
3. Multi-Monitor DPI Aware (or a better name would be Dynamically DPI Aware). This option means that your app can scale and reposition itself whenever the DPI changes. This requires a manifest too, but can be very difficult to code for.
There is actually a 4th type, but it also requires a manifest and is only available with Win10 v1703 or better. Dilletante mentioned that in his reply. It is better than option #1 but not as good as the others.
IMO, minimally, you could use option #2. It will be a learning curve if you have not played with DPI awareness. But based on the PNG image sizes you have, your app should look very good at the system DPI.
Edited. Reason why I say your PNG could look better with option #2, even if it needs to be scaled larger, is because you can use GDI+ or other methods to scale with higher quality. When option #1 applies, your PNG is scaled using probably the worst quality (but fastest) scaling algorithm. You have no control without using a manifest.
Last edited by LaVolpe; Dec 14th, 2017 at 08:14 PM.
Insomnia is just a byproduct of, "It can't be done"
Re: Is possible to let VB6 to autmatically care about PDI
My first question to flyguille is: In what Windows are you experiencing the problems?
Because if you are not setting your program as DPI aware in a manifest file, then any Windows version from Vista and above will automatically scale everything (it is option 1 of Lavolpe list).
You'll should only be experiencing those problems on XP.
Re: Is possible to let VB6 to autmatically care about PDI
Originally Posted by Eduardo-
My first question to flyguille is: In what Windows are you experiencing the problems?
Because if you are not setting your program as DPI aware in a manifest file, then any Windows version from Vista and above will automatically scale everything (it is option 1 of Lavolpe list).
You'll should only be experiencing those problems on XP.
Re: Is possible to let VB6 to autmatically care about PDI
If a control's container object''s scalemode is pixels, there is no auto-positioning/scaling of controls, but the form dimensions will scale. If that container object's scalemode is twips, there is auto-positioning/scaling if your project is DPI aware. Exceptions noted in that DPI Tutorial dilletante referenced.
I am assuming you are declaring your app DPI aware. Is that true? If not, you should have no scaling issues other than poor quality stretching of the form.
I think some of us could use a screenshot of the problem and another of what is expected.
Insomnia is just a byproduct of, "It can't be done"
Re: Is possible to let VB6 to autmatically care about PDI
Originally Posted by LaVolpe
Ok, for those of us that have no idea what we are looking at, what exactly is incorrect and what should it be instead?
all the areas of the form uncover.... just showing the form.backcolor. whatever it is, white, red, or grey and black (in the example).
also see how it affect the usercontrol.print (about font size), but it does not scale positioning / size of the object where text is printed which is rendered in the usercontrol.
So, if it want to magnify, why VB or Window don't scale up any X / Y / HEIGHT / WIDTH which the VB code is outputing? and at the same time scale down when inputs events to code?
Last edited by flyguille; Dec 15th, 2017 at 08:36 AM.
Re: Is possible to let VB6 to autmatically care about PDI
The 2nd image (edited) you showed us helps a bit. Is the form's scalemode pixels? It almost looks as if you have some hardcoded twips to pixel conversions, i.e., SomeTwipValue / 15 or SomePixelValue * 15 to convert to/from pixels.
But what I am a bit confused with is that you say the application is not manifested. So, the application should be thinking it's running at 100% DPI. The images you shown makes me think that DPI is being used. Any special settings in the properties of the executable when you right click on the exe and look at the Compatibility tab?
Insomnia is just a byproduct of, "It can't be done"
Re: Is possible to let VB6 to autmatically care about PDI
ok, I see now two possiblities
1) I scalemode everything to TWIPS, what will be a hell to reworks like 10 skins, after the EXE has it all in scalemode.
2) when the skin defines width/height of the form.... I process that number as ..... (value / 15) * twipsperpixelX or Y (the skin assume it is 15 tpp). but then I needs to flag any 0object which is inside a frame, in the EXE so the EXE knows it needs to do the same conversion for positioning and sizing, because frames hasn't a scalemode option IIRC.
Re: Is possible to let VB6 to autmatically care about PDI
Originally Posted by LaVolpe
The 2nd image (edited) you showed us helps a bit. Is the form's scalemode pixels? It almost looks as if you have some hardcoded twips to pixel conversions, i.e., SomeTwipValue / 15 or SomePixelValue * 15 to convert to/from pixels.
But what I am a bit confused with is that you say the application is not manifested. So, the application should be thinking it's running at 100% DPI. The images you shown makes me think that DPI is being used. Any special settings in the properties of the executable when you right click on the exe and look at the Compatibility tab?
Re: Is possible to let VB6 to autmatically care about PDI
Look flyguille, what you describe makes no sense.
We all know that sometimes there are unexpected situations or Windows can have bugs or there are some strange things that don't behave as expected, but first let's try to frame this to what should be happening normally.
I see three possibilities:
1) That problem happens on XP.
2) Other option is that it is run in a newer Windows but with XP compatibility.
3) You do have a manifest in your exe telling that your program is DPI aware.
If you already checked and you are sure that it is not XP, then only 2 and 3 are left.
Let's see option 2. You already said that there is not compatibility applied.
The compatibility is something that the final user is able to set in a shortcut, so are you sure there is not a compatibility applied to the shortcut?
Option 3. You could have added a resource file from somewhere, from some other project (perhaps that you found it on internet) and it could be there a manifest inside it and you don't know.
Use ResourceHacker to check if the exe has a manifest. It must be resource #24 and it is an XML file.
Did you try it on another PC with a "clean" installation of your program?
Don't expect a magical solution and try to understand the issue, so please keep reading.
What DPI aware means:
It means that your program, or you as the programmer is "aware" that there are different DPI settings that Windows can be configured to run on. And it means that you will handle the issues related to the different DPI settings to assure that your program will display correctly in all the DPI settings.
"I am aware that Windows can have different DPI settings" can be translated to Spanish to "Soy consciente que Windows puede tener diferentes configuraciones de PPP".
DPI means dots per inch. It is translated to PPP in Spanish: puntos por pulgada.
It means that an logical inch (it can be close to a physical inch or not) can have 96 pixels, 120 pixels, 144 pixels or more.
Of course the monitor does not change how many pixels it physically has when you change the setting, so instead, what is changed is the size of the logical inch.
More DPI, the logical "inch" gets bigger.
When a program works in Twips, the sizes are tied to the logical inch. But when it works in pixels, they are is tied to pixels.
When you load an image, even if the ScaleMode is in Twips, the image is in pixels.
Prior to Windows Vista, the monitors weren't very big (mostly) and most of the people had them set to 96 DPI, very few users changed that (many of us had better vision at that time also).
The programs generally assumed they were working in 96 DPI (it is 15 TwipsPerPixels).
When new monitors arrived, and at the time that appeared Windows Vista, many people started to change the DPI setting.
The problem was that many programs weren't able to display themselves properly on different DPI other than 96. So Windows started to lie to the program and tell it that it was running in 96 DPI and made all the scaling itself (by Windows).
Everything is scaled (or almost everything says Lavolpe), although with some blurring.
If you don't want Windows to automatically scale your program, then you need to tell that to Windows. You need to tell that you are "DPI aware" and you will take the responsibility of the scaling yourself.
That's what the DPI aware section of the manifest file means.
So, if you don't have a manifest file in the exe you shouldn't experience other problem than some blurring (at other DPI than 96).
On the other side, if you declare the application as DPI aware, then one way of taking care of the issue is to work all in Twips.
And for the images: (options)
a) To scale the images.
b) have different images for the different DPI settings
c) to know that they will look smaller (in relation to other things that has been scaled) and make the appropriate relocation of whatever is necessary.
Other possibility instead of working in Twips is to work all in pixels.
But that has some issues because VB is mostly already DPI aware and it will automatically scale the fonts, and the controls, even if the ScaleMode is in Pixels, they will be scaled anyway.
You need to set the position and size of every control in pixels in code. Those pixels will be respected and not automatically scaled.
And the fonts need to be scaled down by code.
And other disadvantage is that at higher DPI setting everything in your program will look smaller than what the user could expect, because everything is in pixels, and the pixels in the monitor does not change, so changing the DPI setting won’t have the desired effect in your program because your program will look the same at different DPI settings.
Re: Is possible to let VB6 to autmatically care about PDI
For Lavolpe and dilettante: is there any possibility that the program is using some API that bypasses the lying about the DPI and "something" is working with the actual DPI setting and not with 96?
Re: Is possible to let VB6 to autmatically care about PDI
Another issue is that when you have a monitor with gratuitously high resolution Windows now picks an "appropriate" DPI setting for the user. This started in Windows Vista or Windows 7, I can't recall anymore and a lot of documentation for these obsolete OSs is no longer on MSDN or TechNet, or at least hard to locate with my limited GoogleFu.
This is the main reason to make programs properly DPI-aware or at least use the <gdiScaling/> element in a manifest (see Application Manifests). That requires Windows 10 1703 or later though.
Basically nothing less than Windows 10 1709 is fully supported anymore. Even Win10 1703 goes out of support in September 2018.
If you are not on the Windows 10 Train you are in bad shape. It left the station long ago and just keeps on moving down the tracks away from you.
Last edited by dilettante; Dec 15th, 2017 at 01:28 PM.
Re: Is possible to let VB6 to autmatically care about PDI
Originally Posted by Eduardo-
For Lavolpe and dilettante: is there any possibility that the program is using some API that bypasses the lying about the DPI and "something" is working with the actual DPI setting and not with 96?
Since we have no idea what he is using, I suppose he could be using some pathological library to do his user interface rendering.
Re: Is possible to let VB6 to autmatically care about PDI
Other possibility instead of working in Twips is to work all in pixels.
But that has some issues because VB is mostly already DPI aware and it will automatically scale the fonts, and the controls, even if the ScaleMode is in Pixels, they will be scaled anyway.
You need to set the position and size of every control in pixels in code. Those pixels will be respected and not automatically scaled.
And the fonts need to be scaled down by code.
Yes, that is my problem, that describe all what is happening, I see normal VB controls like textboxes scaling up (size, not position), but don't happens with UserControls, except by the text printed inside that is printed with bigger font done by VB (usercontrol.print "text".
All my forms are setup in PIXEL scalemode, and so, it don't match with the actual size of the form if DPI is different than 96.
I will try to tell Windows it is DPI aware and see what happens.
Last edited by flyguille; Dec 15th, 2017 at 01:26 PM.
Re: Is possible to let VB6 to autmatically care about PDI
Originally Posted by Eduardo-
For Lavolpe and dilettante: is there any possibility that the program is using some API that bypasses the lying about the DPI and "something" is working with the actual DPI setting and not with 96?
No, it is fully 100% rendered using UserControl objects.
and the backgrounds is just the .PICTURE property, which is loaded with PNG images stored in StdPictures variables. Everything graphical is StdPicture variables.
Except frames, which hasn't a background .Picture property, so, I just simulate it with a flat PictureBox as background inside the frame.
Re: Is possible to let VB6 to autmatically care about PDI
Originally Posted by Eduardo-
For Lavolpe and dilettante: is there any possibility that the program is using some API that bypasses the lying about the DPI and "something" is working with the actual DPI setting and not with 96?
Yes, SetProcessDPIAware. Also, not likely but is there an external manifest next to that exe? Granted, internal manifests take precedence, but can be overridden with registry settings. Doubt this is the case, but technically possible.
Another possibility (though may not apply here) is that whatever scaling flyguille is using is based on real DPI. But that would have been intentional by calling APIs to retrieve actual monitor/screen properties via GetDevCaps or newer Win10 APIs.
Originally Posted by dilletante
Another issue is that when you have a monitor with gratuitously high resolution Windows now picks an "appropriate" DPI setting for the user. This started in Windows Vista or Windows 7
This was documented for Win7 but shouldn't be a player for apps without DPI-aware manifests.
Also for flyguille. You removed the 2nd image in post #11. I thought that one showed the problem?
Edited: ignore above statement -- it's back. My browser is probably playing mind games with me
Last edited by LaVolpe; Dec 15th, 2017 at 01:56 PM.
Reason: typos
Insomnia is just a byproduct of, "It can't be done"
Re: Is possible to let VB6 to autmatically care about PDI
Originally Posted by flyguille
... the programs runs from task scheduler elevated.
For those that can answer this: Does task scheduler run scheduled events in the same process as itself? I'd doubt that, but am not exactly sure if another process can set the DPI Awareness context of a process it spawns?
Insomnia is just a byproduct of, "It can't be done"
Re: Is possible to let VB6 to autmatically care about PDI
I'm not sure whether this is a factor but that manifest tells Windows that you are Vista compatible, but does not mark your program as Windows 7 compatible. So no telling what appcompat shims are getting applied.
Re: Is possible to let VB6 to autmatically care about PDI
Originally Posted by LaVolpe
For those that can answer this: Does task scheduler run scheduled events in the same process as itself? I'd doubt that, but am not exactly sure if another process can set the DPI Awareness context of a process it spawns?
Task Scheduler creates a separate process using the credentials it was given to use. I doubt there is any cross-process inheritance of DPI settings or awareness.
Re: Is possible to let VB6 to autmatically care about PDI
Originally Posted by dilettante
Task Scheduler creates a separate process using the credentials it was given to use. I doubt there is any cross-process inheritance of DPI settings or awareness.
@flyguille. Does this problem occur when you open your exe by double clicking on it within Windows Explorer? You mentioned task scheduler and this simply removes that as a possible obstacle.
Originally Posted by dilletante
Instead of just taking stab after stab in the dark it would help to post a small demo Project that reproduces the problem.
Yep, but that may be a "commercial" product?
Insomnia is just a byproduct of, "It can't be done"
No, that problem only happens when the real TwipsPerPixels is not an integer.
For normal DPI's (120 and 144) it doesn't happen.
And it is not only related to UserControls.
Re: Is possible to let VB6 to autmatically care about PDI
Ahh right...Sorry I didn't read the whole thread, the screenshots just reminded me of the size problem that I had to fix in my programs. Thought it might be the case here but now I see the problem is occurring even at 125%.
Re: Is possible to let VB6 to autmatically care about PDI
ok what I did is this
Code:
Private Sub O_Form(OP As Object, ByVal KeyTag As String, ByVal Value As String, Error As Byte)
Dim ObjPicture As StdPicture
Error = 0
With OP
Select Case KeyTag
Case "AUTOREDRAW"
.AutoRedraw = Val(Value)
Case "PICTUREMASK"
Set ObjPicture = LoadAllPics(Value)
Call SkinForm(OP, ObjPicture)
Case "BACKCOLOR"
.BackColor = Val(Value)
Case "PICTURE"
Set .Picture = LoadAllPics(Value)
Case "LEFT"
.Left = (Val(Value) / 15) * Screen.TwipsPerPixelX ' Trying to fix variable DPI problem.
Case "TOP"
.Top = (Val(Value) / 15) * Screen.TwipsPerPixelY ' Trying to fix variable DPI problem.
Case "WIDTH"
.Width = (Val(Value) / 15) * Screen.TwipsPerPixelX ' Trying to fix variable DPI problem.
Case "HEIGHT"
.Height = (Val(Value) / 15) * Screen.TwipsPerPixelY ' Trying to fix variable DPI problem.
Case "CAPTION"
.Caption = Value
Case "ICON"
Set .Icon = LoadAllPics(Value)
Case Else
Error = 1
End Select
End With
End Sub
and it fixed all form size.... it now fits perfect.
In Windows 10 it scales perfectly all FRAMES and buttons etc. In win10 it looks OK now.
But in windows 7, the frames inside don't scale up, the objects inside the frame are rendered BIGGER but not its size/position and the frame itself is not scaled up.
So, all visuals of the objects wich are inside a FRAME objects are cut in half, because its size is the original but its internal rendering (UserControl) is maximized.
Now I will test the same EXE without any manifest.
CHECKED: same result.
It fails only in win7 full updated.
win 10 ok.
Last edited by flyguille; Dec 16th, 2017 at 09:59 AM.
Re: Is possible to let VB6 to autmatically care about PDI
conclusions, everything was happy if all was expressed in pixels, but when I use FRAME they don't has a scalemode, so I was forced to use twips scale.
And mixing twips and pixels for positioning, sizing is a bad idea.
Solutions: a complete rework, everything to twips. But then is the problem that form.picture image won't cover up all the expanded form size atleast in win7.
But is not only changing scalemodes, all usercontrol internal surface is in PIXELs scale, not twips, and switching them to twips means to rewrite all the default constants plus all instances modified properties plus all the values writed by the atleast 10 skins.
-----------------
So, I was willing, is a possible way to tell Windows DON'T scale up my app at all? don't even touch my app?, the user will chose an appropiate skin for large monitor?
Also there is differences of how vb expand native objects vb UserControls objects, in windows7 they are handlered diffent.
In win10 the image is perfect, bigger but perfect.
Last edited by flyguille; Dec 16th, 2017 at 10:54 AM.
Re: Is possible to let VB6 to autmatically care about PDI
Well I tried using the new "GdiScaling" feature in recent versions of Windows 10, this isn't perfect but acceptable for what this demo does. Ok, it doesn't do much.
Note that the Form backdrop get scaled to fit the client area, while the UserControl is not scaled. The latter is intentional. The backdrop image is a little "raggedy" but that's the original image's problem not the scaling.
It looks "good enough" even at 200% (192 DPI). You can do far better by actually being DPI Aware and coding for it, but this is the easiest way to go.
However it might have more problems on a creaky old OS like the dying Windows 7. It runs on Win7 but I haven't tried that with high DPI settings.
Re: Is possible to let VB6 to autmatically care about PDI
@flyguille. Curious. You said all is ok on Win10. Did you change the DPI to 125% in system settings and log out, then log back in?
Also, on the Win7 box, there is an option to use DPI for 100-125% and virtualize for greater DPIs. At least that is what I recall the general rule of thumb was. If your app draws as expected (a bit blurry but ok) at 150% DPI, but not at 125%, on Win7 then this setting may be the cause.
Open the Personalization/Screen properties window and change the DPI to a custom setting. In that window, is an option at bottom of that window to force all apps to use XP style DPI scaling. This option disappeared in Win8. Here's a link that describes setting up DPI on Win 7 with screenshots.
And another question. Eduardo asked you to report back what value Screen.TwipsPerPixelX is when this problem is occurring. I don't think you answered that question. If it is reporting 12 instead of 15 -- bingo! Just put a msgbox at form startup: MsgBox Screen.TwipsPerPixelX
Last edited by LaVolpe; Dec 16th, 2017 at 02:47 PM.
Insomnia is just a byproduct of, "It can't be done"