[AccessD] Interface Callback Class Questions.

Robert Gracie Subscriptions at servicexp.com
Thu Jan 29 20:17:19 CST 2004


Ken,
 Thanks A Million!!

 Yep the report did not have module....:-), and that solved the
problem...

 How in the world do I sink the OnPrint, or OnFormat events...  

with
 mrRpt.Section(acDetail).OnPrint = pcsEventStub

I think I have tried every possible stub, and it seems like it's just
ignored....

Thanks Again!!
Robert Gracie



-----Original Message-----
From: accessd-bounces at databaseadvisors.com
[mailto:accessd-bounces at databaseadvisors.com] On Behalf Of Ken Ismert
Sent: Thursday, January 29, 2004 1:15 PM
To: 'Access Developers discussion and problem solving'
Subject: RE: [AccessD] Interface Callback Class Questions.



Robert,

> The report fires, however none of the events (Close) are being hooked.

The only thing I can think of here is that the Report must have a module
for a class to hook its events. Double-check that 'Has Module' is Yes in
report properties. The module can be blank.

> I can run the report once, any attempt to run the report again fails 
> on "RemoteReportClose mrRpt.Name" ERROR Number 2467....... Object or 
> property... either does not exist or is closed......

I think that if you can hook the Close event, this problem will go away.
CReportHost relies on the Close event to set it's mrRpt reference to
Nothing. If the close event fails, you get a dangling reference - mrRpt
is pointing to an object that has shutdown, and won't respond to further
native property or method requests. It is important to note that the
Report object is still in memory, because it still has one reference,
mrRpt, keeping it alive.

This does suggest adding a failsafe to the CReportHost.CloseRemoteReport
method:

Public Sub CloseRemoteReport()
    On Error GoTo HandleErr
    ' Close Report if Open
    If mrRpt Is Nothing Then Exit Sub
    ' Fires mrRpt_Close
    RemoteReportClose mrRpt.Name
    Exit Sub
HandleErr:
    Select Case Err.Number
    Case 2467   ' Object or Property doesn't exist or is closed
        ' User closed Report, but mrRpt_Close event failed:
        ' Release reference to allow the Report to terminate
        Set mrRpt = Nothing
    Case Else
        Err.Raise Number:=Err.Number, _
            Description:=Err.Description, _
            Source:="CReportHost.CloseRemoteReport" & vbCrLf &
Err.Source
    End Select
    Exit Sub
End Sub

> Do I need to hook the opening report to the events in the CReportHost 
> class internally of the opening report, such as on the OnOpen event? 
> I'm new to the "DEEP" Programming method so I could be way off 
> base.....

One way to look at this is that Events are a 'pull' mechanism. In other
words, declaring an object WithEvents means that you are receiving
events from that object, with no setup on that object's side required.
The COM object framework handles the detials of making sure all
subscribers get the events they signed up for. This is completely
transparent to the object generating the events. What's more, there is
no way in VB6 to tell within an object, say a Report, that other objects
are sinking it's events, AFAIK.

(An aside: since Reports and Forms are not 'standard' COM objects, you
have to go through the trouble of hooking their events. This isn't
entirely bad, as it does allow you to selectively enable/disable events
at runtime, if you so need.)

So, the short answer is, for traditional events, you don't hook events
in the object that generates them.

However, if you choose to use interfaces, you can implement a 'push'
style callback mechanism. In this case, lets say an object, O, wants to
receive 'events'(or more correctly, callbacks) from another object, P. O
would present itself to P, usually through a subscribe call, like:
    ' Code within O
    rP.Init Me   ' Send reference to myself to P
P, when it wants to call back O, would do something like:
    ' Code within P
    rO.Method    ' Some method defined in an interface
                 ' implemented by O
Of course, O has to unsubscribe when it shuts down:
    ' Code within O
    rP.Term Me   ' P sets rO to nothing, allowing
                 ' O to terminate
Interface callbacks, from O's perspective, look and act very much like
events, except that explicit setup and shutdown are required. From P's
perspective, events and callbacks are very different. Events are
internally defined in P, and raised using RaiseEvent. Callbacks are done
using methods of an externally defined interface, with an object
supplied to P at runtime.

Anyway, thanks for your flattering words, and I hope this helps.

-Ken

_______________________________________________
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