• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

Multiple instances of Typelib interfaces?

Started by Stuart Alexander, January 29, 2019, 04:25:17 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Stuart Alexander

Hello all,

I am a newbie to PB however do have programming experience (C/C++/C#/Python etc.) and I am enjoying the change of scene
(in fact it makes me nostalgic for the 80's and my first programming steps with my Acorn BBC Computer (6502 8bit processor).
I'm glad to see BASIC is still evolving..

Anyway, my task is interfacing some AXIS Cameras into a PB system using Typelib 5.0.1 (thanks Jose) against their AzisMediaControl SDK.
I have managed to configure the camera properties and display their output in my application by initialising multiple camera instances
against the single interface INC file. My problem is with events where I want to know which camera originated the event e.g. error or status change and that information isn't coming back into my application, just that an event of a certain type happened [edited for clarity].

A clunky fix I thought would be to duplicate and rename the Interface and Events Typelib files but then PB warns of duplicate GUIDs which
I'm not very familiar with and just incrementing the GUID in my duplicate interface files seems to deeply break my application..if not my PC.
I include some of what Typelib generated:

Any suggestions welcome!
thanks,
Stuart


ControlLib interface:
' ########################################################################################
' Library name: AXISMEDIACONTROLLib
' Version: 1.0, Locale ID = 0
' Description: AxisMediaControl 1.0 Type Library
' Path: C:\Program Files\Axis Communications\Components\AxisMediaControl.dll
' Library GUID: {A48F4EE0-B408-4376-B4C9-BC9CF6E16EBC}
' Code generated by the TypeLib Browser 5.0.1 (c) 2011 by José Roca
' Date: 22 Dec 2017   Time: 00:49:10
' Options used to generate the code:
' - Use METHOD and PROPERTY GET/SET statements
' - Add prefix in parameter names
' ########################################################################################

' ========================================================================================
' CoClass name: AxisMediaControl
' ========================================================================================
' CLSID (Class identifier): {745395C8-D0E1-4227-8586-624CA9A10A8D}
' Help string: AxisMediaControl Class
' Attributes: 2 [&H00000002] [Cancreate]
' ProgID (Program identifier): AxisMediaControl.AxisMediaControl.1
' Version independent ProgID: AxisMediaControl.AxisMediaControl
' Default interface: IAxisMediaControl
' Default interface IID: {19722801-5830-4EC4-BD69-C3CF70776E0E}
' Default events interface: _IAxisMediaControlEvents
' Default events interface IID: {0997C74D-3ACE-4F31-99EC-47BC525E2382}
' Implemented interfaces:
'  IAxisMediaControl (default interface)
'  _IAxisMediaControlEvents (default events interface)
' ========================================================================================

' ========================================================================================
' ProgIDs (Program identifiers)
' ========================================================================================

' CLSID = {745395C8-D0E1-4227-8586-624CA9A10A8D}
$PROGID_AxisMediaControl1 = "AxisMediaControl.AxisMediaControl.1"

' ========================================================================================
' Version independent ProgIDs
' ========================================================================================

' CLSID = {745395C8-D0E1-4227-8586-624CA9A10A8D}
$PROGID_AxisMediaControl = "AxisMediaControl.AxisMediaControl"

' ========================================================================================
' ClsIDs (Class identifiers)
' ========================================================================================

$CLSID_AxisMediaControl = GUID$("{745395C8-D0E1-4227-8586-624CA9A10A8D}")

' ========================================================================================
' IIDs (Interface identifiers)
' ========================================================================================

$IID_IAxisMediaControl = GUID$("{19722801-5830-4EC4-BD69-C3CF70776E0E}")
$IID__IAxisMediaControlEvents = GUID$("{0997C74D-3ACE-4F31-99EC-47BC525E2382}")

' ========================================================================================

' ########################################################################################
' Interface name = IAxisMediaControl
' IID = {19722801-5830-4EC4-BD69-C3CF70776E0E}
' IAxisMediaControl Interface
' Attributes = 4160 [&H00001040] [Dual] [Dispatchable]
' Inherited interface = IDispatch
' ########################################################################################

#IF NOT %DEF(%IAxisMediaControl_INTERFACE_DEFINED)
    %IAxisMediaControl_INTERFACE_DEFINED = 1

INTERFACE IAxisMediaControl $IID_IAxisMediaControl

   INHERIT IDispatch

   ' =====================================================================================
   METHOD Play <101> ( _                                ' VTable offset = 28
   )                                                    ' void
   ' =====================================================================================

Events:
' ########################################################################################
' ########################################################################################
' Class CIAxisMediaControlEvents
' Interface name = _IAxisMediaControlEvents
' IID = {0997C74D-3ACE-4F31-99EC-47BC525E2382}
' _IAxisMediaControlEvents Interface
' Attributes = 4096 [&H1000] [Dispatchable]
' Code generated by the TypeLib Browser 5.0.1 (c) 2011 by José Roca
' Date: 24 Jan 2019   Time: 15:45:37
' ########################################################################################

GLOBAL ErrorString AS STRING

CLASS CIAxisMediaControlEvents GUID$("{DF3E7BF2-2A24-4667-A01C-F1D7BFCF2C05}") AS EVENT

INTERFACE IAxisMediaControlEventsImpl GUID$("{0997C74D-3ACE-4F31-99EC-47BC525E2382}") AS EVENT

  INHERIT IDISPATCH

   ' =====================================================================================
   METHOD OnError <1> ( _
     BYVAL prm_theErrorCode AS LONG _                   ' theErrorCode VT_I4 <Long>
   , BYVAL prm_theErrorInfo AS WSTRING _                ' theErrorInfo VT_BSTR
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================







José Roca

> I have managed to configure the camera properties and display their output in my application by initialising multiple camera instances.

Please, post the code that you're using to create these instances and the code used to connect events.

You can't duplicate the event's class and much less to change its GUID, but you can create multiple instances of the class.

Stuart Alexander

Thanks for the response - here is the relevant code using the single interface:

GLOBAL CameraBox1 AS DWORD
GLOBAL CameraBox2 AS DWORD

GLOBAL pAMC1 AS IAxisMediaControl
GLOBAL pAMC1Events1 AS IAxisMediaControlEventsImpl
GLOBAL pAMC2 AS IAxisMediaControl
GLOBAL pAMC2Events2 AS IAxisMediaControlEventsImpl

CameraBox1 = pWindow.AddOCX(hMainwindow&, %Canvas1, "AxisMediaControl.AxisMediaControl", "", Cam1Xp, Cam1Yp, CamXsz, CamYsz)
CameraBox2 = pWindow.AddOCX(hMainwindow&, %Canvas2, "AxisMediaControl.AxisMediaControl", "", Cam2Xp, Cam2Yp, CamXsz, CamYsz)

        LET pAMC1 = NEWCOM CLSID $CLSID_AxisMediaControl
        LET pAMC1Events1 = CLASS "CIAxisMediaControlEvents"
        pAMC1 = OC_GetDispatch(CameraBox1) ' Initialise pAMC object
        EVENTS FROM pAMC1 CALL pAMC1Events1

       LET pAMC2 = NewCOM CLSID $CLSID_AxisMediaControl
       LET pAMC2Events2 = CLASS "CIAxisMediaControlEvents"
       pAMC2 = OC_GetDispatch(CameraBox2) ' Initialise pAMC object
       EVENTS FROM pAMC2 CALL pAMC2Events2

As far as I understand - any code in the class method is common to the AMC instances so for an error
I send the EZ_SendEvent back to my main loop but am unable to ascertain the source object.

:   ' =====================================================================================
   METHOD OnError <1> ( _
     BYVAL prm_theErrorCode AS LONG _                   ' theErrorCode VT_I4 <Long>
   , BYVAL prm_theErrorInfo AS WSTRING _                ' theErrorInfo VT_BSTR
   )                                                    ' void

     ' *** Insert your code here ***
    EZ_DPrint FUNCNAME$
    EZ_SendEvent "AXIS", 1, prm_theErrorCode, 0
    ErrorString = prm_theErrorInfo
    EZ_DPrint "ErrorInfo: " + prm_theErrorInfo

   END METHOD

Event Loop:

SUB OtherForm_Events(FormName$, CID&, CMsg&, CVal&, Cancel&)
    SELECT CASE FormName$
        CASE "{OPENDLG}", "{SAVEDLG}", "{OPENDLGX}", "{SAVEDLGX}", "{COLORDLG}", "{FONTDLG}", "{PRINTDLG}", "{PAGEDLG}", "{FINDDLG}"
        CASE "{ABORTDLG}"
        CASE "{MSGBOX}"
        CASE "{APP}"     ' Not a Form
            SELECT CASE CMsg&
                CASE %EZ_NoTheme
                CASE %EZ_Terminate
            END SELECT
        CASE "AXIS"
            HandleAxisMessage CID&, CMsg&, CVal&
            ' EZ_DPrint "AXIS Msg Info: " + FormName$ + " CID: " + STR$(CID&) + " CMsg: " + STR$(CMsg&) + " CVal: " + STR$(CVal&)
            ' EZ_DPrint "ErrorString in Object: " + ErrorString
        CASE "{MEDIATEST}"
        'Do something
        CASE ELSE
    END SELECT
END SUB


thanks,
Stuart



José Roca

Add a method to the event class, e.g. SetCameraID


CLASS CIAxisMediaControlEvents GUID$("{DF3E7BF2-2A24-4667-A01C-F1D7BFCF2C05}") AS EVENT

INTERFACE IAxisMediaControlEventsImpl GUID$("{0997C74D-3ACE-4F31-99EC-47BC525E2382}") AS EVENT

  INHERIT IDISPATCH

   INSTANCE CameraID AS DWORD  ' or another type of variable that suits you

   ' =====================================================================================
   METHOD OnError <1> ( _
     BYVAL prm_theErrorCode AS LONG _                   ' theErrorCode VT_I4 <Long>
   , BYVAL prm_theErrorInfo AS WSTRING _                ' theErrorInfo VT_BSTR
   )                                                    ' void

     ' *** Insert your code here ***
     ' e.g. IF CameraID = <the ifentifier that you have set> THEN ...

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SetCameraID <9999> ( _
     BYVAL prm_CameraID AS DWORD _                      ' Camera identifier
   )                                                    ' void

   CameraID = prm_CameraId

   END METHOD
   ' =====================================================================================

END CLASS


and call it fter creating each of the instances of the event class


LET pAMC1Events1 = CLASS "CIAxisMediaControlEvents"
pAMC1Events1.SetCameraID(CameraBox1)

LET pAMC1Events2 = CLASS "CIAxisMediaControlEvents"
pAMC1Events2.SetCameraID(CameraBox2)


This way, when you will receive the event you will know which instance of the class has fired it by checking the CameraID instance variable.

Stuart Alexander

Thanks Jose,

Works perfectly now. The only difference is I have to declare the CameraID INSTANCE
variable directly after the CLASS declaration. The PB compiler doesn't seem to like it within
the INTERFACE block.

Thanks again,
Stuart