MFC Application font issues - dialogs look wrongon Win2k8 - winapi

My legacy application that runs on win2k3 citrix is about to be migrated to win2k8 citrix.
While testing on win2k8 I noticed UI issues that are not apparent on 2k3 - buttons are not wide enough for their labels, text fields are truncated, etc.
I noticed Win2k3 default font is Tahoma and 2k8 uses Segoe UI, not sure if this is the cause
It's a controlled environment that hosts only my application so changing the windows UI settings is preferable to redesigning all my windows and dialogs.
How can i make my application look the same on win2k8 as it does on win2k3?
Here is an example of my login dialog from the rc file. On win2k8 the text "please enter your user id" wraps over 2 lines and is hidden under the edit box.
IDD_LOGON DIALOG DISCARDABLE 0, 0, 545, 361
STYLE WS_POPUP | WS_VISIBLE
FONT 8, "Arial"
BEGIN
LTEXT "Welcome",IDC_USER_LOGON_HEAD1,368,192,140,19
LTEXT "Please enter your User ID",IDC_USER_LOGON_HEAD2,368,220,
118,14
EDITTEXT IDC_USER_LOGON_USER,368,236,81,12,ES_AUTOHSCROLL
LTEXT "and your password",IDC_USER_LOGON_HEAD3,368,260,118,14
EDITTEXT IDC_USER_LOGON_PASSWORD,368,276,81,12,ES_PASSWORD |
ES_AUTOHSCROLL
PUSHBUTTON "OK",IDOK,368,316,50,14,WS_DISABLED
PUSHBUTTON "E&xit",IDCANCEL,424,316,50,14
END
edit:
I did some further investigation by taking some screen shots of the above dialog. it appears the problem is not that the text is the wrong size - the problem in the controls on the dialog are too small!
eg:
for the control IDC_USER_LOGON_PASSWORD which is 81 dialog units x 12 dialog units.
it should be rendered as 142 px by 24 px
instead it is rendered too small as 122 px by 21 px
Does this give anyone any clues?

Looks like you have "Desktop Experience" installed. You can uninstall it, and the server will run in "Classic" mode.
Additionally, you can play with "Personalisation Settings". Open Control panel\Appearance and Personalisation\Display and select "Make text and other items larger or smaller". There you can set the size of each elements. I recommend you set everything at 100%.
Also, if this does not help, you can change Compatibility for the application in Win2k8 to run as Win2k3.

As suggested by Hans, the problem was a DPI setting. The Win2k8 system has a DPI of 96 and the win2k3 system has a DPI of 120.
Setting the DPI on win2k8 to 120 resolves the issue when logged on via remote desktop, however there are still some issues getting citrix settings to respect this DPI settings, but I'm on the right track now.
thanks everyone

Related

DPI scaling a complete dialog box from resource

I setup per-monitor DPI scaling in a Win32 app, and my part works fine, however opening up a dialog box created in the resource editor doesn't scale itself (I would think using dialog units, it would).
Is there a way to scale everything from a dialog resource and be compatible with, say, Win8.1, as well as Win10, and even Win7?
Per-Monitor and Per-Monitor (V2) DPI Awareness:
It is recommended that desktop applications be updated to use
per-monitor DPI awareness mode, allowing them to immediately render
correctly whenever the DPI changes. When an application reports to
Windows that it wants to run in this mode, Windows will not bitmap
stretch the application when the DPI changes, instead sending
WM_DPICHANGED to the application window. It is then the complete
responsibility of the application to handle resizing itself for the
new DPI. Most UI frameworks used by desktop applications (Windows
common controls (comctl32), Windows Forms, Windows Presentation
Framework, etc.) do not support automatic DPI scaling, requiring
developers to resize and reposition the contents of their windows
themselves.
You can resize the dialog box in the WM_DPICHANGED message.
case WM_DPICHANGED:
{
LPRECT lpRect = (LPRECT)lParam;
SetWindowPos(hWnd, nullptr, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, SWP_NOZORDER | SWP_NOACTIVATE);
return 0;
}
Updated:
For per-monitor DPI, v2 is the only one that can handle the dialog DPI scale., v1 does not so on WIndows 8.1 and older versions of Window 10, it has to be done manually. Windows 8.1 and older Windows 10, we don't scale controls. So the solution should be just resize the dialog. It has to enumerate all controls and resize them during WM_DPICHANGED if the dialog is not resizable.

How to manage the application icon on the taskbar?

Intro:
OS: Windows 10
DPI: 96
I got metrics of recommended sizes small (16x16) and large (32x32) icons of my application, called SetClassLong function to set him. Everything is working!
BUT!! After launching the application, the icon displayed in the taskbar has a size of 24x24.
Why such a size? I setted only the recommended 16x16 and 32x32? How can I control the real icon in the taskbar (except for calling SetOverlayIcon)
How can I give the system a 24x24 icon (which one should it be for
other dpi?) If the metric request recommends me 16x16 and 32x32?
Forget about the GetSystemMetrics() since it hasn't been updated in ages. To provide a 24x24 icon that Windows 10 uses for display on the task bar just set the hIcon member of your WNDCLASS to such icon.

Make Windows Common Dialogs "Per Monitor DPI-Aware"

I have a program which was created in VS2008 with MFC.
Now I've modified it to make it "Per Monitor DPI-Aware", and it's almost done. I've modified the manifest and handled the WM_DPICHANGE message. But there's still one problem:
I used CFileDialog class to show Open/Save dialogs, and used SHBrowseForFolder function to show folder selection dialog. But all these dialogs are NOT "Per Monitor DPI-Aware", they won't adjust their UI when you move them between monitors with different DPI settings.
I use spy++ to monitor messages of these dialogs, I find they can receive WM_DPICHANGED message but they just don't handle it.
And I've tested the open file dialog in notepad.exe on Windows 10, it worked perfectly.
Does anyone know how can I make these dialogs "Per Monitor DPI-Aware"?
--------EDIT--------
There're two more problems:
When I move a window to a monitor with different DPI, the window resize itself, but the height of it's title bar and title font-size are not changed.
The checkbox controls' box size is not changed either.
I feel these problems may have some kind of connections, but I can't figure it out.
--------SAD NEWS--------
I compiled microsoft's "DPI Tutorial Sample" with VS2013, and it has the same problem.
https://code.msdn.microsoft.com/DPI-Tutorial-sample-64134744
The titlebar (caption bar) can be scaled by calling EnableNonClientDpiScaling which is available on versions of Windows >= the Windows 10 Anniversary Update (1607).
If you want to DPI scale an older dialog that doesn't support per-monitor DPI scaling you can use SetThreadDpiAwarenessContext (with DPI_AWARENESS_CONTEXT_SYSTEM_AWARE or DPI_AWARENESS_CONTEXT_UNAWARE) to have the top-level windows of the dialog scaled by Windows. The dialog might be blurry but it will at least be sized correctly (also only available on >= 1607 builds of Windows 10). The usage pattern is to call this API before opening the dialog and then restore the previous DPI context immediately after calling the API.
According to MSDN the window that processes WM_DPICHANGED message should return 0. However, any MFC window or control you send WM_DPICHANGED will return 0, since thay call the default window procedure for the unknown messages.
Therefore, judging if some window does process WM_DPICHANGED message by testing its LRESULT return value against zero is not accurate.
The window's title bar of a per-monitor DPI aware application doesn't scale when moving across different DPI monitors as documented on MSDN. Unfortunately, non-client area of the window never adjust the DPI.
Calculator and other per-monitor DPI aware Windows native apps have custom title bar drawing, as described here.

VB6 DTPicker Control date not showing when Enabled=false on Win7 and Win7 SP1

I've got a strange behavior on one of my Win7 machines when using the DTPicker date control.
When the control is not enabled (myDTPicker.Enabled=false) the date text does not show up,it is blank.
The same program on my other Win7 SP1 machine works as expected when (myDTPicker.Enabled=false) the date text is visible and the control is grayed out; this is good.
Originally, the Win7 machine where the date text is blank did not have SP1, so I thought that may be the issue. I upgraded to SP1, but the issue has not gone away. Also rebooted just to make sure.
Do you happen to know what may be causing the date text to be blank when DTPicker.Enabled=false on one Win7 box vs another?
The DTP in VB6 gets its foreground text color from the system's "Disabled Item" font color – so if that's set to a pale gray rather than the more usual dark gray, it will have the effect of making the DTP look blank when it's disabled. You need to go to the Advanced Window Color and Appearance settings dialog to check it.
Not sure if this is your issue, but here my shot in the dark. I've seen this problem before with Windows 7 when DPI was anything other the default. Some laptops these days come with 125% as the default DPI. Try resetting it to 100% and see whether it fixes it.

"Use windows xp style dpi scaling" disables automatic auto-hide of taskbar on W7. Workaround?

We noticed that on W7 with DPI set to > 125% or to > 100% with ("Use windows xp style dpi scaling") turned off, our fullscreen mode (which sets the client rect of our window = desktop rect of the main monitor) no longer hides the task bar like it does for other settings.
(The setting can be found in the Control Panel\Appearance and Personalization\Display section after clicking on the "Set custom text size (DPI)" link)
I found the following interesting article:
http://www.mathies.com/weblog/?p=908
So I set out to try to work around the bug in other means than manually hiding/restoring the taskbar visibility but so far I've failed and currently believe it's a bug in W7 (and possibly vista).
The following applications also fail to work properly in fullscreen mode (the taskbar is still visible):
* Microsoft Visual Studio 2008
* Microsoft Word 2007
* Adobe Reader 9.1.3
These apps work (probably by hiding the task bar through the WIN32 API):
* Powerpoint Slide Show
I also tried creating a brand new MFC-based app and use its "SetFullScreenMode()" functionality but it fails in the same way as all other apps on the list.
For now it seems the only temporary fix which has worked for me is to disable display scaling on high DPI settings for the program your using fullscreen with.
To do this goto properties (right-click the program's shortcut) >> compatability >> and check the option to disable display scaling on high DPI settings.
The only drawback is that you will not get the higher DPI for that program but the taskbar should hide when fullscreen is enabled.
This is a problem that I understand Windows 7 developers are aware of but have not come out with a solution.

Resources