ByRef object arguments taking with multiple types
VB6 is allows almost many implicit conversion of actual arguments values to formal argument types, but C# does not. Consider rvaritem the following example. In the calling code, is used to return different types of variables from a weakly types collection:
Public Function g_Collection_ItemIsDefined(ByVal vobjCollection As Object, Optional ByVal vvarItem As Variant, Optional ByVal vstrKey As String, Optional ByRef rvarItem As Variant) As Boolean
The function is called with many different types of actual arguments so the translation chooses to declare the formal object byref. However, passing an argument by ref is something that requires strict typing. Consequently, the translation must introduce a temporary arg to box the actual argument. For example:
object argTemp1 = blnOperationEnabled; if (basCollection.g_Collection_ItemIsDefined(colItemOperations,null,strOperation,ref argTemp1))
By default the argTemp variable is ONLY initialized from the actual argument and used in the call. It is not moved back to the actual argument after the call. In some cases, this is a breaking change from the VB6 and it must be addressed using various techniques depending on the situation.
The technique described here is the Refactor/Overload command. It may be added to the Compile block in your translation script as in the following example:
... <Compile Project="..." > <Refactor> <OverLoad Identifier="Project1.Form1.MySub.o_Var" Types="Boolean" /> </Refactor> </Compile> ... where Identifier is the fully qualified identifier of the argument to overload Types is a list of source types known to the tool. This can include gmStudio's VB6 types, application types, and external COM types
The effect of adding a refactor/overload command is three-fold:
1) The tool will report warnings about other types used with the argument. These warnings can be used to add more types ot the Types list. For example:
Warning#3005: Passing <App.frmClientGroupSelect.m_DisplayedClientGroupColumns_AdjustColumnHeaders.chdSortColumnHeader> with type <MSComctlLib.ColumnHeader> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmRecipeBookSelect.m_DisplayedRecipeBookColumns_AdjustColumnHeaders.chdSortColumnHeader> with type <MSComctlLib.ColumnHeader> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmFoodClassSelect.m_FoodClass_Populate.nodFoodClass> with type <MSComctlLib.Node> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmFoodClassSelect.m_FoodClass_PopulateChildren.nodParentFoodClass> with type <MSComctlLib.Node> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmClientSelect.m_Clients_Populate.lsiClient> with type <MSComctlLib.ListItem> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmClientSelect.m_DisplayedClientColumns_AdjustColumnHeaders.chdSortColumnHeader> with type <MSComctlLib.ColumnHeader> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmFoodLabelSelect.m_DisplayedFoodLabelColumns_AdjustColumnHeaders.chdSortColumnHeader> with type <MSComctlLib.ColumnHeader> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmNutrientGoalTemplateSelect.m_DisplayedNutrientGoalTemplateColumns_AdjustColumnHeaders.chdSortColumnHeader> with type <MSComctlLib.ColumnHeader> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmMenuTemplateSelect.m_DisplayedMenuTemplateColumns_AdjustColumnHeaders.chdSortColumnHeader> with type <MSComctlLib.ColumnHeader> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.basImportExport.m_RecipeFood_Import.strCustomFoodIDs> with type <String> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmRecipeHACCPs.m_SelectedHACCP_Remove.objSelectedHACCP> with type <NutPro.RecipeHACCP> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmFoodSelect.m_DisplayedFoodColumns_AdjustColumnHeaders.chdSortColumnHeader> with type <MSComctlLib.ColumnHeader> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmFoodSelect.m_Foods_Populate.lsiFood> with type <MSComctlLib.ListItem> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.basProject.m_Exchanges_CompensateForVegetable.strVegetableCalculationItem> with type <String> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmMain.grdFoodLabelFoodNutrients_FetchCellStyle.objFoodLabelNutrient> with type <NutPro.FoodLabelNutrient> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmMain.grdFoodLabelFoodNutrients_FormatText.objFoodLabelNutrient> with type <NutPro.FoodLabelNutrient> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmMain.m_Food_Populate.tabRecipe> with type <MSComctlLib.Tab> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmMain.m_MenuTemplateProfilingFoods_Populate.lsiProfilingFood> with type <MSComctlLib.ListItem> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmFoodQuestionnaire.m_ProfilingFoods_Populate.lsiProfilingFood> with type <MSComctlLib.ListItem> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmMenu.m_ProfilingFoods_Populate.lsiProfilingFood> with type <MSComctlLib.ListItem> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.frmDietRecord.m_ProfilingFoods_Populate.lsiProfilingFood> with type <MSComctlLib.ListItem> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.g_VBObject_Clear.colContainerContents> with type <Collection> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.g_VBObject_Resize.strDefaultDimensions> with type <String> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.g_VBObject_Resize.strOffsetMinimums> with type <String> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.g_VBObject_Resize.colContainerContents> with type <Collection> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.g_VBObject_SetEnabled.colContainerContents> with type <Collection> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.g_VBObjects_LoadContainers.colContainerContents> with type <Collection> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.g_DragCursor_Set.colItemTypeItems> with type <Collection> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant> Warning#3005: Passing <App.g_RecentItems_Add.strRecentItem> with type <String> to <App.g_Collection_ItemIsDefined.rvarItem> with type <Variant>
2) The tool will generated an overload of the method for each type in Types. These overloads deal with marshalling different variables to the weakly typed formal argument in the implementation. Notice that in the wrapper, the temporary arg is moved back actual arg after the call. For example:
public static bool g_Collection_ItemIsDefined(object vobjCollection,object vvarItem,string vstrKey,ref bool rvarItem) { object TemporaryArg1 = rvarItem; bool retVal = g_Collection_ItemIsDefined(vobjCollection,vvarItem,vstrKey,ref TemporaryArg1); rvarItem = Convert.ToBoolean(TemporaryArg1); return retVal; }
3) The tool removes the use of the ref tempArg from the calls where an actual arg of one of the types in Types is passed. For example, the using argTemp1 shown above becomes simply:
if (basCollection.g_Collection_ItemIsDefined(colItemOperations,null,strOperation,ref blnOperationEnabled))
Refactor Generic
<Compile Project="..." > <Refactor> <Generic identifier="Project1.Form1.MySub.o_Var" Types="Integer,String" /> </Refactor> </Compile>