I have an older application for which I want to use DPI virtualization on Windows 7 (also known as blurry form scaling). To try this in an example project, I did the following:
enable 125 % text display on a Windows 7 machine
disabled any manifest for that project
read Monitor.PixelsPerInch with a result of 120
I tried some things, but I was unable to get a result of 96 dpi here:
used <dpiAware>false</dpiAware> in an internal or external supplied manifest
changed application compatibility settings
changed windows theme
I additionaly thought that SetProcessDPIAware is called somwhere in the VCL. I found System.win.HighDpi which contains SetProcessDPIAware in its initialization block, but this unit is not included in my minimal sample.
Sample manifest (setting dpiAware seems to be ignored):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">False</dpiAware>
</windowsSettings>
</application>
</assembly>
Related
I'm looking to control runtime themes in a way that is friendly for version control tools. Be it programmatically, or by some configuration such as a text based manifest file (but not the DPROJ file through the GUI project options).
Is there any such way?
For clarification: The DPROJ is not committed to git because it is auto edited by Delphi for no apparent reason, and contains the command line parameters that anyone can modify daily.
Thanks to #Remy's pointers, this is the code responsible for disabling themes using a custom manifest:
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="5.82.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
The critical parameter is which version of Common Controls is used:
version="5.82.0.0" will disable themes
version="6.0.0.0" and above will enable them
I create a new application with a form that needs to be displayed without scaling but as designed with a fixed dimension in pixels (Position is poScreenCenter for example). When setting Scaled to false, the form is instead displayed with some default width and height, ignoring the designed dimensions. Setting Scaled to true works, it is displayed as designed, but scaling is not wanted.
I have tried to set DPI awareness to None or Unaware, but this has no effect.
I got similar if not the same issues while porting huge CAD/CAM project from BDS2006 C++ -> RAD11 C++ as a test of functionality before purchasing new RAD11:
scaled up all VCL components
but not scaled all glyphs causing very small glyphs
not scaled some forms and dynamic panels causing scaled up components will not fit into their designed area
speed buttons containing Captions even if they should not
ManualDock is corrupting Width,Height causing scale is applied twice on docked windows messing up custom layouts
I was planning to change the sizes of problematic VCL components (really just few form sizes and all glyphs) with code at apps init (or maybe create some utility that adjust *.dfm files like I did before for app auto translations and other stuff before so I have parsers ready to go so that it would not be a big deal) and planning to obtain scaling needed for this either by winapi GetScaleFactorForDevice or by the bugged behavior of ManualDock in RAD11
However before that I needed to start my app with admin priviledges from within RAD11 IDE as I deal with device drivers and stuff that needs admin priviledges...
I found and follow this tutorial:
elevated-privileges-for-delphi-applications
Which Immediately solved all my scaling issues too so no need to handle those for me anymore... Hope it helps you too (maybe even the scaling off option will work again as should have not tested it yet).
Now the App is scaled but correctly (it behaves as not scaled app just bigger)...
So in a nutshell (if the link got broken in time) you need to Add to project a XML file with *.manifest extention like this one:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="Here_Your_Project_filename_without_extention" version="1.0.0.0" processorArchitecture="x86"/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="*"/>
</dependentAssembly>
</dependency>
<!-- Windows Vista application security requirements. -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--Windows 7-->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--Windows Vista-->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
</assembly>
note that Here_Your_Project_filename_without_extention in 3th line just replace it with the projects name. After that you open your:
Project->Options->Application->Manifest
set Manifest file to custom and at the bottom browns and select the created manifest file ...
That is it just recompile your App and run ... Please let me know if it helped or not.
I tested this on Win10 and RAD11 C++ (trial version win32 target)
This let me thinking that scaling related bugs might be caused by something in auto-generated manifest (have no knowledge and experience with those so I am just wild guessing) file which is bypassed by this approach...
I think you also do not need to use the admin rights part of the manifest so you might want to change that once this is already working for you.
I'm working on a per-monitor DPI aware application with multi-monitor capability.
It's necessary to know the design-time PixelsPerInch of the Form to scale it according to the current monitor DPI if the Form is moved across monitors.
The problem is that I don't get PixelsPerInch consistently.
While debugging, in the form's overridden Loaded method I get the correct 120 value.
When running standalone, I get 96 (and so the form scales bigger).
I use Scaled property as false and rescale manually in DoShow with ChangeScale (also setting monitor index/boundsrect if necessary). Then on WM_DPICHANGED, if ever, rescale again (anyway it's not sent while debugging, probably because of the IDE).
All looks fine, just on standalone run it's larger.
Why do I get different numbers for PixelsPerInch? Or at which point should I request the design-time value of it?
I'm using XE7 at the moment.
With a standard (?) win 10 manifest, and call SetProcessDPIAwareness at the very beginning of unit initializations. I prefer it this way, so a "/no_dpi_aware" run is also possible with the blurry windows scaling.
Of course I can just hardcode "120", but I wouldn't like it.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="xxxx" version="3.1.0.0" processorArchitecture="*"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker"/>
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates application support for Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!--The ID below indicates application support for Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!--The ID below indicates application support for Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!--The ID below indicates application support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--The ID below indicates application support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
</assembly>
I have 2 applications written in Delphi. The first exe (with a user interface) calls another using ShellExecuteEx(), which runs as a background process.
When the first exe invokes the second, one of these two things happen:
When I log in as an admin, a UAC dialog comes up with the Allow/Cancel prompts. Selecting Allow continues the execution.
If I log in as non-admin, an admin credentials dialog box is displayed, and I need to enter the admin username/password to continue.
On both occasions, I want the second exe to run without any user intervention. How can I make it possible?
And yes, I tried applying the ElevateCreateProcess mitigation as suggested by SUA tool, but it doesn't seem to work - the behaviour is as before.
Thanks for your help.
The first EXE needs to be launched with elevated privileges to invoke the second without a UAC prompt. Or...you can use a manifest for the second EXE telling Vista that it's not an admin tool and to just run as the current user.
Saved as Second.exe.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<!-- Vista UAC Support -->
<ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
<ms_asmv2:security>
<ms_asmv2:requestedPrivileges>
<ms_asmv2:requestedExecutionLevel level="asInvoker" />
</ms_asmv2:requestedPrivileges>
</ms_asmv2:security>
</ms_asmv2:trustInfo>
</assembly>
What is the file name of your second file?
Vista assumes administrator privileges are needed for certain file names - most notably files with the name "setup" or "install" in them.
Also: If what you want is to be able to run a program with administrator privileges without having Vista throw a UAC prompt up, then you're out of luck. That would be a serious breach of security if that was possible.
Does your second program need administrator privileges?
What happens when you try to execute the second program directly from Explorer? A UAC prompt? If so, then Vista is trying to run it as Administrator, either because of the file name of the file, or because a manifest (internal or external) requests is.
Yes, you'll need an application manifest that looks similar to this
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="UacTest" type="win32"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="highestAvailable"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Take note of the "requestedExecutionLevel" tag
I've got a project that I started in Turbo Delphi, which I recently updated to D2009, and I've noticed a bit of a quirk in the form designer. All the old forms have a Win98 style applied to them. The buttons are gray with sharp square edges, for example. But any new form I've created since the upgrade displays its controls in WinXP style. If I copy a control from an old form and paste it to a new one, the style changes. At runtime, all controls from all forms are shown in XP style.
Any idea what's causing my old forms to show in an old style? I've looked through the properties list, but nothing jumps out at me. But there's obviously something, and it's persistent because saving and reloading doesn't change it. Anyone know where this property is and how I can fix it?
You should enable run time themes.
Did you check?
Project | Options | Application | [ ] Enable Run Time Themes
looks at the uses clause in both a old form and a new one, there may be something diffrent. i know in delphi 7 you had to add xpman (or somerthing like that) to get the windows skin.
Have you checked the dfm files? Sometimes there is something there that is not shown in the propertylist.
Maybe you have a stray Ctl3D (sp?) setting in your dfm?
Well using D2007,
had the same issue on my run time packages. They may where create using D5 or D7.
To fix this issue: simple add a "XP Theme ManiFest" to your culprit package "res" file.
Example of a D2007 manifest:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="CodeGear RAD Studio"
version="11.0.2902.10471"
processorArchitecture="*"/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>