Aero (Glass) Borders For Forms In SCREEN

This tip applies to Windows Vista and Windows 7 only!

If you want Aero effects (glass) for your forms which are shown IN SCREEN (ShowWindow property = 0), simply set the Desktop property for the form to .T.

There are a couple of downsides, though:

  • The form is now able to be dragged outside the VFP SCREEN, which can create some confusion for users.
  • When a form that has been dragged outside the SCREEN is Minimized, it minimizes to the Windows Desktop. One fix for this is to set MinButton = .F., to prevent minimizing the form.

I like the Aero Glass effect in Windows 7 (don’t get me started on Vista!), but Windows 8 no longer has the Aero Glass borders. So, this tip has no effect on Windows 8 (except for the potential user confusion).

But, it’s there if you want to use it!

Stop The Bleeding!

Have you ever noticed that some controls tend to “bleed” when the user clicks on them more than once? I’ve seen it often with OptionGroups and Checkboxes when the BackStyle has been set to transparent.

Multiple clicks cause pixel bleeding

Multiple clicks cause pixel bleeding

The easiest “fix” I’ve found for this (besides making the BackStyle Opaque) is to put the following line of code in a user-actionable event (I usually put it in the Click or InteractiveChange event):

This.Caption = This.Caption

This code doesn’t actually do anything, but I have found that it “stops the bleeding”.

 

Paint It (Almost) Black

In a previous post, I showed an ugly form. Ugly, because it looked awful when I ran the form with the Windows High Contrast Theme.

With the High Contrast Theme, normal black text appears yellow. Which is no problem at all when the text is drawn on a black background. But in my form, the text was drawn over a white shape control, and looked like this (the red arrows point to the yellow text):

Yellow text on a white background

Normal black text turns yellow in High Contrast #1 Theme.

So now I have a form that is unreadable in High Contrast. What I want to do is force Windows to draw the text black (since it is drawn over the white background).

 

There’s An Easy Fix For That!

This is simple to do. I set the ForeColor of the labels that I want to appear as black to RGB(2,2,2). This color change from RGB(0,0,0) is imperceptible to the human eye (it still looks black), but Windows sees it as an absolute color. And since I have changed it to something other than the default, Windows will display the label in my “near-black” color (since it is not the “Default”).

After my session at Southwest Fox, a couple of people said they do the same thing I do to force a label to be black, but they use RGB(1,1,1). Not sure why I picked 2,2,2 – but they’re both “black” to the naked eye — and either setting works fine.

Here’s an example of an instance of my “near-black” label on a form (the top label ForeColor is RGB(0,0,0) – the Default), while the label inside the white shape has a ForeColor of RGB(2,2,2) – or, as I like to call it, “forced black”:

Two labels, two different ForeColors, same effect.

Two labels, two different ForeColors, same effect.

And the same form, this time running in Windows High Contrast Theme:

The "near-black" label stays black

The “near-black” label stays black.

Later in the series, we’ll look at creating sub-classes for different controls. This one I’ll call the lblForceBlack control, subclassed from a base Label class.

Is Your App DPI-Aware?

When you tell Windows Vista (and 7 & 8) that your app is DPI-aware, Windows will not use DPI virtualization for your app and will no longer “lie” when you ask about the DPI settings.

Please note that by telling Windows that your app is DPI-aware, it is completely up to your app (you) to resize your UI in order to match user expectations based on their settings.

There are 2 different ways to tell Windows Vista, 7 and 8 that your app is DPI-aware:

  • a Windows API function, or
  • adding a section to your apps manifest file.

Using a Windows API Function

Windows Vista, 7 and 8 contain an API function named SetProcessDPIAware. The function has no parameters. It returns a zero if the function fails, and a non-zero result if the function succeeds.

Using it from within Visual FoxPro is easy:

DECLARE INTEGER SetProcessDPIAware IN WIN32API
SetProcessDPIAware()

The function simply tells Windows, “This app (process) is DPI Aware, so please do not lie to me. I will handle all of the resizing myself, so my users will see things the way they want to.”

Easy, right? Well, kind of. If you run the code listing above from the VFP Command Window, and if your Windows DPI setting has been set to 144dpi with DPI Virtualization turned on, you’ll get the correct (truthful) font factor from Windows (when you follow the API call with the code listing from a previous post).

BUT, remember this function has told Windows that this process is DPI-aware. And since you’re running the code from within the VFP IDE, you’re essentially telling Windows that Visual FoxPro is DPI-aware.

Unfortunately, Visual FoxPro is not DPI-aware, and has already been “DPI virtualized” by Windows. Causing Windows to suddenly accept that Visual FoxPro is DPI-aware can wreak havoc with the IDE.

If you don’t trust me on this, try it. It’s u-g-l-y!

So, one way we can force Windows to accept the fact that our app is DPI-aware is to simply call the SetProcessDPIAware function – preferably as early in your app as possible. I have seen several forum postings which report calling the function too late can cause Windows to continue to “lie” and use DPI virtualization anyway, though I have not recreated this problem myself.

 

Using Your App Manifest File

Another way to tell Windows Vista (and 7) that the app is DPI-aware is to add the following section to your app manifest file:

<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
   <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true</dpiAware>
   </asmv3:windowsSettings>
</asmv3:application>

If you are not sure about manifest files and adding manifest resources to your Visual FoxPro applications, I recommend the following articles (I’ve been using Markus’ Manifest Tools in my work):

Calvin Hsia: Add a Manifest to Control Your Application Vista UAC Behavior

Craig Boyd: Apply Application Manifest At Compile Time With ProjectHook

Markus Winhard: ManifestTools.zip (based on code from Calvin’s blog above)

If you are not comfortable with messing around with manifest files, the SetProcessDPIAware API function is the way to go. Just be sure it only runs on Vista/Win7/Win8 (or call it in a TRY-CATCH-ENDTRY block) to prevent an error in pre-Vista versions of Windows!

Additional thoughts and (better) explanations of DPI-awareness in Vista can be found in the following article: http://www.rw-designer.com/DPI-aware