Announcement

Collapse
No announcement yet.

notifications from COM servers to user interfaces

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • notifications from COM servers to user interfaces

    How do you create a client interface to receive events from a COM server? I'm thinking particularly of the MSXML2 library which includes the IVBSAXXMLReader interface which sends notifications to the IVBSAXErrorhandler object (this is the one I need to create). There's an "old school" solution in post #20 of this thread but I'm aiming at a version which avoids magic numbers, etc - that was the only option when Jose Roca wrrote the wrappers in 2004!

    Is it necessary to declare the interface prototypes? This fans out into a lot of declarations when interfaces are passed as parameters. Is parameter type checking applied to uncalled methods/properties at run time? If not, can the interface parameters to these calls be redefined as dwords to avoid cascading ddeclarations? Can unreferenced methods/parameters be left out? Example:
    Code:
    ' Interface Name  : IVBSAXXMLReader
    ' Description     : IVBSAXXMLReader interface
    ' Class Name      : SAXXMLReader40
    ' ClassID         : $CLSID_MSXML2_SAXXMLReader40
    ' ProgID          : $PROGID_MSXML2_SAXXMLReader30
    ' Version ProgID  : $PROGID_MSXML2_SAXXMLReader400
    Interface IVBSAXXMLReader $IID_MSXML2_IVBSAXXMLReader 
        Inherit IDispatch
    
        Method getFeature <1282> (Byval strName As WString) As Integer
        Method putFeature <1283> (Byval strName As WString, Byval fValue As Integer)
        Method getProperty <1284> (Byval strName As WString) As Variant
        Method putProperty <1285> (Byval strName As WString, Byval varValue As Variant)
        Property Get entityResolver <1286> () As IVBSAXEntityResolver
        Property Set PutRef_entityResolver <1286> (ByVal oResolver As IVBSAXEntityResolver)
        Property Get contentHandler <1287> () As IVBSAXContentHandler
        Property Set PutRef_contentHandler <1287> (ByVal oHandler As IVBSAXContentHandler)
        Property Get dtdHandler <1288> () As IVBSAXDTDHandler
        Property Set PutRef_dtdHandler <1288> (ByVal oHandler As IVBSAXDTDHandler)
        Property Get errorHandler <1289> () As IVBSAXErrorHandler
        Property Set PutRef_errorHandler <1289> (ByVal oHandler As IVBSAXErrorHandler)
        Property Get baseURL <1290> () As WString
        Property Set baseURL <1290> (ByVal strBaseURL As WString)
        Property Get secureBaseURL <1291> () As WString
        Property Set secureBaseURL <1291> (ByVal strSecureBaseURL As WString)
        Method parse <1292> (Byval varInput As Variant)
        Method parseURL <1293> (Byval strURL As WString)
    End Interface
    Any donations gratefully received.

  • #2
    It's quite easy...

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE ONCE "windows.inc"
    #INCLUDE ONCE "msxml.inc"
    
    CLASS CIVBSAXErrorHandler COMMON
    
    ' ########################################################################################
    ' Interface name = IVBSAXErrorHandler
    ' IID = {D963D3FE-173C-4862-9095-B92F66995F52}
    ' IVBSAXErrorHandler interface
    ' Attributes = 4288 [&H000010C0] [Dual] [Nonextensible] [Dispatchable]
    ' Inherited interface = IDispatch
    ' ########################################################################################
    
    INTERFACE IVBSAXErrorHandlerImpl $IID_IVBSAXErrorHandler
    
       INHERIT IDispatch
    
       ' =====================================================================================
       METHOD error <1339> ( _                              ' VTable offset = 28
         BYVAL oLocator AS IVBSAXLocator _                  ' [in] *oLocator IVBSAXLocator <dispinterface>
       , BYREF strErrorMessage AS WSTRING _                 ' [in][out] *strErrorMessage VT_BSTR
       , BYVAL nErrorCode AS LONG _                         ' [in] nErrorCode VT_I4 <Long>
       )                                                    ' void
    
       OutputDebugString FUNCNAME$
    
       END METHOD
       ' =====================================================================================
       METHOD fatalError <1340> ( _                         ' VTable offset = 32
         BYVAL oLocator AS IVBSAXLocator _                  ' [in] *oLocator IVBSAXLocator <dispinterface>
       , BYREF strErrorMessage AS WSTRING _                 ' [in][out] *strErrorMessage VT_BSTR
       , BYVAL nErrorCode AS LONG _                         ' [in] nErrorCode VT_I4 <Long>
       )                                                    ' void
    
       OutputDebugString FUNCNAME$
    
       END METHOD
       ' =====================================================================================
       METHOD ignorableWarning <1341> ( _                   ' VTable offset = 36
         BYVAL oLocator AS IVBSAXLocator _                  ' [in] *oLocator IVBSAXLocator <dispinterface>
       , BYREF strErrorMessage AS WSTRING _                 ' [in][out] *strErrorMessage VT_BSTR
       , BYVAL nErrorCode AS LONG _                         ' [in] nErrorCode VT_I4 <Long>
       )                                                    ' void
    
       OutputDebugString FUNCNAME$
    
       END METHOD
       ' =====================================================================================
    
    END INTERFACE
    
    END CLASS
    
    ' ########################################################################################
    ' Main
    ' ########################################################################################
    FUNCTION PBMAIN () AS LONG
    
       LOCAL pReader AS IVBSAXXMLReader
       pReader = NEWCOM "Msxml2.SAXXMLReader.6.0"
       
       ' =======================================================================
       ' Register a ErrorHandler dispatch interface
       ' =======================================================================
       LOCAL pErrorHandler AS IVBSAXErrorHandlerImpl
       pErrorHandler = CLASS "CIVBSAXErrorHandler"
       pReader.putref_errorHandler = pErrorHandler
    
       ' =======================================================================
       ' Parse the document
       ' =======================================================================
       pReader.parse "<a>bad xml<a>"  '<-- change as needed
    
       ' =======================================================================
       ' Release the SAX reader
       ' =======================================================================
       pReader = NOTHING
    
    END FUNCTION
    Don't forget the COMMON in CLASS CIVBSAXErrorHandler COMMON or the compiler will remove the methods since nobody is calling them directly.
    Forum: http://www.jose.it-berater.org/smfforum/index.php

    Comment


    • #3
      I have MSXML 6.0 installed. I you have 4.0 use
      pReader = NEWCOM "Msxml2.SAXXMLReader.4.0"
      Forum: http://www.jose.it-berater.org/smfforum/index.php

      Comment


      • #4
        Is it necessary to declare the interface prototypes?
        Yes.

        Is parameter type checking applied to uncalled methods/properties at run time? If not, can the interface parameters to these calls be redefined as dwords to avoid cascading ddeclarations?
        You can use AS IDispatch or AS IUnknown.

        Can unreferenced methods/parameters be left out?
        No.
        Forum: http://www.jose.it-berater.org/smfforum/index.php

        Comment


        • #5
          Originally posted by José Roca View Post
          It's quite easy...
          ... if you know how.

          The COMMON qualifier, which I had completely overlooked (it is a V10 feature) is essential for notifications in OPTIMIZEd code because as you say, none of the methods is called by the code under compilation, they are called by the reader object (IVBSAXXMLReader here). I will drop a line to PowerBASIC Inc suggesting that they add a note to the documentation.

          Thanks José!

          Comment

          Working...
          X