X
-
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.
-
Your examples always demonstrate very good programming style-, Rich.
Leave a comment:
-
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
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
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
Leave a comment:
-
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 FilesLast edited by Richard Angell; 19 Aug 2008, 11:03 PM.
Leave a comment:
-
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 FilesLast edited by Richard Angell; 19 Aug 2008, 03:13 PM.
Leave a comment:
-
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
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
Attached FilesTags: None
Leave a comment: