Monthly Archives: May 2007

VB and Resource Files (Part 3)

1
Filed under Resource Files, Utilities, VB Feng Shui

In case you’ve missed the first 2 posts in this series, I’m discussing the concept of using Resouce files with Visual Basic 6.

In the first part, I talked about how to compile arbitrary information into a resource file and reference it from VB.

In Part 2, I discussed a technique for compiling a VersionInfo resource and writing it into your VB executable, thus replacing the incomplete VB provided VersionInfo resource.

In this installment, I wanted to share a little trick for defining the elements of the “Version number” in a resource (RC) file such that you only have to enter the version number once.

If you recall, I presented a sample RC file the last time, looking like this:

1 VERSIONINFO
FILEVERSION 1,2,3,4
PRODUCTVERSION 1,2,3,4
FILEOS 0x4
FILETYPE 0x1 //// 2 for dll, 1 for exe
{
BLOCK "StringFileInfo"
{
BLOCK "000004b0"
{
VALUE "CompanyName", "MyCompany"
VALUE "ProductName", "MyProduct"
VALUE "FileDescription", "MyFileDesc"
VALUE "LegalCopyright", "MyLegalCopyright"
VALUE "LegalTrademarks", "MyLegalTrademark"
VALUE "OriginalFilename", "MyOriginalFilename"
VALUE "ProductVersion", "1.2.3.4"
VALUE "FileVersion", "1.2.3.4"
VALUE "Comments", "MyComments"
VALUE "InternalName", "MyInternalName"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0000 0x04B0
}
}

If you’ll notice, there is one thing about this script that no lazy programmer worth a macro recorder would tolerate. The Version Number is duplicated several times, and what’s worse, in several different formats.

First, we have the FILEVERSION and PRODUCTVERSION entries, with comma separated numbers.

But then we also have the stringized version of those two elements, that must be specified as period separated elements within quotes.

I don’t have an alcohol fueled Code Sync 5000 robot to keep those numbers straight so I figured I’d just use macro substitution. Right. Turns out, the Resource compiler (RC.EXE) is a mighty fickel beast.

What I envisioned was a simple block to define the version number:

#define MAJOR          1
#define MINOR          0
#define REVISION       0
#define BUILD          116

and then use those definitions further down in the file, like so

FILEVERSION MAJOR,MINOR,REVISION,BUILD

and similiarly

VALUE “ProductVersion”, “MAJOR.MINOR.REVISION.BUILD”

But obviously, there’s a problem; actually, more than just one.

I won’t dwell on the details, but after much head scratching (polite euphimism), I ended up with this joyous concoction:

#define COMMAVER(mj,mn,rv,bl)        mj,##mn,##rv,##bl
// Commaver yields x,y,z,a  (necessary for the numeric versions)

#define PERIODVERPT2( mj )           #mj ""
#define PERIODVERPT3( mj,mn,rv,bl )  PERIODVERPT2( mj ) "." PERIODVERPT2( mn ) "." PERIODVERPT2( rv ) "." PERIODVERPT2( bl )
#define PERIODVER                    PERIODVERPT3( MAJOR,MINOR,REVISION,BUILD )
// PeriodVer yields x.y.z.a (necessary for the stringized versions)

// define the two numeric versions
// always make them the same
#define FILEVER        COMMAVER(MAJOR,MINOR,REVISION,BUILD)
#define PRODUCTVER     FILEVER

// define the two stringized version numbers, we just make them the same
#define STRFILEVER     PERIODVER
#define STRPRODUCTVER  PERIODVER

Then you can use them like so

....
FILEVERSION FILEVER
PRODUCTVERSION PRODUCTVER
....
VALUE "ProductVersion", STRPRODUCTVER
VALUE "FileVersion", STRFILEVER

Get clever with the #include directive and you can easily keep the version numbers of all the separately compiled VB components of your project synchronized and only have to set the version number in a single place.

If there’s a simpler way, I’d love to hear about it. But this works, and it keeps all my version numbers straight.

FIGlets

0
Filed under Utilities

How about a little fun?

I use batch files, make files, etc. to automate build processes quite often, but they can generate output that is, well, so very boring.

Why not liven it up a bit with FIGlets! This is some seriously old school tech, but it’s quite a nice effect if used in moderation.

Instead of just printing:

Build Starting...

in your output, how about:

      ____          __    ___ _____ __
     / __ )__ __(_)/ /___/ / / ___// /_____ ______/ /_(_)___  ____
    / __ // / / / / / __/ /\__ \ / __/ __ `/ ___/  __/ / __ \/ __ `
   / /_/ / /_/ / / / /_/ / ___/ / /_/ /_/ / /   / /_/ / / / / /_/ / _ _
  /_____/\__,_/_/_/\__,_/ /____/\__/\__,_/_/\__/_/_/ /_/ /_ \__, (_/_/_)
                                                           /____/

Makes it much more obvious when things have started or finished.

To generate one-off text snippets like this, go to The Ascii Generator.

or, for real flexibility, just download the original FIGlet command line utility. Be sure to get all the various fonts. Personally, I like the SLANT font the best (the example above is in SLANT).

Then you can just use:

FIGlet -f slant "Build Starting..."
....
FIGlet -f slant "Build Finished..."

in your batch files for some real early 90′s chic!

Microsoft Virtual PC and Shared Folders

2
Filed under Uncategorized

Ok, I admit it. I have a bias towards VMWare. It’s been around forever, and it’s solid as a Bob Seger song. But, the Microsoft offering (Vitual PC) is free and it’s at least usable. But it certainly has it’s share of, shall we say, quirks.

Here’s the latest.

I have 2 VPCs that I use for InstallShield install builds and testing. Both share a folder on the host machine so that I can easily pass installations back and forth between the two.

This morning, a subfolder of the share on one VPC turned up empty. I refreshed the view. Empty. Popped over to the host machine and looked in the folder. It’s there, and has all its files.

I reset permissions. No luck. I unshared and reshared the folder via VPC. Still empty. Rebooted both the VPC and the host machine. Still empty.

At this point, it’s cost me about 30 mins of a Saturday when I’d much rather be anywhere in front of a VPC. I finally just renamed the subfolder, thinking I’ll copy a new set of files down from the network. Lo and behold, the newly renamed subfolder shows up on the VPC, and it now shows its contents! Keep in mind that this folder worked properly yesterday, and that there are other sub-folders in the shared folder that continue to show their contents just fine as well. Just this one folder is at issue.

Hmmm. So I renamed it back to its original name. It goes empty again. Doesn’t show any contents.

Ah, computer voodoo. Or in this case maybe the more appropriate term Microsoft doodoo. At any rate, the install is rebuilt, and I’m off to do something that doesn’t require a plastic rat and 2,304,000 square colored dots.

VB and Lotus Notes

2
Filed under EMail, Software Architecture

Not something that often ends up on a VB developer’s plate I suspect, but I had need to do some investigating of Lotus Notes and possible integration/extension development using VB (classic, v6.0, not .NET).

Come to find out, Notes does have COM support as of 5.0.2b, so appearently, you do not have to dive down into ever joyous C++ in order to take a stroll through Notes-ville. Unfortunately, finding actual documentation for that object model online feels like finding your kid’s matchbox car that fell out of their pocket in the ball pit at Chuck E Cheese. I’ll try to post my results, if any, when I have some.

Now, as to why you’d want to dig into Note, one look here should dissuade all but the foolhardiest of souls. Granted, I know very little of the internals of Notes. From what I understand, internally, it’s actually a quite capable system, and has been for years and years. Still, those screenshots speak volumes.

Me? Well, I have a foot and here’s a Smith and Wesson. With any luck, the obvious won’t happen next.

InstallShield, Product Codes, Package Codes, and Upgrade Codes, Oh my!

3
Filed under Installations

So you’ve created an upgrade item with InstallShield (mine is 11.5), you’ve set everything up right as far as you can tell, and when you run in to upgrade a previous version, the installer pops up the “Modify/Repair/Uninstall” screen of the old version

Aha! You say. Forgot to change the Package code. So a GUID Generate and rebuild later, you try again and this time get this:

Another version of this product is already installed. Installation of this version cannot continue.

You got the Package Code different, Upgrade and Product Code the same in the two versions, and you’ve got a Major Upgrade item setup and configured to recognize the proper Old version number range.

What’s up?

Come to find out, the IS help is a little confused on this topic. When you create a MAJOR UPGRADE to your installation (which, if my experience is any indication, almost EVERY upgrade is a major upgrade), you need to change both the Product Code and the Package Code! But here’s the trick, the Upgrade Code stays the same.

Why? Because appearently, a Major Upgrade is considered an entirely new Product, even though it’s not, because you intend it to upgrade older versions of the product.

But MSI doesn’t use the Product Code for that, it uses the Upgrade Code for that purpose.

So, basic rule is:

When you create a new Version of your app’s installation with InstallShield (or any MSI based Installer, I suspect), be sure to:

  1. Make sure you have an Upgrade Item setup to recognize the proper version range
  2. Make sure you generate a NEW PACKAGE CODE guid
  3. Make sure you generate a NEW PRODUCT CODE guid
  4. Make sure you DO NOT modify the UPGRADE CODE guid (basically, you almost never modify the Upgrade Code guid)
  5. Kneel before the holy altar and make an offering to the MSI gods.

Here’s a handy table from a Macrovision support site article that also might help. Basically, it illustrates when a particular code needs to be changed (the X’s), based on what kind of upgrade the new version of your install is.

Update Type Package Code Product Version Product Code Upgrade Code
Minor Upgrade without Patching X
Minor Upgrade with Patch X X
Major Upgrade X X X

You know, I whipped out an install in InnoSetup in, like, 5 minutes. And it’s free.

Fun with the Word Object Model

0
Filed under Office

Ran into something very interesting with Word, Templates and the Word Object Model today.

I have a Word Addin that creates a Word Template on the fly and loads it when Word is loading up.

The template is used to save any modifications (via the Application.CustomizationContext property) to the Word Toolbar that I have to make while running, which is pretty standard stuff for a Word COM Addin.

Under normal circumstances, this arrangement works quite well. But today, I had a client report a problem where when they’d close Word, they’d get a pop up message that Word failed to save my template, because some other process has it open. Further investigation showed that 2 or more instances of Word were being loaded (in the background by another application), and the multiple instances of Word appeared to be what was causing the issue.

Now, most anyone who’s had to mess with supporting Word as a programmability platform knows it’s not a good scene to encourage multiple instances of Word. It just doesn’t work out all that well. But here I was, and the other app was a necessary one for this client, so uninstalling it was not an option.

After quite a bit of poking around, it turns out that Word appears to have a problem, or at the very least, an oversight.

The Word Object Model supports an Application.DisplayAlerts property, that is supposed to turn off message boxes, but it fails to do so in the case when you obtain a Template object and then use the Save method on it.

So even if you’re trapping errors on the save, intending to handle them through your code, and even if you’ve turned off alerts, using the above property, Word will still pop up that warning box. Since my template is a completely background piece of functionality, the last thing I want users seeing is warnings about Word being unable to save it.

And here’s the kicker. Since you can’t necessarily know whether Word will be successful at saving the template beforehand, there is no way you can determine whether or not you should even attempt to save the template. A classic catch-22.

In the end, I was able to work around this, er, unique, behavior by:

  • during the Word/Addin startup process…
  • Check if my template exists
  • If it doesn’t, create it and set a flag indicating that it’s safe to save (usually during the Word shutdown process)
  • If the template does exist, check if the file is writable (by attempting to open it with write access)
  • If that fails, the template is already opened (likely by another copy of Word) so set the flag indicating to NOT attempt to save the template from this instance of Word.
  • If the file writable check succeeds, the template is writable, indicating that nothing else has it open, so set the flag to indicate that it should be safe to save the template.

It’s not ideal, because, under some very peculiar circumstances, it still might be possible for Word to fail to save the template, and subsequently pop up that warning box. But such is the joy of the Word Object Model!

Visual Basic and line numbers

0
Filed under Utilities, VB Feng Shui

I’ve seen lots of rants over the years saying things along the lines of

Who wants to use a language that looks like this:

10   Print "Hello, World"
20   If x = 1 Then Goto 50
30   Print "Something else"
50   Print "Result was 50"

Or similiar nonsense. Of course, VB only vaguely resembles this style of code anymore, but one thing has remained virtually the same. Line numbers.

If I remember correctly, in BASCOM and BASICA, they were required. Then Basic Professional Developer System (MS BasicPDS) came out and line nums were no longer necessary, but you could still use them if you liked (probably more to be backwardly compatible with all that old BASICA code).

In all the older VBs (pre .NET days), you actually had to add line numbers to the source code itself in order to get them into the program and refer to them (via the ERL function). While this was certainly doable, the resultant code ended up looking like some seriously old-school mash you wouldn’t want to be caught dead delivering (or trying to maintain).

However, being able to report a line number during an error at runtime, at the client site, so it can be logged or reported back to you as a developer is damn near invaluable. Microsoft recognized this enough in .NET to include line number support built in to the error stack and handling subsystem (although the old style line numbers in code and ERL function still work, appearently).

That’s great for .NET, but there’s still a lot of VB6/5 and older code laying around that has to be maintained. So what do you do?

Ages ago, I built a little command line utility to run through every module in a VBP file (and every module of every project in a VBG file, too), and either add or remove line numbers. It output all the files to the same directory, but with “LINED_” prepended to the file name. This tactic makes it very easy to simply DEL LINED_*.* when you’ve compiled the line numbered project to clean things up and not leave line numbered code sitting around. You can run it against individual BAS, FRM, CTL, DSR, CLS, etc files, but if you point it at a VBP or a VBG file, it’ll even rewrite that file so that it’s contents point to the new file names. This makes it very easy to construct a batch file to 1) line number a project, 2) compile it, and 3) kill off the line numbered source files.

For instance, this batch file:

set pfile=%~dpn0
set pname=%~n0
set pdir=%~dp0
vbliner %pfile%.vbp
VB6.EXE /m "%pdir%LINED_%pname%.vbp"
del "%pdir%LINED_*.*"

Just name it the same name as a VBP file, save it to the same folder as your VBP file, and run it.

It will pull the file name and path from the name of the batch file itself (which should be the same as the VBP you want to compile), line number the project, compile it, then delete the line numbered source files when fnished, leaving you with a nice compiled file, completely line numbered but with none of the mess.

Its other nifty trick is to line number the lines using the same algorithm that the VB6 IDE uses to display line numbers as you move through code, as in:

This one trick (which I haven’t seen in any utility to line number VB source), makes it so that you don’t have to keep the line numbered source around so you can refer to it later. Somebody calls up saying they get an error in Module XYZ, line number 10202, all you have to do is pull that version of the module from SourceSafe (you do use version control of some kind, right?), load it up in VB and jump to the given line number. Can’t get much simpler.

VBLiner starts numbering at 10000, the rational behind that being that if you happen to need to include a hardcoded line number in your code for some reason, the automatic numbers hopefully won’t interfer with your hand coded numbers.

Another handy tip. Once you’ve opened your VB project, Right click the project explorer, select ADD, then ADD FILE. Find the BAT file that you just created above, and be sure and check the “Add as Related Document” box before adding it to your project. Now, then, you should be able to simply DBL CLICK on the BAT file from the VB project explorer to run the bat file and compile your project, complete with line numbers, all automatically.

And a final note; VBLiner does ostensibly support removing line numbers from VB files as well, but I’ve never had much use for that facility, so it’s not well tested. As with any freeware, use at your own risk. And it should go without saying, Back up your source files before running it on them.

Download a zip of the utility here and let me know what you think.

VB Swiss Army Knife

3
Filed under Utilities, VB Feng Shui

VB has one of the best IDE’s around. Sure Eclipse is pretty capable, Delphi is quite slick, and for the purists, editors like SlickEdit can make you almost believe you’re coding in an IDE.

But VB’s IDE is the one to beat. And it has been since VB3.

But even the best have issues; mistakes, ommisions, things that jsut could have been so much better.

And that’s where MZTools comes in.

If you haven’t already played with it, download a copy and install it now. Carlos originally built MZTools for VB6 way back when, and that version was (and still is) a free utility. He’s branched out to supporting Visual Studio .NET now, and the newest version is not free, but it is worth every penny.

Take a look at the features page for version 3 (which supports VB6). The Code Review, Code Templates, and Error Handler Templates are gauranteed to save tons of time.

Personally, I don’t like his line numbering support. I feel like the line number applied to a line should be the same as the actual line number in the file, as reported by the VB6 editor, like this:

That way, you don’t have to retain the numbered version of the source to be able to refer back to a specific line number. However, this is a pretty minor nitpick.

In short, MZTools is a massively handy utility to have on you’re VB menu bar. Definitely for VB6 (cause it’s, well, free), and worthy of consideration for .NET.

Outlook Signatures

2
Filed under Office, Utilities

On a lark a few days ago, I decided I’d like to have random rotating quotes appended to my outgoing emails. I use GMail for mail preview (and access when I’m away from my desk), but usually, I use Outlook when I’m at my desk.

Supporting random email signatures in GMail is a topic for another day, and I’ve honestly not even investigated it at all.

But Outlook. Surely, I thought there must be a free little utility to do that out there.

Well there are a few, but most aren’t free, and the few that are, aren’t particularly well built from what I can tell.

The one free one I did see that seemed to hold promise was QLiner. After a quick install, and then converting some quotes to a plaintext file, I fired it up and set things up.

It works, but it seems finicky to me. For one, it doesn’t actually template out the signature, so much as it completely replaces the existing signature with a rebuilt version (with the new quote) on a configurable timeout. So if you sent 3 messages within 5 minutes, and the timeout was set to 10 minutes, it’s likely all 3 messages will have the same quote.

Plus, it seemed to just “stop working” after a time. I never could see a pattern to this, but, invariably, after a few days, I’d notice that the signature wasn’t changing anymore. Stopping and restarting the program fixed it each time, but that’s not the hallmark of a solid app.

In the end, I uninstalled it, and I believe I’m going to throw my hat in the ring on this one.

I’m calling it Sig-Licious. The idea is that it is a simple COM Outlook addin that monitors for new email creation events, intercepts it, and parses and replaces keywords in the signature with specific bits of info.

For instance, {Date}, {Quote}, {QuoteAuthor}, {CurrentTrack} (ie what piece of music you’re listening to right now, if any), etc, etc.

Any thoughts on what other variables might be nice? To totally geek it up, how bout any ol’ Environment Var? Or the content of a performance counter at the time? Or maybe your CPU fan speed? I’m thinking various Active Directory fields might be nice, if available. Or maybe info from arbitrary Text files? Or maybe info from arbitrary posts you store in specific folders within Outlook proper.

I’ll post something when I’ve got it a bit farther than just messageboxes<g>.

Or stop me before I get too far and tell me the URL of that nifty app you’ve found that can do all this. Please!

Update

I found a few more apps out there for this. First, ADOLSign is 129$! For what is essentially a search and replace tool. Jeez.

Then there’s Exclaimer. It’s even more expensive, but does a lot more. For an enterprise setup, I could see spending a few bucks for this sort of functionality, but for your average joe, like me? Um, no.

I also just ran across Symprex Mail Signature Manager. It’s freakin’ expensive and you can only get a min 10 user license, and it appears to require Echange, but if you need something like that, it looks pretty complete.

And finally, Bells and Whistles. It’s also basically a glorified macro search and replace. 29$. Better, but still, 29$ for this?

So far, nothing for the loan gunman looking for nifty sigs. I think I’ll continue on with my little addin.

Icon Editors

2
Filed under Icons, Utilities

I had to do some icon editing recently, and did a little digging for a decent, free (or nearly free) editor that supports the new Vista and XP style icons.

I turned up AWIcons lite that looks pretty good, for a freeware version of their pro app.

Then I happened upon IconFX. Wow! It’s not quite as polished and it’s missing a few minor features, but it’s a pretty slick package.

I also looked at Axialis and IconCool, but both are commercial and in the 50-60$ range, which isn’t bad, but still.

In the end, I like AWIcons for the UI and the ability to sort the icon images within a single icon to the order necessary for XP. It’s an SDI app (meaning you can only open one icon at a time in the app), but you can open multiple instances of the app, and cut/paste works seemlessly between them, so it’s not a deal breaker.

IconFX supports more effects, hue, saturation, plus drop shadow etc, but you can’t reorder the internal images. It is MDI, though, so you can load up any number of icons simultaneously to edit. The UI is a bit clunkier, but still perfectly functional.

There’s a very good writeup of a number of the better editors here. To summarize, they recommend Axialis, followed by MicroAngelo, AWIcons and IconCool. Personally, I ran into errors after installing IconCool, so I’m not so sure about that one.

Looks like there’s hundreds more, but these seem like the most capable. Anybody know of others that are good?