Q. How does the tool determine how to migrate COM ListView.Add to WinForm ListView.Add?
A: This migration is implemented using a RefactorLibrary with some gmSL to facilitate a "deep migration":
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C:\gmTestBed\FileExplorer\proj_csh\usr\Mscomctl.ocx.WinForms.Refactor.xml ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 <RefactorLibrary> 2 <Refactor id="[mscomctl.ocx]" event="mscomctl" > 627 <!-- 628 ********************************************************** 629 * ListView Migration Rules Helper Class 630 ********************************************************** 631 --> 632 <migClass id="ListViewLogic"> ... 671 <Method id="Insert_Index_Key_SmallIcon" type="ListItem" nPram="6" migPattern="%1d.Insert(%2D,%3d,%4d,%6d)" /> 672 <Method id="Insert_Index_Key_Icon" type="ListItem" nPram="6" migPattern="%1d.Insert(%2D,%3d,%4d,%5d)" /> 673 <Method id="Insert_Index_Key" type="ListItem" nPram="6" migPattern="%1d.Insert(%2D,%3d,%4d)" /> 674 <Method id="Insert_Index_SmallIcon" type="ListItem" nPram="6" migPattern="%1d.Insert(%2D,%4d,%6d)" /> 675 <Method id="Insert_Index_Icon" type="ListItem" nPram="6" migPattern="%1d.Insert(%2D,%4d,%5d)" /> 676 <Method id="Insert_Index" type="ListItem" nPram="6" migPattern="%1d.Insert(%2D,%4d)" /> 677 > 678 <Method id="Add_Key_SmallIcon" type="ListItem" nPram="6" migPattern="%1d.Add(%3d,%4d,%6d)" /> 679 <Method id="Add_Key_Icon" type="ListItem" nPram="6" migPattern="%1d.Add(%3d,%4d,%5d)" /> 680 <Method id="Add_Key" type="ListItem" nPram="6" 681 cshPattern="%1d.Add(new ListViewItem { Name=%3d, Text=%4d })" 682 vbnPattern="%1d.Add(New ListViewItem() With {.Name = %3d, .Text = %4d})" 683 /> 684 <Method id="Add_SmallIcon" type="ListItem" nPram="6" migPattern="%1d.Add(%4d,%6d)" /> 685 <Method id="Add_Icon" type="ListItem" nPram="6" migPattern="%1d.Add(%4d,%5d)" /> 686 <Method id="Add" type="ListItem" nPram="6" migPattern="%1d.Add(%4o)" /> 687 </migClass> ... 882 <!-- 883 ********************************************************** 884 * Procedural Transformation Rules 885 ********************************************************** 886 --> 887 <gmSL NameSpace="mscomctl" Class="Transform" Source="Mscomctl.ocx.WinForms.Transform.gmsl" /> 888 </Refactor> 889 </RefactorLibrary>
The migClass provides a structure for declaring and organizing metadata supporting some custom migration requirements. This problem being solved here is that the WinForms ListView does not support all of the same Add operations as the COM ListView: WinForms only has Insert and Add operations as well as only one size of Image. These API changes need be considered when expressing a COM Listview.Add operations with WinForms.ListView. The upgrade solution must examine the call and determine which one of the patterns to use. This analysis and selection is done in the Mscomctl.ocx.WinForms.Transform.gmsl file associated with the MSComCtl API.
Specifically the IListItems_Add routine is automatically called when gmBasic encounters a reference to ListView Add:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C:\gmTestBed\FileExplorer\proj_csh\usr\Mscomctl.ocx.Winforms.Transform.gmsl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 110 int IListItems_Add(int subRoot, int iStart, int iRefer) 111 { 112 int icode; 113 int nCode; 114 tCodeBlock codptr; 115 int oper; 116 int subc; 117 tCodeBlock isOmitted; 118 int nOper; 119 int omitIndex; 120 int omitKey; 121 int omitIcon; 122 int omitSmallIcon; 123 int pattern; 124 125 codptr = Opcode.GetCode(); 126 nCode = Opcode.GetLength() 127 icode = Opcode.GetNext(codptr,iRefer,nCode); 128 subc = 0; 129 oper = Opcode.GetOperation(codptr,icode,subc); 130 if(oper != OPC.MEM) return 0; 131 icode = Opcode.GetNext(codptr,icode,nCode); 132 oper = Opcode.GetOperation(codptr,icode,subc); 133 if(oper != OPC.LEV) return 0; 134 //Index 135 nOper = 0; 136 isOmitted = CodePattern.Read("LEV,DEF,ARG",nOper); 137 omitIndex = CodePattern.Match(icode,isOmitted); 138 icode = Opcode.FindArgumentEnd(codptr,icode,nCode); 139 oper = Opcode.GetOperation(codptr,icode,subc); 140 if(oper != OPC.LEV) return 0; 141 // Key 142 omitKey = CodePattern.Match(icode,isOmitted); 143 icode = Opcode.FindArgumentEnd(codptr,icode,nCode); 144 oper = Opcode.GetOperation(codptr,icode,subc); 145 if(oper != OPC.LEV) return 0; 146 // Text 147 icode = Opcode.FindArgumentEnd(codptr,icode,nCode); 148 oper = Opcode.GetOperation(codptr,icode,subc); 149 if(oper != OPC.LEV) return 0; 150 // Icon 151 omitIcon = CodePattern.Match(icode,isOmitted); 152 icode = Opcode.FindArgumentEnd(codptr,icode,nCode); 153 oper = Opcode.GetOperation(codptr,icode,subc); 154 if(oper != OPC.LEV) return 0; 155 // SmallIcon 156 omitSmallIcon = CodePattern.Match(icode,isOmitted); 157 icode = Opcode.FindArgumentEnd(codptr,icode,nCode); 158 oper = Opcode.GetOperation(codptr,icode,subc); 159 if(oper != OPC.CUF) return 0; 160 161 if(!omitIndex && !omitKey && !omitSmallIcon) 162 { 163 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Insert_Index_Key_SmallIcon"); 164 } 165 else if(!omitIndex && !omitKey && !omitIcon) 166 { 167 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Insert_Index_Key_Icon"); 168 } 169 else if(!omitIndex && !omitKey) 170 { 171 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Insert_Index_Key"); 172 } 173 else if(!omitIndex && omitKey && !omitSmallIcon) 174 { 175 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Insert_Index_SmallIcon"); 176 } 177 else if(!omitIndex && omitKey && !omitIcon) 178 { 179 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Insert_Index_Icon"); 180 } 181 else if(!omitIndex && omitKey) 182 { 183 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Insert_Index"); 184 } 185 else if (omitIndex && !omitKey && !omitSmallIcon) 186 { > 187 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Add_Key_SmallIcon"); 188 } 189 else if (omitIndex && !omitKey && !omitIcon) 190 { 191 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Add_Key_Icon"); 192 } 193 else if (omitIndex && !omitKey) 194 { 195 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Add_Key"); 196 } 197 else if (omitIndex && omitKey && !omitSmallIcon) 198 { 199 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Add_SmallIcon"); 200 } 201 else if (omitIndex && omitKey && !omitIcon) 202 { 203 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Add_Icon"); 204 } 205 else if (omitIndex && omitKey) 206 { 207 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Add"); 208 } 209 else 210 { 211 pattern = Symbol.FindIdentifier("MsComctlLib.ListViewLogic.Add"); 212 } 213 if(pattern == 0) return 0; 214 Opcode.Replace(icode,OPC.PAT,pattern,1); 215 Opcode.Delete(iRefer,2); 216 return 1; 217 }
See also
FileExplorer sample