Announcement

Collapse
No announcement yet.

COM: Newbee Question

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

  • COM: Newbee Question

    I have never written a Win32 application before but I recently purchased PBWin90 with the intention of learning and developing something useful. So, I have been struggling with COM syntax and being able to access the routines in a specific DLL.

    Here is what does work in VB 2005 Express:
    Code:
     
    #INCLUDE "vb_unioaif.inc"
     
    PrivateSub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) HandlesMyBase.Load
    Dim objSession AsObject
    objSession = CreateObject(UV_SESSION_OBJECT)
    If objSession IsNothingThen
    MsgBox("Error creating object", MsgBoxStyle.Critical)
    ExitSub' End the program
    EndIf
    objSession.UserName = "fredsmith"
    objSession.Password = "password"
    objSession.HostName = "host.example.com"
    objSession.AccountPath = "/home/FREDSMITH"
    objSession.Transport = 1
    objSession.Connect()
    If objSession.IsActive Then
    If objSession.HostType = UVT_UNIX Then
    MsgBox("You are connected to a UNIX server")
    Else
    MsgBox("You are connected to a Windows NT system")
    EndIf
    objSession.Disconnect()
    Else
    '
    ' Check for Session errors - display message box with error code
    ' No error means the user cancelled the connection dialog box
    '
    If objSession.Error <> UVE_NOERROR Then
    MsgBox("Unable to open connection :- " & objSession.Error)
    EndIf
    EndIf
    EndSub
    Question
    I feel like I have looked through all the DOC's and samples and have hit a wall. So, any chance someone here on the board could duplicate the above VB in PB? It would be greatly appreciated.

    Here is the include output from the PowerBasic COM Browser
    Here is the DLL file: uniobjects.dll
    Here is the TLB file: uniobjects.tlb
    Here is the VB include file I converted to PB.

    Thanks in advance.

  • #2
    I tested the IBM U2 Client Tools Developer's toolkit.
    This is the PB version of your code.
    Code:
      LOCAL objSession  AS IUnioaifCtrl
    
      objSession = NEWCOM $UV_SESSION_OBJECT 
    
      IF ISFALSE ISOBJECT(objSession) THEN
        MSGBOX "Error creating object"
        EXIT FUNCTION
      END IF
      objSession.UserName = UCODE$("fredsmith")
      objSession.Password = UCODE$("password")
      objSession.HostName = UCODE$("host.example.com") 
      objSession.AccountPath = UCODE$("/home/FREDSMITH")
      objSession.Transport = 1
      objSession.Connect()
      IF objSession.IsActive THEN
        IF objSession.HostType = %UVT_UNIX THEN
          MSGBOX "You are connected to a UNIX server"
        ELSE
          MSGBOX "You are connected to a Windows NT system"
        END IF
        objSession.Disconnect()
      ELSE
        '
        ' Check for Session errors - display message box with error code
        ' No error means the user cancelled the connection dialog box
        '
        IF objSession.Error <> %UVE_NOERROR THEN
          MSGBOX "Unable to open connection :- " + HEX$(objSession.Error)
        END IF
      END IF
    I did not use your pb_unioaif.inc file, because it produced Error 407: Source line too long.
    Dominic Mitchell
    Phoenix Visual Designer
    http://www.phnxthunder.com

    Comment


    • #3
      Perfect! Thank you Dominic!
      Last edited by Lance Jahnke; 3 Nov 2008, 03:42 PM.

      Comment


      • #4
        cannot create UniFile object

        I wrote an application a number of years ago in VB that worked with UniObjects.dll and am trying to port it to PowerBasic. I've run into a
        wall trying to create a file object.

        There is no code in the UniObjects.inc file created by the .com browser
        that has a $PROGID equate for a UniFile object so I resorted to the
        objvar = NEWCOM CLSID CLSID$
        syntax after trying everything else I could think of in the last few days.
        But the message box that says "Error creating File object" still comes
        up. Any ideas?

        Here's the PB code:

        Code:
        #COMPILE EXE
        #DIM ALL
        
        '------------------------------------------------------------------------------
        #INCLUDE ONCE "WIN32API.INC"
        #INCLUDE ONCE "COMMCTRL.INC"
        #INCLUDE ONCE "C:\PBWIN90\INCLUDE\UniObjects.inc"
        #INCLUDE ONCE "C:\PBWIN90\INCLUDE\uvoaif.inc"
        '------------------------------------------------------------------------------
        
        FUNCTION PBMAIN () AS LONG
        
          LOCAL objSession   AS IUnioaifCtrl
          LOCAL objRecord    AS IUniDynArray
          LOCAL objFile      AS IDISPATCH
        
          DIM objFilename     AS STRING
          DIM objRecordId     AS STRING
        
          objSession = NEWCOM "Uniobjects.Unioaifctrl"
        
          IF ISFALSE ISOBJECT(objSession) THEN
            MSGBOX "Error creating objSession object"
            EXIT FUNCTION
          END IF
        
          objSession.UserName    = UCODE$("administrator")
          objSession.Password    = UCODE$("PASSWORD")
          objSession.HostName    = UCODE$("localhost")
          objSession.AccountPath = UCODE$("SYSPROG")
          objSession.Transport   = 0
          objSession.Connect()
          IF ISFALSE objSession.IsActive THEN
            MSGBOX "Unable to open connection: " + STR$( objSession.Error )
            EXIT FUNCTION
          END IF
        
        ' *** this always fails whether NEWCOM, ANYCOM, OR GETCOM
          objFile = ANYCOM CLSID $CLSID_UNIOBJECTSLib_UniFile
          IF ISFALSE ISOBJECT( objFile ) THEN
            MSGBOX "Error creating File object"
            EXIT FUNCTION
          END IF
        
          objFilename = UCODE$( "VOC" )
          objFile = objSession.OpenFile( objFilename )
          IF objSession.Error <> 0 THEN
            MSGBOX "Open objFile Error - " + objFilename + STR$( objSession.Error )
            EXIT FUNCTION
          END IF
        
          objRecordId = UCODE$( "RELLEVEL" )
          OBJECT SET  objFile.objRecordID = objRecordId
          OBJECT CALL objFile.Read
          IF objSession.Error <> 0 THEN
            MSGBOX "Read objRecord Error - " + objRecordId + " - " + STR$( objSession.Error )
            EXIT FUNCTION
          END IF
        
          objSession.Disconnect()
          EXIT FUNCTION
        
        END FUNCTION

        Comment


        • #5
          objvar = NEWCOM CLSID CLSID$
          You cannot do that because an instance of the UniFile object cannot be created directly.
          Check the type flags before attempting to use NEWCOM/GETCOM/ANYCOM.
          For example, notice that the UnioaifCtrl coclass has a cancreate flag
          Code:
          ' ****************************************************************************************
          ' coclass:        UnioaifCtrl
          ' clsid:          {3ED50B8E-0667-11D4-BE19-00104B2A91CE}
          ' ProgID:         Uniobjects.UnioaifCtrl
          ' Version ProgID: Uniobjects.UnioaifCtrl.1
          ' Description:    UnioaifCtrl
          ' Type Flags:     [cancreate]
          ' ----------------------------------------------------------------------------------------
          ' Interface:      IUnioaifCtrl
          ' uuid:           {3ED50B8D-0667-11D4-BE19-00104B2A91CE}
          ' Description:    Dispatch interface for Unioaif Control
          ' Type Flags:     [dual, dispatchable]
          ' ****************************************************************************************
          and the UniFile coclass does not.
          Code:
          ' ****************************************************************************************
          ' coclass:        UniFile
          ' clsid:          {EC1F5578-1C6F-11D4-BE1B-00104B2A91CE}
          ' Description:    UniFile
          ' ----------------------------------------------------------------------------------------
          ' Interface:      IUniFileEx
          ' uuid:           {E4EDDE51-4A34-11D5-88A4-0000E84E5C56}
          ' Description:    Unifile Extension - allow read and write multiple fields
          ' Type Flags:     [dual, dispatchable]
          ' ****************************************************************************************
          Unfortunately, the last time I checked, you cannot use the PowerBASIC COM browser to figure this out.
          You will have to get Microsoft's OleView browser. Phoenix 2.0 will tell you but it does not generate code
          for PB COM 9 direct interface syntax. I have not checked to see if the latest version of José's browser
          addresses this shortcoming.

          By the way, do not use automation syntax on an object that has been instantiated for direct interface access
          Code:
            OBJECT SET  objFile.objRecordID = objRecordId
            OBJECT CALL objFile.Read
          Try the following:
          Code:
            LOCAL objFilename     AS STRING
            LOCAL objRecordId     AS STRING
            LOCAL oObject         AS IDISPATCH
            LOCAL objFile         AS IUniFileEx
            
            objFilename = UCODE$( "VOC" )
            oObject = objSession.OpenFile(objFilename) 
            IF objSession.Error <> 0 THEN
              MSGBOX "Open objFile Error - " + objFilename + STR$( objSession.Error )
              EXIT FUNCTION
            END IF 
            
            objFile = oObject
          
            objRecordId = UCODE$( "RELLEVEL" )
            objFile.objRecordID = objRecordId
            objFile.Read
            IF objSession.Error <> 0 THEN
              MSGBOX "Read objRecord Error - " + objRecordId + " - " + STR$( objSession.Error )
              EXIT FUNCTION
            END IF
          Note:
          The OpenFile method returns IDispatch.

          objFile = oObject

          This does a QueryInterface for IUniFileEx.
          Last edited by Dominic Mitchell; 21 Apr 2010, 04:12 AM.
          Dominic Mitchell
          Phoenix Visual Designer
          http://www.phnxthunder.com

          Comment


          • #6
            Thanks, Dominic

            that got me over the hump. The IDISPATCH variable business is
            still a bit confusing, but I'm sure it will make sense soon.

            For the record, the line that read

            Code:
            objFile.objRecordID = objRecordID
            should have been

            Code:
            objFile.RecordId = objRecordID
            In case anyone else ever tries to use the UniObjects.dll here is
            a bit more code that reads a UniVerse record and displays the
            contents of each of its fields.

            Code:
            #COMPILE EXE
            #DIM ALL
            
            '------------------------------------------------------------------------------
            #INCLUDE ONCE "WIN32API.INC"
            #INCLUDE ONCE "COMMCTRL.INC"
            #INCLUDE ONCE "C:\PBWIN90\INCLUDE\UniObjects.inc"
            #INCLUDE ONCE "C:\PBWIN90\INCLUDE\uvoaif.inc"
            '------------------------------------------------------------------------------
            
            FUNCTION PBMAIN () AS LONG
            
              LOCAL objSession   AS IUnioaifCtrl
              LOCAL objFile      AS IUniFileEx
              LOCAL objRecord    AS IUniDynArray
              LOCAL objField     AS IUniDynArray
              LOCAL oFile        AS IDISPATCH
            
              DIM Filename       AS STRING
              DIM RecordId       AS STRING
              DIM Fielddata      AS STRING
              DIM Fieldcount     AS LONG
              DIM Fieldnumber    AS LONG
            
              objSession = NEWCOM "Uniobjects.Unioaifctrl"
              IF ISFALSE ISOBJECT(objSession) THEN
                MSGBOX "Error creating objSession object"
                EXIT FUNCTION
              END IF
            
              objSession.UserName    = UCODE$("administrator")
              objSession.Password    = UCODE$("PASSWORD")
              objSession.HostName    = UCODE$("localhost")
              objSession.AccountPath = UCODE$("SYSPROG")
              objSession.Transport   = 0
              objSession.Connect()
              IF ISFALSE objSession.IsActive THEN
                MSGBOX "Unable to open connection: " + STR$( objSession.Error )
                EXIT FUNCTION
              END IF
            
              Filename = UCODE$( "VOC" )
              oFile    = objSession.OpenFile(Filename)
              IF objSession.Error <> 0 THEN
                MSGBOX "Open objFile Error - " + Filename + STR$( objSession.Error )
                EXIT FUNCTION
              END IF
            
              objFile = oFile
              IF ISFALSE ISOBJECT( objFile ) THEN
                MSGBOX "objFile not created"
                EXIT FUNCTION
              END IF
            
              RecordId = UCODE$( "RELLEVEL" )
              objFile.RecordID = RecordId
              objFile.Read
              IF objSession.Error <> 0 THEN
                MSGBOX "Read objRecord Error - " + RecordId + " - " + STR$( objSession.Error )
                EXIT FUNCTION
              END IF
            
              objRecord = ANYCOM "Uniobjects.UniDynArray"
              IF ISFALSE ISOBJECT( objRecord ) THEN
                MSGBOX "Unable to create objRecord"
                EXIT FUNCTION
              END IF
            
              objField  = ANYCOM "Uniobjects.UniDynArray"
              IF ISFALSE ISOBJECT( objField ) THEN
                MSGBOX "Unable to create objField"
                EXIT FUNCTION
              END IF
            
              OBJECT GET oFile.Record TO objRecord
              Fieldcount = objRecord.Count
              MSGBOX STR$( Fieldcount )
              Fielddata = objRecord.StringValue
              MSGBOX ACODE$( Fielddata )
              
              FOR Fieldnumber = 1 TO Fieldcount
                objField  = objRecord.Field( Fieldnumber )
                Fielddata = objField.StringValue
                MSGBOX STR$( Fieldnumber) + " - " + ACODE$( Fielddata )
              NEXT Fieldnumber
            
              objSession.Disconnect()
              EXIT FUNCTION
            
            END FUNCTION

            Comment


            • #7
              I have not checked to see if the latest version of José's browser
              addresses this shortcoming.
              In the left side treeview there is a node labeled CoClasses that lists all the classes. Clicking on a CoClass will display in the right side treeview all the information available, such ClsID, ProgIDs, Attributes (CanCreate, Licensed, etc.), InProc server path, default interface name and IID, and implemented interfaces.
              Forum: http://www.jose.it-berater.org/smfforum/index.php

              Comment

              Working...
              X