Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

COM/NON-COM Examples Calculating Vectors and Angles

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

  • COM/NON-COM Examples Calculating Vectors and Angles

    This is the first post in this topic. There will several more in this series shortly. The objective of these posts is to show a published COM compatible DLL, a non-compatible OOP DLL, and the same classes inside of PBWin 9 and PBCC 5 stand-alone programs. Each post will have files to download and try.

    The CLASS CVACALC demonstrates using INSTANCES, CLASS METHODS, METHODS and PROPERTY GET statements. Depending on the provision of 2 parameters via one of the 3 accessible methods, the object will then calculate the remaining possible variables in this scope. These values are, in the contest of a Cartesian grid with the vector having one end at 0,0:
    • X and Y coordinates
    • radian angle
    • degree angle +/- of 0, 360 degree circle
    • degree angle, positive only in a 360 degree span.
    • vector length
    The attached files include PBWin 9 source, PBWin 9 produced DLL, PB COM Browser produced include nd an executable test program. The files in the include are without many of the now added comments in the listings which follow. The first is for the DLL's bas:
    Code:
    '------------------------------------------------------------------------------
    '   CVACALC.BAS   2008
    '   Created by R. Angell    - Public Domain, use at your own risk
    '   Demo of a COM Class "published" in a DLL
    '------------------------------------------------------------------------------
    #COMPILER PBWIN 9
    #COMPILE DLL "CVACalc.Dll"
    #DIM ALL
    'REGISTER NONE must be outside the class def
    'to avoid erasing register values during
    'other processing
    #REGISTER NONE
    '
    'Lets add some info for potential users to retrieve with COM browsers, etc.
    #COM DOC "CVACalc encapsulates several methods for resolving vector values."
    '#COM HELP "MyProg.chm", &H1E00   'no hlep file , but would be spec'd here
    #COM NAME "CVACalc", 0.0001
    #COM GUID GUID$("{D41FF8A7-0507-4919-BF5D-B3715B861D65}")
    #COM TLIB ON    'set to ON to use PB COM Browser to produce include file  
    '---------------
    ' Note: the GUID$ entry above and the 2 following shortly are easily
    '       generated using the right click menu in PB's IDE. Then choose
    '       Insert GUID at the appropriate spots, shown here.  You can
    '       also do this with the Ctrl+Alt+G hotkey.
    '---------------
    %USEMACROS = 1
    #INCLUDE "Win32API.inc"
    
    $CVACALCGUID = GUID$("{A6AE5018-2FBC-4952-B078-A94FC27FF351}")
    $CVACALCIO   = GUID$("{CD68C662-926E-49F2-8B38-526A50469942}")
    
    GLOBAL ghInstance AS DWORD
    '-------------------------------------------------------------------------------
    ' Main DLL entry point called by Windows...
    ' Using standard PB WinMain template function, comments removed
    FUNCTION LIBMAIN (BYVAL hInstance   AS LONG, _
                      BYVAL fwdReason   AS LONG, _
                      BYVAL lpvReserved AS LONG) AS LONG
        SELECT CASE fwdReason
        CASE %DLL_PROCESS_ATTACH
            ghInstance = hInstance
            FUNCTION = 1
    
        CASE %DLL_PROCESS_DETACH
            FUNCTION = 1
    
        CASE %DLL_THREAD_ATTACH
            FUNCTION = 1
    
        CASE %DLL_THREAD_DETACH
            FUNCTION = 1
        END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    '   Here is where we are adding the Class(es).
    '   Note:
    '   For a compliant COM class (AS COM) we are can only use variable types
    '   BYTE, WORD, DWORD, INTEGER, LONG, QUAD, SINGLE, DOUBLE, CURRENCY,
    '   OBJECT, STRING, and VARIANT, when such are published variables.
    '   See "What is a Base Class?" in the Programming Reference\Objects and
    '   COM Programming section of the PBWin 9 help file
    '------------------------------------------------------------------------------
    CLASS CVACALC $CVACALCGUID AS COM
        'INSTANCE variables
        'A unique set of instance variables
        'will be created for every new object,
        'created from this CLASS; and which
        'may only be referenced from within
        INSTANCE ptX          AS DOUBLE
        INSTANCE ptY          AS DOUBLE
        INSTANCE radangle     AS DOUBLE
        INSTANCE vlength      AS DOUBLE
        INSTANCE dangleraw    AS DOUBLE
        INSTANCE dangleABS    AS DOUBLE
        INSTANCE HasValues    AS LONG
    
        'Class Methods are private within
        'the classes' objects, that is they can not be
        'accessed externally, only internally.  You
        'access them using the ME keyword, like this:
        'ME.CalcRadAngle
        CLASS METHOD CalcRadAngle()
            'requires ptX and ptY
            'You can declare local varibles
            'and arrays in a CLASS METHOD or
            'in INTERFACE METHODs
             LOCAL ry,rx AS DOUBLE
             ry = ptY
             rx = ptX
             ! emms
             ! fld ry
             ! fld rx
             ! fpatan
             ! fstp ry
             radangle = ry
        END METHOD
    
    
        CLASS METHOD CalcDegreeAngleRAW()
            'requires radangle
            dangleraw = radangle * 57.29577951308232##
        END METHOD
    
    
        CLASS METHOD CalcDegreeAngleABS()
            'requires dangleraw
            IF dangleraw = 0 THEN dangleraw = radangle * 57.29577951308232##
            IF SGN(dangleraw) = -1 THEN
                dangleABS = 360 + dangleraw
            ELSE
                dangleABS = dangleraw
            END IF
        END METHOD
    
        CLASS METHOD CalcVectorLengthXY()
            'requires ptX and ptY
            vlength = SQR((ptX)^2+(ptY)^2)
        END METHOD
    
        CLASS METHOD  CalcPolar2Rect()
            'requires radangle and  vlength
            'ptX and ptY  are the return values
            'vlength is the distance from origin to point ptX,ptY
            ptX = vlength * COS(radangle)
            ptY = vlength * SIN(radangle)
        END METHOD
    
        CLASS METHOD CalcDegreesToRadians()
             radangle = dangleABS * 0.0174532925199433##
        END METHOD
    
    
        CLASS METHOD Update(BYVAL updcase AS LONG)
            SELECT CASE AS LONG updcase
                CASE 1        'coordinates input updates
                    ME.CalcRadAngle()
                    ME.CalcDegreeAngleRAW()
                    ME.CalcDegreeAngleABS()
                    ME.CalcVectorLengthXY()
    
                CASE 2        'polar input updates
                    ME.CalcPolar2Rect()
                    ME.CalcDegreeAngleRAW()
                    ME.CalcDegreeAngleABS()
    
                CASE 3        'degree angle vector inputs update
                    ME.CalcDegreeAngleABS()
                    ME.CalcDegreesToRadians
                    ME.CalcPolar2Rect()
            END SELECT
            HasValues = 1
        END METHOD
    
        '--------------------------------------------------------------------------
        ' INTERFACES are where we define the externally accessible Methods and
        ' properties for an object created as an INTERFACE type.  While accessible
        ' externally if so specified, an INTERFACE can be marked AS HIDDEN  to
        ' prevent its being documented in the Type Library (.tlb)
        '--------------------------------------------------------------------------
    
        INTERFACE CALCIO $CVACALCIO
            INHERIT IUNKNOWN                 'INHERIT CUSTOM for those who like
    
            'The INTERFACE's methods are equivalent to SUBs and FUNCTIONs
            'these here are like SUBs, but when a METHOD has the
            'FUNCTION style, with the AS vartype return type
            'then the methods value is assigned METHOD = retvalue
            'There are other source and help examples showing this.
            METHOD CalcReset ALIAS "CalcReset" ()
                ptX = 0
                ptY = 0
                dangleraw = 0
                dangleABS = 0
                radangle  = 0
                vlength   = 0
                HasValues = 0
            END METHOD
    
            METHOD XYIn  ALIAS "XYIn" (BYVAL X AS DOUBLE,BYVAL y AS DOUBLE)
                ptX = X
                ptY = Y
                ME.Update(1)
            END METHOD
    
            METHOD PolarIn  ALIAS "PolarIn"(BYVAL radianangle AS DOUBLE,BYVAL vectorlength AS DOUBLE)
                radangle = radianangle
                vlength  = vectorlength
                ME.Update(2)
            END METHOD
    
            METHOD DegreeAngleVector  ALIAS "DegreeAngleVector"(BYVAL angleraw AS DOUBLE,BYVAL vectorlength AS DOUBLE)
                IF SGN(angleraw) = -1 THEN
                    dangleraw = angleraw
                    dangleABS = 180 + angleraw
                ELSE
                    dangleraw = angleraw
                    dangleABS = angleraw
                END IF
                vlength  = vectorlength
                ME.Update(3)
            END METHOD
    
            'Properties are a special kind of method for setting or
            'returning a value. In this demo, we are only returning
            'resulting variable values after one of the primary
            'methods has been called.
    
            PROPERTY GET X ALIAS "x"() AS DOUBLE
                PROPERTY = ptX
            END PROPERTY
    
            PROPERTY GET Y ALIAS "y" () AS DOUBLE
                PROPERTY = ptY
            END PROPERTY
    
            PROPERTY GET radians ALIAS "radians"() AS DOUBLE
                PROPERTY = radangle
            END PROPERTY
    
            PROPERTY GET degrees ALIAS "degrees"() AS DOUBLE
                PROPERTY = dangleABS
            END PROPERTY
    
            PROPERTY GET degreesPM ALIAS "degreesPM"() AS DOUBLE
                PROPERTY = dangleraw
            END PROPERTY
    
            PROPERTY GET vectorlength ALIAS "vectorlength"() AS DOUBLE
                PROPERTY = vlength
            END PROPERTY
    
        END INTERFACE
    END CLASS
    It is to be noted that the new PB COM Browser adds prefixes to property methods as well as specified prefixes for interfaces(s). here is the .inc content.
    Code:
    ' Generated by: PowerBASIC COM Browser v.2.00.0054
    ' DateTime    : 8/18/2008 at 3:05 PM
    ' ------------------------------------------------
    ' Library Name: CVACalc
    ' Library File: F:\PBWin90\RA_MathObjects\CVACalc.tlb
    ' Description : CVACalc encapsulates several methods for resolving vector values.
    ' GUID : {D41FF8A7-0507-4919-BF5D-B3715B861D65}
    ' LCID : 0
    ' Version : 0.1
    
    ' Class Indentifiers
    $CLSID_CVACalc = GUID$("{A6AE5018-2FBC-4952-B078-A94FC27FF351}")
    
    ' Interface Indentifiers
    $IID_RACALCIO = GUID$("{CD68C662-926E-49F2-8B38-526A50469942}")
    
    ' Interface Name  : RACALCIO
    ' Description     : CALCIO is a custom interface for Direct access.
    ' ClassID         : $CLSID_CVACalc
    INTERFACE RACALCIO $IID_RACALCIO 
        INHERIT IUNKNOWN
    
        METHOD CalcReset()
        METHOD XYIn(BYVAL X AS DOUBLE, BYVAL Y AS DOUBLE)
        METHOD PolarIn(BYVAL RADIANANGLE AS DOUBLE, BYVAL VECTORLENGTH AS DOUBLE)
        METHOD DegreeAngleVector(BYVAL ANGLERAW AS DOUBLE, BYVAL VECTORLENGTH AS DOUBLE)
        METHOD Get_X() AS DOUBLE
        METHOD Get_Y() AS DOUBLE
        METHOD Get_radians() AS DOUBLE
        METHOD Get_degrees() AS DOUBLE
        METHOD Get_degreesPM() AS DOUBLE
        METHOD Get_VECTORLENGTH() AS DOUBLE
    END INTERFACE
    And finally a commented listing for the test program.
    Code:
    #COMPILER PBWIN 9
    #COMPILE EXE  "TEST_CVACALC.EXE"
    #DIM ALL
    'we include the definition file produced by PB COM Browser
    'using the .tlb automatically produced by PB when we
    'compiled the DLL where the CLASS has the AS COM type
    #INCLUDE "CVACalc.inc"
    
    FUNCTION PBMAIN () AS LONG
    
        LOCAL X,Y,ra,vl,da  AS DOUBLE   'demo variables
        'Declare the object variable and its class interface type
        LOCAL oVertice      AS RACALCIO
    
        'The following code line lets us use a COM DLL without it needing
        'to be registered, and in this case will have installed in the
        'same directory, but if in another, add the path in the
        'string following the LIB keyword.  The $CLSID is assigned in
        'the CVACalc.inc and is also unique in the DLL
        LET oVertice = NEWCOM CLSID $CLSID_CVACALC LIB "CVACalc.DLL"
    
        X = SQR(2)  'this demo uses a vector 2 inches long,at 45 degrees
        Y = SQR(2)  'from 0,0 so we'll use the coords which are SQR(2)
    
        oVertice.XYIn(X,Y)      'submit vertex coordinates, point not at origin
    
       'we'll store some values for further tests
        ra = oVertice.Get_radians
        vl = oVertice.Get_vectorlength
        da = oVertice.Get_degreesPM
    
        'show the results of each method ... should be the same
        ? "Coordinate data entered with XYIn(X,Y) method." + $CRLF + _
          "Results:"+ $CRLF + _
          "X coordinate"+$TAB+FORMAT$(oVertice.Get_X)+ $CRLF + _
          "Y coordinate"+$TAB+FORMAT$(oVertice.Get_Y)+ $CRLF + _
          "Radian Angle"+$TAB+FORMAT$(oVertice.Get_radians)+ $CRLF + _
          "Vector Lngth"+$TAB+FORMAT$(oVertice.Get_vectorlength)+ $CRLF + _
          "Degrees RAW "+$TAB+FORMAT$(oVertice.Get_degreesPM)+ $CRLF + _
          "Degrees ABS "+$TAB+FORMAT$(oVertice.Get_degrees),%MB_TASKMODAL ,"XYIn Results Report"
        oVertice.CalcReset                  'call method to clear the values
        oVertice.PolarIn(ra,vl)             'submit radian angle and vector length
          ? "Coordinate data entered with PolarIn(radians,vectorlength) method." + $CRLF + _
          "Results:"+ $CRLF + _
          "X coordinate"+$TAB+FORMAT$(oVertice.Get_X)+ $CRLF + _
          "Y coordinate"+$TAB+FORMAT$(oVertice.Get_Y)+ $CRLF + _
          "Radian Angle"+$TAB+FORMAT$(oVertice.Get_radians)+ $CRLF + _
          "Vector Lngth"+$TAB+FORMAT$(oVertice.Get_vectorlength)+ $CRLF + _
          "Degrees RAW "+$TAB+FORMAT$(oVertice.Get_degreesPM)+ $CRLF + _
          "Degrees ABS "+$TAB+FORMAT$(oVertice.Get_degrees),%MB_TASKMODAL ,"PolarIn Results Report"
        oVertice.CalcReset                  'call method to clear the values
        oVertice.DegreeAngleVector(da,vl)   'submit degree angle and vector length
        ? "Coordinate data entered with DegreeAngleVector(degrees,vectorlength) method." + $CRLF + _
          "Results:"+ $CRLF + _
          "X coordinate"+$TAB+FORMAT$(oVertice.Get_X)+ $CRLF + _
          "Y coordinate"+$TAB+FORMAT$(oVertice.Get_Y)+ $CRLF + _
          "Radian Angle"+$TAB+FORMAT$(oVertice.Get_radians)+ $CRLF + _
          "Vector Lngth"+$TAB+FORMAT$(oVertice.Get_vectorlength)+ $CRLF + _
          "Degrees RAW "+$TAB+FORMAT$(oVertice.Get_degreesPM)+ $CRLF + _
          "Degrees ABS "+$TAB+FORMAT$(oVertice.Get_degrees),%MB_TASKMODAL ,"DegreeAngleVector Results Report"
        oVertice.CalcReset          'call method to clear the values, results should be all 0
        ? "oVertice.CalcReset method." + $CRLF + _
          "Results:"+ $CRLF + _
          "X coordinate"+$TAB+FORMAT$(oVertice.Get_X)+ $CRLF + _
          "Y coordinate"+$TAB+FORMAT$(oVertice.Get_Y)+ $CRLF + _
          "Radian Angle"+$TAB+FORMAT$(oVertice.Get_radians)+ $CRLF + _
          "Vector Lngth"+$TAB+FORMAT$(oVertice.Get_vectorlength)+ $CRLF + _
          "Degrees RAW "+$TAB+FORMAT$(oVertice.Get_degreesPM)+ $CRLF + _
          "Degrees ABS "+$TAB+FORMAT$(oVertice.Get_degrees),%MB_TASKMODAL ,"CalcReset Results Report"
    
        LET oVertice = NOTHING  'release the object
    END FUNCTION
    Special thanks to PB for the Power, and to Steve Rossell and Jose Roca for assistance with some issues in the development of these samples.
    Attached Files
    Last edited by Richard Angell; 25 Aug 2008, 09:45 AM. Reason: Updated for #COM TLIB metastatement
    Rick Angell

  • #2
    A NON COM All - In - One CLASS demo

    Here the focus switches to a CLASS embedded in an executable program, but with 2 special "twists". First, we are not publishing the class. Second we are using the variable type EXTended which not supported by the standard COM specification. Also we are using the native names in the code, which we would not necessarily see when using an external DLL/OCX/EXE and definitions from the PB COM Browser. So without further ado, here is the listing:
    Code:
    '------------------------------------------------------------------------------
    '   AllInOne_CVACALC.BAS   2008
    '   Created by R. Angell    - Public Domain, use at your own risk
    '   Demo of a Class and Object internal to a program in PBWin 9
    '   Shows a class using the EXTended precision variable types
    '   which are outside the scope of the COM specification , but
    '   can be used easily in this "unpublished" class situation.
    '------------------------------------------------------------------------------
    #COMPILER PBWIN 9
    #COMPILE EXE  "CVACALC_CLASS_ALL_IN_PBWIN9_PROGRAM.EXE"
    #DIM ALL
    'REGISTER NONE must be outside the class def
    'to avoid erasing register values during
    'other processing
    #REGISTER NONE
    
    ' We are defining here a class private to this app
    ' and without intent to publish the class, so NO
    ' GUID$ or AS COM modifiers are being added.
    CLASS CVACALC
    
        'INSTANCE variables
        'A unique set of instance variables
        'will be created for every new object,
        'created from this CLASS; and which
        'may only be referenced from within
        'that object
        INSTANCE ptX          AS EXT
        INSTANCE ptY          AS EXT
        INSTANCE radangle     AS EXT
        INSTANCE vlength      AS EXT
        INSTANCE dangleraw    AS EXT
        INSTANCE dangleABS    AS EXT
        INSTANCE HasValues    AS LONG
    
        'Class Methods are private within
        'the classes' objects, that is they can not be
        'accessed externally, only internally.  You
        'access them using the ME keyword, like this:
        'ME.CalcRadAngle
    
        CLASS METHOD CalcRadAngle()
            'requires ptX and ptY
            'You can declare local varibles
            'and arrays in a CLASS METHOD or
            'in INTERFACE METHODs
             LOCAL ry,rx AS EXT
             ry = ptY
             rx = ptX
             ! emms
             ! fld ry
             ! fld rx
             ! fpatan
             ! fstp ry
             radangle = ry
        END METHOD
    
        CLASS METHOD CalcDegreeAngleRAW()
            'requires radangle
            dangleraw = radangle * 57.29577951308232##
        END METHOD
    
    
        CLASS METHOD CalcDegreeAngleABS()
            'requires dangleraw
            IF dangleraw = 0 THEN dangleraw = radangle * 57.29577951308232##
            IF SGN(dangleraw) = -1 THEN
                dangleABS = 360 + dangleraw
            ELSE
                dangleABS = dangleraw
            END IF
        END METHOD
    
        CLASS METHOD CalcVectorLengthXY()
            'requires ptX and ptY
            vlength = SQR((ptX)^2+(ptY)^2)
        END METHOD
    
        CLASS METHOD  CalcPolar2Rect()
            'requires radangle and vlength
            'ptX and ptY  are the return values
            'vlength is the distance from origin to point ptX,ptY
            ptX = vlength * COS(radangle)
            ptY = vlength * SIN(radangle)
        END METHOD
    
        CLASS METHOD CalcDegreesToRadians()
             radangle = dangleABS * 0.0174532925199433##
        END METHOD
    
    
        CLASS METHOD Update(BYVAL updcase AS LONG)
            SELECT CASE AS LONG updcase
                CASE 1        'coordinates input updates
                    ME.CalcRadAngle()
                    ME.CalcDegreeAngleRAW()
                    ME.CalcDegreeAngleABS()
                    ME.CalcVectorLengthXY()
    
                CASE 2        'polar input updates
                    ME.CalcPolar2Rect()
                    ME.CalcDegreeAngleRAW()
                    ME.CalcDegreeAngleABS()
    
                CASE 3        'degree angle vector inputs update
                    ME.CalcDegreeAngleABS()
                    ME.CalcDegreesToRadians
                    ME.CalcPolar2Rect()
            END SELECT
            HasValues = 1
        END METHOD
    
        '--------------------------------------------------------------------------
        ' INTERFACES are where we define the externally accessible Methods and
        ' properties for an object created as an INTERFACE type.  While accessible
        ' externally if so specifed, an INTERFACE can be marked AS HIDDEN  to
        ' prevent its being documented in the Type Library (.tlb)
        '--------------------------------------------------------------------------
    
        INTERFACE CALCIO
            'Every interface must inherit, see the help file, and here to have a
            'Direct interface we will inherit from iUnkown.
            INHERIT IUNKNOWN                 'INHERIT CUSTOM for those who like
    
            'The INTERFACE's methods are equivalent to SUBs and FUNCTIONs
            'these here are like SUBs, but when a METHOD has the
            'FUNCTION style, with the AS vartype return type
            'then the methods value is assigned METHOD = retvalue
            'There are other source and help examples showing this.
            METHOD CalcReset ALIAS "CalcReset" ()
                ptX = 0
                ptY = 0
                dangleraw = 0
                dangleABS = 0
                radangle  = 0
                vlength   = 0
                HasValues = 0
            END METHOD
    
            METHOD XYIn  ALIAS "XYIn" (BYVAL X AS EXT,BYVAL y AS EXT)
                ptX = X
                ptY = Y
                ME.Update(1)
            END METHOD
    
            METHOD PolarIn  ALIAS "PolarIn"(BYVAL radianangle AS EXT,BYVAL vectorlength AS EXT)
                radangle = radianangle
                vlength  = vectorlength
                ME.Update(2)
            END METHOD
    
            METHOD DegreeAngleVector  ALIAS "DegreeAngleVector"(BYVAL angleraw AS EXT,BYVAL vectorlength AS EXT)
                IF SGN(angleraw) = -1 THEN
                    dangleraw = angleraw
                    dangleABS = 180 + angleraw
                ELSE
                    dangleraw = angleraw
                    dangleABS = angleraw
                END IF
                vlength  = vectorlength
                ME.Update(3)
            END METHOD
    
            'Properties are a special kind of method for setting or
            'returning a value. In this demo, we are only returning
            'resulting variable values after one of the primary
            'methods has been called.
    
            PROPERTY GET X ALIAS "x"() AS EXT
                PROPERTY = ptX
            END PROPERTY
    
            PROPERTY GET Y ALIAS "y" () AS EXT
                PROPERTY = ptY
            END PROPERTY
    
            PROPERTY GET radians ALIAS "radians"() AS EXT
                PROPERTY = radangle
            END PROPERTY
    
            PROPERTY GET degrees ALIAS "degrees"() AS EXT
                PROPERTY = dangleABS
            END PROPERTY
    
            PROPERTY GET degreesPM ALIAS "degreesPM"() AS EXT
                PROPERTY = dangleraw
            END PROPERTY
    
            PROPERTY GET vectorlength ALIAS "vectorlength"() AS EXT
                PROPERTY = vlength
            END PROPERTY
    
        END INTERFACE
    END CLASS
    '------------------------------------------------------------------------------
    FUNCTION PBMAIN () AS LONG
    
        LOCAL X,Y,ra,vl,da  AS EXT   'demo variables
        'Declare the object variable and its class interface type
        LOCAL oVertice      AS CALCIO
    
        'create the object from the Class CVACALC, on interface CALCIO
        'which is the declared variable type for this object
        LET oVertice = CLASS "CVACALC"
    
        X = SQR(2)  'this demo uses a vector 2 inches long,at 45 degrees
        Y = SQR(2)  'from 0,0 so we'll use the coords which are SQR(2)
    
    
        oVertice.xYIn(X,Y)      'submit vertex coordinates, point not at origin
    
       'we'll store some values for further demo of other methods
    
        ra = oVertice.radians           'the radian angle
        vl = oVertice.vectorlength      'the vector length
        da = oVertice.degreesPM         'the degrees +/- 0 to 360
    
        'show the results of each method ... should be the same
        ? "Coordinate data entered with XYIn(X,Y) method." + $CRLF + _
          "Results:"+ $CRLF + _
          "X coordinate"+$TAB+FORMAT$(oVertice.x)+ $CRLF + _
          "Y coordinate"+$TAB+FORMAT$(oVertice.y)+ $CRLF + _
          "Radian Angle"+$TAB+FORMAT$(oVertice.radians)+ $CRLF + _
          "Vector Lngth"+$TAB+FORMAT$(oVertice.vectorlength)+ $CRLF + _
          "Degrees RAW "+$TAB+FORMAT$(oVertice.degreesPM)+ $CRLF + _
          "Degrees ABS "+$TAB+FORMAT$(oVertice.degrees),%MB_TASKMODAL ,"XYIn Results Report"
        oVertice.CalcReset                  'call method to clear the values
        oVertice.PolarIn(ra,vl)             'submit radian angle and vector length
          ? "Coordinate data entered with PolarIn(radians,vectorlength) method." + $CRLF + _
          "Results:"+ $CRLF + _
          "X coordinate"+$TAB+FORMAT$(oVertice.x)+ $CRLF + _
          "Y coordinate"+$TAB+FORMAT$(oVertice.y)+ $CRLF + _
          "Radian Angle"+$TAB+FORMAT$(oVertice.radians)+ $CRLF + _
          "Vector Lngth"+$TAB+FORMAT$(oVertice.vectorlength)+ $CRLF + _
          "Degrees RAW "+$TAB+FORMAT$(oVertice.degreesPM)+ $CRLF + _
          "Degrees ABS "+$TAB+FORMAT$(oVertice.degrees),%MB_TASKMODAL ,"PolarIn Results Report"
        oVertice.CalcReset                  'call method to clear the values
        oVertice.DegreeAngleVector(da,vl)   'submit degree angle and vector length
        ? "Coordinate data entered with DegreeAngleVector(degrees,vectorlength) method." + $CRLF + _
          "Results:"+ $CRLF + _
          "X coordinate"+$TAB+FORMAT$(oVertice.x)+ $CRLF + _
          "Y coordinate"+$TAB+FORMAT$(oVertice.y)+ $CRLF + _
          "Radian Angle"+$TAB+FORMAT$(oVertice.radians)+ $CRLF + _
          "Vector Lngth"+$TAB+FORMAT$(oVertice.vectorlength)+ $CRLF + _
          "Degrees RAW "+$TAB+FORMAT$(oVertice.degreesPM)+ $CRLF + _
          "Degrees ABS "+$TAB+FORMAT$(oVertice.degrees),%MB_TASKMODAL ,"DegreeAngleVector Results Report"
        oVertice.CalcReset      'call method to clear the values, results should be all 0
        ? "oVertice.CalcReset method." + $CRLF + _
          "Results:"+ $CRLF + _
          "X coordinate"+$TAB+FORMAT$(oVertice.x)+ $CRLF + _
          "Y coordinate"+$TAB+FORMAT$(oVertice.y)+ $CRLF + _
          "Radian Angle"+$TAB+FORMAT$(oVertice.radians)+ $CRLF + _
          "Vector Lngth"+$TAB+FORMAT$(oVertice.vectorlength)+ $CRLF + _
          "Degrees RAW "+$TAB+FORMAT$(oVertice.degreesPM)+ $CRLF + _
          "Degrees ABS "+$TAB+FORMAT$(oVertice.degrees),%MB_TASKMODAL ,"CalcReset Results Report"
        LET oVertice = NOTHING      'release the object
    END FUNCTION
    Attached Files
    Last edited by Richard Angell; 19 Aug 2008, 04:13 PM.
    Rick Angell

    Comment


    • #3
      PBCC version of NON COM Class and Object

      Essentially the same as the PBWin version above.
      The Code:
      Code:
      '------------------------------------------------------------------------------
      '   AllInOne_CVACALC.BAS   2008
      '   Created by R. Angell    - Public Domain, use at your own risk
      '   Demo of a Class and Object internal to a program in PBWin 9
      '   Shows a class using the EXTended precision variable types
      '   which are outside the scope of the COM specification , but
      '   can be used easily in this "unpublished" class situation.
      '-----------------------------------------------------------------------------
      #COMPILER PBCC 5
      #COMPILE EXE  "CVACALC_CLASS_ALL_IN_PBCC_PROGRAM.EXE"
      #DIM ALL
      #REGISTER NONE
      
      CLASS CVACALC
      
          'INSTANCE variables
          'A unique set of instance variables
          'will be created for every new object,
          'created from this CLASS; and which
          'may only be referenced from within
          'that object
          INSTANCE ptX          AS EXT
          INSTANCE ptY          AS EXT
          INSTANCE radangle     AS EXT
          INSTANCE vlength      AS EXT
          INSTANCE dangleraw    AS EXT
          INSTANCE dangleABS    AS EXT
          INSTANCE HasValues    AS LONG
      
          'Class Methods are private within
          'the classes' objects, that is they can not be
          'accessed externally, only internally.  You
          'access them using the ME keyword, like this:
          'ME.CalcRadAngle
      
          CLASS METHOD CalcRadAngle()
              'requires ptX and ptY
              'You can declare local varibles
              'and arrays in a CLASS METHOD or
              'in INTERFACE METHODs
               LOCAL ry,rx AS EXT
               ry = ptY
               rx = ptX
               ! emms
               ! fld ry
               ! fld rx
               ! fpatan
               ! fstp ry
               radangle = ry
          END METHOD
      
          CLASS METHOD CalcDegreeAngleRAW()
              'requires radangle
              dangleraw = radangle * 57.29577951308232##
          END METHOD
      
      
          CLASS METHOD CalcDegreeAngleABS()
              'requires dangleraw
              IF dangleraw = 0 THEN dangleraw = radangle * 57.29577951308232##
              IF SGN(dangleraw) = -1 THEN
                  dangleABS = 360 + dangleraw
              ELSE
                  dangleABS = dangleraw
              END IF
          END METHOD
      
          CLASS METHOD CalcVectorLengthXY()
              'requires ptX and ptY
              vlength = SQR((ptX)^2+(ptY)^2)
          END METHOD
      
          CLASS METHOD  CalcPolar2Rect()
              'requires radangle and vlength
              'ptX and ptY  are the return values
              'vlength is the distance from origin to point ptX,ptY
              ptX = vlength * COS(radangle)
              ptY = vlength * SIN(radangle)
          END METHOD
      
          CLASS METHOD CalcDegreesToRadians()
               radangle = dangleABS * 0.0174532925199433##
          END METHOD
      
      
          CLASS METHOD Update(BYVAL updcase AS LONG)
              SELECT CASE AS LONG updcase
                  CASE 1        'coordinates input updates
                      ME.CalcRadAngle()
                      ME.CalcDegreeAngleRAW()
                      ME.CalcDegreeAngleABS()
                      ME.CalcVectorLengthXY()
      
                  CASE 2        'polar input updates
                      ME.CalcPolar2Rect()
                      ME.CalcDegreeAngleRAW()
                      ME.CalcDegreeAngleABS()
      
                  CASE 3        'degree angle vector inputs update
                      ME.CalcDegreeAngleABS()
                      ME.CalcDegreesToRadians
                      ME.CalcPolar2Rect()
              END SELECT
              HasValues = 1
          END METHOD
      
          '--------------------------------------------------------------------------
          ' INTERFACES are where we define the externally accessible Methods and
          ' properties for an object created as an INTERFACE type.  While accessible
          ' externally if so specifed, an INTERFACE can be marked AS HIDDEN  to
          ' prevent its being documented in the Type Library (.tlb)
          '--------------------------------------------------------------------------
      
          INTERFACE CALCIO
              'Every interface must inherit, see the help file, and here to have a
              'Direct interface we will inherit from iUnkown.
              INHERIT IUNKNOWN                 'INHERIT CUSTOM for those who like
      
              'The INTERFACE's methods are equivalent to SUBs and FUNCTIONs
              'these here are like SUBs, but when a METHOD has the
              'FUNCTION style, with the AS vartype return type
              'then the methods value is assigned METHOD = retvalue
              'There are other source and help examples showing this.
              METHOD CalcReset ALIAS "CalcReset" ()
                  ptX = 0
                  ptY = 0
                  dangleraw = 0
                  dangleABS = 0
                  radangle  = 0
                  vlength   = 0
                  HasValues = 0
              END METHOD
      
              METHOD XYIn  ALIAS "XYIn" (BYVAL X AS EXT,BYVAL y AS EXT)
                  ptX = X
                  ptY = Y
                  ME.Update(1)
              END METHOD
      
              METHOD PolarIn  ALIAS "PolarIn"(BYVAL radianangle AS EXT,BYVAL vectorlength AS EXT)
                  radangle = radianangle
                  vlength  = vectorlength
                  ME.Update(2)
              END METHOD
      
              METHOD DegreeAngleVector  ALIAS "DegreeAngleVector"(BYVAL angleraw AS EXT,BYVAL vectorlength AS EXT)
                  IF SGN(angleraw) = -1 THEN
                      dangleraw = angleraw
                      dangleABS = 180 + angleraw
                  ELSE
                      dangleraw = angleraw
                      dangleABS = angleraw
                  END IF
                  vlength  = vectorlength
                  ME.Update(3)
              END METHOD
      
              'Properties are a special kind of method for setting or
              'returning a value. In this demo, we are only returning
              'resulting variable values after one of the primary
              'methods has been called.
      
              PROPERTY GET X ALIAS "x"() AS EXT
                  PROPERTY = ptX
              END PROPERTY
      
              PROPERTY GET Y ALIAS "y" () AS EXT
                  PROPERTY = ptY
              END PROPERTY
      
              PROPERTY GET radians ALIAS "radians"() AS EXT
                  PROPERTY = radangle
              END PROPERTY
      
              PROPERTY GET degrees ALIAS "degrees"() AS EXT
                  PROPERTY = dangleABS
              END PROPERTY
      
              PROPERTY GET degreesPM ALIAS "degreesPM"() AS EXT
                  PROPERTY = dangleraw
              END PROPERTY
      
              PROPERTY GET vectorlength ALIAS "vectorlength"() AS EXT
                  PROPERTY = vlength
              END PROPERTY
      
          END INTERFACE
      END CLASS
      
      '------------------------------------------------------------------------------
      FUNCTION PBMAIN () AS LONG
      
          LOCAL X,Y,ra,vl,da  AS EXT   'demo variables
          'Declare the object variable and its class interface type
          LOCAL oVertice      AS CALCIO
      
          'create the object from the Class CVACALC, on interface CALCIO
          'which is the declared variable type for this object
          LET oVertice = CLASS "CVACALC"
      
          X = SQR(2)  'this demo uses a vector 2 inches long,at 45 degrees
          Y = SQR(2)  'from 0,0 so we'll use the coords which are SQR(2)
      
      
          oVertice.xYIn(X,Y)      'submit vertex coordinates, point not at origin
      
         'we'll store some values for further demo of other methods
      
          ra = oVertice.radians           'the radian angle
          vl = oVertice.vectorlength      'the vector length
          da = oVertice.degreesPM         'the degrees +/- 0 to 360
      
          'show the results of each method ... should be the same
          ? "----------------------------------------------"
          ? "Coordinate data entered with XYIn(Xcoord,Ycoord) method."
          ? "----------------------------------------------"
          ? "Results:"
          ? "X coordinate"+SPACE$(4)+FORMAT$(oVertice.X)
          ? "Y coordinate"+SPACE$(4)+FORMAT$(oVertice.Y)
          ? "Radian Angle"+SPACE$(4)+FORMAT$(oVertice.radians)
          ? "Vector Lngth"+SPACE$(4)+FORMAT$(oVertice.vectorlength)
          ? "Degrees RAW "+SPACE$(4)+FORMAT$(oVertice.degreesPM)
          ? "Degrees ABS "+SPACE$(4)+FORMAT$(oVertice.degrees)
          oVertice.CalcReset              'call method to clear the values
          oVertice.PolarIn(ra,vl)         'submit radian angle and vector length
          ? "----------------------------------------------"
          ? "Coordinate data entered with PolarIn(radians,vectorlength) method."
          ? "----------------------------------------------"
          ? "Results:"
          ? "X coordinate"+SPACE$(4)+FORMAT$(oVertice.X)
          ? "Y coordinate"+SPACE$(4)+FORMAT$(oVertice.Y)
          ? "Radian Angle"+SPACE$(4)+FORMAT$(oVertice.radians)
          ? "Vector Lngth"+SPACE$(4)+FORMAT$(oVertice.vectorlength)
          ? "Degrees RAW "+SPACE$(4)+FORMAT$(oVertice.degreesPM)
          ? "Degrees ABS "+SPACE$(4)+FORMAT$(oVertice.degrees)
      
          oVertice.CalcReset                  'call method to clear the values
          oVertice.DegreeAngleVector(da,vl)   'submit degree angle and vector length
          ? "----------------------------------------------"
          ? "Coordinate data entered with DegreeAngleVector(degrees,vectorlength) method."
          ? "----------------------------------------------"
          ? "Results:"
          ? "X coordinate"+SPACE$(4)+FORMAT$(oVertice.X)
          ? "Y coordinate"+SPACE$(4)+FORMAT$(oVertice.Y)
          ? "Radian Angle"+SPACE$(4)+FORMAT$(oVertice.radians)
          ? "Vector Lngth"+SPACE$(4)+FORMAT$(oVertice.vectorlength)
          ? "Degrees RAW "+SPACE$(4)+FORMAT$(oVertice.degreesPM)
          ? "Degrees ABS "+SPACE$(4)+FORMAT$(oVertice.degrees)
      
          oVertice.CalcReset  'call method to clear the values, results should be all 0
          ? "----------------------------------------------"
          ? "CalcReset method."
          ? "----------------------------------------------"
          ? "Results:"
          ? "X coordinate"+SPACE$(4)+FORMAT$(oVertice.X)
          ? "Y coordinate"+SPACE$(4)+FORMAT$(oVertice.Y)
          ? "Radian Angle"+SPACE$(4)+FORMAT$(oVertice.radians)
          ? "Vector Lngth"+SPACE$(4)+FORMAT$(oVertice.vectorlength)
          ? "Degrees RAW "+SPACE$(4)+FORMAT$(oVertice.degreesPM)
          ? "Degrees ABS "+SPACE$(4)+FORMAT$(oVertice.degrees)
          ? "----------------------------------------------"
          
          LET oVertice = NOTHING      'release the object
          'Typical termination in PBCC for a demo program ...
          ? ""
          ? "Press a key to quit ...."
          WAITKEY$
      END FUNCTION
      Attached Files
      Last edited by Richard Angell; 20 Aug 2008, 12:03 AM.
      Rick Angell

      Comment


      • #4
        A Non-com Compliant Dll

        This DLL reflects the same class as the ALL-IN-ONE example that is not COM Compliant. However because it uses the EXT datatype which is not supported by the COM standard, no .tlb Type Library can be automatically produced by PBWin9.0. This is because it can not resolve the EXT datatype, so an error 581 would result. I discuss how to work around this in the test code source.

        Primarily you have two options: (1) make it COM compatible just to make a .tlb and use the PB COM Browser to produce a .inc, then edit the DLL source and the .inc to for the desired non-COM standard vartypes and recompile the DLL, delete the now unusable .tlb. === OR === (2) make the .inc include manually. In the first instance, please note that some PB datatypes would not be compatible with that approach in any event.

        As usual though, when you depart from the COM standard and use a datatype native to PB, but not in the COM standard, the results should be used in PB only applications and most likely might not work with other compilers and applications.

        Here's the code for the DLL.
        Code:
        '------------------------------------------------------------------------------
        '   CVACALC_CUSTOM.BAS   2008
        '   Created by R. Angell    - Public Domain, use at your own risk
        '   Demo of a NON-COM Class "published" in a DLL
        '------------------------------------------------------------------------------
        #COMPILER PBWIN 9
        #COMPILE DLL "CVACalc_Custom.Dll"
        #DIM ALL
        'REGISTER NONE must be outside the class def
        'to avoid erasing register values during
        'other processing
        #REGISTER NONE
         
        '---------------
        ' Note: the GUID$ entry above and the 2 following shortly are easily
        '       generated using the right click menu in PB's IDE. Then choose
        '       Insert GUID at the appropriate spots, shown here.  You can
        '       also do this with the Ctrl+Alt+G hotkey.
        '---------------
        %USEMACROS = 1
        #INCLUDE "Win32API.inc"
        
        $CVACALCGUID = GUID$("{0121BC27-5838-4357-9487-1C5B9027A918}")
        $CVACALCIO   = GUID$("{67A37D50-C998-4134-92F2-270840C2FFA6}")
        
        GLOBAL ghInstance AS DWORD
        '-------------------------------------------------------------------------------
        ' Main DLL entry point called by Windows...
        ' Using standard PB WinMain template function, comments removed
        FUNCTION LIBMAIN (BYVAL hInstance   AS LONG, _
                          BYVAL fwdReason   AS LONG, _
                          BYVAL lpvReserved AS LONG) AS LONG
            SELECT CASE fwdReason
            CASE %DLL_PROCESS_ATTACH
                ghInstance = hInstance
                FUNCTION = 1
        
            CASE %DLL_PROCESS_DETACH
                FUNCTION = 1
        
            CASE %DLL_THREAD_ATTACH
                FUNCTION = 1
        
            CASE %DLL_THREAD_DETACH
                FUNCTION = 1
            END SELECT
        END FUNCTION
        '------------------------------------------------------------------------------
        '   Here is where we are adding the Class(es).
        '   Note:
        '   For a compliant COM class (AS COM) we are can only use variable types
        '   BYTE, WORD, DWORD, INTEGER, LONG, QUAD, SINGLE, DOUBLE, CURRENCY,
        '   OBJECT, STRING, and VARIANT, when such are published variables.
        '   See "What is a Base Class?" in the Programming Reference\Objects and
        '   COM Programming section of the PBWin 9 help file
        '   THIS IS A NON-COM COMPLIANT DLL, because we are using EXT dataypes
        '   It is therefore necessary to create by manual edit its include file,
        '   because the PB COM Browser will have no .tlb to access.
        '------------------------------------------------------------------------------
        CLASS CVACALC $CVACALCGUID AS COM    'AS COM req'd to make Class accessible
            'INSTANCE variables
            'A unique set of instance variables
            'will be created for every new object,
            'created from this CLASS; and which
            'may only be referenced from within
            INSTANCE ptX          AS EXT
            INSTANCE ptY          AS EXT
            INSTANCE radangle     AS EXT
            INSTANCE vlength      AS EXT
            INSTANCE dangleraw    AS EXT
            INSTANCE dangleABS    AS EXT
            INSTANCE HasValues    AS LONG
        
            'Class Methods are private within
            'the classes' objects, that is they can not be
            'accessed externally, only internally.  You
            'access them using the ME keyword, like this:
            'ME.CalcRadAngle
            CLASS METHOD CalcRadAngle()
                'requires ptX and ptY
                'You can declare local varibles
                'and arrays in a CLASS METHOD or
                'in INTERFACE METHODs
                 LOCAL ry,rx AS EXT
                 ry = ptY
                 rx = ptX
                 ! emms
                 ! fld ry
                 ! fld rx
                 ! fpatan
                 ! fstp ry
                 radangle = ry
            END METHOD
        
        
            CLASS METHOD CalcDegreeAngleRAW()
                'requires radangle
                dangleraw = radangle * 57.29577951308232##
            END METHOD
        
        
            CLASS METHOD CalcDegreeAngleABS()
                'requires dangleraw
                IF dangleraw = 0 THEN dangleraw = radangle * 57.29577951308232##
                IF SGN(dangleraw) = -1 THEN
                    dangleABS = 360 + dangleraw
                ELSE
                    dangleABS = dangleraw
                END IF
            END METHOD
        
            CLASS METHOD CalcVectorLengthXY()
                'requires ptX and ptY
                vlength = SQR((ptX)^2+(ptY)^2)
            END METHOD
        
            CLASS METHOD  CalcPolar2Rect()
                'requires radangle and  vlength
                'ptX and ptY  are the return values
                'vlength is the distance from origin to point ptX,ptY
                ptX = vlength * COS(radangle)
                ptY = vlength * SIN(radangle)
            END METHOD
        
            CLASS METHOD CalcDegreesToRadians()
                 radangle = dangleABS * 0.0174532925199433##
            END METHOD
        
        
            CLASS METHOD Update(BYVAL updcase AS LONG)
                SELECT CASE AS LONG updcase
                    CASE 1        'coordinates input updates
                        ME.CalcRadAngle()
                        ME.CalcDegreeAngleRAW()
                        ME.CalcDegreeAngleABS()
                        ME.CalcVectorLengthXY()
        
                    CASE 2        'polar input updates
                        ME.CalcPolar2Rect()
                        ME.CalcDegreeAngleRAW()
                        ME.CalcDegreeAngleABS()
        
                    CASE 3        'degree angle vector inputs update
                        ME.CalcDegreeAngleABS()
                        ME.CalcDegreesToRadians
                        ME.CalcPolar2Rect()
                END SELECT
                HasValues = 1
            END METHOD
        
            '--------------------------------------------------------------------------
            ' INTERFACES are where we define the externally accessible Methods and
            ' properties for an object created as an INTERFACE type.  While accessible
            ' externally if so specifed, an INTERFACE can be marked AS HIDDEN  to
            ' prevent its being documented in the Type Library (.tlb)
            '--------------------------------------------------------------------------
        
            INTERFACE CALCIO $CVACALCIO
                INHERIT IUNKNOWN                 'INHERIT CUSTOM for those who like
        
                'The INTERFACE's methods are equivalent to SUBs and FUNCTIONs
                'these here are like SUBs, but when a METHOD has the
                'FUNCTION style, with the AS vartype return type
                'then the methods value is assigned METHOD = retvalue
                'There are other source and help examples showing this.
                METHOD CalcReset ALIAS "CalcReset" ()
                    ptX = 0
                    ptY = 0
                    dangleraw = 0
                    dangleABS = 0
                    radangle  = 0
                    vlength   = 0
                    HasValues = 0
                END METHOD
        
                METHOD XYIn  ALIAS "XYIn" (BYVAL X AS EXT,BYVAL y AS EXT)
                    ptX = X
                    ptY = Y
                    ME.Update(1)
                END METHOD
        
                METHOD PolarIn  ALIAS "PolarIn"(BYVAL radianangle AS EXT,BYVAL vectorlength AS EXT)
                    radangle = radianangle
                    vlength  = vectorlength
                    ME.Update(2)
                END METHOD
        
                METHOD DegreeAngleVector  ALIAS "DegreeAngleVector"(BYVAL angleraw AS EXT,BYVAL vectorlength AS EXT)
                    IF SGN(angleraw) = -1 THEN
                        dangleraw = angleraw
                        dangleABS = 180 + angleraw
                    ELSE
                        dangleraw = angleraw
                        dangleABS = angleraw
                    END IF
                    vlength  = vectorlength
                    ME.Update(3)
                END METHOD
        
                'Properties are a special kind of method for setting or
                'returning a value. In this demo, we are only returning
                'resulting variable values after one of the primary
                'methods has been called.
        
                PROPERTY GET X ALIAS "x"() AS EXT
                    PROPERTY = ptX
                END PROPERTY
        
                PROPERTY GET Y ALIAS "y" () AS EXT
                    PROPERTY = ptY
                END PROPERTY
        
                PROPERTY GET radians ALIAS "radians"() AS EXT
                    PROPERTY = radangle
                END PROPERTY
        
                PROPERTY GET degrees ALIAS "degrees"() AS EXT
                    PROPERTY = dangleABS
                END PROPERTY
        
                PROPERTY GET degreesPM ALIAS "degreesPM"() AS EXT
                    PROPERTY = dangleraw
                END PROPERTY
        
                PROPERTY GET vectorlength ALIAS "vectorlength"() AS EXT
                    PROPERTY = vlength
                END PROPERTY
        
            END INTERFACE
        END CLASS
        The code for the include:
        Code:
        '------------------------------------------------------------------------------
        '   CVACalc_Custom.inc include file  2008
        '   Created by R. Angell    - Public Domain, use at your own risk
        '------------------------------------------------------------------------------
        '
        ' Class Indentifiers
        $CLSID_CVACALC = GUID$("{0121BC27-5838-4357-9487-1C5B9027A918}")
        
        ' Interface Indentifiers
        $IID_RACALCIO = GUID$("{67A37D50-C998-4134-92F2-270840C2FFA6}")
        
        ' Interface Name  : RACALCIO
        ' Description     : CALCIO is a custom interface for Direct access.
        ' ClassID         : $CLSID_CVACALC
        INTERFACE RACALCIO $IID_RACALCIO
            INHERIT IUNKNOWN
        
            METHOD CalcReset()
            METHOD XYIn(BYVAL X AS EXT, BYVAL Y AS EXT)
            METHOD PolarIn(BYVAL RADIANANGLE AS EXT, BYVAL VECTORLENGTH AS EXT)
            METHOD DegreeAngleVector(BYVAL ANGLERAW AS EXT, BYVAL VECTORLENGTH AS EXT)
            METHOD X() AS EXT
            METHOD Y() AS EXT
            METHOD radians() AS EXT
            METHOD degrees() AS EXT
            METHOD degreesPM() AS EXT
            METHOD VECTORLENGTH() AS EXT
        END INTERFACE
        The test program code:
        Code:
        #COMPILER PBWIN 9
        #COMPILE EXE  "TEST_CVACALC_CUSTOM.EXE"
        #DIM ALL
        'PBWIn 9.0 release version will only create a .tlb .
        'Type Library if and only if the variable types are
        'those supported by the COM specification.  These are:
        'BYTE, WORD, DWORD, INTEGER, LONG, QUAD, SINGLE, DOUBLE,
        'CURRENCY, OBJECT, STRING, and VARIANT.
        '
        'Using any other PB vartype will generate an error 581
        'and the .tlb type library file will not be produced
        'if we have a #COM TLIB ON metastatement in our DLL code.
        'Since the default for #COM TLIB is off, a .tlb would
        'not normally be produced from any DLL source with or
        'without a #COM TLIB OFF statement.
        '
        'So when we want or need to have Classes supporting
        'the full range of PB vartypes we therefore must decide on
        'another approach.  Either we make a compatible DLL as was
        'illustrated in the first post, compile, use the PB COM Browser
        'to make a prototype include and then ... edit the DLL source
        'to use the intended vartypes, such as EXT in these samples,
        'set #COM LIB OFF (default) then recompile the DLL. Finally
        'edit the .inc include file by changing the specified vartypes
        'to the ones desired in the first place ... and then finish
        'the using application code.   Cleanup be deleteing the .tlb.
        'In this approach, please note that some PB datatypes would not
        'be compatible in any event and only tthe next approach is usable.
        '
        '*** OR ***
        '
        'For a small DLL, simply produce the .inc include file manually
        'in a manner simular to that for a typical DLL include.  Of course
        'it is needed to place the CLASS ID equates into this include just
        'as he PB COM Browser does for a compliant COM class DLL
        '
        'FINALLY, we should only use a CVACalc_Custom.DLL style library
        'with fully PB produced applications because use with other
        'compilers and programs is not officially nor likely supported
        'or possibly even usable.
        '
        #INCLUDE "CVACalc_Custom.inc"
        
        FUNCTION PBMAIN () AS LONG
        
            LOCAL X,Y,ra,vl,da  AS DOUBLE   'demo variables
            'Declare the object variable and its class interface type
            LOCAL oVertice      AS RACALCIO
        
            'The following code line lets us use a COM DLL without it needing
            'to be registered, and in this case will have installed in the
            'same directory, but if in another, add the path in the
            'string following the LIB keyword.  The $CLSID is assigned in
            'the CVACalc.inc and is also unique in the DLL
            LET oVertice = NEWCOM CLSID $CLSID_CVACALC LIB "CVACalc_Custom.DLL"
        
            X = SQR(2)  'this demo uses a vector 2 inches long,at 45 degrees
            Y = SQR(2)  'from 0,0 so we'll use the coords which are SQR(2)
        
            oVertice.XYIn(X,Y)      'submit vertex coordinates, point not at origin
        
           'we'll store some values for further tests
            ra = oVertice.radians
            vl = oVertice.vectorlength
            da = oVertice.degreesPM
        
            'show the results of each method ... should be the same
            ? "Coordinate data entered with XYIn(X,Y) method." + $CRLF + _
              "Results:"+ $CRLF + _
              "X coordinate"+$TAB+FORMAT$(oVertice.X)+ $CRLF + _
              "Y coordinate"+$TAB+FORMAT$(oVertice.Y)+ $CRLF + _
              "Radian Angle"+$TAB+FORMAT$(oVertice.radians)+ $CRLF + _
              "Vector Lngth"+$TAB+FORMAT$(oVertice.vectorlength)+ $CRLF + _
              "Degrees RAW "+$TAB+FORMAT$(oVertice.degreesPM)+ $CRLF + _
              "Degrees ABS "+$TAB+FORMAT$(oVertice.degrees),%MB_TASKMODAL ,"XYIn Results Report"
            oVertice.CalcReset                  'call method to clear the values
            oVertice.PolarIn(ra,vl)             'submit radian angle and vector length
              ? "Coordinate data entered with PolarIn(radians,vectorlength) method." + $CRLF + _
              "Results:"+ $CRLF + _
              "X coordinate"+$TAB+FORMAT$(oVertice.X)+ $CRLF + _
              "Y coordinate"+$TAB+FORMAT$(oVertice.Y)+ $CRLF + _
              "Radian Angle"+$TAB+FORMAT$(oVertice.radians)+ $CRLF + _
              "Vector Lngth"+$TAB+FORMAT$(oVertice.vectorlength)+ $CRLF + _
              "Degrees RAW "+$TAB+FORMAT$(oVertice.degreesPM)+ $CRLF + _
              "Degrees ABS "+$TAB+FORMAT$(oVertice.degrees),%MB_TASKMODAL ,"PolarIn Results Report"
            oVertice.CalcReset                  'call method to clear the values
            oVertice.DegreeAngleVector(da,vl)   'submit degree angle and vector length
            ? "Coordinate data entered with DegreeAngleVector(degrees,vectorlength) method." + $CRLF + _
              "Results:"+ $CRLF + _
              "X coordinate"+$TAB+FORMAT$(oVertice.X)+ $CRLF + _
              "Y coordinate"+$TAB+FORMAT$(oVertice.Y)+ $CRLF + _
              "Radian Angle"+$TAB+FORMAT$(oVertice.radians)+ $CRLF + _
              "Vector Lngth"+$TAB+FORMAT$(oVertice.vectorlength)+ $CRLF + _
              "Degrees RAW "+$TAB+FORMAT$(oVertice.degreesPM)+ $CRLF + _
              "Degrees ABS "+$TAB+FORMAT$(oVertice.degrees),%MB_TASKMODAL ,"DegreeAngleVector Results Report"
            oVertice.CalcReset          'call method to clear the values, results should be all 0
            ? "oVertice.CalcReset method." + $CRLF + _
              "Results:"+ $CRLF + _
              "X coordinate"+$TAB+FORMAT$(oVertice.X)+ $CRLF + _
              "Y coordinate"+$TAB+FORMAT$(oVertice.Y)+ $CRLF + _
              "Radian Angle"+$TAB+FORMAT$(oVertice.radians)+ $CRLF + _
              "Vector Lngth"+$TAB+FORMAT$(oVertice.vectorlength)+ $CRLF + _
              "Degrees RAW "+$TAB+FORMAT$(oVertice.degreesPM)+ $CRLF + _
              "Degrees ABS "+$TAB+FORMAT$(oVertice.degrees),%MB_TASKMODAL ,"CalcReset Results Report"
        
            LET oVertice = NOTHING  'release the object
        END FUNCTION
        Attached Files
        Last edited by Richard Angell; 25 Aug 2008, 11:06 AM. Reason: Updated for .tlb/no .tlb workarounds
        Rick Angell

        Comment


        • #5
          Your examples always demonstrate very good programming style-, Rich.
          --Theo Gottwald
          ------------------------------------------------
          76706 Dettenheim * Germany * [email protected]
          ------------------------------------------------
          Joses Forum * Theo's Link Site * IT-Berater.org

          Comment


          • #6
            Thanks Theo.
            Rick Angell

            Comment


            • #7
              I have updated both posts and files for the COM and Non-COM DLL. These are produced with the release version of PBWin 9.0. Please pay special attention to the comments in both the posts and the code as they attempt to convey some important concepts to keep in mind, especially in the Non-COM compliant DLL case.
              Rick Angell

              Comment

              Working...
              X