Desktop Alerts Tip: Building App-Specific Alert EXE’s

When I first wrote the Desktop Alerts, I pictured a perfect world where everyone had one set of VFP runtimes and the Desktop Alerts would be installed, once, on every computer in the world.

Alas, the world is not perfect. Some apps install VFPALERT.EXE to the app folder, some do not. Some developers add new functionality and recompile the VFPALERT project, some do not. Some recompile it in VFP9SP2, some do not.

To make things easier on yourself and your fellow developers, I recommend compiling your own application-specific version of the Desktop Alerts for each application, and including it (along with ALERT.WAV) with your installer.

Let’s say I’ve written the following three software products, and I want to include Desktop Alerts functionality with all three:

ABC Accounting
BCD Bookkeeper
CDE Customer Manager

On the one hand, I could install the Desktop Alerts to one specific location, and all three products would use that one install.

But, if my customer is using software from another vendor that also uses the Desktop Alerts (and, especially a modified/recompiled version), I may not get the same functionality I expected.

So, since I have three different products, I’m going to create three versions of the Desktop Alerts COM EXE Server, and install each one with its respective product.

MAKE SURE TO SELECT REGENERATE COMPONENT IDs IN THE PROJECT BUILD WINDOW IF YOU ARE DOING THIS!!!

Build Dialog in Visual FoxPro

 

I’ll take the original source code (from the VFPAlert.zip file from VFPX), and compile it three times (with new Component IDs for each one) using the following filenames:

ABCALERT.EXE
BCDALERT.EXE
CDEALERT.EXE

Then I can distribute each one with their respective product.

In the ABC Accounting software, I would use:

oAlertMgr = CREATEOBJECT(“ABCAlert.AlertManager”)

Instead of the usual “VFPAlert.AlertManager”.

This also frees me up to recompile the alerts in VFP8 (if my app is written in VFP8), without having to rely on installing VFP9SP2 runtimes along with my app just to support the alerts.

All I need at this point is to add ABCALERT.EXE and ALERT.WAV to my ABC Accounting app installer (and make sure to run ABCALERT.EXE with the REGSERVER flag during the install) and I have an all-new, app-specific version of Desktop Alerts just for my app – without having to worry about another vendor’s application “taking over” the Desktop Alerts.

Desktop Alerts 1.0.0 (Production Release)

After 4 years in beta, I’ve posted a new version of the Desktop Alerts as a Production Release on VFPX.

You can download the latest source code and whitepaper at:

http://vfpx.codeplex.com/releases/view/79034

The new version includes a couple of changes/enhancements for improved Vista/Windows 7 compatibility.

There is a new property for the AlertManager class: cSettingsPath. This property can be filled by calling the new AlertManager method SetSettingsPath. Send in the full path of a “writeable” folder where the settings file should be written (DACONFIG.XML).

Another new property of the AlertManager class is lCleanMemory. The default value is .F. – if you set this value to .T. the AlertManager will attempt to reduce memory consumption by calling some code I stole leveraged from Sergey’s blog.

I also updated the Settings window to default to Segoe UI, 9.  There are new settings in the VFPALERT.H file which can hold “fallback” font name and size for users on earlier (pre-Vista) versions of Windows.  The include file currently uses Tahoma,9 as the “fallback”.

I’ll be posting some new notes on the Codeplex site tomorrow. Basically, a FAQ sheet that answers some common questions about installing, etc.

Enjoy!

Updated: Special thanks to Rick Schummer for the friendly reminder to release, and Art Bergquist for editing notes from the original whitepaper!

From A Hog To Just A Pig With A Simple Windows API Call

One of the first questions I got about the Desktop Alerts was, “How much memory and other system resources does this use?”

This was during the presentation in Chicago in December of 2006. My response was the typical, “Oh, not much at all. It’s very light.”

Well, I fired up Task Manager (in front of everyone in the room), and was shocked to find this tiny little app using 10MB of memory — even when it was just sitting there, doing nothing!

“Hmmm,” I thought, “This thing is a hog.”

Not a huge issue, especially compared to a Catastrophic Failure, so I put it on the backburner (which is to say I promptly forgot all about it — if only my apps could free up memory as easily as my brain does).

I recently worked on an app that uses the Microsoft Web Browser control on a Visual FoxPro form as the primary UI for the app. Works well for the most part, but checking memory usage in Task Manager showed a tremendous amount of resources being hogged by the app, even when the user is just sitting there looking at the screen and doing nothing.

“Hmmm,” I thought, “this thing is a hog, too.”

(I started looking at the app’s memory usage after a couple of users with “programming experience” mentioned it…)

Luckily for me, in January of this year Sergey Berezniker wrote about using the Windows API to lower the memory usage of your application.

Simple, straightforward, and very simple to implement.

I put it in the app, and was amazed by how much memory was saved by a simple function call. I went from about 60MB at application startup to about 8MB.

After 6 months in production, I’ve seen no problems reported about the app that would indicate a problem with this function, so yesterday I decided to look at adding it to the Desktop Alerts.

Here’s a quick sampling of the results (Windows XP Professional Service Pack 3):

1. AlertManager Initialized, waiting for something to do:

Before Change (Hog) After Change (Pig)

2. First Alert created and visible:

Before Change (Hog) After Change (Pig)

3. Three alerts visible on screen:

Before Change (Hog) After Change (Pig)

4. All alerts cleared, AlertManager waiting for next command:

Before Change (Hog) After Change (Pig)

 

So, with one simple Windows API call, we’ve reduced the memory usage by almost 80%, turning this gigantic hog into a smaller pig. I’ve seen similar results in Vista, though the memory usage in Vista was much lower to start with than in XP, so the results of the change aren’t quite as dramatic.

One interesting thing, though. See the User Name column in the screenshots? The user changed from Kevin Ragsdale to SYSTEM. So, not only has a hog become a pig, its name has been changed as well. In Windows Vista, the User Name stays put as Kevin Ragsdale.

Anyone that can explain this to me without causing my head to explode — feel free to explain in the comments.

This API function is available in Windows 2000 and higher so, if you have any OS stragglers you’ll want to bracket the function call with something like this:

IF VAL(OS(3)) >= 5    && Skip if earlier than Windows 2000
   ** Do your thing
ENDIF

And yes, I do have a ton of code “out there” that uses this bracket a lot…

Catastrophic Failure and Desktop Alerts

Yesterday, I posted a screenshot of my scariest error message. It was a message I had gotten while playing with the Desktop AlertsRandy Jean commented that he saw the same error with the Desktop Alerts.

In the Alert class nResult_Assign() method, I had the Alert calling its Release() method. So, if you had code like this:

oMgr = CreateObject("VFPAlert.AlertManager")
oAlert = oMgr.NewAlert()
oAlert.Alert("Howdy")
oAlert.Alert("Howdy Again")

The first Alert() works just as expected.

The second Alert() causes the “Catastrophic Failure” message. Why? Because oAlert had RELEASEd itself. And here I am, sitting with an object reference (oAlert) for which theVARTYPE() function returns an “O”.

One way to see if the Alert still exists is to check the Alerts collection Count property. In the above example, this would be something like:

lnAlerts = oMgr.Alerts.Count

If you look at the Alert class Release() method and comment out the RELEASE THIS line, you can then “reuse” the alert as many times as you want.

This post originally appeared on the Foxite Weblogs site.