[AccessD] Off the wall Events question...

John W. Colby jcolby at colbyconsulting.com
Thu Feb 13 00:28:00 CST 2003


Drew,

Given your familiarity with VB why don't you create an ocx.  OCXs can raise
events.

That could be placed on a form (or even in a class which forms a wrapper to
the ocx), then a reference to the ocx itself (not the class that contains
it) could be dimmed in any form that needed it and it's event sunk in the
form (or class).

Something of that nature anyway.

I used an ocx for the comm object from visual basic.  By placing it on a
form I could sink it's events in that form.  I never tried to make the comm
object dim a public object but if you can do that then other forms can set a
reference to the same object by getting it from the open form.  Each form
that gets a pointer to the object should be able to declare it's own
instance of the object withevents thus could sink the calendar's events.  I
don't know how you are going to tell the object what form / control is
requesting a date service so that is a bit muddy.

In a2K (which has RaisEvents) I built a message class for exactly this kind
of situation.  The message class was dimensioned public in a module, thus
any other class that wanted to use it could dim a variable of type dclsMsg
(Deep class!).  The msg class simply had methods that anyone could call with
a mail type of From / To / Subject / Message parameters.

Anyone could send a message simply by referencing the global message class
and calling the method.  The message class then raised an event passing
along the 4 parameters.  Anyone that wanted to receive messages from the
message channel dims a dclsMsg withevents, points to the global msg class,
then sinks the message event.  Thus any message on the channel gets to
everyone watching the channel.  It is up to each watcher to watch the "to"
param for it's name or something that it knows means the message is to it.

I used a form that when opened, grabbed a pointer to the message class, then
watched for it's name in the "To" param.  It performed it's action, then
returned a message to the caller found in the "from" parameter, putting it's
name in it's message's From param.  The caller was watching for a return
message.  Does that make sense?

To: "frmCalendar"
From: "FrmClient"
Subject: "txtCreditAprvdDate"
Msg: #StartDate#

the calendar processes the date, and when the user finishes with the
calendar, returns the message:

To: "FrmClient"
From: "FrmCalendar"
Subject: "txtCreditAprvdDate"
Msg: #ManipulatedDate#

The calendar form has dimmed withevents lclsMsg as dclsMsg and set it =
gdclsMsg.  It then sinks the message event from the message class.

sub ldclsMsg_Msg(strTo as string, strFrom as string, strSubject as string,
varMsg as variant)
	'Do something with the message when it arrives
	if strTo = me.name  then
		'Do something cool with the message
		'Save the strFrom to know what form sent the message
		'Save the strSubject to know what control on the calling form the date is
going back into.
		'manipulate the date
		'When the user is finished manipulating the date...
		ldclsMsg.Msg strFrom, me.name, strSubject, #ManipulatedDate
	endif
end sub


With a message channel like this, anyone can send a message, whether or not
they are watching for a return message.  Anyone can watch for messages
simply by dimming a variable:

dim ldclsMsg as dclsMsg
	set ldclsMsg = gdclsMsg 'this was initialized by the framework

Once dimmed, the class (or form) watching the message channel sinks the
message event

sub ldclsMsg_Msg(strTo as string, strFrom as string, strSubject as string,
varMsg as variant)
	'Do something with the message when it arrives
	if strTo = me.name and strFrom = "frmCalendar" then
		'Do something cool with the message
		if strsubject = "txtCreditAprvdDate" then
			txtCreditAprvdDate.value = varMsg
		endif
	endif
end sub

Notice that you can have as many of these message channels as you want.  Set
up a global message channel just for the calendar.  Only forms wanting to
use the calendar watch the channel.

So... obviously this can only be done using a message class in A2K or above
since only A2K or above can do the RaiseEvent in the message class.  However
in A97 you might be able to build something similar by using an ocx that is
referenced in a variable in a class somewhere.  In fact you might even be
able to implement a "message ocx" that performs the above functionality.
Dim the ocx in a public variable, then anyone that wants to send messages
just calls the ocx's message method passing the params.  Anyone wanting to
listen to the message channel dims a local (to the form or class) variable
to hold a pointer to a message OCX, then sets that pointer to point to the
already initialized global message ocx.  Sink it's events in this class and
form and watch for messages.

Anyway, this is overly long and perhaps not at all interesting, but after
the thread today about withevents I thought I'd throw it out there.

In fact, I just went looking and all of the code for the message class is
available in a demo on our web site.  Click on my last many to many
article - May 2002 - Combining Withevents and RaiseEvents.  At the top of
the article is a link to Demo.  Download the demo and watch three forms send
and receive messages on a message channel using exactly the process
described above.

John W. Colby
Colby Consulting
www.ColbyConsulting.com

-----Original Message-----
From: accessd-admin at databaseadvisors.com
[mailto:accessd-admin at databaseadvisors.com]On Behalf Of Drew Wutka
Sent: Wednesday, February 12, 2003 11:49 PM
To: 'AccessD at databaseadvisors.com'
Subject: [AccessD] Off the wall Events question...


With all of the posts about events recently, something just dawned on me.
Actually, it came crashing down on me.

I have been rewriting my MiniCalendar form lately.  My original works, but
is far from elegant, or even slick.  I had visualized a lot of changes I
wanted to incorporate, and just starting wacking at them all.

So far I have gotten some neat 'features', such as a rounded form, extended
dropdown capability, etc.  However, one of the new features that I had
planned on, I now know I can't do directly.  The old form accepted a form
name and control name, and would return a date to that control.  What I
wanted to use in this version was raiseevent, to fire an event on the
calling form.  Thinking in VB 6 mode, I didn't even realize this would be a
problem with Access 97, since I can do this easily in VB 6.  But with all of
the recent posts, I realized that event and raiseevent are reserved keywords
in Access 97 (VBA 5.0), but do nothing.

ARG!!!!

So, does anyone know how to accomplish the same thing in Access 97.  I will
be making a 2000 version of my calendar, so obviously I can use event and
raiseevent there, but I am developing the new version in 97 first, so I need
a work around.  I am thinking about using one of the form's current events,
and triggering it.  (Probably AfterUpdate).  I wanted my own event, but that
doesn't look possible.  I even tried hunting through the VBA .dll's, to see
if I could fudge an API or two, but no luck there.

Any thoughts?

Drew
_______________________________________________
AccessD mailing list
AccessD at databaseadvisors.com
http://databaseadvisors.com/mailman/listinfo/accessd
Website: http://www.databaseadvisors.com






More information about the AccessD mailing list