PDA

View Full Version : Please Improve ThinBasic



kcvinu
01-05-2021, 20:58
Hi Eros,
I was working on a GUI toolkit. But some imperfections in Thinbasic got in my way. They are as follows.

Private is not working. So now we can access any private variable from a type.
We need properties in thinBasic. I hope you cn imitate FreeBasic's property.
We need Function overloading in thinBasic. Especially constructor overloading is important.
Please update CodePtr to take a function with 6 parameters. See this function signature.




Function Subclassproc(
hWnd As Dword,
uMsg As Dword,
wParam As Dword,
lParam As Long,
uIdSubclass As Long,
dwRefData As Long ) As Long

We need to pass the pointer of this function, in order to subclass a control. CodePtr now take functions with only 4 params. So please consider this.
I hope you complete these when you have time.

ReneMiner
06-05-2021, 20:55
for your Private request:
Do not use variables to store data. Use the Heap-memory that will allow you to grant access to any data by your rules.
Use variables local then to place the udt upon the data-pointers.

For the properties:
If you want to apply additional properties to some Window or control create simple udts for that to store additional information
- order a bit by control types, i mean the window will not have the same additional properties as a button has.
Use like a basic type for information that all items have in common as


type tUIObjectInfo
pType as Dword ' point the position where you store the typeOf(a control or dialogs udt)
' as .pType = Heap_AllocByStr( typeOf( the udt.name that you append to this control )
' it will work as this already but save a lot of memory and create a function that will remember
' where the name is stored so you can use the same value in .pType - that will also let you compare
' if objects are similar, i.e. same typename if same pointer to typename...
pText as Dword ' most objects have a text or caption. you can store up to 2 GB in one string and only append the pointer here
' makes all objects same-sized. You can as well append an array of pointers >> put them together to a string
' sPtr$=MKDWD$(ptr1, ptr2, ptr3,...) and store it : .pText=Heap_AllocByStr(sPtr$)
'that were the way to store it seperated to lines for multiline textboxes or lists & dropdown.lists and
' any arrays of dynamic data
flags As Long ' you can use bitflags and binary operators "AND|OR" to store plenty of information about usage of certain ' subelements likewise pText were to treat as simple text or its a joined array to parse by a delimiter or a table to ' parse or stored data is as above an array of pointers where each pointer points 1 line of text.
X1 as Long ' the first(left) position of this object
Y1 as Long ' the top position
X2 as Long ' the last position of this object - it were the very right pixel on the client of this objects parent
' you can obtain the width of it - or do it the other way and store the width instead
Y2 as Long ' same to height
End Type



this maybe 7 subelements were what all visible items in a windows-environment have in common, perhaps you require things as Enabled, Visible, BlinkOnFocus, just add it if all shall have it.

now you might need an additional udt for the main-window that shall contain a menu and some accelerator table



type tMainWindow extends tUIObjectInfo
hMenu as Dword ' also can be Long, but handles and pointers are usually unsigned, i.e. no negative values
hAccell as Long
End Type

' and you will create controls:
type tBasicControl extends tUIObjectInfo
CtrlID as Long ' all controls will have a ControlID...
End Type

the types based on another type have automatic all properties of the one that they "extends"

and then you want a few buttons that will perform actions. you would create a basic button typethat extends tBasicControl to provide standards as simple PushButtons that will change a state or commandbuttons that will instantly fire a sub, others were to open a dedicated dropdown or checkboxes, option buttons etc. for each special button you would create an extends-basic button-udt. Many of the items properies are part of the controls in UI already but some you are missing or should be private?
Remind yourself and make the text-property of a Passwoord-control private and create the private-text property in a way that it can only be retrieved in a function with byref tUIObject-parameter and decide if the referenced object varptr is one who gets granted the access. Or add the varptr to the dataptr and add your lucky number that nobody knows that you store to the pText-slot and nobody knows how to use this number - even you need the correct controls udt-storage location (i.e. varptr for your udt) and your lucky number to subtract it and then you know where you get the data.

and then, thats what you must think previously - besides some planning - ,


Declare Function SetProp Lib "user32.dll" Alias "SetPropW" (ByVal hwnd As Long, ByVal lpString As Asciiz, ByVal hData As Long) As Long
Declare Function GetProp Lib "user32.dll" Alias "GetPropW" (ByVal hWnd As Dword, ByVal lpString As Asciiz) As Long
Declare Function RemoveProp Lib "user32.dll" Alias "RemovePropW"(ByVal hwnd As Long, ByVal lpString As Asciiz) As Long


3 functions that will allow you to attach the additional properties to anything that has a Windows-handle.
As You see its all WideString and null-terminated, so you would probably store the pointer of "myButton_123" additional data like



String PropertyName = UTF8ToWideChar$("ControlExtraData") & String$(4, $NUL)
' the property name can be anything. For same properties often used it makes sense to store the name
' instead to repeatedly create it

Dword PointerToAdditionalData = Heap_Allocate(SizeOf(mySpecialButtonType))
Local x as mySpecialButtonType At PointerToAdditionalData
Heap_Set(x.pText,"Hello i am the special Button") ' one of many ways to store something at heap
x.CtrlID = myButton_123.ID


SetProp(myButton_123.handle, PropertyName, PtrToAdditionalData )


thus there is no AddProp - SetProp will do, means if you change the location by allocating it elsewhere that you must also change the pointer to the properties which is attached to the hWnd. You can as well use named properties and add them one by one.
GetProp will return you the stored pointer, i.e. position where you find your data or 0 if property with the passed name is not available on the windows-object thats handle was passed. maybe also error < 0 if no such handle

kcvinu
09-05-2021, 16:29
@Rene Miner,

Thanks for the reply. I am not sure I get your idea completely. I think SetProp and GetProp seems a good idea but how does it solve the problem I stated ?
My problem was the access scope of a property. If I declare something as private, it should remain private. Correct me if I am wrong. And once again sorry for not understanding what you described.

ReneMiner
11-05-2021, 05:42
Lets see ... some thoughts to it... if we want something not exposed to the whole project but only available to a certain udt-element then we must not store it directly into a global variable and the data of array members must not be stored in DSA (dynamic structure array) nor DPA ( dynamic pointer array) since this would allow to calculate the start of the other elements data.

We do not have objects, classes and interfaces of classes as known from other languages in tB since tB was invented as a procedural language. Most .net-languages are object-based and driven by Events. And if no event to handle the core language idles waiting for events, ready to fire a procedure then.

Also we do not have the code modules that provide their own variables scope but all outside functions is on a global scope, means

we need to create a variables scope that lets us access global as now (public to anything) but seperates individual modules information to different code units - for the file-extensions it would make a difference then:

a loaded units code were something separate to the global scope. Even the MAIN-unit were to see as separated from global scope but sharing all its functions and variables with the other units by default.
In fact the main function can not be called while its running already - it were to throw an ERROR if tbmain is called from any other function or by itself recursively - and its local variables are private to it.
TBMain or AppEntrypoint were to elevate to be on a higher scope than global.

The main-unit consists of the TBMain-function only by default. But the scope of Main would allow functions that can be called from TBMain only and private variables, i.e. shared on Main-scope level between the main-scope functions. Already to separate
anything that happens before Main-scope is entered: type definitions, contants, external declarations or global variables / all this what is now pure global scope only became "Public" in ownership of main-scope.

Default on mainscope : functions without explicit declaring them Private are public. Globally accessible to anything while private functions or variables are available on main-scope only. Keyword "Global" were an alias for "Public Dim" only. Even declarations of external functions were actually available to anything or private to the units scope.

What is now "Global scope" becomes "Project scope" and were to define in the project file before the main-scope is entered.

Then the keyword "Public" were the way of a unit to open some of its encapsulated scope to grant global / project-wide access by declaring it public or "Private" to keep it on scope-level.
"Shared" could specifiy a selection of project members that might use the same data.
Included files for that were included on the scope global: accessible to all while from a unit included files would be included to the units scope - except the unit uses keyword "Public" to allow the included data being global... Functions and variables of an include-file were what extends the modules. To make it better than visual studio and to differ code-Units from the arbitrary udt
the units should be named within a project to give the ability of instancing, extending and inheritage and

#Include were to separate: file extensions .inc or .tBasicI to be included to the calling units scope prefixed with the units instance name or public/ global without prefix. I am not sure if it were a good idea to use dot-notation to append extensions/functions/variables on a scope of a unit. it might be confusing whether is that an udt or a class ... I think
Since its like files/about files... - backslash offers unitname\Functions_or_variables_name or unit\includename\property already common easy to understand or arrow-notation c-like "->" or double-double-colon :: which is common in a language that starts with P , or to enclose these tokens by simply with some braces to groups {somehow;separated_bunch_of;expressions}
or the underscore (advantage: wordchar, does not split tokens when parsing / disadvantage tokens are not split to seperate portions) is secondar. Its just as type-functions that same functions are shared by referenced members

my god, its already too much to read...