How to avoid DPI awareness in a QtApplication for Windows - c++

I have a QtWebKit application and I want to avoid DPI awareness. I tried adding a manifest as documented in MSDN but it only worked in Windows 8.1 (not in Windows 8 and lower versions.)
Inspecting the Qt source code (4.7) I found inside the file qapplication_win.cpp the following snippet:
// Notify Vista and Windows 7 that we support highter DPI settings
ptrSetProcessDPIAware = (PtrSetProcessDPIAware)
QLibrary::resolve(QLatin1String("user32"), "SetProcessDPIAware");
if (ptrSetProcessDPIAware)
ptrSetProcessDPIAware();
For more information take a look at the Commit
That said, I don't really know why it's working in Windows 8.1 and more importantly how can I disable this Qt feature... any Macro/Qt API I should use?

Related

C++ Windows API - How to retrieve font scaling percentage on Windows 10

My goal is to be able to adjust the font size at runtime in a C++ app, based on the monitor resolution.
In this question, it's explained how to get the font scaling percentage, but the suggested function GetScaleFactorForMonitor requires Windows 8.1. My C++ app must run on Windows 7 or higher. I have tried several proposed solutions based on getting the ratio of device caps parameters, but they all get 1.0 on a Windows 10 system where the Windows "Make everything bigger" setting is 150%.
Per the MS docs, Visual Studio is adding "dpiAware" to the manifest (this is a setting I can change). Probably because the app is being built on a Windows 7 system, the VS-generated manifest does not include Windows 10 as a supported O/S. If I add the lines
<!--This Id value indicates the application supports Windows 10, Windows Server 2016 and Windows Server 2019-->
<supportedOS Id="{{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
to the manifest, when I run the app on Windows 10, I get a "side-by-side" error.
How can I get this "make everything bigger" and the "make text bigger" settings on a Windows 7 or 10 system?
Build system: 64-bit Windows 7, Visual Studio 2019 16.7.7 Run system: Windows 7 or later
After discussing in the comments, it turns out your actual problem is that you don't declare DPI awareness in your manifest correctly.
You need to merge this into your manifest:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
</assembly>
Explanation:
dpiAware true is recognized by Windows 7 and Windows 10, and declares system-wide DPI awareness (DPI_AWARENESS_SYSTEM_AWARE). System-wide means that it assumes that all applications on all monitors use the same DPI setting).
dpiAwareness is recognized by Windows 10 (Windows 7 ignores it) and, if present, supersedes dpiAware. It declares per-monitor DPI awareness (DPI_AWARENESS_PER_MONITOR_AWARE), which means that each monitor can have different DPI settings and your application must handle that correctly.(2)
If you do not include this manifest, Windows will virtualize the DPI, meaning it will act as if the DPI setting is always at 96 (100%), and then Windows merely scales the bitmaps (blurry). This is a compatibility measure that ensures that applications which do not implement DPI code can still appear bigger.
Then, on Windows 7, you get the scaling factor using the GetDeviceCaps function with LOGPIXELSX and LOGPIXELSY, and dividing the result by 96 (because 96 dpi is "100%").(1) This will give you the DPI setting of the main monitor. GetDeviceCaps has been the way to get this setting since Windows XP. This will also do fine on Windows 10 if and only if you do not declare DPI awareness per monitor.
On Windows 10, if you declare DPI awareness per monitor, GetDeviceCaps will not suffice because it only returns the DPI setting for the main display. But if you declare PerMonitorV2, then you are obliged to implement per-monitor DPI correctly. To do this, you can call GetDpiForWindow, or MonitorFromWindow + GetDpiForMonitor.
Since you want your executable to run on both Windows 7 and Windows 10, you cannot link against GetDpiForWindow and GetDpiForMonitor because those functions do not exist in Windows 7. You will need manually link at runtime using GetProcAddress.
To merge the manifest, you can use the Manifest Tool in Visual Studio (Project Properties -> Manifest Tool). Put the entire manifest XML text from above into a file (e.g. DpiAwareness.manifest), and specify that under Manifest Tool -> Input and Output -> Additional Manifest Files.
As for the "Make text bigger" accessibility setting: It is a relatively new WinRT setting that is meant for UWP apps. You're not really expected to use it in Win32 applications, so it's going awkward in Win32. I can't help you there because I hate all things UWP. UWP can go die in a fire.
(1) I have never seen a DISPLAY device with a non-1:1 aspect ratio though. It is probably only useful for printers. The fact that GetDpiForWindow, which is the most modern of the mentioned functions, only returns one number, suggests that it is probably safe to assume that the DPI in X direction will always be equal to the DPI in Y direction (on DISPLAY devices).
(2) Note that there is also dpiAwareness PerMonitor (without V2). This is more or less a now-obsolete hack that came with Windows 8. Don't bother with it.

Xbox 360 Wireless Controller is not working via C++/WinRT and Windows.Gaming.Input API in console application

I trying to use Windows.Gaming.Input API via C++/WinRT from Windows Console Application and it is not working as supposed with Xbox 360 Wireless Controller (reported as Xbox 360 Wireless Receiver for Windows (0x045e:0x0000)).
I got GamepadAdded event, then trying to read gamepad state via gamepad.GetCurrentReading() and seems GamepadReading struct is not filled at all for Xbox 360 Wireless Controller.
Also I found that there is some strange error message on MSVS debug console:
onecoreuap\xbox\devices\api\winrt\pnpdevicewatcher.cpp(500)\Windows.Gaming.Input.dll!00007FFE453AABC7: (caller: 00007FFE453AA367) ReturnHr(1) tid(4e04) 80070006 The handle is invalid.
Xbox One Game Controller (0x045e:0x02d1) is working fine though.
What is wrong with my code? Or this is bug in Windows?
Code is here: https://github.com/DJm00n/cppwinrtgamepad
Using Windows 10 1809, MSVS 2017 15.9.9, cppwinrt v1.0.190211.5, Windows SDK v10.0.17763.0, xusb22.sys v10.0.17163.1, xboxgip.sys v10.0.17163.1.
PS: I also tried UWP Simple3DGameXaml app from https://github.com/microsoft/Windows-universal-samples repo - and both controllers works in it.
This is a known issue. Apparently this is caused by how focus handling works. Windows.Gaming.Input basically doesn't work for console apps as a result, but does work for Win32 or UWP apps that have a window in focus.
Note that the one case where the Xbox One controller worked for you is only because both the user was an admin -and- because you had developer mode enabled. It wouldn't work from a console app at all otherwise.
If you need game controller support for a legacy Win32 console app, you should use XINPUT. See this blog post.
In order to help us investigate this issue more clearly, could you please share your Visual Studio 2017 version to us? You can get version info selecting Help -> About Microsoft Visual Studio, then selecting Copy Info from the right side of the About dialogue.
Could you please check if you can reproduce this issue on 1903 with SDK 18362?
By the way, it will be better if you can upgrade your project dependencies as well, what you are using is an old version of the Microsoft.Windows.CppWinRT NuGet package: 1.0.190211.5. The current latest stable version is v2.0.190722.3.
Besides, the C++ Language Standard was set in project properties, but the value was not set. This should be set to ISO C++17 Standard (/std:c++17) under Project Properties -> C/C++ > Language > C++ Language Standard.
Thanks for your collaboration.

Windows 10 Creators Update (1703) crashes our application

Our users are experiencing crashes when Windows 10 Creators Update (1703) is automatically installed through Windows Updates. The Windows application of ours is a multilevel, C++ WinForms application. The application can start, but if we click on certain menus, it crashes. Appears to be a graphics issue or something to do with fonts, perhaps. Why?
When the Windows 10 1703 update was applied, the installer replaced the Windows/Fonts directory and did not include shortcuts to fonts included elsewhere in Windows.
In our case, our application was needing Lucida Sans Typewriter font, which had been registered with Windows, but located in a bundled JRE for IBM Client Access off Program Files (Our application uses some IBM Client Access components).
Shortcuts of the Lucida fonts were in the Windows/Fonts directory before the update, but absent after the update (which caused our application to crash).
The Fix: We had to copy/paste all the Lucida fonts (there are 8 of them) required from the embedded JRE/lib/fonts directory into the Windows/Fonts directory to resolve the issue. We found if we did this before the 1703 update or after, our application continued to work.
The Lesson: We are going to ensure our applications use fonts that we control 100%, by copying them into Windows/Fonts during install.

Qt/c++: How to set platform independent application icon?

I am developing my Qt (c++) application on MacBook. However, the application might run in both Windows and Mac Systems.
Is there is a way to set platform independent application icon ?!
Setting application icons is already independent, Windows and OS X require different icon formats: http://doc.qt.io/qt-5/appicon.html
the application might run in both Windows and Mac Systems
Right, but not the same executable (binary), you'll compile two versions, one for Windows and one for Mac. Executable icon could be displayed by the OS (when aplication icon is shown on desktop, task bar...) before the application is actually started. So this icon cannot be set programmatically, it must be set at compilation time. And, you must refer to this post to know how to set the application icon for binaries on each different platform.

Stopping the explorer.exe taskbar from opening when using the windows file explorer on XP

I am creating a shell-replacement for developers, which creates a new windows user, titled "developer" and only when you log into this user, should the shell be launched.
The replacement start menu is replaced with a shell based terminal with great features, the taskbar is replaces with a tree based view for windows, and the process monitor is replaced with a view where you can attach process monitors, debuggers, profiles, and memory leak detectors, etc.
I would like my application replace the regular windows shell. I have however came across a registry key that, on windows 7, works just fine. but on windows XP if I use the regular windows XP file manager the windows XP task bar from explorer.exe launches, even though I changed said registry entry!
Does anybody have any idea what it is I need to do to fully replace the windows shell AND taskbar using windows XP while still retaining use of the windows based file manager?: )
Edit:
Using C++, developing using NetBeans using Qt for my gui library. however, as I do not think this should effect the answer, I figured I would include it either way.
I believe Windows XP does not support per-user shell replacement (not sure, it's been a while since I played with the desktop stuff), but you should be able to set the 'Shell' entry under HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon and prevent Explorer from registering itself as the shell when it first runs. This will affect all the users in the machine, of course.