
Programming a VB6 dll (trying to understand class variables)
I'm trying to program some of my own message box functions and put them in a dll to be used by my other VBScript and VB .exe projects. The first one I am trying to make is a Message Box that can take up to five arguments. The first one will be the message box title. The other 4 will be the caption for each button. The dll function will pass back the caption of the button that was clicked by the user.
So what kind of variables do I need and how do I pass them to the form when I open the form? And how do I pass the value of the clicked button back to the user?
Here's the code I have but it doesn't compile. My class module is named cMsgBoxes. I don't know where to go from here:
Option Explicit
Public strTitle As Variant
Public strcmd1 As Variant
Public strcmd2 As Variant
Public strcmd3 As Variant
Public strcmd4 As Variant
Public strMsgBox As Variant
Public Property Let Title(strTitle As String)
Title = strTitle
End Property
Public Property Let Command1(strcmd1 As String)
Command1 = strcmd1
End Property
Public Property Let Command2(strcmd2 As String)
Command2 = strcmd2
End Property
Public Property Let Command3(strcmd3 As String)
Command3 = strcmd3
End Property
Public Property Let Command4(strcmd4 As String)
Command4 = strcmd4
End Property
Function MsgBox4Button(strTitle As String, strcmd1 As String, Optional strcmd2 As String, Optional strcmd3 As String, Optional strcmd4 As String)
Load frmMsgBox4Button
MsgBox4Button = strMsgBox
End Property
My Form Code:
Option Explicit
Private Sub cmd1_Click()
cMsgBoxes.strMsgBox = Me.cmd1.Caption
Unload Me.Name
End Sub
Private Sub cmd2_Click()
cMsgBoxes.strMsgBox = Me.cmd2.Caption
Unload Me.Name
End Sub
Private Sub cmd3_Click()
cMsgBoxes.strMsgBox = Me.cmd3.Caption
Unload Me.Name
End Sub
Private Sub cmd4_Click()
cMsgBoxes.strMsgBox = Me.cmd4.Caption
Unload Me.Name
End Sub
Private Sub Form_Load()
Me.Caption = strTitle
Me.cmd1.Caption = Trim(strcmd1)
Me.cmd2.Caption = Trim(strcmd2)
Me.cmd3.Caption = Trim(strcmd3)
Me.cmd4.Caption = Trim(strcmd4)
If Nz(Me.cmd1.Caption, "") = "" Then
Me.cmd1.Visible = False
Unload Me.Name
End If
If Nz(Me.cmd2.Caption, "") = "" Then Me.cmd2.Visible = False
If Nz(Me.cmd3.Caption, "") = "" Then Me.cmd3.Visible = False
If Nz(Me.cmd4.Caption, "") = "" Then Me.cmd4.Visible = False
End Sub
Private Function Nz(strValue As Variant, strChangeTo As String) As String
If Not IsNull(strChangeTo) Then
If strValue = Null Then strValue = strChangeTo
End If
End Function
So what kind of variables do I need and how do I pass them to the form when I open the form? And how do I pass the value of the clicked button back to the user?
Here's the code I have but it doesn't compile. My class module is named cMsgBoxes. I don't know where to go from here:
Option Explicit
Public strTitle As Variant
Public strcmd1 As Variant
Public strcmd2 As Variant
Public strcmd3 As Variant
Public strcmd4 As Variant
Public strMsgBox As Variant
Public Property Let Title(strTitle As String)
Title = strTitle
End Property
Public Property Let Command1(strcmd1 As String)
Command1 = strcmd1
End Property
Public Property Let Command2(strcmd2 As String)
Command2 = strcmd2
End Property
Public Property Let Command3(strcmd3 As String)
Command3 = strcmd3
End Property
Public Property Let Command4(strcmd4 As String)
Command4 = strcmd4
End Property
Function MsgBox4Button(strTitle As String, strcmd1 As String, Optional strcmd2 As String, Optional strcmd3 As String, Optional strcmd4 As String)
Load frmMsgBox4Button
MsgBox4Button = strMsgBox
End Property
My Form Code:
Option Explicit
Private Sub cmd1_Click()
cMsgBoxes.strMsgBox = Me.cmd1.Caption
Unload Me.Name
End Sub
Private Sub cmd2_Click()
cMsgBoxes.strMsgBox = Me.cmd2.Caption
Unload Me.Name
End Sub
Private Sub cmd3_Click()
cMsgBoxes.strMsgBox = Me.cmd3.Caption
Unload Me.Name
End Sub
Private Sub cmd4_Click()
cMsgBoxes.strMsgBox = Me.cmd4.Caption
Unload Me.Name
End Sub
Private Sub Form_Load()
Me.Caption = strTitle
Me.cmd1.Caption = Trim(strcmd1)
Me.cmd2.Caption = Trim(strcmd2)
Me.cmd3.Caption = Trim(strcmd3)
Me.cmd4.Caption = Trim(strcmd4)
If Nz(Me.cmd1.Caption, "") = "" Then
Me.cmd1.Visible = False
Unload Me.Name
End If
If Nz(Me.cmd2.Caption, "") = "" Then Me.cmd2.Visible = False
If Nz(Me.cmd3.Caption, "") = "" Then Me.cmd3.Visible = False
If Nz(Me.cmd4.Caption, "") = "" Then Me.cmd4.Visible = False
End Sub
Private Function Nz(strValue As Variant, strChangeTo As String) As String
If Not IsNull(strChangeTo) Then
If strValue = Null Then strValue = strChangeTo
End If
End Function
ASKER CERTIFIED SOLUTION
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.

>The variables in the class module didn't have to be declared at the top of the module as public. Is that normal?
Not sure I understand. The one public variable is at the top (before any routines) and it is public. And this is not only normal it must be done this way. Private module or class level variables also have to be at the top before any routines.
>We were able to change some of the properties of the form before actually showing the form. This seems kind of strange to me too.
Think of a form as an automatically instanced class. As soon as you reference the form or any of it's properties VB instantiates it but keeps it hidden. There are two ways to close a form: unload and hide. Unload destroys the class instance and any variables. Hide just hides the window but keeps the class instance in memory.
>As soon as the form is unloaded, the dll is no longer in use?
The form and the DLL are two different objects. The DLL owns the form so if you destroy the DLL instance the form will also be destroyed. But destroying the form instance does not destroy the DLL instance. Excel most likely keeps an instance of the DLL around as long as the workbook is open.
>I did have to change the form to modal
The default is vbModal. You only need to specify the parameter when you want a modeless form.
Kevin
Not sure I understand. The one public variable is at the top (before any routines) and it is public. And this is not only normal it must be done this way. Private module or class level variables also have to be at the top before any routines.
>We were able to change some of the properties of the form before actually showing the form. This seems kind of strange to me too.
Think of a form as an automatically instanced class. As soon as you reference the form or any of it's properties VB instantiates it but keeps it hidden. There are two ways to close a form: unload and hide. Unload destroys the class instance and any variables. Hide just hides the window but keeps the class instance in memory.
>As soon as the form is unloaded, the dll is no longer in use?
The form and the DLL are two different objects. The DLL owns the form so if you destroy the DLL instance the form will also be destroyed. But destroying the form instance does not destroy the DLL instance. Excel most likely keeps an instance of the DLL around as long as the workbook is open.
>I did have to change the form to modal
The default is vbModal. You only need to specify the parameter when you want a modeless form.
Kevin

ASKER
>>The variables in the class module didn't have to be declared at the top of the module as public. Is that normal?
>Not sure I understand. The one public variable is at the top (before any routines) and it is public. And this is not only >normal it must be done this way. Private module or class level variables also have to be at the top before any routines.
Notice that the class module doesn't declare public variables for those variables that are used in the function. I've seen some examples that show that those variables must be declared publicly at the top of the class module, and once again in the function.
>>I did have to change the form to modal
>The default is vbModal. You only need to specify the parameter when you want a modeless form.
I beg to differ. My dll failed to work. It returned an error that the form couldn't be used because it wasn't modal. And I didn't specify any state for the form to open in. After specifying modal, everything worked fine.
Looking at your answer, I'm not sure how the function knows when to hand back the value of Response. It would appear to me that execution of code continues after the form has been hidden. Otherwise this function would hand back an empty string value before my form even gets clicked on. It would also appear to me that the instance of the dll ends (or shall we say the function comes to an end) after we unload frmMsgBox4Button.
frmMsgBox4Button.Show 1 'Code execution is suspended until form gets hidden or unloaded???
MsgBox4Button = frmMsgBox4Button.Response 'Value of Response is retrieved from hidden form???
Unload frmMsgBox4Button 'Function is completed and the dll is no longer in use after this line???
>Not sure I understand. The one public variable is at the top (before any routines) and it is public. And this is not only >normal it must be done this way. Private module or class level variables also have to be at the top before any routines.
Notice that the class module doesn't declare public variables for those variables that are used in the function. I've seen some examples that show that those variables must be declared publicly at the top of the class module, and once again in the function.
>>I did have to change the form to modal
>The default is vbModal. You only need to specify the parameter when you want a modeless form.
I beg to differ. My dll failed to work. It returned an error that the form couldn't be used because it wasn't modal. And I didn't specify any state for the form to open in. After specifying modal, everything worked fine.
Looking at your answer, I'm not sure how the function knows when to hand back the value of Response. It would appear to me that execution of code continues after the form has been hidden. Otherwise this function would hand back an empty string value before my form even gets clicked on. It would also appear to me that the instance of the dll ends (or shall we say the function comes to an end) after we unload frmMsgBox4Button.
frmMsgBox4Button.Show 1 'Code execution is suspended until form gets hidden or unloaded???
MsgBox4Button = frmMsgBox4Button.Response 'Value of Response is retrieved from hidden form???
Unload frmMsgBox4Button 'Function is completed and the dll is no longer in use after this line???

>Notice that the class module doesn't declare public variables for those variables that are used in the function. I've seen some examples that show that those variables must be declared publicly at the top of the class module, and once again in the function.
I don't follow. There is only one variable declared in the entire module:
Public Response As String
And it is a public variable. What do you think are variables that are declared but not at the top of the module?
>I beg to differ. My dll failed to work. It returned an error that the form couldn't be used because it wasn't modal. And I didn't specify any state for the form to open in. After specifying modal, everything worked fine.
Very strange indeed. If you open the help file for Excel VBA or VB and look at the Show method you will see that the default is vbModal and that's how we use that parameter. In any event, it's always better to be specific.
>It would appear to me that execution of code continues after the form has been hidden.
Execution is synchronous when a modal form is displayed. This means that, while the form is visible, the routine MsgBox4Button halts until the form is hidden or unloaded.
Kevin
I don't follow. There is only one variable declared in the entire module:
Public Response As String
And it is a public variable. What do you think are variables that are declared but not at the top of the module?
>I beg to differ. My dll failed to work. It returned an error that the form couldn't be used because it wasn't modal. And I didn't specify any state for the form to open in. After specifying modal, everything worked fine.
Very strange indeed. If you open the help file for Excel VBA or VB and look at the Show method you will see that the default is vbModal and that's how we use that parameter. In any event, it's always better to be specific.
>It would appear to me that execution of code continues after the form has been hidden.
Execution is synchronous when a modal form is displayed. This means that, while the form is visible, the routine MsgBox4Button halts until the form is hidden or unloaded.
Kevin

>Code execution is suspended until form gets hidden or unloaded???
Yes.
>Value of Response is retrieved from hidden form???
Yes.
>Function is completed and the dll is no longer in use after this line???
Sort of. The user form is destroyed but the DLL instance may still be around.
Kevin
Yes.
>Value of Response is retrieved from hidden form???
Yes.
>Function is completed and the dll is no longer in use after this line???
Sort of. The user form is destroyed but the DLL instance may still be around.
Kevin

ASKER
Sorry you are having so much trouble understanding me. Here's how some examples on the web show, concerning the variables:
Option Explicit
Public strTitle as String
Public strcmd1 As String
Public strcmd2 As String
Public strcmd3 As String
Public strcmd4 As String
Public Function MsgBox4Button(strTitle As String, strcmd1 As String, Optional strcmd2 As String, Optional strcmd3 As String, Optional strcmd4 As String) As String
Option Explicit
Public strTitle as String
Public strcmd1 As String
Public strcmd2 As String
Public strcmd3 As String
Public strcmd4 As String
Public Function MsgBox4Button(strTitle As String, strcmd1 As String, Optional strcmd2 As String, Optional strcmd3 As String, Optional strcmd4 As String) As String

ASKER
>What do you think are variables that are declared but not at the top of the module?
I suspect they are variables that only exist for the scope of the function. As to being local or public? I thought they are local only.
Please Review:
http://www.tutorial-web.com/asp/dll/
I suspect they are variables that only exist for the scope of the function. As to being local or public? I thought they are local only.
Please Review:
http://www.tutorial-web.com/asp/dll/

Not sure where those came from. The only variables you need are the ones defined in the routine definition:
Public Function MsgBox4Button(strTitle As String, strcmd1 As String, Optional strcmd2 As String = " ", Optional strcmd3 As String = " ", Optional strcmd4 As String = " ") As String
And the routine should be in a regular module, not a class module.
The code I posted is all you need to make the solution work.
Kevin
Public Function MsgBox4Button(strTitle As String, strcmd1 As String, Optional strcmd2 As String = " ", Optional strcmd3 As String = " ", Optional strcmd4 As String = " ") As String
And the routine should be in a regular module, not a class module.
The code I posted is all you need to make the solution work.
Kevin
ASKER
The variables in the class module didn't have to be declared at the top of the module as public. Is that normal?
We were able to change some of the properties of the form before actually showing the form. This seems kind of strange to me too.
As soon as the form is unloaded, the dll is no longer in use?
I did have to change the form to modal, correct a typo in the class module, and set the button visible properties in the class module. Please refer to the new code I've pasted below.
cMsgBoxes Class Module Code:
Option Explicit
Public Function MsgBox4Button(strTitle As String, strcmd1 As String, Optional strcmd2 As String = " ", Optional strcmd3 As String = " ", Optional strcmd4 As String = " ") As String
With frmMsgBox4Button
.Caption = strTitle
.cmd1.Caption = strcmd1
.cmd2.Caption = strcmd2
.cmd3.Caption = strcmd3
.cmd4.Caption = strcmd4
If Trim(.cmd2.Caption) = "" Then .cmd2.Visible = False
If Trim(.cmd3.Caption) = "" Then .cmd3.Visible = False
If Trim(.cmd4.Caption) = "" Then .cmd4.Visible = False
End With
frmMsgBox4Button.Show 1
MsgBox4Button = frmMsgBox4Button.Response
Unload frmMsgBox4Button
End Function
frmMsgBox4Button Form Module Code:
Option Explicit
Public Response As String
Private Sub cmd1_Click()
Response = cmd1.Caption
Me.Hide
End Sub
Private Sub cmd2_Click()
Response = cmd2.Caption
Me.Hide
End Sub
Private Sub cmd3_Click()
Response = cmd3.Caption
Me.Hide
End Sub
Private Sub cmd4_Click()
Response = cmd4.Caption
Me.Hide
End Sub
For future reference of anyone else trying to do what I'm doing here, here's how I'm using this dll. I just keep it in the directory of my .exe or my VBScript file. No need to register this dll if you do that. I've compiled the project with the project name "MsgBoxes" and named the dll "MsgBoxes.dll". In my code I use late binding:
VBScript:
Dim objMsgBox, MyMsgBox
Set objMsgBox = CreateObject("MsgBoxes.cMs
MyMsgBox = objMsgBox.MsgBox4Button("W
MsgBox MyMsgBox
Set objMsgBox = Nothing