Hello. I use an activeX exe and a multiuse class for an IPC purpose (using a
shared pool of Global Vars)
It works well for that purpose, but now i am trying to add event management
The MultiUse Class is istanciated 3 times.
There is some basic event management (the class raise some events when some
methods are called)
there are 3 clients : the first two register and unregister to the Active X
server, the third is an event sink.
However it does not work. i actually think that it is not possible with my
design.
Thank you for any hints !
Here is some code.
///// Active X exe code excerpt : ////
//// ServiceActivity Class Module :
Public Event AppReg()
Public Event AppUnReg()
Sub RegisterApp()
some code
Raise AppReg
End Sub
Sub UnregisterApp()
some code
Raise AppUnReg
End Sub
///Client 1 & 2 code excerpt : ////
Dim sa as ServiceActivity
set sa = new ServiceActivity
...
sa.RegisterApp
...
sa.UnRegisterApp
///Client 3 code excerpt : ///
Dim Withevents sa as ServiceActivity
set sa = new ServiceActivity
Sub sa_AppReg()
'Never fired
end sub
Sub sa_AppUnReg()
'Never fired
end sub
Tony Proctor - 30 Jul 2003 18:40 GMT
The events are only delivered to modules declaring the same object instance
(or a copy of it) using WithEvents. Each client will have a different
instance of the ServiceActivity class and so won't see each other's events.
As an illustration: Within just one of these clients, if
Private WithEvents sa1 As ServiceActivity
Private WithEvents sa2 As ServiceActivity
...etc...
Set sa1 = New ServiceActivity
Set sa2 = New ServiceActivity
then a RaiseEvent AppReg in sa1 would only deliver it to the handler
sa1_AppReg. However, if
Set sa1 = New ServiceActivity
Set sa2 = sa1
then a RaiseEvent AppReg in sa1 would only deliver it to both the handlers
sa1_AppReg and sa2_AppReg.
The reason I mention this is that the workaround involves generating a local
"synchronisation" event within your ActiveX EXE, and letting each instance
of your ServciesActivity class handle it. The handlers would simply raise
the external event for the benefit of the clients. In order words, instead
of a raw RaiseEvent on the external event, call a method in an instance of a
local class that raises the local event. Let me know if you want any code.
Tony Proctor
> Hello. I use an activeX exe and a multiuse class for an IPC purpose (using a
> shared pool of Global Vars)
[quoted text clipped - 53 lines]
> 'Never fired
> end sub
Tony Proctor - 30 Jul 2003 19:15 GMT
I thought I'd include a demonstration of what I meant anyway. I'm afraid my
explanations are not always very clear...
========== ActiveX EXE - AppClass.cls =========
Private WithEvents oLocalSynch As SynchClass 'Local reference to oSynch
Event ExtEv(i As Integer) ' The external event
Public Sub RaiseExtEv(i As Integer)
' Need to raise the external event on all clients. Rather than doing
' "RaiseEvent ExtEv(i)", just raise the local synchronisation event
' to let all instances of AppClass know
oLocalSynch.DoSynch (i)
End Sub
Private Sub Class_Initialize()
' Make sure we have a single global reference-copy of the
synchronisation class
If oSynch Is Nothing Then
Set oSynch = New SynchClass
End If
' Copy it to our local synchronisation object so we can receive events
on it
Set oLocalSynch = oSynch
End Sub
Private Sub oLocalSynch_SynchEv(i As Integer)
' We've received the synchronisation event. Generate the external event
for our client
RaiseEvent ExtEv(i)
End Sub
========== ActiveX EXE - SynchClass.cls ========
Event SynchEv(i As Integer) 'The synchronisation event
Public Sub DoSynch(i As Integer)
' Raise the local synchronisation event
RaiseEvent SynchEv(i)
End Sub
========== ActiveX EXE - Module1.bas =========
Public oSynch As SynchClass
========== TestProg - Form1.frm ==============
Private WithEvents oApp As EXE.AppClass
Private Sub Command1_Click()
oApp.RaiseExtEv (App.ThreadID And &HFF)
End Sub
Private Sub Form_Load()
Set oApp = New EXE.AppClass
End Sub
Private Sub oApp_ExtEv(i As Integer)
MsgBox "Event triggered with " & CStr(i)
End Sub
========================================
Form1 needs a single command button called Command1.
Compile TestProg.exe, with a reference to the ActiveX EXE
project, and execute two or more instances of it.
Hit the button on any of them and you see that each client
process is notified. The parameter is derived from the thread
ID merely to emphasis that the notifications originate from the
same instance of TestProg.
Tony Proctor
> Hello. I use an activeX exe and a multiuse class for an IPC purpose (using a
> shared pool of Global Vars)
[quoted text clipped - 53 lines]
> 'Never fired
> end sub
Xylos - 31 Jul 2003 11:54 GMT
Thank you. It works very well.!
However in my special case, 2 of the VB clients of the ActiveX exe are
services (using NT service ocx)
the last VB client is executed in the context of the interactive user.
The result is that services run their own Active X process, so does the
client.
i dont know if it is possible with the windows API to make the user client
to use the ActiveX spawned by the services, (LocalSystem context)
it begins to be interesting...
> I thought I'd include a demonstration of what I meant anyway. I'm afraid my
> explanations are not always very clear...
[quoted text clipped - 126 lines]
> > 'Never fired
> > end sub
Tony Proctor - 31 Jul 2003 13:23 GMT
You can configure this using dcomcnfg. The 'Identity' tab of the properties
for your component will allow a single copy to be created under a specific
account, as opposed to the default when involves a separate copy for each
distinct client user.
The same setting can also be made programmatically in the registry, say as
part of an installation procedure.
Tony Proctor
> Thank you. It works very well.!
> However in my special case, 2 of the VB clients of the ActiveX exe are
[quoted text clipped - 143 lines]
> > > 'Never fired
> > > end sub