The message class - RAISING events

jwcolby54

Member
Local time
Yesterday, 19:07
Joined
May 19, 2025
Messages
51
I read with interest a thread which described the machinations that folks went through to do something that is simple with RaiseEvent.
The OP wanted a form with a ton of buttons on it. She created a clsBtn (good job) which the form used to encapsulate each buttons. As many buttons as the OP wanted. Saved into a collection. Good Job.

BUT... she wanted the button click to do something back on the form. Hmmmm... without a variable dimmed Withevents, there is no direct way to do this. But it can be done with a very useful singleton message class. Get a pointer to this clsMsgPD and store it in the class header Withevents... and the magic begins.

This is mostly just aircode, written in the middle of the night as my daughter slept. But I will work with anyone who wishes to actually try this.

First the clsCmd. Store this in a class named clsCmd. I acttually wrote this class and it compiles.

Option Compare Database
Option Explicit

Private WithEvents mCmd As CommandButton 'Holds a pointer to the command button

Private Sub Class_Terminate()
Set mCmd = Nothing 'Clean up behind our Self
End Sub

Public Function fInit(lCmd As CommandButton) 'Get a pointer to a command button
Set lCmd = mCmd 'and store it in the header of this class
End Function

'
'Now sink the click event
'
Private Sub mCmd_Click()
'
'call the message class to send a message
'Say who we are in the first parameter
'And pass a pointer to the actual command button in the last parameter
'
clsMsgPD.Send mCmd.Name, "", "", mCmd
End Sub

Let's create a simple clsMsgPD (PreDeclared). It doesn't do much except raise an event to send a message. Suppose we create a singleton clsMsgPD.
I have used clsMsgPD for years. It functions as described.

Place the following in a new class and save it as clsMsgPD. Export it to a text file.
Change 'Attribute VB_PredeclaredId = True
Import back into the database.

Option Compare Database
Option Explicit
'
'clsMsgPD is a "PreDeclared" class which does not have to be instantiated.
'This has been done by exporting clsMsg, editing it in an editor setting
'and pulling it back in.

'Attribute VB_PredeclaredId = True
'
'And then importing the class back into Access.
'I then renamed clsMsg1 to clsMsgPD.
'
Public Event Message(varFrom As Variant, varTo As Variant, _
varSubj As Variant, varMsg As Variant)
Public Event MessageSimple(varMsg As Variant)

Function Send(varFrom As Variant, varTo As Variant, _
varSubj As Variant, varMsg As Variant)
RaiseEvent Message(varFrom, varTo, varSubj, varMsg)
' Debug.Print "From: " & varFrom & vbCrLf & "To: " & varTo & vbCrLf & "Subj: " & varSubj & vbCrLf & "Msg: " & varMsg
End Function

Function SendSimple(varMsg As Variant)
RaiseEvent MessageSimple(varMsg)
' Debug.Print varMsg
End Function

Now anybody from anywhere can raise a message. The key here is that RaiseEvent can pass variants. And variants can contain anything including pointers to objects such as a button. So the varMsg parameter can be the actual button if so desired. OR it can simply be the name of the button. OR it can be the back color of the button. You get the idea.

In a new form place a text box on the form called txtSomeMsg. And BUNCH of buttons named Cmd1, Cmd2, Cmd3 etc.

Now in the header of the form with all these buttons on it:

'Get an instance of that singleton or "predeclared" class
Dim Withevents mClsMsgPD as clsMsgPD.

'And a collection to hold all the clsMsg instances
Dim mcolClsButtons as collection

Private Sub Form_Open(Cancel As Integer)
Set mcolClsButtons = new Collection
Set mClsMsgPD = new clsMsgPD
lclsCmdFactory Cmd1
lclsCmdFactory Cmd2
lclsCmdFactory Cmd3
'... as many times as you want
End Sub
'
'NEVER forget to clean up behind ourselves
'
Private Sub Form_Close()
Set mClsMsgPD = Nothing
Set mcolClsButtons = Nothing
End Sub
'
'this is a factory for creating instances of clsCmd and storing them in the collection
'
function clsCmdFactory(lCmd As CommandButton )
dim lclsCmd as clsCmd
Set lclsCmd = new clsCmd
lclsCmd.fInit(lCmd)
'
'And store the new clsCmd instance in the collection
'
mcolClsButtons.add lclsCmd
end function

'
'This is the event sink for the message class which the form is listening to
'In here we will expect the clsButton to send itself (the actual button object)
'as the varMsg parameter.
'
Private Sub mClsMsgPD_Message(varFrom As Variant, varTo As Variant, varSubj As Variant, varMsg As Variant)
dim lBtn as CommandButton

'varMsg will be a pointer to a button which is sending a message
Set lBtn = varMsg 'This code coerces the variant message into a command button

txtSomeMsg = lBtn.Name & " is calling back to the form which contains me."

End Sub
 
I had a client that wanted a bound form with a bunch of smallish text boxes which could contain paragraphs or even pages of text. The user couldn't actually see more than a couple of lines of whatever was in the text box. This is a problem...

I created an unbound form frmDataEntry with a huge text box on it. It listened to the message class described in the post above.

The form with all of the smallish text boxes used a clsTxt to wrap each instance of the little text boxes and clsTxt listened for the dblclick event. The clsTxt would open the frmDataEntry and call clsMsgPD, passing a pointer to the text box where the data should eventually be stored.

frmDataEntry listened to clsMsgPD.

In the frmDataEntry, as the form opened, it would grab the pointer to the text box and store it in a variable in the header of the form. It would grab any existing text already in the text box passed in and place it into the huge text box so the user could see and edit the data in the text box passed in. The user could then edit the data to his / her heart's content. When finished, the user would simply close the form. The form closing would take the text in the huge data entry text box and place it into the text box passed in. When the user found themselves back in the original form, all the data entered into the data entry form would be neatly placed in the text box that they had double clicked in.

A somewhat difficult problem easily handled with events.

See my book on the subject being discussed elsewhere in the forums.
 

Users who are viewing this thread

Back
Top Bottom