В VB6 (из-за требований клиента) мне нужно иметь возможность выполнять несколько экземпляров ActiveX EXE, которые я написал для загрузки файлов на несколько устройств через RS232.VB6 Несколько экземпляров объекта ActiveX
Я разработал тестовое приложение, которое, я думаю, отражает то, что мне нужно делать. Во-первых, ActiveX EXE, который имитирует процесс загрузки, называемый TClass. Этот ActiveX EXE вызывает события сообщить свой текущий прогресс в следующим образом:
TClass.exe (ActiveX EXE, Instancing = SingleUse, Threading Model = Thread на объект)
Option Explicit
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Public Event Progress(Value As Long)
Public SeedVal As Long
Public Sub MultByTwo()
Dim i As Integer
Dim lVal As Long
lVal = SeedVal
For i = 0 To 10
Sleep (2000)
lVal = lVal * 2
RaiseEvent Progress(lVal)
Next i
Exit Sub
End Sub
Следующая класс обертку для создания экземпляра TClass и обрабатывать обратного вызова события (Прогресс), назовем его WClass (AxtiveX DLL, Instancing = MultiUse, квартира Каскадный):
Option Explicit
Public WSeedVal As Long
Public WResultVal As Long
Private WithEvents MYF87 As TClass.TargetClass
Private Sub Class_Initialize()
' Set MYF87 = CreateObject("TClass.TargetClass")
Set MYF87 = New TClass.TargetClass
End Sub
Public Function Go() As Integer
MYF87.SeedVal = WSeedVal
MYF87.MultByTwo
End Function
Public Sub MYF87_Progress(Value As Long)
WResultVal = Value
DoEvents
End Sub
Public Function CloseUpShop() As Integer
Set MYF87 = Nothing
End Function
и, наконец, пользовательский интерфейс для создания экземпляра WClass. Это простая форма приложение:
Option Explicit
Private lc1 As WClass.WrapperClass
Private lc2 As WClass.WrapperClass
Private lc3 As WClass.WrapperClass
Private lc4 As WClass.WrapperClass
Private lc5 As WClass.WrapperClass
Private Sub cmd1_Click()
Set lc1 = CreateObject("WClass.WrapperClass")
lc1.WSeedVal = CInt(txt1.Text)
lc1.Go
End Sub
Private Sub cmd2_Click()
Set lc2 = CreateObject("WClass.WrapperClass")
lc2.WSeedVal = CInt(txt2.Text)
lc2.Go
End Sub
Private Sub cmd3_Click()
Set lc3 = CreateObject("WClass.WrapperClass")
lc3.WSeedVal = CInt(txt3.Text)
lc3.Go
End Sub
Private Sub cmd4_Click()
Set lc4 = CreateObject("WClass.WrapperClass")
lc4.WSeedVal = CInt(txt4.Text)
lc4.Go
End Sub
Private Sub cmd5_Click()
Set lc5 = CreateObject("WClass.WrapperClass")
lc5.WSeedVal = CInt(txt5.Text)
lc5.Go
End Sub
Private Sub Form_Load()
Timer1.Interval = 2000
Timer1.Enabled = True
End Sub
Private Sub Form_Unload(Cancel As Integer)
If Not lc1 Is Nothing Then
lc1.CloseUpShop
Set lc1 = Nothing
End If
If Not lc2 Is Nothing Then
lc2.CloseUpShop
Set lc2 = Nothing
End If
If Not lc3 Is Nothing Then
lc3.CloseUpShop
Set lc3 = Nothing
End If
If Not lc4 Is Nothing Then
lc4.CloseUpShop
Set lc4 = Nothing
End If
If Not lc5 Is Nothing Then
lc5.CloseUpShop
Set lc5 = Nothing
End If
End Sub
Private Sub Timer1_Timer()
If Timer1.Enabled Then
Timer1.Enabled = False
If Not lc1 Is Nothing Then
txtRes1.Text = CStr(lc1.WResultVal)
txtRes1.Refresh
End If
If Not lc2 Is Nothing Then
txtRes2.Text = CStr(lc2.WResultVal)
txtRes2.Refresh
End If
If Not lc3 Is Nothing Then
txtRes3.Text = CStr(lc3.WResultVal)
txtRes3.Refresh
End If
If Not lc4 Is Nothing Then
txtRes4.Text = CStr(lc4.WResultVal)
txtRes4.Refresh
End If
If Not lc5 Is Nothing Then
txtRes5.Text = CStr(lc5.WResultVal)
txtRes5.Refresh
End If
Timer1.Interval = 2000
Timer1.Enabled = True
End If
DoEvents
End Sub
txt1, txt2, txt3, txt4 и txt5 являются элементами текста, которые обеспечивают начальное значение, что заканчивает получение передается TClass как свойство. txtRes1, txtRes2, txtRes3, txtRes4 и txtRes5 являются текстовыми элементами для хранения результатов TClass.MultByTwo, как сообщается через вызов RaiseEvent Progress(). cmd1, cmd2, cmd3, cmd4 и cmd5 привязаны к соответствующим вышеперечисленным функциям _Click и создают экземпляр WClass.WrapperClass и все происходит. У формы также есть объект Timer, называемый Timer1, который срабатывает каждые 2 секунды. Единственная цель этого - обновить пользовательский интерфейс из общедоступных свойств в WClass.
Я создал TClass для TClass.exe и WClass для WClass.dll и ссылался на WClass.dll из приложения пользовательского интерфейса. Когда я запускаю форму и нажимаю cmd1, первое, что я замечаю, это то, что Timer1_Timer больше не срабатывает, поэтому мой интерфейс никогда не обновляется. Во-вторых, если я нажму на cmd2, он загорится, но, похоже, заблокирует выполнение первого экземпляра.
Я провел пару дней, читая сообщения и инструкции по MSDN ... не повезло ... любая помощь была бы принята с благодарностью!
Спасибо!
Обновление: Я изменил класс оболочки WClass.dll, чтобы реализовать рекомендации по использованию функций обратного вызова. Смотрите ниже:
V2: WClass.dll (ActiveX DLL, потоковое, Instancing = MULTIUSE)
Option Explicit
Public WSeedVal As Long
Public WResultVal As Long
Public Event WProgress(WResultVal As Long)
Private WithEvents MyTimer As TimerLib.TimerEx
Private WithEvents MYF87 As TClass.TargetClass
Private gInterval As IntervalData
Private Sub Class_Initialize()
Set MyTimer = CreateObject("TimerLib.TimerEx")
' Set MyTimer = New TimerLib.TimerEx
Set MYF87 = CreateObject("TClass.TargetClass")
' Set MYF87 = New TClass.TargetClass
End Sub
Public Function Go() As Integer
gInterval.Second = 1
MyTimer.IntervalInfo = gInterval
MyTimer.Enabled = True
End Function
Private Sub MyTimer_OnTimer()
MyTimer.Enabled = False
MYF87.SeedVal = WSeedVal
MYF87.MultByTwo
End Sub
Public Sub MYF87_Progress(Value As Long)
WResultVal = Value
RaiseEvent WProgress(WResultVal)
DoEvents
End Sub
Public Function CloseUpShop() As Integer
Set MYF87 = Nothing
End Function
необходимых изменения в UI Классе:
Option Explicit
Private WithEvents lc1 As WClass.WrapperClass
Private WithEvents lc2 As WClass.WrapperClass
Private WithEvents lc3 As WClass.WrapperClass
Private WithEvents lc4 As WClass.WrapperClass
Private WithEvents lc5 As WClass.WrapperClass
Private Sub cmd1_Click()
' MsgBox ("Begin UI1.cmd1_Click")
Set lc1 = CreateObject("WClass.WrapperClass")
lc1.WSeedVal = CInt(txt1.Text)
lc1.Go
' MsgBox ("End UI1.cmd1_Click")
End Sub
Public Sub lc1_WProgress(WResultVal As Long)
txtRes1.Text = CStr(WResultVal)
txtRes1.Refresh
DoEvents
End Sub
Private Sub cmd2_Click()
Set lc2 = CreateObject("WClass.WrapperClass")
lc2.WSeedVal = CInt(txt2.Text)
lc2.Go
End Sub
Public Sub lc2_WProgress(WResultVal As Long)
txtRes2.Text = CStr(WResultVal)
txtRes2.Refresh
DoEvents
End Sub
Private Sub cmd3_Click()
Set lc3 = CreateObject("WClass.WrapperClass")
lc3.WSeedVal = CInt(txt3.Text)
lc3.Go
End Sub
Public Sub lc3_WProgress(WResultVal As Long)
txtRes3.Text = CStr(WResultVal)
txtRes3.Refresh
DoEvents
End Sub
Private Sub cmd4_Click()
Set lc4 = CreateObject("WClass.WrapperClass")
lc4.WSeedVal = CInt(txt4.Text)
lc4.Go
End Sub
Public Sub lc4_WProgress(WResultVal As Long)
txtRes4.Text = CStr(WResultVal)
txtRes4.Refresh
DoEvents
End Sub
Private Sub cmd5_Click()
Set lc5 = CreateObject("WClass.WrapperClass")
lc5.WSeedVal = CInt(txt5.Text)
lc5.Go
End Sub
Public Sub lc5_WProgress(WResultVal As Long)
txtRes5.Text = CStr(WResultVal)
txtRes5.Refresh
DoEvents
End Sub
Private Sub Form_Load()
' Timer1.Interval = 2000
' Timer1.Enabled = True
Timer1.Enabled = False
End Sub
Private Sub Form_Unload(Cancel As Integer)
If Not lc1 Is Nothing Then
lc1.CloseUpShop
Set lc1 = Nothing
End If
If Not lc2 Is Nothing Then
lc2.CloseUpShop
Set lc2 = Nothing
End If
If Not lc3 Is Nothing Then
lc3.CloseUpShop
Set lc3 = Nothing
End If
If Not lc4 Is Nothing Then
lc4.CloseUpShop
Set lc4 = Nothing
End If
If Not lc5 Is Nothing Then
lc5.CloseUpShop
Set lc5 = Nothing
End If
End Sub
я все еще вижу такое же поведение. .. Нажмите cmd1, затем я вижу, что результаты начинаются в txtRes1. Нажмите cmd2, результат прекратит обновление в txtRes1 и txtRes2 до тех пор, пока он не завершится, а затем обновления txtRes1.
Я бы не ожидал, что это сработает в отладчике VB6, так как оно однопоточно, но создает исполняемый файл и запускает этот исполняемый файл, который все еще производит эти же результаты.
Я также попытался изменить способ создания моего TClass (Новый или CreateObject) - никакой разницы не заметил. Я также пытался использовать New и CreateObject() при создании WClass тоже ... все еще не делая то, что я хотел бы сделать ...
Вы можете выполнить все три файла сразу, если вы измените exe от singleuse до multiuse. Вам не нужно работать с скомпилированной версией, пока вы не перейдете на SingleUse на exe, и вам никогда не придется работать с dll. – BobRodes