Thursday, April 26, 2018

Add a fading effect to your VFP Forms


Add a fading effect to your forms

By creating forms that fade in and out gradually, you can add a pleasing visual effect to your Visual FoxPro applications

You might have noticed in your favourite Windows applications that some windows fade in gradually when they open, rather than appearing instantly. Similarly, when a window is closed, it might take a second or so to fade out, rather than disappearing in a flash. This can present a pleasing visual effect (provided it's used sparingly). The technique works especially well with popup windows and alerts that the user might not be expecting. The gradual emergence of a window is often kinder on the eye than one that suddenly flashes onto the screen.

In this article, we'll explain how to add this fading effect to your Visual FoxPro forms. We'll also describe a simple form class, named FadeForm, that incorporates the technique. You can download the class and use it straight away to build your own fading forms. See below for download instructions.

Essentially, the technique involves gradually increasing or decreasing the transparency of the form. Even if you aren't interested in creating fading forms, you can adapt the code for other situations where you might want to make a form partially transparent.

A couple of caveats

Before we go any further, we must point out a couple of limitations of this technique. First, it requires certain API calls that only work in Windows 2000 or above. If your users still use Windows 98, you won't be able to offer them this feature.

More importantly, the technique only works with top-level forms. A top-level form is one that appears independently of your main application's outer window. By default, it has its own button on the Windows taskbar (you can hide the button by setting the ShowInTaskbar property to .F.), and it can be moved outside the outer window. To create a top-level form, set the form's ShowWindow property to 2 (we have already done that in the FadeForm class in this article's download).

Making a form transparent

To perform its magic, the fading form uses a Windows API function named SetLayeredWindowAttributes(). This function can help a form perform several interesting visual tricks. The one that we are interested in here is its ability to make a form transparent. More exactly, it can increase or decrease the degree of opacity of a form in very small steps. The opacity factor can range from 0 (completely transparent) to 255 (completely opaque).

So, to make a form appear gradually, you start out by making it completely transparent. You then keep increasing the opacity until the form is completely opaque. Similarly, to make the form fade out, you start with the maximum opacity (255) and decrease it until it reaches zero.

Declaring the API functions

Before you can do any of this, you need to declare the SetLayeredWindowAttributes() function within VFP. You must also declare a couple of other API calls: SetWindowLong, which flags the form as a 'layered window', and Sleep(), which lets you introduce a short delay after each adjustment to the opacity factor.

Like all API declarations, these DECLAREs should ideally be issued once only, near the start of the session. For convenience, the FadeForm class in the download file executes the declarations in its Load event, but this is far from ideal. It means that the functions will be re-declared every time any form based on the class is instantiated, which is wasteful of resources. We suggest you move these declarations to a suitable point near the start of your main program.

Here is the code to declare the API functions (the first two of these require Windows 2000 or above):

DECLARE INTEGER SetWindowLong In Win32Api ;
  INTEGER HWnd, INTEGER Index, INTEGER NewVal

DECLARE INTEGER SetLayeredWindowAttributes In Win32Api ;
  INTEGER HWnd, STRING ColorKey, ;
  INTEGER Opacity, INTEGER Flags

DECLARE Sleep IN WIN32API INTEGER Duration

Making the form appear …
The actual work of making the form appear gradually is done in the FadeIn method, which should be called from the form's Init. Because the form is normally invisible during its initialisation, FadeIn should ideally be called towards the end of the Init's processing. This is done automatically from the Init method of the FadeForm class. If you override the Init method, be sure to explicitly call FadeForm at a suitable point.

The FadeIn method starts by checking a form property named lFade, which acts as a master switch for the fade effect. This property is set to .F. by default. To enable fading, be sure to change it to .T.

Here's the main part of the code in the FadeIn method:

* If fade effect not required, do nothing
IF NOT thisform.lFade
  RETURN
ENDIF

* Start by making the form fully transparent
SetWindowLong(THISFORM.hWnd, -20, 0x00080000)
SetLayeredWindowAttributes(THISFORM.hWnd, 0, 0, 2)

* Show the form (this tells VFP to show the form; at this
* stage, nothing will appear on the screen, because the
* form is still fully transparent)
thisform.Visible = .T.

* Now gradually fade in, taking about one second to do so
lnTrans = 10
DO WHILE .T.
  SetLayeredWindowAttributes(THISFORM.hWnd, 0, lnTrans, 2)
  lnTrans = lnTrans + 10
  IF lnTrans > 255
    EXIT
  ENDIF Sleep(35)
ENDDO

* The form is now fully opaque
If you want to adjust the speed of the fade-in, change the numeric value passed to the Sleep() function. This is the number of milliseconds during which the method will pause each time the opacity factor is adjusted. Increase this figure to make the form fade in more slowly; decrease it to do the reverse.

… And disappear
The class's FadeOut method (not shown here) works in the same way as FadeIn, the main difference being that it decreases the opacity factor rather than increasing it. Also, FadeOut doesn't need to alter the form's Visible property.

You call FadeOut from the form's Destroy method. As with FadeIn, the class in the download file does this by default. If you override its Destroy, you should be sure to call FadeOut explicitly. (Take care not to call FadeOut or FadeIn more than once per form session, or you will create a very strange visual effect.)

Download the class
Click the link below to download our FadeForm class. The class is contained in a class library (FadeForm.VCX) which in turn is packaged into a zip file. The total size of the download is only 3 KB.





You can either use the class as it is, or extract the code for use in your own forms or classes. Either way, read the Documentation method, which contains notes on how to use the class.

No comments:

Post a Comment