Blog from March, 2017

New gmStudio Case Studies and Testimonials

A handful of recent customers allowed us to publish brief descriptions of their VB6/COM upgrade projects and their testimonials of success with gmStudio. Learn how small teams successfully completed large, ambitious VB6/COM upgrade efforts with the help of gmStudio. Read the case studies 

Adding WPF Support for VB.NET

The gmStudio distribution includes a sample demonstrating an upgrade of VB6 forms to WPF. This sample was originally implemented for C# only. In this release, we added a WPF sample for VB.NET and published a blog article to describe how we did it.

gmBasic: Upgrade Engine Update

gmBasic is a powerful code processor that reads, interprets, and rewrites VB6/ASP/COM systems as .NET (C# or VB.NET). We are always improving gmBasic so that it is more robust and flexible and it produces cleaner, more correct results. This distribution, Version 30.44, includes several enhancements:

  • Improves the general, right out-of-the-box, ability to produce build-complete .NET code from very large, very complex VB6 systems (most recently including enhancements needed to upgrade a Comprehensive Tax Preparation of 19 inter-related VBPs referencing 993 unique files containing over 1.4M unique LOC and 42 third party COM components)
  • Improves rewriting complex GoSub blocks as separate functions
  • Improves handling undeclared variables
  • Improves rewriting complex conditional expressions that mix booleans and enums
  • Improves relocating local Const variables when needed to initialize local Static arrays
  • Improves rewriting Select/Case statements
  • Improves rewriting designer code enum properties initialized with an undefined numeric values
  • Improves rewriting IIf with incompatible true/false result types
  • Improves determining if a control or its default property is needed when referenced from outside the host form
  • Improves rewriting large numeric literal expressions to prevent compile-time overflow
  • Improves identifying collection properties and migrating complex references to collection element
  • Improves rewriting binary operations involving decimal and DateTime quantities
  • Improves rewriting logic for control arrays as logic using SortedList
  • Improves handling files that had internal naming collision
  • Improves rewriting the Unload control statement
  • Improves rewriting references to the Index property of control arrays.
  • Improves propagating custom interface events to Implementing classes
  • Improves rewriting very large numeric consts that were specified as string literals
  • Improves inferring and propagating the rank and marshalling of array parameters
  • Improves placement of temporary variables created in nested code blocks
  • Improves type inference for collections of collections
  • Improves rewriting Friend interface members as public
  • Improves rewriting parameterized properties

gmStudio: Upgrade Solution Development Environment Update

Powered by gmBasic, gmStudio is a development environment for creating high-performance, custom VB6/ASP/COM to .NET upgrade solutions. We are always adding functionality to gmStudio and also making it easier to use. This distribution includes several enhancements:

  • Adds support for Side-by-Side Code Viewer with ASP upgrade projects
  • Adds support for creating new gmStudio projects from the command line interface
  • Improves default results folder naming conventions to use a simpler, more natural form
  • Improves Close Project behavior
  • Improves error handling and reporting for Meta-Language and Translation processes
  • Adds Double-Click to Edit User-Files on the Configuration form
  • Improves Edit Project Name behavior on the Configuration form
  • Improves the Search Reporting for XML files in the User and System folder by reporting fully qualified location of matches.
  • Improves default Search List/Reporting layout when their orientation changes
  • Improves Visual Studio Solution Generator to set stable project GUIDs based on upgrade project task names
  • Corrects Task order displayed on the Upgrade Wizard to reflect build order and processing order
  • Corrects new projects to suppress upgrading Collections/Dictionaries to strongly-typed Generic collections

Sample Upgrade Rules Update

gmStudio ships with a collection of sample upgrade rules that can be used to add custom features to your upgrade solution. These XML documents and gmSL scripts are distributed as source that you may modify to fit your unique requirements. The latest distribution of sample rules files includes several improvements:

  • Adds scripts showing how VB6 forms may be upgraded to WPF/XAML for VB.NET. Formerly this was only available for C#

Sample Upgrade Solutions Update

Great Migrations publishes a number of sample VB6/ASP upgrade solutions to illustrate the capabilities of gmStudio. The samples were updated to reflect the latest product improvements and conventions.

  • Adds a sample demonstrating VB6 forms to WPF/XAML for VB.NET. Formerly this was only available for C#

Abstract
The gmStudio distribution includes a sample demonstrating an upgrade of VB6 forms to WPF.  This sample was originally implemented for C#.  The purpose of this article is to describe how we added a WPF sample for VB.NET and provide insights into advanced customization.  The work required changes to the following metalanguage files:

  • enumerations.xml
  • vbcontrols.xml
  • locSubsystem.gmsl
  • wpfSubsystem.gmsl
  • vb7lang.xml
  • VBASIC.xml

Background
A Subsystem is a collection of related upgrade rules that provide a specific upgrade feature.  The current WPF/C# sample uses subsystem=wpf and subsystem=loc (light-weight object oriented C# coding style).  The two subsystems are activated by adding two commands to the translation script:

<Select SubSystem="wpf"/>
<Select SubSystem2="loc"/>

Generally speaking, the WPF/VB.NET sample will be analogous to the WPF/C# sample. However, the problems are in the details: I initially find the WPF subsystem contains several C#-specific patterns in vbcontrols.xml; for example, there are int and double casts as well as a few other C# patterns relating to data binding:

 

vbcontrols.xml
 <pattern id="Top.Set" >
 <wpf narg="2" code="Canvas.SetTop(%2d,(double)(%1d))\c" />
 <all narg="2" code="%2d.Top = %1d\c" />
 </pattern> 

 

What is needed here is a VB.NET form for some WPF operations. This is analogous to the situation with SubSystem=loc/lob where some patterns need both a VB.NET and a C# form.  For WPF we will need a pair of subsystems, wpf/wpb, for C#/VB.NET respectively. The new subsystem is added to enumerations.xml:

<MetaLanguage>
<Enumeration id="Dialects" >
...
 <Entry id="wpf" migName="LNG_WPF" value="9" />
 <Entry id="loc" migName="LNG_LOC" value="10" />
 <Entry id="lob" migName="LNG_LOB" value="11" />
 <Entry id="wpb" migName="LNG_WPB" value="12" /> <------ added
 </Enumeration>

 

Returning to vbcontrols.xml, I can add wpb versions of the dailect-specific wpf patterns, for example:

vbcontrols.xml
 <pattern id="Top.Set" >
 <wpb narg="2" code="Canvas.SetTop(%2d,%1d)\c" /> <------ added
 <wpf narg="2" code="Canvas.SetTop(%2d,(double)(%1d))\c" />
 <all narg="2" code="%2d.Top = %1d\c" />
 </pattern>
I find another dialect-specific WPF pattern in VBASIC.XML.   This pattern specifies the operation needed to start a WPF application.  A VB.NET version is added:

 

VBASIC.XML
 <pattern id="WPO">
 <subcode id="SetCanvas">
 <wpf narg="3" code="%2d.%3d = %1d\c"/>
 <all narg="3" code="Canvas.Set%3d(%2d, %1d)\c"/>
 </subcode>
 <subcode id="RunProject" >
 <wpb narg="4" code="Dim app As New %4d.App : app.Run(%1d)\c" /> <------------ added 
 <all narg="4" code="new %4d.App().Run(%1d)\c" />
 </subcode>
 </pattern> 

In order to activate the new wpb subsystem, I need to modify the CompilerInfo handlers to include wbp in the Subsystem stack for Dialect=vbn. The CompilerInfo handlers are gmSL routines that are called by the tool when it begins processing the Compile command in a translation script. There is a CompilerInfo handler for Subsystem=loc and I will add one for SubSystem=wpf.   The change must be made to load the subsystems in the correct order of precedence based on the selected .NET language dialect. 

CompilerInfo Event Handlers
locSubsystem.gmsl
int locCompilerInfo(int dummy1, int dummy2)
{   
   if(Select.Dialect == Dialects.vbn)
   {
      if (Select.SubSystem == Dialects.wpb)
      {
         Select.Subsystem = Dialects.wpb;
         Select.Subsystem2 = Dialects.wpf;
         Select.Subsystem3 = Dialects.lob;
         Select.Subsystem4 = Dialects.loc;
      }
      else
      {
         Select.Subsystem = Dialects.lob;
         Select.Subsystem2 = Dialects.loc;
      }
   }
   else
   {
      if (Select.SubSystem == Dialects.wpf)
      {
         Select.Subsystem  = Dialects.wpf;
         Select.Subsystem2 = Dialects.loc;
      }
   }
   return 0;
}

wpfSubsystem.gmsl
int wpfCompilerInfo(int dummy1, int dummy2)
{
   if(Select.Dialect == Dialects.vbn)
   {
         Select.Subsystem = Dialects.wpb;
         Select.Subsystem2 = Dialects.wpf;
         Select.Subsystem3 = Dialects.lob;
         Select.Subsystem4 = Dialects.loc;
   }
   else
   {
         Select.Subsystem = Dialects.wpf;
         Select.Subsystem2 = Dialects.loc;
   }
   return 0;
}

There are several places in authortext.gmsl testing for the presence of a subsystems. For these more complex multi-subsystem scenarios, they may also need to check SubSystem2, Subsystem3, etc. authortext.xml must also be modified to allow for this. A utility function, hasSubSystem, will be used to help make these tests in a consistent way.

authortext.gmsl
int hasSubSystem(int theSubSystem)
{
 if (Select.SubSystem ==theSubSystem) return 1;
 if (Select.SubSystem2==theSubSystem) return 2;
 if (Select.SubSystem3==theSubSystem) return 3;
 if (Select.SubSystem4==theSubSystem) return 4;
 if (Select.SubSystem5==theSubSystem) return 5;
 return 0;
} 

Several other simple changes relating to default assembly references and Imports statements were needed to support WPF for VBN.   These are done by modifying in authortext.gmsl. 

A critical part of supporting the WPF upgrade relates to authoring XAML from the VB6 forms and declaring the WPF Application class.  This work is done in the wpfSubSystem.gmsl script.  This gmSL script contains various upgrade event handlers and supporting routines that are called by gmBasic at the appropriate times during the authoring process.   Support for VB.NET was added by making the code in wpfSubSystem.gmsl dialect-specific: adding logic to author either C# or VB.NET code depending on the dialect setting.

Next, I add an entry to VB7Lang.xml so that both the wpf SubSystem and the new wpb SubSystem will invoke the upgrade event handlers implemented in  WPFSubsystem.gmsl:

VB7Lang.xml
<gmSL NameSpace="gmSL" class="WPFSubSystem" Source="%UserFolder%\WPFSubsystem.gmsl" /> 
<gmSL NameSpace="gmSL" class="WPBSubSystem" Source="%UserFolder%\WPFSubsystem.gmsl" /> <-------------- added 
I need to recompile the Metalanguage using the modified files. This creates a binary metalanguage file that can be used during the translation process.
  
With these changes, the WPF feature may be activated by adding one line to a translation script:

 

<Select SubSystem="wpf"/> 

 

The above now works for both Dialect=csh and Dialect=vbn.  Note: the WPF upgrade subsystem is a limited implementation: it supports most VB6 intrinsic controls and the COM TabControl (TabDlg).  Additional VB6/COM controls and other features may be added by modifying the appropriate language scripts and COM description files.  Contact us if you have any questions.


New gmStudio Testimonials

A number of our recent customers allowed us to publish brief descriptions of their VB6/COM upgrade projects and their testimonials of success with gmStudio.  Learn how small teams successfully completed large, ambitious VB6/COM upgrade efforts with the help of gmStudio.