?
Solved

Communicating between Module and Class Module

Posted on 2003-03-31
10
Medium Priority
?
240 Views
Last Modified: 2010-04-07

Hi

I have a DLL project that has a module and a class module.
For some reason, I cannot call the class module functions
from the module.

1.  Why is this?
2.  Any suggested work-arounds?

Reasons for doing this:
I would like the class to raise an event - something I cannot do from
the regular module (right?).  Some of the code in the module CANNOT
exist in a class module because it uses the AddressOf function.  So
I have to go back and forth between the two with the functionality.

Bob
0
Comment
Question by:BobsExEx
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
10 Comments
 
LVL 10

Expert Comment

by:aeklund
ID: 8239755
1. You cannot call a function within a class unless you create the object:
 dim o as new Class1
 o.Function

2. I just did the same thing, here is how I did it..

In your module declare a module level variable of your class: Public m_oClass as Class1

In your class Initialize Event set that public module variable to the same instance of the class:
Private Sub Class1_Initialize()
  Set m_oClass = Me
End Sub

In your class Terminate Event set that public module variable to nothing to clean up the resources
Private Sub Class1_Terminate()
  Set m_oClass = Nothing
End Sub

Now, the call... In your module you can now call any public property, sub, function in your class: Call m_oClass1.Function

To hide the sub/function from out of process application, declare it with the Friend keyword: Friend Sub MyFunction()

Hope that helps...
0
 
LVL 10

Expert Comment

by:aeklund
ID: 8239824
Here is a working example of the above:

'module code:
Option Explicit

Public m_oObject As Class1

Public Sub CallBackFunction()
  Call m_oObject.DoSomething
End Sub

'class code: (name=Class1)
Option Explicit

Private Sub Class_Initialize()
  Set m_oObject = Me
End Sub

Private Sub Class_Terminate()
  Set m_oObject = Nothing
End Sub

Friend Sub DoSomething()
  Msgbox "It worked!"
End Sub
0
 

Author Comment

by:BobsExEx
ID: 8239884
Interesting idea.  I have already put in what you said and it is similar to your later message.

However, everytime I try to run it (by starting the app, then switching to another app so that a WM Message comes through), the entire IDE crashes without a message or anything.

When I comment out the call to the class sub, then the IDE doesn't crash (even keeping all declarations and "set"s the same).  I have error handling in there but it doesn't even get to that point.

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:BobsExEx
ID: 8239892
Interesting idea.  I have already put in what you said and it is similar to your later message.

However, everytime I try to run it (by starting the app, then switching to another app so that a WM Message comes through), the entire IDE crashes without a message or anything.

When I comment out the call to the class sub, then the IDE doesn't crash (even keeping all declarations and "set"s the same).  I have error handling in there but it doesn't even get to that point.

0
 
LVL 10

Accepted Solution

by:
aeklund earned 2000 total points
ID: 8240144
Are you sure all your variables are declared correctly?  When working with windows hooks and callbacks, everyting must be correct for it to work... I created a similar project to yours and hooked to a window and waiting for a WM_ACTIVATE message...

'module code:
Option Explicit

Public m_oClass1 As Class1
Public Const GWL_WNDPROC  As Long = (-4)
Private Const WM_PASTE = &H302
Private Const WM_VSCROLL = &H115
Private Const WM_ACTIVATE = &H6

Public Declare Function CallWindowProc Lib "user32" _
   Alias "CallWindowProcA" _
  (ByVal lpPrevWndFunc As Long, _
   ByVal hWnd As Long, _
   ByVal msg As Long, _
   ByVal wParam As Long, _
   ByVal lParam As Long) As Long

Public Declare Function SetWindowLong Lib "user32" _
   Alias "SetWindowLongA" _
  (ByVal hWnd As Long, _
   ByVal nIndex As Long, _
   ByVal wNewWord As Long) As Long

Public hOldWindow As Long

Public Function WindowProc(ByVal hWnd As Long, _
                           ByVal uMsg As Long, _
                           ByVal wParam As Long, _
                           ByVal lParam As Long) As Long
 
  'Debug.Print uMsg
  Select Case uMsg
    Case WM_ACTIVATE
      m_oClass1.DoSomething
     
  End Select
   
  'Pass along to default window procedure.
  WindowProc = CallWindowProc(hOldWindow, hWnd, uMsg, wParam, lParam)
End Function

'class code (Class1)
Option Explicit

Private hHookedWindow As Long

Public Sub HookWindow(hWnd As Long)
  hHookedWindow = hWnd
  hOldWindow = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Friend Function DoSomething() As Long
  Debug.Print "Did Something"
  'You will only see this if you add both dll and exe projects in the same ide project as a group project
 
End Function
Private Sub Class_Initialize()
  Set m_oClass1 = Me
End Sub

Private Sub Class_Terminate()
  Call SetWindowLong(hHookedWindow, GWL_WNDPROC, hOldWindow)
  Set m_oClass1 = Nothing
End Sub


'out-of-process form code (make sure you have reference to Class1)
Option Explicit

Dim o As Class1

Private Sub Form_Load()
  Set o = New Class1
  o.HookWindow Me.hWnd
 
End Sub

Private Sub Form_Unload(Cancel As Integer)
  Set o = Nothing
End Sub


You cannot put a msgbox in the DoSomething code, it will crash since you would essentially be stopping window messages from getting through and halting on a msgbox.
0
 

Author Comment

by:BobsExEx
ID: 8240218
aeklund

Yeah, I had replaced the msgbox with a debug.print just in case.

I am going to play around with it some more and I will get back to you.

0
 

Author Comment

by:BobsExEx
ID: 8240464
You get the prize, bro.

I appreciate your work on this so I threw an extra 250 pts on.  I don't think I would have figured that out.

It still runs with some instability but I think it has to do with my running in the IDE and breaking out before messages are processed correctly.

Thanks
0
 

Author Comment

by:BobsExEx
ID: 8240468
oh - I can't add award more than 500 per question...

Thanks again.
0
 

Author Comment

by:BobsExEx
ID: 8240469
Very nice.  Tough stuff.

Bob
0
 
LVL 10

Expert Comment

by:aeklund
ID: 8241091
Glad to help.  Thanks for the points...  I was stuck on a similar problem and took me some time to figure it out, but this is how I did it and it works like a charm.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
This article describes how to use a set of graphical playing cards to create a Draw Poker game in Excel or VB6.
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question