Link to home
Start Free TrialLog in
Avatar of Random_Dent
Random_Dent

asked on

Problem with RaiseEvent/WithEvents in VB6 ActiveX dll

I am having issues either raising an event or identifying the raised event in VB6.  I really don't know why this isn't working.

I have a Project Group set up, with an exe project calling a function in the dll.  It passes all of the information to the dll and processes correctly straight up to and including the RaiseEvent line.  I have a WithEvents in the Exe that should display a messagebox when the event is captured.  I'm not sure whether the RaiseEvent isn't working or whether the WithEvents isn't working.  I believe the issue is with the raised event because another customer can't catch the event either with their code.  Is there something I'm missing in the code?  Is there an easier way to troubleshoot this?

Here is the snippet of code in the Exe that passes a request to the ActiveX dll, which works:

Private Sub Command1_Click()
    Dim obj As clsTestDirect
    Set obj = New clsTestDirect
   
    Result = obj.TestRequest(arrRequest, strFlags)
End Sub

Here is the code inside the class in the ActiveX Dll that is being called and should raise the event:


Public Event Navigate(ScreenID, arrData)



Function TestRequest(arrRequest, strFlags)

   ' This Function is getting called
   ' The code does a bunch of validating, logging,
   ' and processing and eventually proceeds to the
   ' RaiseEvent line

   ' ..... [code] .....

   RaiseEvent Navigate(PageID, arrData)

End Function



Here is the code inside the Exe to try to handle the event, which is never executed:


Private WithEvents GetProgress As clsTestDirect

Private Sub Form_Load()
    Set GetProgress = New clsTestDirect
End Sub

Private Sub GetProgress_Navigate(PageID, arrData)
    MsgBox "PageID:" & PageID
End Sub



I also tried putting the WithEvent stuff in a class inside the Exe

Private WithEvents GetProgress As clsTestDirect

Private Sub Class_Initialize()
    Set GetProgress = New clsTestDirect
End Sub

Private Sub GetProgress_Navigate(PageID, arrData)
    MsgBox "PageID:" & PageID
End Sub
Avatar of Dana Seaman
Dana Seaman
Flag of Brazil image

Try adding this code to ActiveX Dll.

MsgBox "Before RaiseEvent Navigate"
RaiseEvent Navigate(PageID, arrData)
MsgBox "After RaiseEvent Navigate"

What is Instancing Property of your ActiveX Class.
5-Multiuse?
Avatar of Random_Dent
Random_Dent

ASKER

Both MessageBoxes display fine when I test.

The Instancing is indeed set to 5 - MultiUse
Do you have On Error Resume Next or similar in Function TestRequest?
Perhaps you could add an Error handler to see if there is an error with PageID or arrData.
There is no Resume Next on.  If I were to change the "Navigate" event name to "Navigates", it does error.  PageID is a string that I am setting, and arrData is a valid name/value pair array that I am building right before I call the RaiseEvent.  To verify, I implemented the following code:

MsgBox "Before Raise:" & arrData(0) & PageID
            RaiseEvent Navigate(PageID, arrData)
MsgBox "After Raise"

The messagebox properly shows my first name/value pair ("RequestDateTime") and the string I am passing in PageID.

I've never used events prior to this.  For all I know the event could be raising correctly, but I'm not catching it properly using the With Events code...
SOLUTION
Avatar of EDDYKT
EDDYKT
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
EDDYKT,

That worked but I'm not quite sure it is what I need.  The problem is that user 1 (me) makes a call to the dll with to raise an event.  A 3rd party program is supposed to be listening for that event to be raised and execute a process when the raised event is detected (with the data provided in the raised event).  The 3rd party program isn't seeing the event being raised.
who make that dll?
you?

you have to post some code at least.

I have no clue why it's not working.
I am writing the DLL.  A 3rd party program will call the registered dll's "TestRequest" function and pass two parameters in, an array with data and a flags string to allow testing and logging functions.  The dll will do a bunch of code and will culminate with raising the "Navigate" public event.  A different 3rd party program should be listening for that flagged event to process the data array and screen information to display the appropriate data in a LOB application.  The only way I can see the raised event is if my test application is both firing the TestRequest and listening for the response (via your helpful suggestion of this:

Private Sub Command1_Click()
    GetProgress.TestRequest "1", "2"
End Sub

It does properly raise the event, but it doesn't seem to be doing it so another party can monitor for it.

Thank you very much for your help so far.  It seems like I'm so close...

Here is a cleaned version of all of the code (with the exception of the logging function I call):


Public Event Navigate(ScreenID, arrData)

Public Function TestRequest(arrRequest, strFlags)

    Result = lib_FileLogEvent(g_ShowMessages, g_LogMessages, "TestRequest", "Initializing TestRequest")
   
    If Not IsArray(arrPFFWScreenRequest) Then
        Result = lib_FileLogEvent(g_ShowMessages, g_LogMessages, "TestRequest", "Request is not an array")
        TestRequest = "-2" ' Invalid Request Array
        Exit Function
    End If
       
    Dim arrCount, arrParameter
    For arrCount = 0 To UBound((arrRequest)
        arrParameter = Split((arrRequest(arrCount), "==")
        If UBound(arrParameter) = 1 Then
            Select Case arrParameter(0)
               Case "Order Number"
                    strOrderNumber = Trim(arrParameter(1))
               Case "Customer Name"
                    strCustomerName = Trim(arrParameter(1))
               Case "Customer Number"
                    strCustomerNumber = Trim(arrParameter(1))              
               Case "LOB App Screen"
                    strScreenID = Trim(arrParameter(1))              
            End Select
        End If
    Next

    If Len(strScreenID) = 0 Then
        Result = lib_FileLogEvent(g_ShowMessages, g_LogMessages, "TestRequest", "LOB Screen ID Not Specified")
        TestRequest = "-4" ' Missing Screen ID
        Exit Function
    End If
   
    Select Case strScreenID
        Case "CustomerOrder"
            Dim strData, arrData
            strData = "RequestDateTime==" & Now() & "||" & _
                        "OrderNumber ==" & strOrderNumber & "||" & _
                        "CustomerNumber==" & strCustomerNumber & "||" & _
                        "CustomerName==" & strCustomerName
            arrData = Split(strData, "||")
            Result = lib_FileLogEvent(g_ShowMessages, g_LogMessages, "TestRequest", "Before Raise Event")
            RaiseEvent Navigate(strScreenID, arrData)
            Result = lib_FileLogEvent(g_ShowMessages, g_LogMessages, "TestRequest", "Event Raised")
            TestRequest = "0"
        Case Else
            Result = lib_FileLogEvent(g_ShowMessages, g_LogMessages, "TestRequest", "Screen ID Not Implemented")
            TestRequest= "-5" ' Screen ID not Implemented
            Exit Function
    End Select

End Function

           
can you see it if you write a simple vb application and trap for the Navigate event?

If you do, then it's 3 rd party app's problem

also if it goes into this checking, then no event is fired back. Are you sure it is not inside the if check case?

If Len(strScreenID) = 0 Then
        Result = lib_FileLogEvent(g_ShowMessages, g_LogMessages, "TestRequest", "LOB Screen ID Not Specified")
        TestRequest = "-4" ' Missing Screen ID
        Exit Function
    End If

Also


Case Else
            Result = lib_FileLogEvent(g_ShowMessages, g_LogMessages, "TestRequest", "Screen ID Not Implemented")
            TestRequest= "-5" ' Screen ID not Implemented
            Exit Function

Each instance of the class (i.e. Set GetProgress = New clsTestDirect) is independant so when the 3rd party creates his instance to the DLL class it has no relation to whatever you are doing with your local instance. Calling GetProgress.TestRequest will raise event on your machine but will have no effect on the instance the 3rd party is running and events will never be seen.

If each instance of the class is truly independant, is there a way to broadcast an event (or other method of passing the data) within the computer session?

To really muck things up, this dll will reside on a terminal server.  There will be multiple Application 1s connecting to the same dll to raise an event (or pass data in some way) to multiple Application 2s.  We need the data from App1 to be shared through the dll only to the App2 that is under the same user session.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial