Results 1 to 4 of 4

Thread: Never use Len when you use unicode string.

  1. #1
    Member
    Join Date
    Aug 2015
    Location
    Keralam, India
    Posts
    118
    Rep Power
    17

    Never use Len when you use unicode string.

    Hi all,
    Last day, I was trying to create a static control (Label) for my gui toolkit. Eventually, I need to implement the AutoSize property for my tLabel type.
    After a few minutes of google search, I ended up in GetTextExtentPoint32W function. Here is the header.
    Declare Function GetTextExtentPoint32 Lib "Gdi32.dll" Alias "GetTextExtentPoint32W"(Byval hdc As Dword, 
                                                                                          Byval lpString As string,
                                                                                          ByVal c As Int32,
                                                                                          Byval psizl As Long) As Boolean
    
    The third parameter c is the length of the string in question. At first, I've use Len(Me.Text) for that. I got wrong results. My primary suspect was the type of second parameter. So I tried to change it to Asciiz, Wstring etc. But no luck. After wasting some hours, I decided to read about string functions in Win32. At that time, I noticed the lstrlenW function. Suddenly, I realized my mistake. Then I warped up lstrlen in a function like this.
    Function StrLen(sValue As String) As Int32
      Return lstrlen(UTF8ToWideChar$(sValue))
    End Function
    
    And here is the header.
    Declare Function lstrlen Lib "Kernel32.dll" Alias "lstrlenW"(ByVal lpString as string) As int32
    
    Then I got the correct result.
    Last edited by kcvinu; 30-04-2021 at 10:33.

  2. #2
    thinBasic MVPs ReneMiner's Avatar
    Join Date
    Oct 2012
    Location
    Germany
    Age
    51
    Posts
    1,418
    Blog Entries
    1
    Rep Power
    156
    Quote Originally Posted by kcvinu View Post
    thats right. For Unicode, especially WideString use LenW.

    Hint: If an Win32-Function ends with a Capital Char and involves Strings as Parameter or returned value it a signals

    ...A: to be ANSI
    ...W: for unicode wide

    ...Ex: there was previously another Function that got Extended in any way now.


    and for thinBasic: if you see something trailing some keywords:

    ...$ : get ready to receive a string
    ...W : widechar involved
    ...Z : terminating zero ,for Utf-7/8 Ascii append $NUL,
    for Utf-16 append mkWrd$(0) or mkByt$(0, 0) or String$(2, $Nul)
    UCS-2/Utf-32 append mkDwd$(0), i.e. Repeat$(4, $Nul) or Chr$(0, 0, 0, 0)


    ...F is a faster solution of a function but requires mostly to work with a value stored to a dimensioned variable
    accepts virtually applied variables upon the memory as well.

    In some cases if subelement of subelement within an array of udt...

    its anyway fast style to name the thing locally when its used more than once.
    saves you repeatedly to type in "the same corners where to go around" like
     local lSetting as Long at varptr( 
                       myApp_settings.Editorsettings(
                                %Userdefined + currentUserID).codepage  )
    
    ' now that long thing above is just: lSetting
    
    before you type this a second or third time you will certainly consider to place a local name there and not calculate a second time %Userdefined+currrentUserID and additional every dot to signal it goes down another branch.of.something = that means for the processor to find the matching subelements name, lookup the distance from the root and add it - for each and every dot you typed

    Consider to move the name that is covering the bytes in memory and puts the mask of a variable onto it to another position relative to its current position is to prefer over calculating from the root (here: varptr(myApp_Settings)) again.
    To find distance and direction of movement subtract the actual position from the target position. Thats easy.

    setAt( lSetting, GetAt(lSetting)+(anotherUserID - currentUserID) * SizeOf(Editorsettings) )
    
    ' or if the next setting just were following the current:
    
    setAt(lSetting, GetAt(lSetting)+ SizeOf(lSetting))
    
    What you pre-calculate using "Brains 2.0 incl. ExpansionPack" while you are coding will make your code run faster
    running thinBasic in HP Pavillon Desktop 590 a0xxx 8GB Ram AMD A6-9225 Radeon R4 5Compute Cores 2C+3G @2.6GHz

    OS: downgraded again to Windows 10 Enterprise x64 10.0.18363 Build 18363 (1909)
    (alternate OS: modified WinRE - boot from a fake ramdisk - currently in "reconstruction mode")

  3. #3
    Member
    Join Date
    Aug 2015
    Location
    Keralam, India
    Posts
    118
    Rep Power
    17
    @Rene Miner,
    I am sorry, I didn't get you. I am confused about "SetAt". What is it used for ? To set a pointer at new memory location ?

  4. #4
    thinBasic MVPs ReneMiner's Avatar
    Join Date
    Oct 2012
    Location
    Germany
    Age
    51
    Posts
    1,418
    Blog Entries
    1
    Rep Power
    156
    Quote Originally Posted by kcvinu View Post
    @Rene Miner,
    I am sorry, I didn't get you. I am confused about "SetAt". What is it used for ? To set a pointer at new memory location ?
    SetAt will place a virtual variable to another position
    GetAt will retrieve the current position
    IF you

    Dim x Like myObject.typename$ At myObject.DataPtr
    ' now x will let you access myObject 
    ' and if you have another object of the same type:
    if myOtherObject.typename$ = myObject.typename$ then
      setAt(x, myOtherObject.DataPtr)
      ' now x is myOtherObject
    endif
    'if you have an array/string/heap of dataptrs that point to objects 
    'lets say
    String sPtrs= mkDWD$(ptr1, ptr2, ptr3)
    ' easy to append more:
    sPtrs &= mkdwd$(ptr4, ptr5)
    
    store them to a heap 
    Dword pMyHeap=Heap_AllocByStr(sPtrs)
    
    ' append more? 
    Heap_Set(pMyHeap, Heap_Get(pMyHeap) & mkdwd$(ptr7, ptr8,...))
    
    'you could set a surfing-dword at the first or last one 
    Local surfer as Dword at pMyHeap
     '                                               (or at Heap_End(pMyHeap -3) to go backwards)
    repeat
    
    ' do something with the object the surfer points now
    ' will be one of ptr1, ptr2, ptr3 etc.
    
    ' then push the surfer forward 
      SetAt(Surfer, GetAt(Surfer) + SizeOf(Surfer) )
    '                                     - SizeOf... to go backward
    until getAt(Surfer)>= Heap_End(pMyHeap)
    '                  < pMyHeap if backwards
    
    this allows to iterate through an array. if the array is pointers (Dword) then the pointers can point different types,
    its like an array where any member can be of another type
    And
    Sub DoSomethingWith(byval pData as dword, byval sTypename as string)
    
    Local X LIKE sTypename at pData
    x.doSomething()
    End Sub
    
    lets you call same named functions on different types
    Last edited by ReneMiner; 02-05-2021 at 13:38.
    running thinBasic in HP Pavillon Desktop 590 a0xxx 8GB Ram AMD A6-9225 Radeon R4 5Compute Cores 2C+3G @2.6GHz

    OS: downgraded again to Windows 10 Enterprise x64 10.0.18363 Build 18363 (1909)
    (alternate OS: modified WinRE - boot from a fake ramdisk - currently in "reconstruction mode")

Similar Threads

  1. How to display unicode string in ThinBasic controls
    By kcvinu in forum UI (User Interface)
    Replies: 4
    Last Post: 03-04-2021, 02:06
  2. need a Unicode working example
    By fkapnist in forum thinBasic General
    Replies: 8
    Last Post: 27-11-2018, 09:39
  3. Does ThinAir supports Unicode ?
    By kcvinu in forum thinAir General
    Replies: 19
    Last Post: 29-08-2016, 14:57
  4. Proposed Wide String (Unicode) support in OxygenBasic
    By Charles Pegge in forum O2h Compiler
    Replies: 2
    Last Post: 27-02-2011, 04:08
  5. Is this ASCII, ANSI, UNICODE or something else?
    By martin in forum thinAir General
    Replies: 12
    Last Post: 29-04-2009, 09:56

Posting Permissions

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