The following are some of the most common issues generated by the Visual Basic Upgrade Companion.
1002 - LSet cannot assign one type to another
Description
This occurs when a type is assigned to another, using the LSet Function, LSet Function copies all the source bytes from one type and then assigns then makes that the other type points to the copy. Currently, there is no way to determine the expected behavior for these cases.
Recommendations
You can manually assign all the values and pass them from a class to another. You could require byte functions, so please be sure of how the function passes the data from one type to another. For example, if you have a type that contains a string and the other has an array of strings of length 2, then you must make a function that splits and assigns the first array into two characters pieces, and then assign them to the second type array.
VB6 Original Code
Public Type TypeA
x As Integer
End Type
Public Type TypeB
x As Integer
End Type
Public Sub LSetTest()
Dim aType As TypeA
Dim bType As TypeB
aType.x = 3
LSet bType = aType
End Sub
C# Upgraded Code
publicstructTypeA{publicshort x;}publicstructTypeB{publicshort x;}publicstaticvoidLSetTest(){TypeA aType =newTypeA();TypeB bType =newTypeB();aType.x=3; //UPGRADE_ISSUE: (1002) LSet cannot assign one type to another. //LSet(bType, aType);UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("LSet");}
VB.NET Upgraded Code
Public Structure TypeA
Dim x As Short
End Structure
Public Structure TypeB
Dim x As Short
End Structure
Public Sub LSetTest()
Dim aType As New TypeA()
Dim bType As New TypeB()
aType.x = 3
'UPGRADE_ISSUE: (1002) LSet cannot assign one type to another.'
'LSet(bType, aType)'
UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("LSet")
End Sub
1010 - The preceding line couldn't be parsed
Description
Because of an unexpected error, VBUC could not parse a specific line, method, or code block.
Recommendations
This issue should be addressed manually by comparing the upgraded file with the original one and rewriting the missing code in the upgraded file.
1014 - 1% statement is not supported
Recommendations
We recommend using the Upgrade Option GoSub Conversion, this feature enables the support of GoSub statements by creating Local Functions (Only in C#). For more information check the latest MSDN documentation on Local functions.
Another way could be adding a method with the body of the label called by the GoSub manually. This will require passing all the necessary variables as byref parameters in the respective method.
VB6 Original Code
Private Sub Form_Load()
Dim total As Integer
GoSub InsideSub
MsgBox total
Exit Sub
InsideSub:
For i = 0 To 10
total = total + i
Next i
Return
End Sub
C# Upgraded Code
privatevoidForm_Load(){int total =0; //UPGRADE_ISSUE: (1014) GoSub statement is not supported. //UPGRADE_TODO: (1065) Error handling statement (Go Sub) could not be converted.UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("GoSub Label (InsideSub)");MessageBox.Show(total.ToString(),AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));return; InsideSub:for (int i =0; i <=10; i++) { total += i; } //UPGRADE_WARNING: (2081) Return has a new behavior.return ;}
C# Expected Code
In this case, GoSub Conversion was selected, creating a local function.
privatevoidForm_Load(){int i =0;int total =0;InsideSub();MessageBox.Show(total.ToString(),AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));return;voidInsideSub() {for (i = 0; i <=10; i++) { total += i; } }}
VB.NET Upgraded Code
Private Sub Form_Load()
Dim total As Integer
'UPGRADE_ISSUE: (1014) GoSub statement is not supported.'
GoSub InsideSub
MessageBox.Show(CStr(total), My.Application.Info.Title)
Exit Sub
InsideSub:
For i As Integer = 0 To 10
total += i
Next i
'UPGRADE_WARNING: (2081) Return has a new behavior.'
Return
End Sub
VB.NET Expected Code
As we mentioned before, the GoSub conversion is a feature available only in C#, which means we are not using this feature in this case.
Private Sub Form_Load()
Dim total As Integer
InsideSub(total)
MessageBox.Show(CStr(total), My.Application.Info.Title)
End Sub
Private Sub InsideSub(ByRef total As Integer)
For i As Integer = 0 To 10
total += i
Next i
End Sub
1043 - Class instancing was changed to public
Description
In Visual Basic 6.0, instance creation was controlled by the instancing property of a class, which set both the access level (Public, Private, Friend) of a class and the way an object could be created. In Visual Basic .NET, the instancing property is no longer supported; you control how an object can be created by setting the access level of the constructor (Sub New):
Visual Basic 6.0 Instancing
Visual Basic .NET
Private
Class Access attribute: Private
PublicNotCreatable
Class Access attribute: Public. Declare the constructor Friend (Friend Sub New)
MultiUse
Class Access attribute: Public. Declare the constructor Public (Public Sub New)
There is no direct equivalent for SingleUse, GlobalSingleUse, or GlobalMultiUse instancing in Visual Basic .NET; when the instancing property is set to one of these values, the access level of both the class and the constructor is set to Public during the upgrade.
Recommendations
Check the code. The behavior may be slightly different than it was in Visual Basic 6.0, and you may need to change the access level of the class and/or the constructor.
1046 - %1 Parameter '%2' is not supported, and was removed
Description
The VBUC contains a set of methods and parameter mappings for VB6 and .NET. Included in this information are markers that indicate when parameters have been removed from their .NET counterparts. Whenever a parameter that has been removed is found in the original source code, this EWI is emitted by the VBUC. Currently, there is no way to determine expected behavior for these cases, the final solution will depend on the resolution approach.
Recommendations
There is no straightforward solution for this issue because some of the removed parameters may not have an equivalent in .NET at all. In some cases, the parameters change the behavior of the invoked method. The same effect might be possible by setting property values in the new .NET object. Likewise, an overload of the method might be available that provides this functionality. In other cases, there is no equivalent parameter to substitute, and it will be necessary to include code to replicate the desired functionality in .NET. Finally, in some cases, the omitted parameters cause no discernable difference. They can be safely omitted in most cases without affecting the functional equivalence. Common causes of this EWI involve the use of the Size, ColorDepth, X, and Y parameters of the LoadPicture function. It is also emitted in some uses of Interaction.AppActivate.
VB6 Original Code
Public Sub LoadFormPicture(ByVal picBox As PictureBox)
picBox.Picture = VB.LoadPicture("calc3.gif", 4, vbLPColor, 320, 86)
End Sub
C# Upgraded Code
publicvoidLoadFormPicture(PictureBox picBox){ //UPGRADE_ISSUE: (1046) LoadPicture Parameter 'Y' is not supported, and was removed. //UPGRADE_ISSUE: (1046) LoadPicture Parameter 'X' is not supported, and was removed. //UPGRADE_ISSUE: (1046) LoadPicture Parameter 'ColorDepth' is not supported, and was removed. //UPGRADE_ISSUE: (1046) LoadPicture Parameter 'Size' is not supported, and was removed.picBox.Image=Image.FromFile("calc3.gif");}
VB.NET Upgraded Code
Public Sub LoadFormPicture(ByVal picBox As PictureBox)
'UPGRADE_ISSUE: (1046) LoadPicture Parameter 'Y' is not supported, and was removed.'
'UPGRADE_ISSUE: (1046) LoadPicture Parameter 'X' is not supported, and was removed.'
'UPGRADE_ISSUE: (1046) LoadPicture Parameter 'ColorDepth' is not supported, and was removed.'
'UPGRADE_ISSUE: (1046) LoadPicture Parameter 'Size' is not supported, and was removed.'
picBox.Image = Image.FromFile("calc3.gif")
End Sub
2038 - Form property 1%.ScaleMode is not supported
Description
In VB6, you could use a scale mode different from pixels to use as the unit for measures and locations in a form. This is not longer supported by .NET.
Recommendations
Use these functions to convert units to pixels, depending on the scale mode. The Unit can be centimeters, millimeters, inches, etc.
Public Sub SetScaleMode()
Me.ScaleMode = 1 'Twips
End Sub
C# Upgraded Code
publicvoidSetScaleMode(){ //UPGRADE_ISSUE: (2038) Form property ewi2038.ScaleMode is not supported.this.ScaleMode=PrinterHelper.ScaleModeConstants.VbTwips; //Twips}
VB.NET Upgraded Code
Public Sub SetScaleMode()
'UPGRADE_ISSUE: (2038) Form property ewi2038.ScaleMode is not supported.'
Me.ScaleMode = PrinterHelper.ScaleModeConstants.VbTwips 'Twips
End Sub
2064 - %1 %2 %3.%4 was not upgraded
Description
The VBUC converts members of a VB6 control library to their .NET equivalents whenever possible. The corresponding .NET elements are chosen to provide functional equivalence on the target platform.
In particular scenarios, some class properties may not have a direct equivalent in .NET or may have not be mapped in the current release of the VBUC. The VBUC generates this EWI to inform the user about these specific cases.
Also, some constants or static classes may not have a direct equivalent in the .NET core libraries or no mapping association exists in the specific version of the VBUC in use.
Since the Stub Generation upgrade option is normally enabled, the VBUC will create dummy declarations for these properties and reference them instead of the original reference to the not-supported property. This feature reduces the amount of compilation errors and provides the user with the possibility to manually implement the property's functionality in the stub declaration.
The final solution will depend on the approach taken and the particulars of the application being migrated.
It will be necessary to implement the original property functionality through other means. This goal can be achieved through one of the following approaches:
Implement the functionality from scratch.
If the stub generation feature is enabled, it can be implemented in one place: the generated stub declaration.
If the stub generation feature is not used, it is necessary to change all references to the new .NET implementation.
Use an already existing method/property.
From .NET core libraries: Depending on what functionality is expected from a property, a particular VBUC user might be satisfied with a .NET equivalent, which, while not 100% equivalent, is sufficient for the specific case.
From third-party libraries: Some vendors might provide functionality previously available in VB6 and not in the .NET core libraries.
Refactor the code to use another method/property. This strategy makes sense when the underlying .NET object models are very different to the VB6 ones. In these cases, it is likely that a new approach will be the key.
VB6 Original Code
Public Sub GetProperty(ByVal PropBag As PropertyBag)
Dim mask As String
mask = PropBag.ReadProperty("Mask", "none")
MsgBox "Mask is: " & mask
End Sub
C# Upgraded Code
publicvoidGetMaskProperty(UpgradeStubs.PropertyBag PropBag){ //UPGRADE_ISSUE: (2064) PropertyBag method PropBag.ReadProperty was not upgraded. //UPGRADE_WARNING: (1068) PropBag.ReadProperty() of type Variant is being forced to string.string mask =ReflectionHelper.GetPrimitiveValue<string>(PropBag.ReadProperty("Mask","none"));MessageBox.Show("Mask is: "+ mask,AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));}publicclassPropertyBag{publicobjectReadProperty(string Name_Renamed,object DefaultValue) {UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("VBRUN.PropertyBag.ReadProperty");returndefault(object); }publicvoidWriteProperty(string Name_Renamed,object Value,object DefaultValue) {UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("VBRUN.PropertyBag.WriteProperty"); }}
Public Sub GetMaskProperty(ByVal PropBag As UpgradeSolution1Support.UpgradeStubs.PropertyBag)
'UPGRADE_ISSUE: (2064) PropertyBag method PropBag.ReadProperty was not upgraded.'
'UPGRADE_WARNING: (1068) PropBag.ReadProperty() of type Variant is being forced to String.'
Dim mask As String = ReflectionHelper.GetPrimitiveValue(Of String)(PropBag.ReadProperty("Mask", "none"))
MessageBox.Show("Mask is: " & mask, My.Application.Info.Title)
End Sub
VB.NET Expected Code
Public Sub GetMaskProperty(ByVal PropBag As UpgradeSolution1Support.UpgradeStubs.PropertyBag)
Dim mask As String = ReflectionHelper.GetPrimitiveValue(Of String)(PropBag.ReadProperty("Mask", "none"))
MessageBox.Show("Mask is: " & mask, My.Application.Info.Title)
End Sub
Public Class PropertyBag
Private bag As Dictionary(Of String, String) = New Dictionary(Of String, String)
Public Function ReadProperty(ByVal Name_Renamed As String, Optional ByVal DefaultValue As Object = Nothing) As Object
If Not bag.ContainsKey(Name_Renamed) Then
Return DefaultValue
Else
Return bag(Name_Renamed)
End If
End Function
Public Sub WriteProperty(ByVal Name_Renamed As String, ByVal Value As Object, Optional ByVal DefaultValue As Object = Nothing)
If Microsoft.VisualBasic.Information.IsNothing(Value) Then
bag.Add(Name_Renamed, DefaultValue)
Else
bag.Add(Name_Renamed, Value)
End If
End Sub
End Class
2068 - %1 %2 was not upgraded
Description
The VBUC is capable of mapping VB6 library members to .NET equivalents. These equivalents are chosen to provide maximum functional equivalence on the target platform.
Some class properties may not have a direct equivalent in specific scenarios because there is no equivalent in the .NET libraries or because no mapping association exists in VBUC.
Recommendations
There is no unique solution for this issue because some class properties may not have an equivalent in .NET at all.
The entire set of not-mapped elements requires the manual implementation of the missing member. The Stub Generation feature will assess the manual effort needed to reach functional equivalence by isolating all not-upgraded class properties in a single source file.
For these cases, we implement the PropertyBag and its methods in the VBRUN_PropertyBag class.
VB6 Original Code
Private Sub Command1_Click()
Dim objBag As New PropertyBag
' Attempt with empty Property Bag, default value'
GetMaskProperty objBag
objBag.WriteProperty "Mask", "Zorro"
'Attempt with PropertyBag with mask value'
GetMaskProperty objBag
End Sub
Public Sub GetMaskProperty(ByVal PropBag As PropertyBag)
Dim mask As String
mask = PropBag.ReadProperty("Mask", "none")
MsgBox "Mask is: " & mask
End Sub
C# Upgraded Code
privatevoidCommand1_Click(Object eventSender,EventArgs eventArgs){ //UPGRADE_ISSUE: (2068) VBRUN.PropertyBag object was not upgraded.UpgradeStubs.PropertyBag objBag =newUpgradeStubs.PropertyBag(); // Attempt with empty Property Bag, default valueGetMaskProperty(objBag); //UPGRADE_ISSUE: (2064) PropertyBag method objBag.WriteProperty was not upgraded.objBag.WriteProperty("Mask","Zorro",null); //Attempt with PropertyBag with mask valueGetMaskProperty(objBag);}//UPGRADE_ISSUE: (2068) VBRUN.PropertyBag object was not upgraded.publicvoidGetMaskProperty(UpgradeStubs.PropertyBag PropBag){ //UPGRADE_ISSUE: (2064) PropertyBag method PropBag.ReadProperty was not upgraded. //UPGRADE_WARNING: (1068) PropBag.ReadProperty() of type Variant is being forced to string.string mask =ReflectionHelper.GetPrimitiveValue<string>(PropBag.ReadProperty("Mask","none"));MessageBox.Show("Mask is: "+ mask,AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));}publicclassPropertyBag{publicobjectReadProperty(string Name_Renamed,object DefaultValue) {UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("VBRUN.PropertyBag.ReadProperty");returndefault(object); }publicvoidWriteProperty(string Name_Renamed,object Value,object DefaultValue) {UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("VBRUN.PropertyBag.WriteProperty"); }}
C# Expected Code
privatevoidCommand1_Click(Object eventSender,EventArgs eventArgs){UpgradeStubs.PropertyBag objBag =newUpgradeStubs.PropertyBag(); // Attempt with empty Property Bag, default valueGetMaskProperty(objBag);objBag.WriteProperty("Mask","Zorro",null); //Attempt with PropertyBag with mask valueGetMaskProperty(objBag);}publicvoidGetMaskProperty(UpgradeStubs.PropertyBag PropBag){string mask =ReflectionHelper.GetPrimitiveValue<string>(PropBag.ReadProperty("Mask","none"));MessageBox.Show("Mask is: "+ mask,AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));}publicclassPropertyBag{privateDictionary<string,object> bag =newDictionary<string,object>();publicobjectReadProperty(string Name_Renamed,object DefaultValue) {if (bag.ContainsKey(Name_Renamed) ==false)return DefaultValue;elsereturnbag[Name_Renamed]; }publicvoidWriteProperty(string Name_Renamed,object Value,object DefaultValue) {if(Value ==null) {bag.Add(Name_Renamed, DefaultValue); }else {bag.Add(Name_Renamed, Value); } }}
VB.NET Upgraded Code
Private Sub Command1_Click(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles Command1.Click
'UPGRADE_ISSUE: (2068) VBRUN.PropertyBag object was not upgraded.'
Dim objBag As New UpgradeSolution1Support.UpgradeStubs.PropertyBag()
' Attempt with empty Property Bag, default value'
GetMaskProperty(objBag)
'UPGRADE_ISSUE: (2064) PropertyBag method objBag.WriteProperty was not upgraded.'
objBag.WriteProperty("Mask", "Zorro")
'Attempt with PropertyBag with mask value'
GetMaskProperty(objBag)
End Sub
'UPGRADE_ISSUE: (2068) VBRUN.PropertyBag object was not upgraded.'
Public Sub GetMaskProperty(ByVal PropBag As UpgradeSolution1Support.UpgradeStubs.PropertyBag)
'UPGRADE_ISSUE: (2064) PropertyBag method PropBag.ReadProperty was not upgraded.'
'UPGRADE_WARNING: (1068) PropBag.ReadProperty() of type Variant is being forced to String.'
Dim mask As String = ReflectionHelper.GetPrimitiveValue(Of String)(PropBag.ReadProperty("Mask", "none"))
MessageBox.Show("Mask is: " & mask, My.Application.Info.Title)
End Sub
Public Class PropertyBag
Public Function ReadProperty(ByVal Name_Renamed As String, Optional ByVal DefaultValue As Object = Nothing) As Object
UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("VBRUN.PropertyBag.ReadProperty")
Return Nothing
End Function
Public Sub WriteProperty(ByVal Name_Renamed As String, ByVal Value As Object, Optional ByVal DefaultValue As Object = Nothing)
UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("VBRUN.PropertyBag.WriteProperty")
End Sub
End Class
VB.NET Expected Code
Private Sub Command1_Click(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles Command1.Click
Dim objBag As New UpgradeSolution1Support.UpgradeStubs.PropertyBag
' Attempt with empty Property Bag, default value'
GetMaskProperty(objBag)
objBag.WriteProperty("Mask", "Zorro")
'Attempt with PropertyBag with mask value'
GetMaskProperty(objBag)
End Sub
Public Sub GetMaskProperty(ByVal PropBag As UpgradeSolution1Support.UpgradeStubs.PropertyBag)
Dim mask As String = ReflectionHelper.GetPrimitiveValue(Of String)(PropBag.ReadProperty("Mask", "none"))
MessageBox.Show("Mask is: " & mask, My.Application.Info.Title)
End Sub
Public Class PropertyBag
Private bag As Dictionary(Of String, String) = New Dictionary(Of String, String)
Public Function ReadProperty(ByVal Name_Renamed As String, Optional ByVal DefaultValue As Object = Nothing) As Object
If Not bag.ContainsKey(Name_Renamed) Then
Return DefaultValue
Else
Return bag(Name_Renamed)
End If
End Function
Public Sub WriteProperty(ByVal Name_Renamed As String, ByVal Value As Object, Optional ByVal DefaultValue As Object = Nothing)
If Microsoft.VisualBasic.Information.IsNothing(Value) Then
bag.Add(Name_Renamed, DefaultValue)
Else
bag.Add(Name_Renamed, Value)
End If
End Sub
End Class
2070 - Constant %1 was not upgraded
Description
Some constants may not have a direct equivalent in .NET or may not be mapped to a given equivalent in the current release of the VBUC.
Recommendations
There is no straightforward solution for this issue because some class properties may not have an equivalent in .NET at all.
The entire not-mapped set of elements requires the manual implementation of the missing member. The stub generation feature will assess the manual effort needed to reach functional equivalence by isolating all not-upgraded class properties in a single source file.
Public Sub CustomCursor()
Command1.MousePointer = VBRUN.MousePointerConstants.vbCustom
Command1.MouseIcon = LoadPicture("C:\Picture.cur")
End Sub
C# Upgraded Code
publicvoidCustomCursor(){ //UPGRADE_ISSUE: (2070) Constant vbCustom was not upgraded.Command1.Cursor= vbCustom;Command1.Cursor=newCursor((newBitmap(Image.FromFile("C:\\Picture.cur"))).GetHicon());}
Public Sub CustomCursor()
'UPGRADE_ISSUE: (2070) Constant vbCustom was not upgraded.'
Command1.Cursor = vbCustom
Command1.Cursor = New Cursor((New Bitmap(Image.FromFile("C:\Picture.cur"))).GetHicon())
End Sub
VB.NET Expected Code
Public Sub CustomCursor()
Command1.Cursor = New Cursor((New Bitmap(Image.FromFile("C:\Picture.cur"))).GetHicon())
End Sub
7003 - The Hdc should be released once it is used for safety
Description
This EWI is emitted when a handle to a device context is being used in Visual Basic 6.0 code. In the .Net environment, unmanaged handles like Hdc need to be released back to the GDI system. Failure to do so can result in general errors appearing in the application.
Recommendations
The first thing to consider is that .Net uses GDI+ instead of GDI for its graphics operations. GDI+ is generally easier to work with within the .Net framework and doesn't require calls to unmanaged code. However, GDI+ is a bit slower than regular GDI. So careful consideration must be paid to the performance of the application and the benefits of GDI+ vs GDI considered.
In this case, two solutions will be given, one involving GDI and an alternative version using GDI+, and in the expected code it will be shown as follows:
Common code - Necessary changes to apply in both cases, we changed the signature of the DrawText method, so we'll have to update the call in the Paint event since we're now sending the Graphics object from PaintEventArgs as a parameter instead of the PictureBox.
GDI Solution - For this solution, we had to add a few more GDI methods, namely SetBkMode and SetTextColor. Additionally, CreateFont and DeleteObject could also be added to the list if the font needs to be set. This is necessary because .NET handles drawing with GDI+, so if we want to change GDI's properties we'll have to do it through GDI calls. Also, the .Net PictureBox does not have Font properties we can set.
GDI+ Solution - In this case, we use the DrawString method of the System.Drawing.Graphics object.
Visual Basic 6.0 documentation
Additional information that might be helpful while handling this EWI.
Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
Private Sub DrawText(ByVal pctCanvas As PictureBox, ByVal sText As String, ByVal lLeft As Long, ByVal lTop As Long)
'== Set the picture box properties'
pctCanvas.ForeColor = vbBlack
pctCanvas.FontName = "MS Sans Serif"
pctCanvas.FontBold = False
pctCanvas.FontSize = 8.25
'== draw the text'
Dim hdcValue As Long
hdcValue = pctCanvas.hdc
Call TextOut(hdcValue, lLeft, lTop, sText, Len(sText))
End Sub
Private Sub Picture1_Paint()
DrawText Me.Picture1, "This is a test", 10, 10
DrawText Me.Picture1, "This is another test", 40, 40
End Sub
C# Upgraded Code
//Form1.csprivatevoidDrawText(PictureBox pctCanvas,string sText,int lLeft,int lTop){ //== Set the picture box's properties //UPGRADE_ISSUE: (2064) PictureBox property pctCanvas.ForeColor was not upgraded. More Information: https://www.mobilize.net/vbtonet/ewis/ewi2064pctCanvas.setForeColor(Color.Black); //UPGRADE_WARNING: (2045) Only TrueType and OpenType fonts are supported in Windows Forms. More Information: https://www.mobilize.net/vbtonet/ewis/ewi2045pctCanvas.Font=pctCanvas.Font.Change(name:"MS Sans Serif", bold:false, size:8.25f); //== draw the text //UPGRADE_WARNING: (7003) The Hdc should be released once it is used for safety More Information: https://www.mobilize.net/vbtonet/ewis/ewi7003int hdcValue =pctCanvas.CreateGraphics().GetHdc().ToInt32();UpgradeSolution1Support.PInvoke.SafeNative.gdi32.TextOut(hdcValue, lLeft, lTop,ref sText,Strings.Len(sText));}privatevoidPicture1_Paint(Object eventSender,PaintEventArgs eventArgs){DrawText(this.Picture1,"This is a test",10,10);DrawText(this.Picture1,"This is another test",40,40);}//SafeMethods/gdi32.cspublicstaticintTextOut(int hdc,int X,int Y,refstring lpString,int nCount){returnUpgradeSolution1Support.PInvoke.UnsafeNative.gdi32.TextOut(hdc, X, Y,ref lpString, nCount);}//UnsafeMethods/gdi32.cs[DllImport("gdi32.dll", EntryPoint ="TextOutA", CharSet =CharSet.Ansi, SetLastError =true, ExactSpelling =true)]externpublicstaticintTextOut(int hdc,int X,int Y, [MarshalAs(UnmanagedType.VBByRefStr)] refstring lpString,int nCount);
C# Expected Code
Common Code
privatevoidPicture1_Paint(Object eventSender,PaintEventArgs eventArgs){DrawText(eventArgs.Graphics,"This is a test",10,10);DrawText(eventArgs.Graphics,"This is another test",40,40);}
privatevoidDrawText(Graphics g,string sText,int lLeft,int lTop){Font font =newFont("Microsoft Sans Serif",8.25f,FontStyle.Regular,GraphicsUnit.Point,0);SolidBrush brush =newSolidBrush(Color.Black);g.DrawString(sText, font, brush, lLeft, lTop);}
VB.NET Upgraded Code
'Form1.vb'
Private Sub DrawText(ByVal pctCanvas As PictureBox, ByVal sText As String, ByVal lLeft As Integer, ByVal lTop As Integer)
'== Set the picture boxs properties'
'UPGRADE_ISSUE: (2064) PictureBox property pctCanvas.ForeColor was not upgraded.'
pctCanvas.setForeColor(Color.Black)
'UPGRADE_WARNING: (2045) Only TrueType and OpenType fonts are supported in Windows Forms.'
pctCanvas.Font = pctCanvas.Font.Change(name:="MS Sans Serif", bold:=False, size:=8.25)
'== draw the text'
'UPGRADE_WARNING: (7003) The Hdc should be released once it is used for safety'
Dim hdcValue As Integer = pctCanvas.CreateGraphics().GetHdc().ToInt32()
UpgradeSolution1Support.SafeNative.gdi32.TextOut(hdcValue, lLeft, lTop, sText, Strings.Len(sText))
End Sub
Private Sub Picture1_Paint(ByVal eventSender As Object, ByVal eventArgs As PaintEventArgs) Handles Picture1.Paint
DrawText(Me.Picture1, "This is a test", 10, 10)
DrawText(Me.Picture1, "This is another test", 40, 40)
End Sub
'SafeMethods/gdi32.vb'
Public Function TextOut(ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer, ByRef lpString As String, ByVal nCount As Integer) As Integer
Return UpgradeSolution1Support.UnsafeNative.gdi32.TextOut(hdc, X, Y, lpString, nCount)
End Function
'UnsafeMethods/gdi32.vb'
Public Module gdi32
Declare Function TextOut Lib "gdi32" Alias "TextOutA"(ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal lpString As String, ByVal nCount As Integer) As Integer
End Module
VB.NET Expected Code
Common Code
Private Sub Picture1_Paint(ByVal eventSender As Object, ByVal eventArgs As PaintEventArgs) Handles Picture1.Paint
DrawText(eventArgs.Graphics, "This is a test", 10, 10)
DrawText(eventArgs.Graphics, "This is another test", 40, 40)
End Sub
GDI Solution
'Form1.vb'
Private Const TRANSPARENT As Integer = 1
Private Sub DrawText(ByVal g As Graphics, ByVal sText As String, ByVal lLeft As Integer, ByVal lTop As Integer)
Dim hdc As IntPtr
hdc = g.GetHdc()
UpgradeSolution1Support.SafeNative.gdi32.SetBkMode(hdc, TRANSPARENT)
UpgradeSolution1Support.SafeNative.gdi32.SetTextColor(hdc, System.Drawing.ColorTranslator.ToWin32(Color.Black))
UpgradeSolution1Support.SafeNative.gdi32.TextOut(hdc.ToInt32(), lLeft, lTop, sText, sText.Length)
g.ReleaseHdc(hdc)
End Sub
'SafeMethods/gdi32.vb'
Public Function TextOut(ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer, ByRef lpString As String, ByVal nCount As Integer) As Integer
Return UpgradeSolution1Support.UnsafeNative.gdi32.TextOut(hdc, X, Y, lpString, nCount)
End Function
Public Function SetBkMode(ByVal hdc As IntPtr, ByVal iBkMode As Integer) As Integer
Return UpgradeSolution1Support.UnsafeNative.gdi32.SetBkMode(hdc, iBkMode)
End Function
Public Function SetTextColor(ByVal hdc As IntPtr, ByVal crColor As Integer) As Integer
Return UpgradeSolution1Support.UnsafeNative.gdi32.SetTextColor(hdc, crColor)
End Function
'UnsafeMethods/gdi32.vb'
Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal lpString As String, ByVal nCount As Integer) As Integer
Declare Function SetBkMode Lib "gdi32" Alias "SetBkMode" (ByVal hdc As IntPtr, ByVal iBkMode As Integer) As Integer
Declare Function SetTextColor Lib "gdi32" Alias "SetTextColor" (ByVal hdc As IntPtr, ByVal crColor As Integer) As Integer
GDI+ Solution
Private Sub DrawText(ByVal g As Graphics, ByVal sText As String, ByVal lLeft As Integer, ByVal lTop As Integer)
Dim font As System.Drawing.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0)
Dim brush As System.Drawing.SolidBrush = New System.Drawing.SolidBrush(Color.Black)
g.DrawString(sText, font, brush, lLeft, lTop)
End Sub