|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Global class and WithEventsI have a class which I needed to make global because it is used in/ on different forms, and the class opens and closes port handles, so I cannot simply make a few more copies of them. However, on some of the forms, I would need a notification about events that the class handles. Normally in my form I would dim the class and receive the events by RaiseEvent like this: private withevents m_Class as Class1 But since the class is global, I cannot do this. Does somebody have any ideas? I don't want to poll the class with a timer to query the event... Thank you! Alex Consider using a Standard Module. It is by default global in its' scope. As
a Form object loads it can pass a reference to itself to the Module via Public Property. (The same Public Property can be used to set the reference to Nothing as the corresponding Form unloads.) By creating a Public Sub within a Forms' code module your Standard Module can communicate with the Form using it's Module-Level Form Variable. (i.e. Call mForm1.MySub().) Spence Show quoteHide quote "Alexandros Peropulous" <perop***@gmail.com> wrote in message news:%23u7%23sJUSLHA.796@TK2MSFTNGP02.phx.gbl... > Hello! > > I have a class which I needed to make global because it is used in/ on > different forms, and the class opens and closes port handles, so I cannot > simply make a few more copies of them. > > However, on some of the forms, I would need a notification about events > that the class handles. > > Normally in my form I would dim the class and receive the events by > RaiseEvent like this: > > private withevents m_Class as Class1 > > But since the class is global, I cannot do this. > > Does somebody have any ideas? I don't want to poll the class with a timer > to query the event... > > Thank you! > Alex "Alexandros Peropulous" <perop***@gmail.com> wrote Can you define global, a little better? Every class module you add is> I have a class which I needed to make global because it is used in/ on > different forms, and the class opens and closes port handles, so I > cannot simply make a few more copies of them. available to any other code module in the project. You don't get more global than that unless you are talking about access from different programs, which you did not mention.... > Normally in my form I would dim the class and receive the events by Why can't you do that? That is exactly how you go about recieving> RaiseEvent like this: > > private withevents m_Class as Class1 > > But since the class is global, I cannot do this. events from a class.... LFS "Larry Serflaten" <serfla***@gmail.com> wrote in message I'm getting the idea he has a cls file with events that he wants to use news:i5k7ja$e4p$1@news.eternal-september.org... : Why can't you do that? That is exactly how you go about recieving : events from a class.... globally. But since WithEvents won't work in a module and he doesn't have a central form, but rather several different ones depending on various criteria, he wants to be able to instance his class with the events for use from any form. That said, the OP might want to review this gem from Karl's site: http://vb.mvps.org/samples/SyncEvts/ (Several ways to share events (timers, in this demo) amongst multiple objects) - Kev
Show quote
Hide quote
On Tue, 31 Aug 2010 21:29:14 -0400, "Kevin Provance" <k@p.c> wrote: I noticed that my other response to the OP was truncated. And perhaps> >"Larry Serflaten" <serfla***@gmail.com> wrote in message >news:i5k7ja$e4p$1@news.eternal-september.org... > >: Why can't you do that? That is exactly how you go about recieving >: events from a class.... > >I'm getting the idea he has a cls file with events that he wants to use >globally. But since WithEvents won't work in a module and he doesn't have a >central form, but rather several different ones depending on various >criteria, he wants to be able to instance his class with the events for use >from any form. > >That said, the OP might want to review this gem from Karl's site: >http://vb.mvps.org/samples/SyncEvts/ (Several ways to share events (timers, >in this demo) amongst multiple objects) > mercifully, as that article is far more useful than my rambling. <g> I think what was bothering the OP was simply that he was not aware he could set m_Class to a 'global' object. Private WithEvents m_Class As Class1 Set m_Class = globalInstanceOfClass1 I generally prefer to provide a constructor and pass the object as a parameter to avoid embedding a "global', and to make it a little clearer that the class has an outside dependency. But that is a matter of style. -ralph
Show quote
Hide quote
"ralph" <nt_consultin***@yahoo.net> wrote in message And where exactly are you making those declarations?news:ctjr7693b51j7o698mj38q4oiusqn5cap6@4ax.com... : On Tue, 31 Aug 2010 21:29:14 -0400, "Kevin Provance" <k@p.c> wrote: : I noticed that my other response to the OP was truncated. And perhaps : mercifully, as that article is far more useful than my rambling. <g> : : I think what was bothering the OP was simply that he was not aware he : could set m_Class to a 'global' object. : : Private WithEvents m_Class As Class1 : Set m_Class = globalInstanceOfClass1 : : I generally prefer to provide a constructor and pass the object as a : parameter to avoid embedding a "global', and to make it a little : clearer that the class has an outside dependency. But that is a matter : of style.
Show quote
Hide quote
On Wed, 1 Sep 2010 01:03:20 -0400, "Kevin Provance" <k@p.c> wrote: Inside a module that needs the Event services of a Class1 object.> >"ralph" <nt_consultin***@yahoo.net> wrote in message >news:ctjr7693b51j7o698mj38q4oiusqn5cap6@4ax.com... >: On Tue, 31 Aug 2010 21:29:14 -0400, "Kevin Provance" <k@p.c> wrote: > >: I noticed that my other response to the OP was truncated. And perhaps >: mercifully, as that article is far more useful than my rambling. <g> >: >: I think what was bothering the OP was simply that he was not aware he >: could set m_Class to a 'global' object. >: >: Private WithEvents m_Class As Class1 >: Set m_Class = globalInstanceOfClass1 >: >: I generally prefer to provide a constructor and pass the object as a >: parameter to avoid embedding a "global', and to make it a little >: clearer that the class has an outside dependency. But that is a matter >: of style. > >And where exactly are you making those declarations? See Nobody's post for one example. -ralph On Tue, 31 Aug 2010 21:25:15 +0200, Alexandros Peropulous
<perop***@gmail.com> wrote: Show quoteHide quote >Hello! Why not?> >I have a class which I needed to make global because it is used in/ on >different forms, and the class opens and closes port handles, so I >cannot simply make a few more copies of them. > >However, on some of the forms, I would need a notification about events >that the class handles. > >Normally in my form I would dim the class and receive the events by >RaiseEvent like this: > >private withevents m_Class as Class1 > >But since the class is global, I cannot do this. > Creat On 01/09/2010 00:57, ralph wrote:
Show quoteHide quote > On Tue, 31 Aug 2010 21:25:15 +0200, Alexandros Peropulous If the object is "Global" in a COM server then I don't think there is an > <perop***@gmail.com> wrote: > >> Hello! >> >> I have a class which I needed to make global because it is used in/ on >> different forms, and the class opens and closes port handles, so I >> cannot simply make a few more copies of them. >> >> However, on some of the forms, I would need a notification about events >> that the class handles. >> >> Normally in my form I would dim the class and receive the events by >> RaiseEvent like this: >> >> private withevents m_Class as Class1 >> >> But since the class is global, I cannot do this. >> > > Why not? explicit instance that you can assign to a variable. I assume they mean the Global where you can access the members without declaring an object, just like the VB and VBA objects. This can be worked around byt only using a single explicit reference as others have suggested. -- Dee Earley (dee.ear***@icode.co.uk) i-Catcher Development Team iCode Systems (Replies direct to my email address will be ignored. Please reply to the group.) On Thu, 02 Sep 2010 11:26:06 +0100, Dee Earley
<dee.ear***@icode.co.uk> wrote: Show quoteHide quote >On 01/09/2010 00:57, ralph wrote: Are you talking about "late binding"???>> On Tue, 31 Aug 2010 21:25:15 +0200, Alexandros Peropulous >> <perop***@gmail.com> wrote: >> >>> Hello! >>> >>> I have a class which I needed to make global because it is used in/ on >>> different forms, and the class opens and closes port handles, so I >>> cannot simply make a few more copies of them. >>> >>> However, on some of the forms, I would need a notification about events >>> that the class handles. >>> >>> Normally in my form I would dim the class and receive the events by >>> RaiseEvent like this: >>> >>> private withevents m_Class as Class1 >>> >>> But since the class is global, I cannot do this. >>> >> >> Why not? > >If the object is "Global" in a COM server then I don't think there is an >explicit instance that you can assign to a variable. > >I assume they mean the Global where you can access the members without >declaring an object, just like the VB and VBA objects. > >This can be worked around byt only using a single explicit reference as >others have suggested. I can't see where the OP suggested he was using late-binding or an external component. -ralph On 02/09/2010 15:16, ralph wrote:
Show quoteHide quote > On Thu, 02 Sep 2010 11:26:06 +0100, Dee Earley No, I never mentioned any form of binding.> <dee.ear***@icode.co.uk> wrote: > >> On 01/09/2010 00:57, ralph wrote: >>> On Tue, 31 Aug 2010 21:25:15 +0200, Alexandros Peropulous >>> <perop***@gmail.com> wrote: >>> >>>> Hello! >>>> >>>> I have a class which I needed to make global because it is used in/ on >>>> different forms, and the class opens and closes port handles, so I >>>> cannot simply make a few more copies of them. >>>> >>>> However, on some of the forms, I would need a notification about events >>>> that the class handles. >>>> >>>> Normally in my form I would dim the class and receive the events by >>>> RaiseEvent like this: >>>> >>>> private withevents m_Class as Class1 >>>> >>>> But since the class is global, I cannot do this. >>> >>> Why not? >> >> If the object is "Global" in a COM server then I don't think there is an >> explicit instance that you can assign to a variable. >> >> I assume they mean the Global where you can access the members without >> declaring an object, just like the VB and VBA objects. >> >> This can be worked around byt only using a single explicit reference as >> others have suggested. > > Are you talking about "late binding"??? > I can't see where the OP suggested he was using late-binding or an One of their previous posts was an OOP COM server hosting the Comm32 > external component. control. One of the instancing modes in a COM server is GlobalMultiuse. I believe this is the "global" they are referring to. -- Dee Earley (dee.ear***@icode.co.uk) i-Catcher Development Team iCode Systems (Replies direct to my email address will be ignored. Please reply to the group.) On Thu, 02 Sep 2010 16:39:48 +0100, Dee Earley
<dee.ear***@icode.co.uk> wrote: > Still it wouldn't make any difference.>> I can't see where the OP suggested he was using late-binding or an >> external component. > >One of their previous posts was an OOP COM server hosting the Comm32 >control. >One of the instancing modes in a COM server is GlobalMultiuse. >I believe this is the "global" they are referring to. Private WithEvents m_Class As Class1 Set m_Class = globalInstanceOfClass1 is how it is done. *unless "globalInstanceOfClass1" is an Object Reference to a type Object and not of type Class1. But I doubt this is the case since the OP was apparently able to implement an Class1.IConnection~ interface before deciding to go "global". But this is so obvious, I must be missing something. <g> -ralph On 02/09/2010 18:21, ralph wrote:
Show quoteHide quote > On Thu, 02 Sep 2010 16:39:48 +0100, Dee Earley I don't think Global (in COM instancing) gives you access to a single > <dee.ear***@icode.co.uk> wrote: > > >> >>> I can't see where the OP suggested he was using late-binding or an >>> external component. >> >> One of their previous posts was an OOP COM server hosting the Comm32 >> control. >> One of the instancing modes in a COM server is GlobalMultiuse. >> I believe this is the "global" they are referring to. > > Still it wouldn't make any difference. > > Private WithEvents m_Class As Class1 > Set m_Class = globalInstanceOfClass1 > > is how it is done. > > *unless "globalInstanceOfClass1" is an Object Reference to a type > Object and not of type Class1. But I doubt this is the case since the > OP was apparently able to implement an Class1.IConnection~ interface > before deciding to go "global". > > But this is so obvious, I must be missing something.<g> instance to assign as you will. As it has already been determined to be a single global variable, this is all moot now though :) -- Dee Earley (dee.ear***@icode.co.uk) i-Catcher Development Team iCode Systems (Replies direct to my email address will be ignored. Please reply to the group.) On 06/09/2010 08:54, Dee Earley wrote:
> On 02/09/2010 18:21, ralph wrote: Having said that, this works:>> But this is so obvious, I must be missing something.<g> > > I don't think Global (in COM instancing) gives you access to a single > instance to assign as you will. Dim X As VB.Global Set X = VB.Global MsgBox X.Forms.Count Oh well :) -- Dee Earley (dee.ear***@icode.co.uk) i-Catcher Development Team iCode Systems (Replies direct to my email address will be ignored. Please reply to the group.) "Dee Earley" <dee.ear***@icode.co.uk> wrote See the post from 09/02/2010. Global simply meant application wide,> One of their previous posts was an OOP COM server hosting the Comm32 > control. > One of the instancing modes in a COM server is GlobalMultiuse. > I believe this is the "global" they are referring to. declared public in a standard module.... LFS Try:
' Module1 Public g_Class As Class1 Public Sub Main() Set g_Class = New Class1 Form1.Show End Sub ' Form1 Private WithEvents m_Class as Class1 Private Sub Form_Load() Set m_Class = g_Class End Sub Private Sub Form_Unload() Set m_Class = Nothing End Sub I want to instantiate the class only ONCE, therefore I declare it in a
module Now here is all my code: Module1: -------------------------------------- Option Explicit Public g As Class1 Public Sub Main() Set g = New Class1 Form1.Show Form2.Show Form3.Show End Sub -------------------------------------- Class1: Option Explicit Public Event NewMessage(ByVal uString As String) Public Sub SendGlobalMessage(ByVal u As String) RaiseEvent NewMessage(u) End Sub -------------------------------------- Form1: Option Explicit Private Sub Command1_Click() g.SendGlobalMessage Me.Text1.Text 'I want form2 and form3 to get that event. 'But I don't want to do this with a timer End Sub Private Sub Form_Load() End Sub -------------------------------------- Form2: Option Explicit Private WithEvents m As Class1 Private Sub m_NewMessage(ByVal uString As String) Me.Caption = uString End Sub -------------------------------------- Form3: Option Explicit Private WithEvents m As Class1 Private Sub m_NewMessage(ByVal uString As String) Me.Caption = uString End Sub "Alexandros Peropulous" <perop***@gmail.com> schrieb im Newsbeitrag Nothing wrong with that - and you've done thatnews:%23aXSPEpSLHA.5572@TK2MSFTNGP02.phx.gbl... > I want to instantiate the class only ONCE, therefore > I declare it in a module already in Sub Main with: Set g = New Class1 > Private Sub Command1_Click() No problem, just add a single Line:> > g.SendGlobalMessage Me.Text1.Text > > 'I want form2 and form3 to get that event. > 'But I don't want to do this with a timer Set m = g into your Form_Load() routines of Form2 and Form3 and you're done. The line: Set m = g does not create an instance - it just sets an additional Reference-Variable 'm' to the instance which is also *pointed-to* by the globally reachable Reference-Variable 'g'. Maybe to make that a little bit more clear, a VB- Object-Instance (created either per 'New' or per 'CreateObject') is thereby allocated on the Process-Heap and available/accessable throughout the whole VB-Process/Thread. You can manage the accessibility of this always "globally available by principle" Object-Instance over the scope your Object-*Variables* (which are only Pointers to this Instance). So, in other words, if you decide to *create* a new Instance in the "least hidden Private-Class", but then manage, to pass the referencing Variable of this "alleged privately created Instance" (by Parameter in an Event or however) to a globally defined VB-Object-Variable of the same (Class-)Type, then this is in no way different from what you currently do (creating the instance in Sub Main) - so it does not matter *where* you create the instance - accessibility of the instance is only determined by one (or the other) current Variable which points to it - and this current Variables scope. Olaf Let that be a lesson to ya... :-)
Show quoteHide quote "Alexandros Peropulous" <perop***@gmail.com> wrote in message news:OMHo2KtSLHA.2100@TK2MSFTNGP04.phx.gbl... > Jesus, thanks a lot!! "Alexandros Peropulous" <perop***@gmail.com> wrote Then you need to be sure the New command is only executed ONCE.> I want to instantiate the class only ONCE, therefore I declare it in a > module > Option Explicit That should do it! At that point you have one instance each of> > Public g As Class1 > > Public Sub Main() > > Set g = New Class1 > > Form1.Show > Form2.Show > Form3.Show > > End Sub Class1, Form1, Form2, and Form3. To begin listening for messages, you need to get access to that one global instance: > -------------------------------------- In forms 2 and 3, you need that WithEvents declaration AND> Form2: > > Option Explicit > > Private WithEvents m As Class1 > > Private Sub m_NewMessage(ByVal uString As String) > > Me.Caption = uString > > End Sub a live instance of Class1. To get the live instance, add: Private Sub Form_Load() Set m = g End Sub That does not create a new instance, it makes m and g point to the very same object, which is what you want to happen. Including the same in form 3, you end up with 3 (Class1 type) variables all pointing to the same (Class1 type) object. Then, to follow 'best practices' guidelines, you'd want to release all of your objects when you are done with them: Private Sub Form_Unload(Cancel As Integer) Set m = Nothing ' < Forms 2 & 3 If Forms.Count = 1 Then ' < All forms Set g = Nothing End if End Sub HTH LFS |
|||||||||||||||||||||||