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:
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.
And finally a commented listing for the test program.
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.
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
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
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
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
Comment