CVersion class implementation

Once somebody (me, in this case) writes a version class, the rest of us (you, in this case) can simply use it without understanding how it works. The code of CVersion is somewhat complex, but it doesn’t introduce any new programming techniques, so I’ll just give a “Cliff notes” summary here and encourage you to look up the details in VERSION.CLS.

Version data comes in two parts. The first part is a block of numeric data in a UDT. This comes out the same in any language: version 1.0 in Japanese or Urdu is still version 1.0. The second part consists of language-specific string data. One block of strings—the only one currently recognized by CVersion—is in a translated form meant to be usable from any version of the program.

The Create method starts by calling GetFileVersionInfoSize. You pass this function the name of the executable file, and it returns the size of the version data and a handle to the data. You then pass the size, the handle, the executable name, and a buffer (of the given size) to GetFileVersionInfo, which fills the buffer.

You now have a block of version data in an unreadable format. You must call VerQueryValue to read it. You pass some semirandom strings to VerQueryValue to first get the fixed UDT portion of the data and later get a hexadecimal key (case-sensitive and with leading zeros) that identifies the translated version of the data. You could then call VerLanguageName to get language-specific data, but I don’t. The Create method of CVersion saves the key, the UDT for fixed data, and the data block (as a string) in private variables of the class.

Class properties based on fixed data simply return fields of the internal UDT variable. Class properties based on the language-specific string data call Ver­QueryValue, passing the saved key and data string to it.

Got all that? There will be a quiz. Actually, the Windows API documentation on this subject is not very clear, and programming the class was not easy. It’s much easier to follow my completed code.

CVersion implements only the most common part of version
resources, so there’s plenty of room to enhance it. For example, you can embed language-specific version information in a file and then use version resource functions to extract different version data for different languages.