String Properties and Binary Stash Files
VBLM has the ability to extract the string properties that VB4+ stores in binary stash files. It also can extract some - but not all - string properties that 3rd party VBX and OLE controls store in binary stash files.
Note: The new control container file types introduced with VB5 all have binary stash files, and VBLM4+ works with then exactly as VBLM3 worked with FRX files. Since "FRX file" is shorter and easier to say than "binary stash file," however, I haven't bothered to change all of the terminology in this topic. But whenever it says "VBLM does such and such with FRX files," it implies that it has identical functionality for all binary stash files.
When the Extract String from FRX Files SX option is checked (it's located on the Misc tab, and checked by default), VBLM extracts certain string properties from FRX files. They appear in the LTE with "FRX_" prepended to the property name. If you translate these strings, VBLM rebuilds the FRX files when it does a build and replaces the original text with the translations.
There are many issues surrounding the storage, translation, and replacement of strings in FRX files. From the author's perspective, it's a huge pain in the neck requiring lots of special case code in every part of the program (extraction, translation, and build) . The issues are discussed below.
Background
FRX files are binary data files originally designed for the storage of form properties that could not be saved in text format; icons and bitmaps, for example. 3rd party custom control vendors adopted the practice of storing string data in FRX files, usually enumerated property strings like the balloon help in Sheridan's Designer Widgets and column headings in many grid and spreadsheet controls. I became aware of this when users called to ask why VBLM wasn't extracting these properties. The answer was that VBLM 2.x extracted strings only from FRM files.
I explored the possibility of supporting these controls, but realized that it was an impossible task. All of the vendors use different, undocumented (and hence subject to change without notice) data structures to store the strings. You could get the strings out, but you couldn't put them back in with different lengths without knowing the format of the data structure. Worse yet, VB loads FRX data via file offsets, which means that any length error screws up all offsets that follow. Corrupt FRX files are guaranteed to make VB GPF.
The work around for this problem is to set the property strings dynamically. VBLM has no problem finding balloon help strings, for example, if they're set in the Form_Load event with code like SSToolBar1.ToolsetToolHelp(0) = "Balloon Help"
VB4+
Microsoft adopted FRX storage of property strings in VB4 itself (and expanded this in VB5), leaving me no choice but to figure out how to support it.
Fortunately, VB4 stores strings in the FRX in a straightforward manner that was easy to figure out. In particular, VB4+ always stores the text property of multiline textboxes, and the enumerated list property of list and combo boxes, in the FRX file. Sometimes (for reasons that elude me) it also sticks caption properties in the FRX. In each case, the string data has a few header bytes describing what follows.
Rather than hard coding these three storage methods into VBLM, I adopted a scheme that uses entries in the INI file to describe storage methods. The benefit of this scheme is that it is extensible; if you know (or can decipher) the method that a control uses to store strings in the FRX, you may be able to describe it to VBLM. In fact, while I was at it I deciphered Crescent's enumerated Content property and MicroHelp's enumerated ColTitle. On the other hand, there are still limitations discussed at the end of this topic.
How VBLM Reads & Rebuilds FRX Files
If you look in VBLM.INI, you'll see a section entitled [FRXStorageMethods] that looks like this:
[FRXStorageMethods]
VBCaption=0,4,0,0
VBText=0,3,0,0
VBList=1,2,0,2,0,1
Each named storage method is described by a list of numbers. To know what they mean, see FRX Storage Method Format.
You'll also see a [FRXProperties] section. This section lists the control/property pairs that store strings in the FRX file, and the storage method that they use to do so:
[FRXProperties]
Label.Caption=VBCaption
TextBox.Text=VBText
ListBox.List=VBList
etc.
When VBLM encounters one of the listed pairs while extracting strings, it reads the data out of the FRX file using the encoded storage method. When VBLM encounters one of the listed pairs while building a new single language version, it uses the storage method format to rewrite the FRX file.
Translating FRX Properties in the LTE
Most FRX properties require special handling during translation because they are either enumerated or have embedded carriage returns. The only ones that don't (that I know of, anyway) are the Label.Captions that VB4 sometimes mysteriously FRX's.
VBLM uses a single tilde "~" as the item separator in enumerated property strings. Thus if VBLM extracts a four-item List property, you'll see Form1.CarListBox.List = "Buick~Olds~Chevy~Ford" and you translate it as"Toyota~Nissan~Mazda~Honda".
VBLM uses a double tilde as an alias for carriage returns. Thus if it extract a multiline Text property, you'll see Form1.CarTextBox.Text = "Buick~~Olds" and you translate it as"Toyota~~Nissan".
To find out if VBLM extracted any FRX properties from your project, search the LTE and look for "FRX_" in the string instance names.
FRX Properties and the Build Step
FRX properties present no special issues except for the OleObjectBlob problem (see below) when building a new single-language executable; VBLM simply uses the storage method info to rewrite each entry as required, and updates all FRX offset entries as it rewrites FRM files.
There are significant issues when building a runtime-switched version of your app, however. These are illustrated under RSV Code Modifications: Code Section, Control Containers
The OleObjectBlob Problem
The OleObjectBlob property associated with some controls can cause problems if VBLM relocates it when it rewrites the FRX file. VBLM will warn you about this during the build. Please see The OleObjectBlob Problem for a longer discussion.
Limitations
For all of the work that's gone into making VBLM work with strings stored in FRX files, it still can't deal with controls like Designer WIdgets, TrueGrid, etc. The reason is that the makers of these controls have opted to use large complex data structures with a single cryptic entry point to store all of the non-standard properties they use; Sheridan, for example, writes thousands of bytes into the FRX and calls it "Prop58". Reverse engineering is out of the question, so the solution remains as it was before: to get VBLM to extract these strings for translation, you still need to set them dynamically in code.