Results 1 to 1 of 1

Thread: Console as UIControl or AddressOf(,,,)

  1. #1
    thinBasic MVPs ReneMiner's Avatar
    Join Date
    Oct 2012
    Location
    Germany
    Age
    51
    Posts
    1,398
    Blog Entries
    1
    Rep Power
    154

    Console as UIControl or AddressOf(,,,)

    When trying to create a user-defined control that will not mimic- but really act and react as the original cmd.exe - i did some research and stumbled across this article:

    Using the DOS Command Prompt from Inside a VB Form

    After i studied that a bit - it not only shows how to create the basic control - but also how to spawn a new thread within the current script ] which might be interesting for those who want to do some multithreading-
    - and again the requirement to pass an AddressOf which is substituted in thinBasic using CodePTR but not working with any combination of parameters i thought why it would not work. we have Function_GetPtr that is not accessible from outside of thinBasic-scope but in any case thinCore - that creates the pointers - could "delegate" by memorizing my passed thinBasic-Functionptr with

    lets say the special keyword:

    AddressOf( Byval mythinBasicScriptFunction As thinBasicScriptFunctionName, ByRef Handler As Number)
    to create a handler
    and instead of the parameter that asks the AddressOf i could later write
    Call[back] To Handler or Handler._I_CALL_NOW

    the parser would find the keyword AddressOf - and send it to a function that i can not call nor see from thinBasic-script because it is not a regular function that would provide a keyword ---

    --- but a method of a private thincore class-variable, udt, datatype.... Name it "Method.X" for now

    Class methods are basically functions --- that should have an address in the sense of AddressOf.

    ' in thinBasic script i have to
    Declare Function dllFuncName Alias "realFuncName"([ByRef|ByVal any parameters],
        ...,{ByRef|Byval} pFuncAddr As lpWhateverProc,...,[ByRef|ByVal any parameters]) As ResultType
    
    ' so later I would use
    dim myResult as ResultType
    
    myResult = dllFuncName([any parameters]..., AddressOf(yeah what?),...,[any parameters])
    
    ' now think back to the declaration. 
    ' When i study the declaration i know in advance that i 
    ' must pass an AddressOf(something) 
    ' but thincore does not know from the variables names.
    ' except (go back to declaration):
    
    
    Declare Function dllFuncName Alias "realFuncName"([ByRef|ByVal any parameters],
     ..., {ByRef|ByVal} pFuncAddr As lpWhateverProc,... ,[{ByRef|ByVal} any parameters]) As ResultType
    
    Dim Handler as Number ' dllFuncNameHandler for thinCore
    [Declare|Substitute] AddressOf( [Callback] mythinBasicScriptFunction, Handler)
    
    or using new vartype/udt/class:
    Dim Handler As [New] AddressOf([Callback] mythinBasicScriptFunction)
    


    now core is informed to connect mythinBasicScriptfunction before i call dllFuncName ---

    Thincore will return the AddressOf method.X after the parser took a look ahead for the function that i named as myThinBasicScriptFunction. See below at "Is the function/header prefixed as CallBack?"

    --- and i have received in Byref passed or dimensioned dedicated type variable "Handler" a number that i will use later when i call as

    Dim myResult As ResultType
    
    myResult = dllFuncName([any parameters],...,[Call[ At]|Callback[ At]|Using] Handler[.CallToActivate], ...,[any parameters])
    

    Looking quite loose na - ...

    the internal thincore-class method, thats address is to be used would look alike this:

    class x[handler]class
      internalCall as Long
     
    ' assumed user-scriptfunctions can/must receive a 32Bit number if not a callback. 
    ' no matter if or what parameters are reality and must return a 32Bit-numeral as result
    
     method X(Optional byval bReceived() as byte) As Long
    
       static pScriptfunctions As String ' <= dynamic array of ptrs
       static thinHandles As String   ' from handles it should know if the associated scriptfunction is a callback
                                             ' alike if Handle > 0x7FFFFFFF consider it a callback 
       static activState as String
    
    String sParam
    Dword pParams, pMem, pFunc
    Long lPos, lStart, Replied
    Long isActive = 0x87654321 
    
     if Scriptfunctions <> "" then
    
       local pScrFunc(lenf(pScriptfunctions)/SizeOf(Pointer))) As Pointer At Strptr(pScriptfunctions)
       local hndle(ubound(pScrFunc)) as Dword at Strptr(thinHandles)
       local state(ubound(pScrFunc)) as Long at Strptr(activState)
    
       select case this.InternalCall
         Case 0 
          ' no its a call from somewhere else
        
       ' find a registered scriptfunction that is in active state = ready to be called
           while lStart < Ubound(pScrFunc)
              lPos = Array Scan state(lStart +1), = isActive
              if lPos = 0 then 
                 'did not find any active scriptfunction ?
                 ' just ignore that we were called 
                  ' give an error-message to the user to register his scriptfunctions correctly
                 ' free any allocated memory
                   if pMem then Heap_Free(pMem)
                ' and bye bye
                   Exit function
                endif 
                 lStart += lPos
                 if hndle(lStart) >= 0x7FFFFFFF then 
                     ' it's a callback 
    
                    if not callbackReady then 
                       ' get it ready now (fill in pseudo-variables etc and evaluate the function parameters)
                        callBackReady = true
                    endif 
                    ' call the callback at pScriptFunc(lStart)
               else
                 '  its another scriptfunction
                 if sParam = "" then
    
                   ' get parameters ready,
                select case ubound(bReceived) 
                case 0
              ' no parameters...
                   sParam = String$(4, $NUL)  ' create 32Bit var = 0
               case 1 to 3
                ' pad using $NUL to have it 4 bytes 
                 sParam = memory_get(varptr(bReceived(1)), Selectexpression) & Repeat$(4-SelectExpression, $NUL))
              case 4
                 
                  sParam = Memory_Get(Varptr(bReceived(1)),4)
              case else
                 ' its more than 32 bit... put it to memory and pass the pointer to the users scriptfunction
                 pMem = heap_Alloc(SelectExpression)
                 memory_copy(pMem, Varptr(bReceived), SelectExpression)
                sParam = MKDWD$(pMem)
            end Select 
    
           ' sParam should hold 4 bytes now that are the binary apperance of a 32 bit numeral 
           ' if user expects more than a 32 bit number he know its a pointer...
    
               pFunc =pScriptFunc(lStart)
               call pFunc( sParam ) to Replied
              if replied > 0 then
                 ' that was the function supposed to receive this message
                 ' check what is the reply
                  ' react and finally free the parameters data
                  if pMem then Heap_Free(pMem)
                  Exit While
              endif
        wend
    
       case %RegisterNewScriptfunction
           ' bReceived() will hold the information that was passed with AddressOf and detected by the parser
             ' look ahead to the pointed function if meets requirements
             ' determine if callback, create new handle 
            '  append scriptfunctionPtr, handle & state to the static strings/arrays 
       
    
      case %scriptfunctionActivated
           ' user called passing "Call To|Using" parameter with the handler  
           ' check if handler valid, if callback and if ok return AddressOf Method.x to be inserted in the actual call
         ' set the scriptfunction to active state
    end select
    ' clear the flag
    this.InternalCall = 0
    
    End Method
    
    When i declare a Function|Sub as user i must specify ByRef/ByVal in front of a parameter.

    For any other parameters that are to pass ByRef (or without to specify Byval) to the win32-Api:

    i as user must declare them ByVal and
    pass the VarPtr of a variable
    or pass a
    Pointer32 to sufficient allocated memory
    .
    (Alias DWord As Pointer32)
    That works for sure.


    Now when i declare some parameter AddressOf:
    thincore does a call to its above mentioned private class-variables method or to a function which is not visible to COM.
    The class needs a property that will be set by thinCore to signal the method when it was called by thincore to setup a new
    AdressOf(something), to invoke a call = to mark a scriptfunction as currently active recipient or to set it inactive or to query any information internally so the method knows from the flag what to do.
    The method must always clear the flag of course so if any call without flag: it is the call(back) from API to the method.X's address.

    Method.X needs 3static function variables (or can be properties of the class as well).
    Either dynamic strings or dynamic arrays of long or dword (or virtual dynamic arrays upon dynamic strings)

    They correspond, means

    element 1 of array scriptfuncptrs is associated to
    element 1 of the handlers that the method assigned and associated to
    element 1 of the current states

      Array1                Array2            Array3
    ScriptfuncPtr(1)   Handler(1)     State(1)
    ScriptfuncPtr(2)   Handler(2)     State(2)
    ScriptfuncPtr(...)  Handler(...)    State(...)
    
    ' simply:
    <associate>ScriptfuncPtr(Index) <==> Handler(Index) <==>  State(Index)</associate>
    
    The first Array/String would hold the passed thinBasic-scriptFunction-Pointers and the second Array/String would hold the Handlers that the method assigned to keep track. The validity of a handler proves that the AddressOf-declaration was done correctly and successful if there is a valid scriptfuncptr with the same index.
    the third array is actually not containing any pointers but flags that will keep the method informed if there is a call to expect / i.e.
    the scriptfunction is an active recepient for any callbacks that might come in.

    since any parameters are passed from thinBasic-script to the API are byval now there is nothing to store nor transform when my script calls the api/function, they can be passed right through.

    When i Declare...AddressOf, i also name the function that will be used to receive any parameters.

    Is the function/header prefixed as CallBack?

    If yes,
    it will receive the parameters as CBHNDL and all the other generic callback-pseudo-variables and the function header must not have any parameters between the parenthesis and return a value As Long, mandatory it is a function then. No Sub allowed.
    Anything does not follow the rules => RTE !!!

    If no,
    all the parameters must be byval and it can return only a message to Method.X that says:
    0: message not processed, wrong recipient
    +1: message received and processed - if bit not set Method.X should call the next scriptfunction on its list
    +2: reply "TRUE" to sender,( implements 1) means to return a value of -1 to the calling function from API
    +4: continue passing messages here (implements 1) means to keep this scriptfunctions state as still active
    ====
    result = 1 or result = 3 will set the state of this scriptfunction to 'no more active':method.x will not call this anymore
    result = 0 or result = 5 or result = 7 will not change the state

    to the
    parameters of myScriptFunction

    ByRef can not be here as usual. The user will have to split whatever parameters himself if more than 1 Byte to expect
    it can be "Byval b() as Byte" or "byval bin$ as Rawtext"
    thincore"s Method.X would just pass the bytes that it received as raw binary string
    or allocate a heap and pass the pointer

    its up to the user to split and parse it to parameters that can be passed to other script-functions.
    He knows what data to expect and can be happy to receive the data at all since it was impossible before. And still is - regarding dynamic data to a universal format without to have billions of functions to achieve it.


    Last edited by ReneMiner; 26-03-2021 at 22:15. Reason: title ...
    running thinBasic in HP Desktop Pavillon 8GB Ram AMD A6-9225 Radeon R4 5Compute Cores 2C+3G @2.6GHz

    OS1: Windows x64 Pro 10.0.18363.418
    OS2: ThinDE (WinRE+.NetCore-based customized Developement Environment)

Similar Threads

  1. Console Box and Console Readline
    By TheOne in forum Console
    Replies: 8
    Last Post: 22-03-2011, 18:32
  2. console simulation ui
    By Lionheart008 in forum UI (User Interface)
    Replies: 1
    Last Post: 09-01-2010, 11:23
  3. my first console script :)
    By Lionheart008 in forum Console
    Replies: 2
    Last Post: 18-02-2009, 13:14
  4. console window
    By fravado in forum Shout Box Area
    Replies: 3
    Last Post: 08-04-2008, 15:26
  5. console scripts
    By sandyrepope in forum Console: source code examples for beginners
    Replies: 4
    Last Post: 16-02-2007, 02:11

Posting Permissions

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