Results 1 to 2 of 2

Thread: Help please: module classes - Properties

  1. #1
    thinBasic MVPs
    Join Date
    Oct 2012
    Rep Power

    Post Help please: module classes - Properties

    Does anyone know how to use thinBasic_class_AddProperty() ?

      ' Add a property to a class previously created with thinBasic_Class_Add
        DECLARE FUNCTION thinBasic_Class_AddProperty  _
                                LIB   "thinCore.dll"                        _
                                ALIAS "thinBasic_Class_AddProperty"         _
                                (                                           _
                                    BYVAL pClass                AS LONG   , _     '---Poiter to a class. This is the value returned by thinBasic_Class_Add
                                    BYVAL sPropertyName         AS STRING , _     '---Name of the Class to be created
                                    BYVAL PropertyReturnType    AS LONG   , _
                                    BYVAL PtrToPropertyFunction AS LONG     _     '---Pointer to a method function that will handle method execution
                                 ) AS LONG
    this seems incomplete to me.

    Properties as i kniow have usually 3 procedures Let, Get and Set that are present or not present for every UDT-Subelement and the presence of the
    property-procedure determinesif there is a default value and if access allowed to read or write at all.

    Let := the initial, predefined, default setting applied on creation to any new object of the type, inherited from prototypes if no own dedicated Let is present for the inherited property. An empty Let-procedure will override the inherited setting just because it is present. Without a Let-procedure a property will contain Nothing
    when the object that owns the propertyt is created.

    Get := request to pass the data that is stored for this property. Required within the Get-procedure is a read-only- reference that holds full Function-name (stacklevel below this) which in case UDT-function will also hold the type of the invoker of that call. To assure it's not a virtual fake using a layover the call-invokers varptr mus be followed down all stack levels and if the stack level above the first appearance of the caller is _CREATE and the name of the variable on that level is "ME" then for sure the call is invoked by the referenced object that was dimensioned on the memory-position which matches the current varptr. Without a Get-procedure the property is limited to a public "Can Set if condition"-state and the owner can still decide no, the condition is not valid for you since its not possible from outside to check the properties current state.

    Set := request to fill a passed value into the memory-position that represents the properties data. Of course data must match in type, size and count if property were an array. If not matching - bye bye. Caller can not alter properties by pushing a value in to make it fit but request the owner to shape the property in a way that the data will fit. In case the owner expects it the property will be prepared anyway or there is a dedicated method that were known to the calls-invoker. Without a Set-procedure the data at most public read-only , if none of the both is present the property is totally private.

    Property <propertyname> Let(byRef data as Typeof(This.<propertyname>))
         data = <InitialSetting and one more if sunday>
    End Property
    Property <propertyname> Get(Byval Invoker As thinbasic_ObjectSecuritycheckresultEx) As TypeOf(This.<propertyname>)
        if (Typeof(me) <> Invoker.DetectedType Then 
          SendMessage(hSecurity, %SM_Intruder, "attempt", Invoker.CurrentLocation)
          Exit Property
    End Property
    Property <propertyName> Set( Byval Invoker As As thinbasic_ObjectSecuritycheckresultEx, Byref data As Typeof(this.<propertyname>)
       if condition=OK Then This.Property=data
    End Property
    the "thnBasic_ObjectSecurityCeckResultt" were a small udt that provides infformation as TypeOf(Invoker), Varptr(Invoker) , FunctionName of the lowest stacklevel where a variable at same position appears for the firrst time. Must be down from current stack level and stop where no variable is dimensioned on this position and go 1 level up again . There we have the function where the caller was created in. if one more level up is no function that ends with "_CREATE" means if the type of the property-owner has a create-function the invoker of the call is not real. If the function ends with "_Create" it also tells the type as that the variable was created when we remove 7 chars on the right. ("_CREATE") remains a type-name, ideally the name of the variable as what the typename is replaced when a function is called on a type.
    However, security-information is combined of
    3 sdk-functions:
    thinBasic_VariableGetList           retrieve list of all variable names on a stack-levels below starting level, i.e. at the callers level 
    thinBasic_StackGetList             retrieve the function-name on all  stack-levels below current (= callers level)
    thinBasic_VariableGetInfoEX   actually we are interested only in 3  values  searchkey, dataptr and stacklevel
    2 thinbasic-functions
    VarPtr()                            required the varptr of the call-invoker. as a type function requires a reference it should not be difficult 
                                          to retrieve from where in memory the call was made. 
    Function_StackGetLevel     assure the current stack level is the one above starting investigation.
    ATTENTION: If you pass Function_GetStacklevel as a parameter it will not return the stacklevel of the caller
    but is evaluated on arrival and returns the called stacklevel but not the callers level. Conserve the result
    -before you pass it - into a variable to pass the real value of your current stacklevel

    How it works: As first determine varptr of the caller and get the current stacklevel
    then get the stacklist as
    String sFunc()
    Long nLevels = Parse Ucase$(thinBasic_StackGetList($NUL), sFunc, $NUL
    nLevels should equal current stacklevel, sFunc(nLevels) should hold the functions name where inside you are.
    if its shifted by 1 there might be an unforseen app_entry through a side-entrance ,

    that can be abusing _Create-function as app_entrypoint,

    no tbMain present or never entered ( it would usually appear in sFunc(2) )
    the never-exit from a callback by buillding a mainloop inside a callback-function
    (- bad idea - windows will shut you down soon as not responding app)

    or with some suicidalwild approach catapulting yourself
    using codepointers of dlls to jump from function to function -

    testing a dubious module that will implement finally the long time missed
    - but by some genius brand-new developed GOTO-statement for thinbasic
    where you exit another function as the one that as entered before.

    Risky, hot stuff that can shoot not just your tb-installation
    including the destruction of the root-folder in thats subdir your script or dll is located.
    If your scripts are saved to "%systemdrive%\Users\Username\whatever"
    the effect is hitting the most vulnerable spot - of the os,

    say "good bye users" and your only chance is reduced to the fact that you have
    a 3rd party tool as 7zFM , Multicommander or TotalCommander opened which could
    rescue something through exraction of a backup that contains also the users folder.
    It will not rescue the content of the users folder nor your data inside, but save you
    the complete re-install-procedure of windows

    Ops... sorry-...

    yes...err where was i ... the invoker of the call to a type function - determine list of functions that build the current "stack-level-ladder"
    then go down 1 level,
    obtain list of variables on the level, iterate the variable-names pass the names to thinBasic_GetVariableInfoEx and also the current stack level and compare the DataPtr that is filled in by the function.
    If it matches, then you passed the name that the invoker has on this stacklevel .
    continue and repeat the same procedure
    get variable names and pass them to compare dataptr with the varptr. if there is no match on this level means you are below the level where the invoker was dimensioned. So you find already function of first appearance and the name as that thew suspect was dimensioned.

    A lot of useful information you will get if you go 2 levels up again when you are below the first appearance level. the functions name con that level can tell you if the invoker is a virtual or a real variable. If the name of the function ends with "_CREATE" you have found a real variuable, remove the 7 chars from the right, i.e. Left$(s, Lenf(s)-7) : that reveals the udt as that the suspect was dimensioned. . The not-presence of a create-function is not necessarily a sign of evil. But if a create-function is present for the type and our invoker is not member of an array it remains the virtual variable that is used by someone with no good intentions.

    Accidental no one will make any effort for disguise of some variable being another one. There are already tools available and we have the additional option to use iinheritage of some secret security-features that a native classification in thinbasic could have. For the classification required are the properties that will elevate types to become prototypes =templates of cllass-objects. the other thing is the script structure which is currently procedural mainly. Some UI-items as the webbrowser-control contains the requiremnents to make an app event-driven - no own mainloop but all is reaction on user-actions. a very stable and simple way of building an app. Threadsafe by nature and actually fits the behaviour if a script runs window-bound in thinbasic. Losing focus halts the execution . Good for windows but we can get over this already using all kinds of triggers (timers not bound to a window, sending of callback messages in an endless loop of one calls two-two calls three,.three calls four...) and there are couple of more ways to stay in race without having a windows-focus.


    sorry... i know...
    the scriptfiles themselves must have written something on the first and last line of the file. Using invisible ink, and the line on top were
    Type fullpath_scriptfilename.tBasic[C|I|U]?
    and the last line were
    End Type
    now scriptfiles were to classify into a MainScript and only the one with the app-entry-point has the very special rights to acccess all that is created by the main-function ("GOD-MODE") , other functions contained within the Main-scriptfile have limited rights as they share a common variable-scope that is not shared with any other file what is defined PUBLIC or COMMON were shared by the functions that are located within same Script-Area which ends if physically another scope is errected

    . Type-definitions, Unions, ergo classes and callback functions are barriers that limit the valid range where the scriptfile itself is an udt.
    Same rule for all: no udt can intersect the borders of another udt. if the script is an udt the mainscript centralizes the valid area of the major-app-scope
    special declarations-section - the part of any udt-definition between the first line "Type tTypename" and the headline of the first Method where for an udt where the subelements are defined anbut only definitions, dimensionss, declaration, enumerations, namelists etc.

    the scope-free area of the main-scriptfile is where DIM will by default create global variables. Privates can not be for non-property-owners but functions within the main-scriptfile share the subelements of a hidden type that are assigned to this hidden udt when using the keyword PUBLIC and in all functions that share the Public range on all the hidden utds properties are virtual variables local dimensioned over the subelements of the hidden udt as soon any function is entered that is defined within this "public" udts invisible Typ-End Type range, creating the illusion that same named variables of same type as outside of the function would survive what usually happens to any local variables when a function is terminated.

    Public is an illusion , created by virtual alias/layover with same name as the udt-elements of thew hidden type that wears a scriptname and that is not to be dimensioned as a variable. There is no further protection required functtions and anything else of the project that is not connected to the "Aura of TBMain" will not be supplied with the virtual pre-dimensioned variables upon the scriptname-type.
    There is another type of scripts that could have a scope . the unit. pretty simple . if contains not a type- statement in the first and end type in the last line but is called unit (tBasicU) the requiremmeents are simple: No UDT/class/Union end Type/class/ Unionblock allowed. Only functions and subs. Outside of functions and subs declarations, definitions, enumerations, resource-blocks only but no executed code that exceeds initial assignment for that simple core-functions are ok as Hex$, ASC, ABS, Fix, MinMax . Also preparsing statements, directives all what starts with a #-char is only a allowed outside of scriptfunctions and ignores any scope range- Not influencd as these keywords do not interact with variables content but theirs availability.
    in no case the mainscript nor a unit must expose major structural keywords utsidw of a function/sub- end function/sub frame. this means Do/While/For/Repeat loop-conditionals and If, Select Case, Try-Catch, Call - pretty much all core keywords that alone will raise an error. -
    exceptions are lines starting Declare, Alias Uses, Module that actually were to place in global scope areas.

    Enough na- too much!

    Really? but am not finished. Maybe you continue reading another time...

    When the whole script is divided to aereas that have own variable scopes , units that either contain one real type/class/union only or none are elevated to kind of pseudo-class - wait -remove the unions or add functions to them . without functions the unions are nothing equal to types nor classes but the closes relatives of arrays that suffer the same faith.

    properties to types ... make prototypes.

    Prototype never Extends any other Type and all elevated types (name them class now when their ancestor is a prototype)
    Any class can have different types of objects. and all objects of a class can have the inherited properties which make them the same class . Some objects will have the same additional properties that are not inherited but lets these seem to have a similar layout or equal appearance. And these not-inherited properties that similar objects have in common can not be inherited from non-prototypes. inheritable is only what is individual attached. Properties from a pool are not individual. The way to create a new prototype from an existing object is cloning. A clone will not have inherited connections to any previous prototype. It's a clone. Artificial reconstructed. All its properties are created as new from scratch. That base makes it a valid prototype and can implement also properties that the original object received before it was cloned . Cloning implements copys of methods, properties and variables that are attached to other objects in non-inheritable manner and allows to inherit them from the clone as prototype. Cloning really means to copy the code that assembles the final layout with all and every bit - and here is an unbeatable advantage that an interpreter has - especially when it is able not only to assemble the unit-file for the new prototype on the fly but can also shell a new process async , drop required information to a file it shares with the new process and the user will not even know that the program he was still looking at 1 second ago has ended and what he looks at now is another process. And if you woul tell him-he 'd just smile at you and say something like

    "you're kidding me. i know you're fun-type. Kind a fun-tastic touched Grow up kiddo this is serious work i'm doing here go and play sum-thin harhar got it? wordplay ?sum --- thin - Im a fun-type two . Point zero harhar..."

    within Prototype udtName -End Prototype the Keyword Function becomes Method

    ...oh yeah where was i ? Guess i had a vision or sum-thin...

    Anyone knows what rules are to play for these PROPERTIES?


    For Array-elements it's not possible to request information as this because new Array-elements could come and go by redim, means also an array can never be prototype nor an object but at most mimic the data-structure. Elemets of Arrays will be sorted and carry an "Exit Property"-sign that will become valid and is executed as soon the condition "inside property-procedure" is met. functions that are not scoped through a Type-End Type frame surrounding them
    Last edited by ReneMiner; 08-04-2022 at 03:25.
    I think there are missing some Forum-sections as beta-testing and support

  2. #2
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Brno - Czech Republic
    Rep Power
    Hi Rene,

    if I may, I can offer you example of thinBasic_Class_AddProperty in the source code of thinBasic StringBuilder module:

    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

Similar Threads

  1. Keywords, constants, UDTs and classes for each module
    By Petr Schreiber in forum Sources, Templates, Code Snippets, Tips and Tricks, Do you know ...
    Replies: 3
    Last Post: 08-02-2018, 23:25
  2. Doubt about classes in another module
    By kcvinu in forum Module Classes
    Replies: 10
    Last Post: 08-11-2016, 20:09
  3. Module classes
    By ErosOlmi in forum thinBasic vaporware
    Replies: 19
    Last Post: 02-12-2011, 12:15
  4. Article: Module classes
    By ErosOlmi in forum vBCms Comments
    Replies: 9
    Last Post: 30-06-2011, 16:38
  5. Properties
    By efgee in forum O2h Compiler
    Replies: 7
    Last Post: 03-09-2010, 23:09

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts