Reputation: 129
I am currently upgrading our software from VB6 to VB.NET and doing so one DLL at a time. The EXE will be last since it has a lot of third party UI controls.
One issue that I found is that the VB6 version of the DLL housed an IProgressCallBack class that was acting like an interface class (which does not officially exist in VB6) and allowed the EXE to get progress reports from the DLL and display it on the screen for the user.
When this DLL is migrated the IProgressCallBack class can be set as an Interface class, but then it cannot be 'Set' to the instance of the form using it. But if I create it as just a normal class, it still will not let me 'Set' it to the instance of the form using it since they are two different object types.
I need to know how do I either make the IProgressCallBack class work between VB6 and VB.NET or what is an alternate solution to keep the VB6 UI informed of the progress of the .NET DLL?
Here is an example of the VB6 version of both and how they work:
VB6 DLL: IProgressCallBack
Option Explicit
Public Function NotifyProgress(ByVal Progress As Single, ByRef isCancel As Boolean) As Boolean
End Function
VB6 DLL: MainFunctions Class
Public ProgressNotify As IProgressCallBack
Public Sub DoWork()
Dim l As Long
For l = 1 to 100
Sleep 10 'sleep for 1/100 of a second
ProgressNotify.NotifyProgress 1, False
Next
End Sub
VB6 EXE
Implements IProgressCallBack
Dim m_oMainFunc As MainFunctions
Private Sub cmdStart_Click()
Set m_oMainFunc = New MainFunctions
Set m_oMainFunc.ProgressNotify = Me
m_oMainFunc.DoWork
Set m_oMainFunc = Nothing
End Sub
Public Function IProgressCallBack_NotifyProgress(ByVal Progress As Single, isCancel As Boolean) As Boolean
lblStatus.Caption = CStr(Round(Progress)) & "%"
pbStatus.Value = Round(Progress)
Me.Refresh
End Function
Thanks, Chris
Upvotes: 1
Views: 604
Reputation: 129
I have not exactly found the answer to the question I posted above, but I have found a nice workaround. Essentially I pass in the form as an object to the class pretending to be an interface and directly call the interface method that resides on the form to update the screen. Here is the code sample of how I do this:
VB.NET DLL: IProgressCallBack Class
Dim m_oForm As Object
Public Sub New(ByRef oForm As Object)
m_oForm = oForm
End Sub
Public Function NotifyProgress(ByVal Progress As Single, ByRef isCancel As Boolean) As Boolean
m_oForm.IProgressCallBack_NotifyProgress(Progress, isCancel)
End Function
VB.NET DLL: MainFunctions Class
Public ProgressNotify As IProgressCallBack
Public Sub New()
'Need Public Sub New() with no parameters for all Com Classes
MyBase.New()
End Sub
Public Sub Initialize(ByRef oForm As Object)
ProgressNotify = New IProgressCallBack(oForm)
End Sub
Public Sub DoWork()
For l As Long = 1 to 100
Threading.Thread.Sleep(10) 'sleep for 1/100 of a second
ProgressNotify.NotifyProgress(l,False)
Next
End Sub
VB6 EXE
Dim m_oMainFunc As TestDLL_Net.MainFunctions
Private cmdStart_Click()
Set m_oMainFunc = New TestDLL_Net.MainFunctions
m_oMainFunc.Initialize Me
m_oMainFunc.DoWork
Set m_oMainFunc = Nothing
End Sub
Public Function IProgressCallBack_NotifyProgress(ByVal Progress As Single, isCancel As Boolean) As Boolean
DoEvents
lblStatus.Caption = CStr(Round(Progress)) & "%"
Me.Refresh
pbStatus.Value = Round(Progress)
End Function
This provides the same result as the VB6 DLL to VB6 EXE example posted above, and the changes in the EXE are minimal to make it work.
Thanks, Chris
Upvotes: 1