Using RefactorLibraries Files for COM API replacement

Overview

Upgrading a real-world VB6 application typically requires replacing COM APIs with .NET APIs. gmStudio uses and open, extensible COM type system to facilitate automating these types of COM upgrades. The COM type system used by the upgrade process is declared in a set of files called Interface Description Files (IDFs). IDFs are XML text files that declare all of the elements of an API: the enumerations, classes, structs, etc. IDFs are detailed dow the level of individual method arguments. An standard set of IDFs are generated for you by gmStudio from the COM binaries used by your application. The IDF generation process usually works completely automatically, but in some cases it is necessary to manually locate and generate IDFs for atypical COM type libraries.

Standard IDFs are designed to direct the translation to use either a stub framework exposing the original COM API or an interop wrapper around the COM binary. The default is to let the gmStudio generate the stub framework and referecne it in the translated application code. This state of translation: referencing a stub framework is an initial step to facilitate building and verifying the standard translations. Once this step is completed, the IDFs may be modified to direct the translator to replace the COM APIs with some other API. The replacement techniques require modifying the IDF to change how its elements are referenced in translated code.

There are two ways to modify IDFs:

  • Modify the IDF XML files directly, or
  • Modify the IDF information with refactoring commands

This document describes how to use the second approach.  See this article for a discussion of COM Replacements by modifying IDFs directly.  

Mig.IDF Files

A Mig.IDF file is an XML text file that contains refactoring commands associated with a given IDF. Using Mig.IDF files provides a more deliberate, and arguably superior approach to organizing COM migration rules for each API. Compared to COM replacements done by modifying IDFs directly, using Mig.IDF files can be easier to create and easier to see what is being migrated because the rules are more clearly identified and explicit. Note also that Mig files are applied to the generated IDF, so re-generating the IDF will not disturb the associated Mig.IDF file.

An Example: MSComCtlLib.ProgressBar to a WinForms.ProgressBar

Let's say you want to migrate MSComCtlLib.ProgressBar to a WinForms.ProgressBar. This is a pretty easy migration as the WinForms control is very similar to the COM control.   

First you create a Mig.IDF file for the MSComCtl.ocx API taht contains progress bar. This file must be named "Mig." followed by the name of the COM IDF containing the class/control that you want to migrate in this case, the name is Mig.MSComCtl.ocx.xml. An initial version of this file is shown below.

<RefactorLibrary>
<Refactor id="[MSComCtl.ocx]">
<Migrate location="DoNotDeclare" migName="System.Windows.Forms" />
<Migrate id="IProgressBar.Min" migName="Minimum" />
<Migrate id="IProgressBar.Max" migName="Maximum" />
<Migrate id="IProgressBar.Appearance" migStatus="mustCorrect" />
<migClass id="NetControl.ProgressBar" migName="System.Windows.Forms.ProgressBar" parent="ProgressBar">
<property id="Location" value="(Left,Top)" nPram="2" migPattern="new System.Drawing.Point(%1d, %2d)" />
<property id="Name" type="string" value="SYM.name" />
<property id="Size" value="(Width,Height)" nPram="2" migPattern="new System.Drawing.Size(%1d, %2d)" />
<property id="TabIndex" type="Integer" value="TabIndex" default="0" />
<!-- NOT MAPPED for designer Appearance = System.Windows.Forms.AppearanceConstants.cc3D; -->
</migClass>
</Refactor>
</RefactorLibrary>

In addition to implicit loading RefactorLibrary files using the mig.IDF file naming convention, it is also possible (and recommended) to explicitly name RefactorLibrary files with more descriptive names and "register" them using Registry-MigFile commands prior to the <Compile> .  For example:

<Registry type="MigFile" source="RICHTX32.OCX" target="RICHTX32.OCX.WinForms.Refactor" />

The above rule tell gmBasic to load RICHTX32.OCX.WinForms.Refactor.xml every time it processes a VBP (or ASP site) that references RICHTX32.OCX.   We call this registering a RefactorLibrary.


The Mig.IDF file should be placed in "user" folder in the project work space along with the other upgrade scripts, code, and documentation you are developing for your upgrade solution.

For this example, I placed the mig file in the usr\idf\3pc folder in my project workspace.

Next, you activate the Mig.IDF by taking advantage of gmStudio's folder conventions. For example, the following ScriptRule sets the primary configuration folder to usr\idf\3pc then loads the IDF. The tool will search for the IDF and load it then search for the Mig.IDF file and apply the refactoring commands.

<ScriptRule id="MSComCtlLib">
<Option>
<Select Target="..\usr\idf\3pc"/>
<reference id="MSComCtl.ocx" />
</Option>
</ScriptRule>

Finally, this ScriptRule may integrated into the main translation script template using a <ScriptRule> command:

<gmBasic>
<Storage Action="Create" Identifier="%JobId%" />
<select Target="%UserFolder%" />
<Select Local="%IdfFromCodeFolder%" />
<Select System="%IdfFromIdlFolder%" />
...
<ScriptRule id="MSComCtlLib" /> 

<Compile Project="%SrcPath%" />
<Analyse />
<Output Status="New" Filename="%BndPath%" />
<Author />
<Storage Action="Close" />
</gmBasic>

When translator processes any VBP code that references this API, it will do so according to the modified IDF rules.

Basic Processor V30.76(07/18/18) System Build(07/18/18 5:26:53)
...
Loading reference:[MSComCtl.ocx] \gmClients\Client\poc\proj\idf\FromIdl\MSComCtl.ocx.xml
Loading reference:[Mig.MSComCtl.ocx] \gmClients\Client\poc\proj\usr\idf\3pc\Mig.MSComCtl.ocx.xml
...