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!

Don’t Miss the Deadline

Updated: Links point to the 2011 Southwest Fox Conference. Click here for the current conference.

The Southwest Fox 2011 Conference kicks-off Wednesday, October 26th with four pre-conference sessions.

Whether you’re interested in client-server developmentFoxPro and Smartphones,FoxInCloud, or getting started with ASP.NET MVC3, this years pre-conference schedule has something for everyone.

And I know a way you can attend one of these half-day ($99) sessions for free. Simply register for Southwest Fox before July 1st.

Want to be eligible to save even more $$$ on the conference? Check out the conference scholarships which will provide three very lucky people with a $150 “rebate” (see the website for rules and regulations).

Scholarship drawing eligibility and the free pre-conference session are available only for those who register before July 1st.

As of this writing (June 29th), there are 50 Super Saver registrations still available. Super Saver registration is $645, a discount of $125 off the regular conference rate.

The clock is ticking… Save yourself (or your boss) some $$$ and reserve your spot for THE go-to conference of the year!

Southwest Fox 2011 Links: SessionsScholarshipsRegistration

Southwest Fox 2011

Updated: Links point to the 2011 Southwest Fox Conference. Click here for the current conference.

Shortly after the speakers and sessions for the Southwest Fox 2011 Conference were announced, I received the following testimonial via email:

Dear Kevin,
I saw your name in the list of speakers for Southwest Fox 2011
and I've got to say, Southwest Fox is
THE GO-TO CONFERENCE OF THE YEAR!
Love,
Mom

I’m really excited about this years conference, and I’ll be even better prepared thanks to “dependable” Doug! Registration starts June 1st!

SET PROCEDURE TO MyDll

I use the Microsoft Web Browser Control as the primary UI for an app. This means I need a ton of support files like cascading stylesheets, javascript files, images, etc.

Typically, I create a subfolder in the Windows “Temp” (SYS(2023)) folder for the HTML files, then subfolders for each of the support file types (CSS, JS, IMG). I don’t like to install the support files with the app, because there’s always someone out there that wants to modify the files or just poke around to see how some things get done.

In the past, I simply included the support files in the EXE and did a series of STRTOFILE()’s to copy the files to the temporary location. But as the app (and the number of support files it uses) grows, it really bloats the EXE. So I created a DLL which contained all the included files, with methods to do the file copying.

During startup, the EXE instantiates the OLEPUBLIC classes in the DLL and fires the methods to copy the files. Works great, and it keeps the size of the EXE a bit smaller.

Yep, works great. Except when the DLL doesn’t get properly registered during the install, and the instantiation fails. I get error reports from time to time where the DLL hasn’t been registered. Though I’ve been unable to recreate it here, it seems the common denominator is a particular anti-virus software solution – I’m looking at you, Kaspersky.

So, I’m stuck with needing to manually register the DLL if it hasn’t been registered. I suppose I could use Reg-Free COM, manifest files, elevation, etc. to register the DLL programmatically, but I worry about going through all of that only to find that it still won’t register for the same reason it didn’t during installation (I’m still looking at you, Kaspersky).

I stumbled on an idea earlier this week and thought I’d give it a try. The idea was to SET PROCEDURE TO MyDll. Why not create a DLL, then, instead of going through registering it, just SET PROCEDURE to it and call the methods?

Duh. Can’t do it. It’s an object method, and I haven’t created the object.

So I did a little refactoring on the DLL. It contains one OLEPUBLIC class, which is nothing more than a class definition – no properties, no methods, no nothing. Then I split the methods out to simple FUNCTIONs.

Recompiled the DLL, then got rid of the registration info that was added to the Windows Registry. Then I tried the SET PROCEDURE TO.

The pseudocode looks like this:

IF MyDll.dll Exists then
   SET PROCEDURE TO MyDll.dll
   MyFunction()
   RELEASE PROCEDURE MyDll.dll
ENDIF

And, it worked! No registration, just a simple check to see if the file exists. If it does, run the method. This assumes, of course, that the method exists (since there’s no PEMSTATUS I can check – remember, no object or class exists).

Now for the disclaimer (before the comments start rolling in):

  1. Yes, I am well aware that SET PROCEDURE TO was not designed to be used this way.
  2. Yes, I know the best way to “fix” the problem is to determine what the problem actually is and find a “real” solution.
  3. Yes, I know this wouldn’t be considered “best practice”.

On the other hand, though, my purpose for this is pretty specific, and was completed very quickly. Plus, with a little bit of coding on the app’s update procedure, I can now update the DLL anytime I need to, without having to install a whole new update. Best of all, it appears that the problem has been solved.  I still try to instantiate the object first, but if it fails I fallback to the new “unregistered” DLL. Not a single error report since the last update.

So far, so good…