Results 1 to 34 of 34

Thread: Questions about RC6 (2021-04-13)

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Resolved Questions about RC6 (2021-04-13)

    I encountered several problems while using RC6:

    (1) RC6 provides DynObj to implement dynamic properties and dynamic functions. Is there an example to demonstrate how to implement dynamic functions?

    (2) Chrome has a very useful function: Pretty-Print SourceCode, I'd like to know if WebView2 has a similar function?

    (3) I know how to use cFSO.ReadTextContent(FileName,,CP_UTF8) to read a JS file. If I save this JS file as binary into WebArchive(WV.ReadContentsFromByteArray), how can I read this JS file as a UTF8 string from WebArchive?

    Much Appreciated.
    Last edited by SearchingDataOnly; Apr 13th, 2021 at 12:55 AM.

  2. #2
    PowerPoster
    Join Date
    Jun 2013
    Posts
    5,602

    Re: Several questions about RC6

    Quote Originally Posted by SearchingDataOnly View Post
    (1) RC6 provides DynObj to implement dynamic properties and dynamic functions. Is there an example to demonstrate how to implement dynamic functions?
    See below:
    Code:
    Private Sub Form_Load()
      Dim oDyn As Object
      Set oDyn = New_c.DynObj
          oDyn = "{a:123, b:'xyz'}" 'js-like prop-initializing (a as integer, b as string)
          oDyn.c = True 'vb-like prop-initializing (c as boolean)
          oDyn.f = "function(arg){return this.a - arg}" 'func-def in js-notation (this. is similar to Me.)
      
      'Ok, readout-tests:
      Debug.Print oDyn.a, oDyn.b, oDyn.c, oDyn.f(81)
      
      'finally the built-in JSON-serialization:
      Debug.Print oDyn.toJSON
    End Sub

    Quote Originally Posted by SearchingDataOnly View Post
    (2) Chrome has a very useful function: Pretty-Print SourceCode, I'd like to know if WebView2 has a similar function?
    I've never experimented with Pretty-Printing in Chrome...
    You'll have to rely on your own "Google-Fu", to find out whether Edge/Chromium can do the same.

    If I would need that, I'd probably do it in the context of a decent js-Code-Editor-lib (like e.g. Monaco).

    Quote Originally Posted by SearchingDataOnly View Post
    (3) I know how to use cFSO.ReadTextContent(FileName,,CP_UTF8) to read a JS file. If I save this JS file as binary into WebArchive(WV.ReadContentsFromByteArray), how can I read this JS file as a UTF8 string from WebArchive?
    If you want to store UTF8 FileContent at the binary level (in a WebArchive),
    I'd already read it out this way via: ByteArr = New_c.FSO.ReadByteContent(FileName).

    And since the WebArchive will always hand you a ByteArray back (via "PathKey"),
    you could pass it along to other "receivers who can deal with UTF8-ByteArrays directly" -
    or convert it into a VB-String the usual way via New_c.Crypt.UTF8ToVBString(ByteArr)

    HTH

    Olaf

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: Several questions about RC6

    Quote Originally Posted by Schmidt View Post
    See below:
    Code:
    Private Sub Form_Load()
      Dim oDyn As Object
      Set oDyn = New_c.DynObj
          oDyn = "{a:123, b:'xyz'}" 'js-like prop-initializing (a as integer, b as string)
          oDyn.c = True 'vb-like prop-initializing (c as boolean)
          oDyn.f = "function(arg){return this.a - arg}" 'func-def in js-notation (this. is similar to Me.)
      
      'Ok, readout-tests:
      Debug.Print oDyn.a, oDyn.b, oDyn.c, oDyn.f(81)
      
      'finally the built-in JSON-serialization:
      Debug.Print oDyn.toJSON
    End Sub
    DynObj is my dream thing, it's extremely useful to me.


    Quote Originally Posted by Schmidt View Post
    I've never experimented with Pretty-Printing in Chrome...
    You'll have to rely on your own "Google-Fu", to find out whether Edge/Chromium can do the same.

    If I would need that, I'd probably do it in the context of a decent js-Code-Editor-lib (like e.g. Monaco).
    Good advice

    Quote Originally Posted by Schmidt View Post
    If you want to store UTF8 FileContent at the binary level (in a WebArchive),
    I'd already read it out this way via: ByteArr = New_c.FSO.ReadByteContent(FileName).

    And since the WebArchive will always hand you a ByteArray back (via "PathKey"),
    you could pass it along to other "receivers who can deal with UTF8-ByteArrays directly" -
    or convert it into a VB-String the usual way via New_c.Crypt.UTF8ToVBString(ByteArr)
    New_c.Crypt.UTF8ToVBString(ByteArr) solved my problem. Much appreciated.

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Hi Olaf,
    I'd like to know whether RC6 will provide cThemeWin10, if it can be provided, it will save a lot of development workload.

  5. #5
    PowerPoster
    Join Date
    Jun 2013
    Posts
    5,602

    Re: [RESOLVED] Several questions about RC6

    Quote Originally Posted by SearchingDataOnly View Post
    Hi Olaf,
    I'd like to know whether RC6 will provide cThemeWin10, if it can be provided, it will save a lot of development workload.
    Yes, it will be the default-theme in the next releases...
    (and I'll probably integrate most vbWidgets-Classes into the RC6 directly as well).

    RC5 + the matching vbWidgets.dll will still default to the Win7-like theme though...

    Olaf

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Hi Olaf,

    I need to calculate the length of a string through a string pointer, and I know that this can be achieved through the lstrlen API. But the lstrlen API does not seem to be that safe , and I want to minimize the use of Win-APIs. I'd like to know whether RC6 can provide a simple and efficient way to calculate the length of a string through a string pointer?

    It seems to be calculated like this in C#:
    Code:
    var len = 0;
    while (((byte*)textPtr)[len] != 0)
         len++;
    I don't know whether RC6 can provide a way to traverse every character in memory through the string pointer.

  7. #7
    PowerPoster
    Join Date
    Jun 2013
    Posts
    5,602

    Re: [RESOLVED] Several questions about RC6

    Quote Originally Posted by SearchingDataOnly View Post
    I need to calculate the length of a string through a string pointer, and I know that this can be achieved through the lstrlen API.
    But the lstrlen API does not seem to be that safe , ...
    It operates in exactly the same way as the example-code you've shown.

    Quote Originally Posted by SearchingDataOnly View Post
    I don't know whether RC6 can provide a way to traverse every character in memory through the string pointer.
    Currently not (since better support for "pointy-stuff" like that will be better placed directly at compiler-level later on).

    Besides, basic APIs like lstrlen are low-level enough, that one can find equivalent support in the c-runtimes on any platform.

    So, in case this is "in preparation for future platform-independence", you only need to avoid APIs,
    which are clearly "Win-only" (stuff from gdi32, gdiplus, comctl32, DirectX...)

    HTH

    Olaf

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Thanks for the detailed reply.

    Please take a look at the following features that whethe they are necessary to be added to RC6:

    cArrayList:
    IndexByItemValue
    ItemExists
    RemoveByItemValue

    cCrypt:
    VBStringFromPtr(pData As Long, ByteLen As Long, Optional IsRaw16Bit As Boolean, Optional CodePage As MSCodePages)
    Last edited by SearchingDataOnly; Feb 15th, 2021 at 10:27 PM.

  9. #9

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    I'd like to know if it is possible to add the ReadOnly property to cCollection, for example:

    Code:
    Public Property Get ItemList() As cCollection
        Set ItemList = m_ItemList
        ItemList.ReadOnly = True
    End Property
    Or

    Code:
    Public Property Get ItemList() As cCollection
        Set ItemList = m_ItemList.Clone
        ItemList.ReadOnly = True
    End Property
    Or
    Code:
    Public Property Get ItemList() As cReadOnlyCollection
        Set ItemList = m_ItemList
    End Property
    When the ItemList has the ReadOnly property, the ItemList will not allow the AddNewItem and RemoveItem operations to be performed, it is not even allowed to modify the properties of the item members in the collection.

    IMO, the third method (cReadOnlyCollection) is the most elegant.
    Last edited by SearchingDataOnly; Feb 15th, 2021 at 10:32 PM.

  10. #10
    Frenzied Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    1,838

    Re: [RESOLVED] Several questions about RC6

    How about creating a cCollectionReadOnly class that implements the cCollection "read" properties? You could also Implement the cCollection class and raise an error when any Write properties are accessed. By implementing the cCollection you could still pass cCollectionReadOnly objects to methods that expect a cCollection. Something like this (untested):

    Code:
    Option Explicit
    
    Implements cCollection
    
    Private mo_Collection As cCollection
    
    Public Sub InitializeCollection(po_Collection As cCollection)
       ' Call with a cCollection object to initialize
       If Not mo_Collection Is Nothing Then Err.Raise 70, , "Class already initialized."
       
       Set mo_Collection = po_Collection
    End Sub
    
    Private Sub cCollection_Add(Item As Variant, Optional Key As Variant, Optional Before As Variant, Optional After As Variant)
       Err.Raise 70, , "This object is read-only."
    End Sub
    
    Private Property Let cCollection_CompatibleToVBCollection(ByVal RHS As Boolean)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_CompatibleToVBCollection() As Boolean
       cCollection_CompatibleToVBCollection = Me.CompatibleToVBCollection
    End Property
    
    Public Property Get CompatibleToVBCollection() As Boolean
       CompatibleToVBCollection = Me.CompatibleToVBCollection
    End Property
    
    Private Property Let cCollection_Content(RHS() As Byte)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_Content() As Byte()
       cCollection_Content = Me.Content
    End Property
    
    Public Property Get Content() As Byte()
       Content = mo_Collection.Content
    End Property
    
    Private Function cCollection_Count() As Long
       cCollection_Count = Me.Count
    End Function
    
    Public Property Get Count() As Long
       Count = mo_Collection.Count
    End Property
    
    Private Function cCollection_Enumerator(Optional EnumIndex As Long = -1&) As Variant
       cCollection_Enumerator = Me.Enumerator
    End Function
    
    Public Property Get Enumerator() As Variant
       Enumerator = mo_Collection.Enumerator
    End Property
    
    Private Function cCollection_Exists(Key As Variant) As Boolean
       cCollection_Exists = Me.Exists(Key)
    End Function
    
    Public Function Exists(Key As Variant) As Boolean
       Exists = mo_Collection.Exists(Key)
    End Function
    
    Private Property Get cCollection_IndexByKey(Key As Variant, Optional ByVal Force_EvenIfNonExistent As Boolean) As Long
       cCollection_IndexByKey = Me.IndexByKey(Key, Force_EvenIfNonExistent)
    End Property
    
    Public Property Get IndexByKey(Key As Variant, Optional ByVal Force_EvenIfNonExistent As Boolean) As Long
       IndexByKey = mo_Collection.IndexByKey(Key, Force_EvenIfNonExistent)
    End Property
    
    Private Property Get cCollection_IndexBySortKeyIndex(ByVal IdxZeroBased As Long) As Long
       cCollection_IndexBySortKeyIndex = Me.IndexBySortKeyIndex(IdxZeroBased)
    End Property
    
    Public Property Get IndexBySortKeyIndex(ByVal IdxZeroBased As Long) As Long
       IndexBySortKeyIndex = mo_Collection.IndexBySortKeyIndex(IdxZeroBased)
    End Property
    
    Private Property Get cCollection_IsJSONArray() As Boolean
       cCollection_IsJSONArray = Me.IsJSONArray
    End Property
    
    Public Property Get IsJSONArray() As Boolean
       IsJSONArray = mo_Collection.IsJSONArray
    End Property
    
    Private Property Get cCollection_IsJSONObject() As Boolean
       cCollection_IsJSONObject = Me.IsJSONObject
    End Property
    
    Public Property Get IsJSONObject() As Boolean
       IsJSONObject = mo_Collection.IsJSONObject
    End Property
    
    Private Property Set cCollection_Item(Key As Variant, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Let cCollection_Item(Key As Variant, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_Item(Key As Variant) As Variant
       cCollection_Item = Me.Item(Key)
    End Property
    
    Public Property Get Item(Key As Variant) As Variant
       Item = mo_Collection.Item(Key)
    End Property
    
    Private Property Set cCollection_ItemByIndex(ByVal IdxZeroBased As Long, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Let cCollection_ItemByIndex(ByVal IdxZeroBased As Long, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_ItemByIndex(ByVal IdxZeroBased As Long) As Variant
       cCollection_ItemByIndex = Me.ItemByIndex(IdxZeroBased)
    End Property
    
    Public Property Get ItemByIndex(ByVal IdxZeroBased As Long) As Variant
       ItemByIndex = mo_Collection.ItemByIndex(IdxZeroBased)
    End Property
    
    Private Property Set cCollection_ItemBySortKeyIndex(ByVal IdxZeroBased As Long, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Let cCollection_ItemBySortKeyIndex(ByVal IdxZeroBased As Long, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_ItemBySortKeyIndex(ByVal IdxZeroBased As Long) As Variant
       cCollection_ItemBySortKeyIndex = Me.ItemBySortKeyIndex(IdxZeroBased)
    End Property
    
    Public Property Get ItemBySortKeyIndex(ByVal IdxZeroBased As Long) As Variant
       ItemBySortKeyIndex = mo_Collection.ItemBySortKeyIndex(IdxZeroBased)
    End Property
    
    Private Function cCollection_ItemExists(ItemValue As Variant, Optional FoundItemIndex As Long, Optional ByVal StringCompareMode As VbCompareMethod) As Boolean
       cCollection_ItemExists = Me.ItemExists(ItemValue, FoundItemIndex, StringCompareMode)
    End Function
    
    Public Function ItemExists(ItemValue As Variant, Optional FoundItemIndex As Long, Optional ByVal StringCompareMode As VbCompareMethod) As Boolean
       ItemExists = mo_Collection.ItemExists(ItemValue, FoundItemIndex, StringCompareMode)
    End Function
    
    Private Property Get cCollection_KeyByIndex(ByVal IdxZeroBased As Long) As Variant
       cCollection_KeyByIndex = Me.KeyByIndex(IdxZeroBased)
    End Property
    
    Public Property Get KeyByIndex(ByVal IdxZeroBased As Long) As Variant
       KeyByIndex = mo_Collection.KeyByIndex(IdxZeroBased)
    End Property
    
    Private Property Get cCollection_KeyBySortKeyIndex(ByVal IdxZeroBased As Long) As Variant
       cCollection_KeyBySortKeyIndex = Me.KeyBySortKeyIndex(IdxZeroBased)
    End Property
    
    Public Property Get KeyBySortKeyIndex(ByVal IdxZeroBased As Long) As Variant
       KeyBySortKeyIndex = mo_Collection.KeyBySortKeyIndex(IdxZeroBased)
    End Property
    
    Private Function cCollection_MakeLCID(ByVal LangID As RC6.LangIDs, Optional ByVal SortID As RC6.SortIDs = 0&) As Long
       cCollection_MakeLCID = Me.MakeLCID(LangID, SortID)
    End Function
    
    Public Function MakeLCID(ByVal LangID As RC6.LangIDs, Optional ByVal SortID As RC6.SortIDs = 0&) As Long
       MakeLCID = mo_Collection.MakeLCID(LangID, SortID)
    End Function
    
    Private Property Set cCollection_Prop(Key As Variant, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Let cCollection_Prop(Key As Variant, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_Prop(Key As Variant) As Variant
       cCollection_Prop = Me.Prop(Key)
    End Property
    
    Public Property Get Prop(Key As Variant) As Variant
       Prop = mo_Collection.Prop(Key)
    End Property
    
    Private Sub cCollection_Remove(Key As Variant)
       Err.Raise 70, , "This object is read-only."
    End Sub
    
    Private Sub cCollection_RemoveAll()
       Err.Raise 70, , "This object is read-only."
    End Sub
    
    Private Sub cCollection_RemoveByIndex(ByVal IdxZeroBased As Long)
       Err.Raise 70, , "This object is read-only."
    End Sub
    
    Private Function cCollection_SerializeToJSONString() As String
       cCollection_SerializeToJSONString = Me.SerializeToJSONString
    End Function
    
    Public Function SerializeToJSONString() As String
       SerializeToJSONString = mo_Collection.SerializeToJSONString
    End Function
    
    Private Function cCollection_SerializeToJSONUTF8() As Byte()
       cCollection_SerializeToJSONUTF8 = Me.SerializeToJSONUTF8
    End Function
    
    Public Function SerializeToJSONUTF8() As Byte()
       SerializeToJSONUTF8 = mo_Collection.SerializeToJSONUTF8
    End Function
    
    Private Sub cCollection_SetStringCompareFlags(ByVal flags As RC6.CmpFlags, Optional ByVal lcid As RC6.LCIDs, Optional ByVal SortID As RC6.SortIDs = 0&)
       Err.Raise 70, , "This object is read-only."
    End Sub
    
    Private Property Get cCollection_SortKeyIndexByIndex(ByVal IdxZeroBased As Long) As Long
       cCollection_SortKeyIndexByIndex = Me.SortKeyIndexByIndex(IdxZeroBased)
    End Property
    
    Public Property Get SortKeyIndexByIndex(ByVal IdxZeroBased As Long) As Long
       SortKeyIndexByIndex = mo_Collection.SortKeyIndexByIndex(IdxZeroBased)
    End Property
    
    Private Property Get cCollection_SortKeyIndexByKey(Key As Variant, Optional ByVal Force_EvenIfNonExistent As Boolean) As Long
       cCollection_SortKeyIndexByKey = Me.SortKeyIndexByKey(Key, Force_EvenIfNonExistent)
    End Property
    
    Public Property Get SortKeyIndexByKey(Key As Variant, Optional ByVal Force_EvenIfNonExistent As Boolean) As Long
       SortKeyIndexByKey = mo_Collection.SortKeyIndexByKey(Key, Force_EvenIfNonExistent)
    End Property
    
    Private Function cCollection_SortKeysCount() As Long
       cCollection_SortKeysCount = Me.SortKeysCount
    End Function
    
    Public Function SortKeysCount() As Long
       SortKeysCount = mo_Collection.SortKeysCount
    End Function
    
    Private Property Get cCollection_StringCompareMode() As RC6.StringCompareModeEnum
       cCollection_StringCompareMode = Me.StringCompareMode
    End Property
    
    Public Property Get StringCompareMode() As RC6.StringCompareModeEnum
       StringCompareMode = mo_Collection.StringCompareMode
    End Property
    
    Private Property Let cCollection_StringCompareMode(ByVal RHS As RC6.StringCompareModeEnum)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_UniqueKeys() As Boolean
       cCollection_UniqueKeys = Me.UniqueKeys
    End Property
    
    Private Property Get UniqueKeys() As Boolean
       UniqueKeys = mo_Collection.UniqueKeys
    End Property
    
    Private Property Let cCollection_UniqueKeys(ByVal RHS As Boolean)
       Err.Raise 70, , "This object is read-only."
    End Property

  11. #11

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Quote Originally Posted by jpbro View Post
    How about creating a cCollectionReadOnly class that implements the cCollection "read" properties? You could also Implement the cCollection class and raise an error when any Write properties are accessed. By implementing the cCollection you could still pass cCollectionReadOnly objects to methods that expect a cCollection. Something like this (untested):

    Code:
    Option Explicit
    
    Implements cCollection
    
    Private mo_Collection As cCollection
    
    Public Sub InitializeCollection(po_Collection As cCollection)
       ' Call with a cCollection object to initialize
       If Not mo_Collection Is Nothing Then Err.Raise 70, , "Class already initialized."
       
       Set mo_Collection = po_Collection
    End Sub
    
    Private Sub cCollection_Add(Item As Variant, Optional Key As Variant, Optional Before As Variant, Optional After As Variant)
       Err.Raise 70, , "This object is read-only."
    End Sub
    
    Private Property Let cCollection_CompatibleToVBCollection(ByVal RHS As Boolean)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_CompatibleToVBCollection() As Boolean
       cCollection_CompatibleToVBCollection = Me.CompatibleToVBCollection
    End Property
    
    Public Property Get CompatibleToVBCollection() As Boolean
       CompatibleToVBCollection = Me.CompatibleToVBCollection
    End Property
    
    Private Property Let cCollection_Content(RHS() As Byte)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_Content() As Byte()
       cCollection_Content = Me.Content
    End Property
    
    Public Property Get Content() As Byte()
       Content = mo_Collection.Content
    End Property
    
    Private Function cCollection_Count() As Long
       cCollection_Count = Me.Count
    End Function
    
    Public Property Get Count() As Long
       Count = mo_Collection.Count
    End Property
    
    Private Function cCollection_Enumerator(Optional EnumIndex As Long = -1&) As Variant
       cCollection_Enumerator = Me.Enumerator
    End Function
    
    Public Property Get Enumerator() As Variant
       Enumerator = mo_Collection.Enumerator
    End Property
    
    Private Function cCollection_Exists(Key As Variant) As Boolean
       cCollection_Exists = Me.Exists(Key)
    End Function
    
    Public Function Exists(Key As Variant) As Boolean
       Exists = mo_Collection.Exists(Key)
    End Function
    
    Private Property Get cCollection_IndexByKey(Key As Variant, Optional ByVal Force_EvenIfNonExistent As Boolean) As Long
       cCollection_IndexByKey = Me.IndexByKey(Key, Force_EvenIfNonExistent)
    End Property
    
    Public Property Get IndexByKey(Key As Variant, Optional ByVal Force_EvenIfNonExistent As Boolean) As Long
       IndexByKey = mo_Collection.IndexByKey(Key, Force_EvenIfNonExistent)
    End Property
    
    Private Property Get cCollection_IndexBySortKeyIndex(ByVal IdxZeroBased As Long) As Long
       cCollection_IndexBySortKeyIndex = Me.IndexBySortKeyIndex(IdxZeroBased)
    End Property
    
    Public Property Get IndexBySortKeyIndex(ByVal IdxZeroBased As Long) As Long
       IndexBySortKeyIndex = mo_Collection.IndexBySortKeyIndex(IdxZeroBased)
    End Property
    
    Private Property Get cCollection_IsJSONArray() As Boolean
       cCollection_IsJSONArray = Me.IsJSONArray
    End Property
    
    Public Property Get IsJSONArray() As Boolean
       IsJSONArray = mo_Collection.IsJSONArray
    End Property
    
    Private Property Get cCollection_IsJSONObject() As Boolean
       cCollection_IsJSONObject = Me.IsJSONObject
    End Property
    
    Public Property Get IsJSONObject() As Boolean
       IsJSONObject = mo_Collection.IsJSONObject
    End Property
    
    Private Property Set cCollection_Item(Key As Variant, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Let cCollection_Item(Key As Variant, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_Item(Key As Variant) As Variant
       cCollection_Item = Me.Item(Key)
    End Property
    
    Public Property Get Item(Key As Variant) As Variant
       Item = mo_Collection.Item(Key)
    End Property
    
    Private Property Set cCollection_ItemByIndex(ByVal IdxZeroBased As Long, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Let cCollection_ItemByIndex(ByVal IdxZeroBased As Long, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_ItemByIndex(ByVal IdxZeroBased As Long) As Variant
       cCollection_ItemByIndex = Me.ItemByIndex(IdxZeroBased)
    End Property
    
    Public Property Get ItemByIndex(ByVal IdxZeroBased As Long) As Variant
       ItemByIndex = mo_Collection.ItemByIndex(IdxZeroBased)
    End Property
    
    Private Property Set cCollection_ItemBySortKeyIndex(ByVal IdxZeroBased As Long, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Let cCollection_ItemBySortKeyIndex(ByVal IdxZeroBased As Long, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_ItemBySortKeyIndex(ByVal IdxZeroBased As Long) As Variant
       cCollection_ItemBySortKeyIndex = Me.ItemBySortKeyIndex(IdxZeroBased)
    End Property
    
    Public Property Get ItemBySortKeyIndex(ByVal IdxZeroBased As Long) As Variant
       ItemBySortKeyIndex = mo_Collection.ItemBySortKeyIndex(IdxZeroBased)
    End Property
    
    Private Function cCollection_ItemExists(ItemValue As Variant, Optional FoundItemIndex As Long, Optional ByVal StringCompareMode As VbCompareMethod) As Boolean
       cCollection_ItemExists = Me.ItemExists(ItemValue, FoundItemIndex, StringCompareMode)
    End Function
    
    Public Function ItemExists(ItemValue As Variant, Optional FoundItemIndex As Long, Optional ByVal StringCompareMode As VbCompareMethod) As Boolean
       ItemExists = mo_Collection.ItemExists(ItemValue, FoundItemIndex, StringCompareMode)
    End Function
    
    Private Property Get cCollection_KeyByIndex(ByVal IdxZeroBased As Long) As Variant
       cCollection_KeyByIndex = Me.KeyByIndex(IdxZeroBased)
    End Property
    
    Public Property Get KeyByIndex(ByVal IdxZeroBased As Long) As Variant
       KeyByIndex = mo_Collection.KeyByIndex(IdxZeroBased)
    End Property
    
    Private Property Get cCollection_KeyBySortKeyIndex(ByVal IdxZeroBased As Long) As Variant
       cCollection_KeyBySortKeyIndex = Me.KeyBySortKeyIndex(IdxZeroBased)
    End Property
    
    Public Property Get KeyBySortKeyIndex(ByVal IdxZeroBased As Long) As Variant
       KeyBySortKeyIndex = mo_Collection.KeyBySortKeyIndex(IdxZeroBased)
    End Property
    
    Private Function cCollection_MakeLCID(ByVal LangID As RC6.LangIDs, Optional ByVal SortID As RC6.SortIDs = 0&) As Long
       cCollection_MakeLCID = Me.MakeLCID(LangID, SortID)
    End Function
    
    Public Function MakeLCID(ByVal LangID As RC6.LangIDs, Optional ByVal SortID As RC6.SortIDs = 0&) As Long
       MakeLCID = mo_Collection.MakeLCID(LangID, SortID)
    End Function
    
    Private Property Set cCollection_Prop(Key As Variant, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Let cCollection_Prop(Key As Variant, RHS As Variant)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_Prop(Key As Variant) As Variant
       cCollection_Prop = Me.Prop(Key)
    End Property
    
    Public Property Get Prop(Key As Variant) As Variant
       Prop = mo_Collection.Prop(Key)
    End Property
    
    Private Sub cCollection_Remove(Key As Variant)
       Err.Raise 70, , "This object is read-only."
    End Sub
    
    Private Sub cCollection_RemoveAll()
       Err.Raise 70, , "This object is read-only."
    End Sub
    
    Private Sub cCollection_RemoveByIndex(ByVal IdxZeroBased As Long)
       Err.Raise 70, , "This object is read-only."
    End Sub
    
    Private Function cCollection_SerializeToJSONString() As String
       cCollection_SerializeToJSONString = Me.SerializeToJSONString
    End Function
    
    Public Function SerializeToJSONString() As String
       SerializeToJSONString = mo_Collection.SerializeToJSONString
    End Function
    
    Private Function cCollection_SerializeToJSONUTF8() As Byte()
       cCollection_SerializeToJSONUTF8 = Me.SerializeToJSONUTF8
    End Function
    
    Public Function SerializeToJSONUTF8() As Byte()
       SerializeToJSONUTF8 = mo_Collection.SerializeToJSONUTF8
    End Function
    
    Private Sub cCollection_SetStringCompareFlags(ByVal flags As RC6.CmpFlags, Optional ByVal lcid As RC6.LCIDs, Optional ByVal SortID As RC6.SortIDs = 0&)
       Err.Raise 70, , "This object is read-only."
    End Sub
    
    Private Property Get cCollection_SortKeyIndexByIndex(ByVal IdxZeroBased As Long) As Long
       cCollection_SortKeyIndexByIndex = Me.SortKeyIndexByIndex(IdxZeroBased)
    End Property
    
    Public Property Get SortKeyIndexByIndex(ByVal IdxZeroBased As Long) As Long
       SortKeyIndexByIndex = mo_Collection.SortKeyIndexByIndex(IdxZeroBased)
    End Property
    
    Private Property Get cCollection_SortKeyIndexByKey(Key As Variant, Optional ByVal Force_EvenIfNonExistent As Boolean) As Long
       cCollection_SortKeyIndexByKey = Me.SortKeyIndexByKey(Key, Force_EvenIfNonExistent)
    End Property
    
    Public Property Get SortKeyIndexByKey(Key As Variant, Optional ByVal Force_EvenIfNonExistent As Boolean) As Long
       SortKeyIndexByKey = mo_Collection.SortKeyIndexByKey(Key, Force_EvenIfNonExistent)
    End Property
    
    Private Function cCollection_SortKeysCount() As Long
       cCollection_SortKeysCount = Me.SortKeysCount
    End Function
    
    Public Function SortKeysCount() As Long
       SortKeysCount = mo_Collection.SortKeysCount
    End Function
    
    Private Property Get cCollection_StringCompareMode() As RC6.StringCompareModeEnum
       cCollection_StringCompareMode = Me.StringCompareMode
    End Property
    
    Public Property Get StringCompareMode() As RC6.StringCompareModeEnum
       StringCompareMode = mo_Collection.StringCompareMode
    End Property
    
    Private Property Let cCollection_StringCompareMode(ByVal RHS As RC6.StringCompareModeEnum)
       Err.Raise 70, , "This object is read-only."
    End Property
    
    Private Property Get cCollection_UniqueKeys() As Boolean
       cCollection_UniqueKeys = Me.UniqueKeys
    End Property
    
    Private Property Get UniqueKeys() As Boolean
       UniqueKeys = mo_Collection.UniqueKeys
    End Property
    
    Private Property Let cCollection_UniqueKeys(ByVal RHS As Boolean)
       Err.Raise 70, , "This object is read-only."
    End Property
    Very clever solution. Thank you very much, jpbro.

    If Olaf could integrate cCollectionReadOnly into RC6, it would be a wonderful thing.

  12. #12

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Hi jpbro, I tested your method and it is great.
    Attached Files Attached Files
    Last edited by SearchingDataOnly; Feb 16th, 2021 at 01:44 AM.

  13. #13

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    I'd like to know whether there is a RC6 class corresponding to C# Encoding Class?

    I saw that cCrypt and cFSO in RC6 contain some operations related to encoding and decoding, but it seems that there is no special class to handle all operations related to encoding and decoding.

    There are encoding classes that simulate .NET in vbCorLib, but there are more than 20 classes related to encoding and decoding in it.
    Last edited by SearchingDataOnly; Feb 19th, 2021 at 09:46 AM.

  14. #14
    Fanatic Member
    Join Date
    Sep 2010
    Location
    Italy
    Posts
    585

    Re: [RESOLVED] Several questions about RC6

    @Olaf
    Hello I wanted to report a small lack of backward compatibility of the last version RC 6.0.0.3

    Code:
        ' .SetSourceRGBA             .DrawText
        ' .DrawText                  .SetSourceRGBA
        ' .RoundedRect : .Fill       .RoundedRect : .Fill
    On the left how was my code.
    With the previous version of RC6 it worked correctly.
    With the latest version the color it chooses is white with full alpha (1,1,1,1)
    It behaves like the DrawText instruction resets the chosen color.

    On the right the right code for the new version.
    SetSourceRGBA just before RoundedRect.

    Not very important, however I'm curious and wanted to make it known to Olaf.

  15. #15
    PowerPoster
    Join Date
    Jun 2013
    Posts
    5,602

    Re: [RESOLVED] Several questions about RC6

    Quote Originally Posted by reexre View Post
    @Olaf
    Hello I wanted to report a small lack of backward compatibility of the last version RC 6.0.0.3

    Code:
        ' .SetSourceRGBA             .DrawText
        ' .DrawText                  .SetSourceRGBA
        ' .RoundedRect : .Fill       .RoundedRect : .Fill
    On the left how was my code.
    With the previous version of RC6 it worked correctly.
    With the latest version the color it chooses is white with full alpha (1,1,1,1)
    It behaves like the DrawText instruction resets the chosen color.

    On the right the right code for the new version.
    SetSourceRGBA just before RoundedRect.

    Not very important, however I'm curious and wanted to make it known to Olaf.
    Thanks... good catch
    (I did further cleanups regarding FontOutput in 6.0.3, which is now entirely routed over cairo)...

    The former behaviour is now restored in version 6.0.4, which I will updload in the next hours
    (a TextColor set via CC.SelectFont shall be independent from "normal CC-(Color)patterns").

    @Jason
    6.0.4 will include (besides the most recent SQLite-version) also most of the suggestions,
    you've sent via Email.

    @SearchingDataOnly
    You are right, that cCrypt currently contains also a lot of "normal CoDec- (as well as compression) stuff" -
    but for reasons of backward-comp, I'll better not move that over into new to introduce cCodec- or cCompression-Classes.

    Olaf
    Last edited by Schmidt; Feb 22nd, 2021 at 03:24 AM.

  16. #16
    Fanatic Member
    Join Date
    Sep 2010
    Location
    Italy
    Posts
    585

    Re: [RESOLVED] Several questions about RC6

    hello, a curiosity:
    While I was making fonts created from lines 1 pixel thick. (rendered via cc.lineto cc.moveto cc.stroke) I noticed that in cairo rendering the coordinates are "shifted" by 0.5 pixels.
    The issue has nothing to do with antialiasing.
    I was surprised by this behavior.
    I would have preferred (expected), that by giving as input INTEGER value coordinates, I would get an output like the second line.
    Maybe this is a standard (of cairo) ... and for lines/objects thicker than 1 pixel this system makes sense.
    However I would have preferred the opposite.


    Download Image
    https://photos.app.goo.gl/LW411eqENqYUnyFt6

  17. #17
    PowerPoster
    Join Date
    Jun 2013
    Posts
    5,602

    Re: [RESOLVED] Several questions about RC6

    Quote Originally Posted by reexre View Post
    hello, a curiosity:
    While I was making fonts created from lines 1 pixel thick. (rendered via cc.lineto cc.moveto cc.stroke)
    I noticed that in cairo rendering the coordinates are "shifted" by 0.5 pixels.
    ...
    I've tried to explain the cairo-coordsystem in post #5 in this thread:
    https://www.vbforums.com/showthread....=1#post5354093

    So, in short - the problem is not with the Fill-Command of a given path...

    Cairos CoordSys is defined by the outside of the Pixel-Boundaries of a given Surface-Size.
    If you create a 3x3Bitmap (via Cairo.CreateSurface(3, 3)) -
    and follow up with a path-def like CC.Rectangle 0,0,3,3
    followed by a CC.Fill ...
    then the entire Bitmap-area gets filled *exactly* (without anything "spilling over" the boundaries of the underlying surface)

    Not so with the Stroke-command (where "half the linewidth" is drawn at the outside of the path, and "half the linewidth to its inside").

    So, if you have a larger amount of "Paths to render with Stroke" (and a LineWidth of 1),
    then you can ensure proper behaviour with Int(x), Int(y) Coords -
    but will have to wrap all these drawings up with:
    Code:
    CC.Save
       CC.TranslateDrawings 0.5, 0.5
       '... do all your Int-based Path-defs and Strokings here
    CC.Restore
    ... to meet "the inside of the Pixels with a LineWidth of 1"

    HTH

    Olaf

  18. #18

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    GapBuffer is a data structure that can greatly improve the efficiency of CodeEditor. In addition, GapBuffer can also be used to store the states of UI components, such as Jetpack Compose. I'd to know if it is possible to add class GapBuffer to RC6?

    https://www.scintilla.org/gapbuffer.html
    https://www.codeproject.com/Articles...ric-Gap-Buffer

    GapBuffer.cs
    Code:
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Text;
    
    namespace ScintillaNET
    {
        // Do error checking higher up
        // http://www.codeproject.com/Articles/20910/Generic-Gap-Buffer
        [DebuggerDisplay("Count = {Count}")]
        internal sealed class GapBuffer<T> : IEnumerable<T>
        {
            private T[] buffer;
            private int gapStart;
            private int gapEnd;
    
            public void Add(T item)
            {
                Insert(Count, item);
            }
    
            public void AddRange(ICollection<T> collection)
            {
                InsertRange(Count, collection);
            }
    
            private void EnsureGapCapacity(int length)
            {
                if (length > (gapEnd - gapStart))
                {
                    // How much to grow the buffer is a tricky question.
                    // Our current algo will double the capacity unless that's not enough.
                    var minCapacity = Count + length;
                    var newCapacity = (buffer.Length * 2);
                    if (newCapacity < minCapacity)
                    {
                        newCapacity = minCapacity;
                    }
    
                    var newBuffer = new T[newCapacity];
                    var newGapEnd = newBuffer.Length - (buffer.Length - gapEnd);
    
                    Array.Copy(buffer, 0, newBuffer, 0, gapStart);
                    Array.Copy(buffer, gapEnd, newBuffer, newGapEnd, newBuffer.Length - newGapEnd);
                    this.buffer = newBuffer;
                    this.gapEnd = newGapEnd;
                }
            }
    
            public IEnumerator<T> GetEnumerator()
            {
                var count = Count;
                for (int i = 0; i < count; i++)
                    yield return this[i];
    
                yield break;
            }
    
            IEnumerator IEnumerable.GetEnumerator()
            {
                return this.GetEnumerator();
            }
    
            public void Insert(int index, T item)
            {
                PlaceGapStart(index);
                EnsureGapCapacity(1);
    
                buffer[index] = item;
                gapStart++;
            }
    
            public void InsertRange(int index, ICollection<T> collection)
            {
                var count = collection.Count;
                if (count > 0)
                {
                    PlaceGapStart(index);
                    EnsureGapCapacity(count);
    
                    collection.CopyTo(buffer, gapStart);
                    gapStart += count;
                }
            }
    
            private void PlaceGapStart(int index)
            {
                if (index != gapStart)
                {
                    if ((gapEnd - gapStart) == 0)
                    {
                        // There is no gap
                        gapStart = index;
                        gapEnd = index;
                    }
                    else if (index < gapStart)
                    {
                        // Move gap left (copy contents right)
                        var length = (gapStart - index);
                        var deltaLength = (gapEnd - gapStart < length ? gapEnd - gapStart : length);
                        Array.Copy(buffer, index, buffer, gapEnd - length, length);
                        gapStart -= length;
                        gapEnd -= length;
    
                        Array.Clear(buffer, index, deltaLength);
                    }
                    else
                    {
                        // Move gap right (copy contents left)
                        var length = (index - gapStart);
                        var deltaIndex = (index > gapEnd ? index : gapEnd);
                        Array.Copy(buffer, gapEnd, buffer, gapStart, length);
                        gapStart += length;
                        gapEnd += length;
    
                        Array.Clear(buffer, deltaIndex, gapEnd - deltaIndex);
                    }
                }
            }
    
            public void RemoveAt(int index)
            {
                PlaceGapStart(index);
                buffer[gapEnd] = default(T);
                gapEnd++;
            }
    
            public void RemoveRange(int index, int count)
            {
                if (count > 0)
                {
                    PlaceGapStart(index);
                    Array.Clear(buffer, gapEnd, count);
                    gapEnd += count;
                }
            }
    
            public int Count
            {
                get
                {
                    return buffer.Length - (gapEnd - gapStart);
                }
            }
    
    #if DEBUG
            // Poor man's DebuggerTypeProxy because I can't seem to get that working
            private List<T> Debug
            {
                get
                {
                    var list = new List<T>(this);
                    return list;
                }
            }
    #endif
    
            public T this[int index]
            {
                get
                {
                    if (index < gapStart)
                        return buffer[index];
    
                    return buffer[index + (gapEnd - gapStart)];
                }
                set
                {
                    if (index >= gapStart)
                        index += (gapEnd - gapStart);
    
                    buffer[index] = value;
                }
            }
    
            public GapBuffer(int capacity = 0)
            {
                this.buffer = new T[capacity];
                this.gapEnd = buffer.Length;
            }
        }
    }
    Last edited by SearchingDataOnly; Feb 24th, 2021 at 05:47 AM.

  19. #19

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Another question:

    I know that only user-defined types in the public object module can be used as elements of cCollection or cArrayList. But in many cases, we hope to use user-defined types in internal modules as elements of cCollection or cArrayList.

    Is it possible to pre-define several general User-Defined Types in RC6 for users to use? E.g:

    Code:
    Public Type LongType2
        Field As Long 
        Field2 As Long 
    End Type
    
    Public Type LongType3
        Field As Long 
        Field2 As Long 
        Field3 As Long
    End Type
    
    Public Type LongType4
        Field As Long 
        Field2 As Long 
        Field3 As Long
        Field4 As Long
    End Type
    
    ...
    ...
    
    Public Type LongType9
        ...
        ...
    End Type
    Test code:
    Code:
    Public Sub TestArrayList()
        Dim oList As cArrayList
        Dim myType As LongType3
        
        Set oList = New_c.ArrayList(exLongType3)
        
        myType.Field = 100
        myType.Field2 = 123
        myType.Field3 = 555
        
        oList.Add myType
        
    End Sub
    Last edited by SearchingDataOnly; Feb 24th, 2021 at 09:38 AM.

  20. #20

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Or, RC6 provides a way for users to create user-defined types instead of creating TLB, for example:

    Code:
    Public Sub DefineType(TypeName As String, ParamArray FieldNameAndFieldType() As Variant)
    
    End Sub

  21. #21
    PowerPoster ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    2,823

    Re: [RESOLVED] Several questions about RC6

    your Udt is never only going to be of Type Long?

    you can use LSet to pass a Udt, it will be a fixed lenght that you have to define

    take this in a Modul
    Code:
    Public Type CustomerProps
      CustomerID As Long
      Name As String * 50
      Phone As String * 25
      Address1 As String * 30
      Address2 As String * 30
      City As String * 20
      State As String * 2
      ZipCode As String * 10
      IsNew As Boolean
      IsDeleted As Boolean
      IsDirty As Boolean
    End Type
    
    Public Type CustomerData
      Buffer As String * 172
    End Type
    the Buffer Class
    Code:
    Option Explicit
    
    Private Type BufferProps
      Length As Integer
      EstCount As Long
      MaxCount As Long
      Count As Long
    End Type
    
    Private Type BufferData
      Buffer As String * 8
    End Type
    
    Private Const BUFFER_START = 9
    Private mstrBuffer As String
    Private mudtProps As BufferProps
    Private mlngPos As Long
    
    Public Sub Initialize(Length As Integer, EstimatedCount As Long)
    
      With mudtProps
        .Length = Length
        .EstCount = EstimatedCount
        .MaxCount = EstimatedCount
        .Count = 0
        mstrBuffer = Space$(BUFFER_START + .MaxCount * .Length)
        mlngPos = BUFFER_START
      End With
    
    End Sub
    
    Public Sub Add(Data As String)
    
      With mudtProps
        If .Count = .MaxCount Then
          mstrBuffer = mstrBuffer & _
            Space$(mudtProps.EstCount / 2 * mudtProps.Length)
          .MaxCount = .MaxCount + mudtProps.EstCount / 2
        End If
    
        Mid$(mstrBuffer, mlngPos, .Length) = Data
        mlngPos = mlngPos + .Length
        .Count = .Count + 1
      End With
    
    End Sub
    
    Public Function GetState() As String
    
      Dim udtData As BufferData
    
      LSet udtData = mudtProps
      Mid$(mstrBuffer, 1, Len(udtData.Buffer)) = udtData.Buffer
      GetState = Left$(mstrBuffer, mlngPos)
    
    End Function
    
    Public Sub SetState(Buffer As String)
    
      Dim udtData As BufferData
      
      udtData.Buffer = Mid$(Buffer, 1, Len(udtData.Buffer))
      LSet mudtProps = udtData
      mstrBuffer = Buffer
    
    End Sub
    
    Public Property Get Item(Index As Long) As String
    
      Item = Mid$(mstrBuffer, BUFFER_START + (Index - 1) * _
        mudtProps.Length, mudtProps.Length)
    
    End Property
    
    Public Function Count() As Long
    
      Count = mudtProps.Count
    
    End Function
    
    Public Function Length() As Long
    
      Length = mudtProps.Length
    
    End Function
    
    Public Property Let Item(Index As Long, Buffer As String)
    
      Mid$(mstrBuffer, BUFFER_START + (Index - 1) * _
        mudtProps.Length, mudtProps.Length) = Buffer
    
    End Property
    in the Customer Class
    Code:
    Option Explicit
    
    Event Valid(IsValid As Boolean)
    
    Private mudtProps As CustomerProps
    Private mudtSave As CustomerProps
    
    Private mflgNew As Boolean
    Private mflgDeleted As Boolean
    Private mflgDirty As Boolean
    Private mflgEditing As Boolean
    Private WithEvents mobjValid As BrokenRules
    
    Public Sub BeginEdit()
    
      If mflgEditing Then Err.Raise 445
      
      ' save object state
      LSet mudtSave = mudtProps
      mflgEditing = True
    
    End Sub
    
    Public Sub CancelEdit()
    
      If Not mflgEditing Then Err.Raise 445
      
      mflgEditing = False
      mflgDeleted = False
      mflgDirty = False
      ' restore object state
      LSet mudtProps = mudtSave
      
    End Sub
    
    Private Function GetState() As String
    
      Dim udtData As CustomerData
    
      With mudtProps
        .IsDeleted = mflgDeleted
        .IsNew = mflgNew
        .IsDirty = mflgDirty
      End With
    
      LSet udtData = mudtProps
      GetState = udtData.Buffer
    
    End Function
    
    Private Sub SetState(Buffer As String)
    
      Dim udtData As CustomerData
      
      udtData.Buffer = Buffer
      LSet mudtProps = udtData
    
    End Sub

    getting you head around the other stuff is fun, believe me
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  22. #22

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Hi ChrisE,

    I read your code carefully, but I still don't understand its meaning. Could you explain your code? For example, what purpose can it achieve. Much appreciated.

  23. #23

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    @Olaf:

    It's recommended to add two alias methods for Append and AppendNL of cStringBuilder: Add and AddNL

  24. #24

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    @Olaf:

    It's recommended to add GetFileNameWithoutExtension or GetFileNameWithNoExtension to cFSO.

  25. #25

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    @Olaf:

    It's recommended to add cVBLabel, cVBImage and cVBPictureBox components to RC6.

    We know that VB.Label and VB.Image are super lightweight controls, we can place tens of thousands or VB.Label and VB.Image in a Form. But we seem to be unable to place tens of thousands of UserControls in a Form (even if we set this control to Windowless and HasDC = False), because system resources will be exhausted.

    In many cases, we can use VB.Label, VB.Image and VB.Timer to combine many lightweight controls without subclassing.

    I know that there is cVBDraw in RC5/RC6. If RC6 can provide super-lightweight components such as cVBLabel, cVBImage and cVBPictureBox, then many people can use familiar methods to develop custom controls in RC6. Of course, this requirement is not urgent and can be considered in the future.
    Last edited by SearchingDataOnly; Mar 25th, 2021 at 09:26 AM.

  26. #26

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    @Olaf:

    The new RC6 has added some new methods (Add, AddNL, GetFileNameWithoutExtension), which is great.

    I found that New_c.FSO.GetFileNameWithoutExtension("c:\temp\myClass.cls") returns "c:\temp\myClass".

    I think it would be better if the return value is "myClass" instead of "c:\temp\myClass"

  27. #27
    PowerPoster
    Join Date
    Jun 2013
    Posts
    5,602

    Re: [RESOLVED] Several questions about RC6

    Quote Originally Posted by SearchingDataOnly View Post
    I found that New_c.FSO.GetFileNameWithoutExtension("c:\temp\myClass.cls") returns "c:\temp\myClass".

    I think it would be better if the return value is "myClass" instead of "c:\temp\myClass"
    I've considered that already - but decided that "leaving a potentially preceding path intact",
    (not destroying already existing information) - will be in the end less confusing for a user...

    In the scenarios where I needed that so far, (as e.g. converting a bitmap-file, then writing it to a png-file in the same path) -
    leaving the preceding path intact would have been exactly what was needed.

    Besides, in case the Inp-Param is a FullPath, you could easily write it this way, to get the desired result:
    Code:
    With New_c.FSO
      Debug.Print .GetFileNameWithoutExtension(.GetFileNameFromFullPath(FullPath))
    End With
    Now that I've written the above ...

    Have just included a new optional Parameter "WithoutExtension" (defaulting to False),
    into GetFileNameFromFullPath - so that the above can (in the next release) also be written this way:
    Code:
    Debug.Print New_c.FSO.GetFileNameFromFullPath(FullPath, True)

    Olaf

  28. #28

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Quote Originally Posted by Schmidt View Post
    Have just included a new optional Parameter "WithoutExtension" (defaulting to False),
    into GetFileNameFromFullPath - so that the above can (in the next release) also be written this way:
    Code:
    Debug.Print New_c.FSO.GetFileNameFromFullPath(FullPath, True)
    Very nice.

    Quote Originally Posted by Schmidt View Post
    I've considered that already - but decided that "leaving a potentially preceding path intact",
    (not destroying already existing information) - will be in the end less confusing for a user...

    In the scenarios where I needed that so far, (as e.g. converting a bitmap-file, then writing it to a png-file in the same path) -
    leaving the preceding path intact would have been exactly what was needed.

    Besides, in case the Inp-Param is a FullPath, you could easily write it this way, to get the desired result:
    Code:
    With New_c.FSO
      Debug.Print .GetFileNameWithoutExtension(.GetFileNameFromFullPath(FullPath))
    End With
    Since GetFileNameFromFullPath has a new optional parameter, GetFileNameWithoutExtension may be renamed as: RemoveFileExtension or RemoveExtension or RemoveFullPathExtension. Of course, GetFileNameWithoutExtension is also a good function name.

    Edit:
    Maybe it can be like this:
    (1) New_c.FSO.GetFileNameFromFullPath("c:\Temp\Myclass.cls", True) => Myclass
    (2) New_c.FSO.RemoveFullPathExtension("c:\Temp\Myclass.cls") => c:\Temp\Myclass
    (3) New_c.FSO.GetFileNameWithoutExtension("c:\Temp\Myclass.cls") => Myclass
    Last edited by SearchingDataOnly; Mar 27th, 2021 at 08:55 PM.

  29. #29

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    @Olaf:

    It's recommended to add RelPath And AbsPath to cFSO.

    Code:
    Function RelPath(ByVal AbsolutePath As String) As String 
    Function AbsPath(ByVal RelativePath As String) As String
    
    Function GetAbsolutePathName(ByVal CurrentDirectory As String, ByVal RelativePath As String) As String
    Function GetRelativePathName(ByVal CurrentDirectory As String, ByVal AbsolutePath As String) As String
    Here is an example in Python:

    Code:
    print os.path.relpath("d:/MyProj/MyFile.txt")
    #..\MyProj\MyFile.txt
    
    ...
    ...
    path = "..\MyProj\MyFile.txt"
    print os.path.abspath(path)
    #D:\MyProj\MyFile.txt
    Last edited by SearchingDataOnly; Apr 4th, 2021 at 10:51 AM.

  30. #30

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    @Olaf:

    It's recommended to add an optional parameter AutoCreateParentPath to cFSO.CreateDirectory.

    Code:
    Public Function CreateDirectory(ByVal Path As String, Optional ByVal AutoCreateParentPath As Boolean = False) As Boolean

    When I want to create the path "C:\0\1\2\3\4\5", I need to perform the following steps:

    New_c.FSO.CreateDirectory "C:\0\1"
    New_c.FSO.CreateDirectory "C:\0\1\2"
    New_c.FSO.CreateDirectory "C:\0\1\2\3"
    New_c.FSO.CreateDirectory "C:\0\1\2\3\4"
    New_c.FSO.CreateDirectory "C:\0\1\2\3\4\5"

    If theres is optional parameter AutoCreateParentPath in FSO.CreateDirectory, I only need to execute:
    New_c.FSO.CreateDirectory "C:\0\1\2\3\4\5", True

    Below is my code:
    Code:
    Public Function MyCreateDirectory(ByVal sPath As String, Optional ByVal bAutoCreateParentPath As Boolean = False) As Boolean
        Dim nPos As Long:       Dim sParentPath As String
        Dim nStart As Long
        
        With New_c.FSO
            If bAutoCreateParentPath = False Then
                MyCreateDirectory = .CreateDirectory(sPath):       Exit Function
            End If
            
            sPath = Trim$(Replace$(sPath, "/", "\"))
            If Right$(sPath, 1) = "\" Then
                .EnsurePathEndSep sPath, True
            End If
            
            nStart = 1
            nPos = InStr(nStart, sPath, "\")
            
            Do While nPos <> 0
                sParentPath = Mid$(sPath, 1, nPos - 1)
                If .FolderExists(sParentPath) = False Then
                    If .CreateDirectory(sParentPath) = False Then
                        Exit Function
                    End If
                End If
                nStart = nPos + 1
                nPos = InStr(nStart, sPath, "\")
            Loop
            
            MyCreateDirectory = .CreateDirectory(sPath)
        End With
        
    End Function
    Last edited by SearchingDataOnly; Apr 4th, 2021 at 07:09 AM.

  31. #31
    Frenzied Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    1,838

    Re: [RESOLVED] Several questions about RC6

    Quote Originally Posted by SearchingDataOnly View Post
    When I want to create the path "C:\0\1\2\3\4\5", I need to perform the following steps:

    New_c.FSO.CreateDirectory "C:\0\1"
    New_c.FSO.CreateDirectory "C:\0\1\2"
    New_c.FSO.CreateDirectory "C:\0\1\2\3"
    New_c.FSO.CreateDirectory "C:\0\1\2\3\4"
    New_c.FSO.CreateDirectory "C:\0\1\2\3\4\5"
    Try:

    Code:
    New_c.FSO.EnsurePath "C:\0\1\2\3\4\5"

  32. #32

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Quote Originally Posted by jpbro View Post
    Try:

    Code:
    New_c.FSO.EnsurePath "C:\0\1\2\3\4\5"
    Oh, wonderful ! Thank you very much, jpbro.

  33. #33

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Quote Originally Posted by Schmidt View Post
    Quote Originally Posted by SearchingDataOnly View Post
    (1) RC6 provides DynObj to implement dynamic properties and dynamic functions. Is there an example to demonstrate how to implement dynamic functions?
    See below:
    Code:
    Private Sub Form_Load()
      Dim oDyn As Object
      Set oDyn = New_c.DynObj
          oDyn = "{a:123, b:'xyz'}" 'js-like prop-initializing (a as integer, b as string)
          oDyn.c = True 'vb-like prop-initializing (c as boolean)
          oDyn.f = "function(arg){return this.a - arg}" 'func-def in js-notation (this. is similar to Me.)
      
      'Ok, readout-tests:
      Debug.Print oDyn.a, oDyn.b, oDyn.c, oDyn.f(81)
      
      'finally the built-in JSON-serialization:
      Debug.Print oDyn.toJSON
    End Sub
    HTH

    Olaf
    Hi Olaf,

    I just re-studied your tutorial "VB6 LightWeight COM and vbFriendly-BaseInterfaces", which contains several examples of "class factory". I'd like to know whether RC6.DynObj is implemented by a "class factory"(to be precise, it's an implementation similar to cPropStorage.cls). Thanks.

    In addition, could I understand it this way: "LightWeight COM" means converting the bulky VB6-Classes into "C-style defined Classes", just like transpiling "TypeScript-Classes" into "JavaScript-Functions"?

    Furthermore, could we use "C-style defined Classes" to implement objects/functions similar to JavaScript.
    Last edited by SearchingDataOnly; Apr 7th, 2021 at 06:49 AM.

  34. #34

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2020
    Posts
    447

    Re: [RESOLVED] Several questions about RC6

    Question: Directly access V8-js-engine in Edge-Chromium.

    In most cases, we do not need UI when executing JavaScript code in VB6, for example (cJSWrap):
    We can use CreateObject("htmlfile") to call the IE engine to perform JavaScript code, but the IE-WebBrowser window does not need to appear.

    Now, we can access V8-js-engine through RC6.WebView2-Binding (Edge-Chromium), and execute JS code through V8, but we need to pass an hWnd. I'd like to know whether we can access V8-js-engine in Edge-Chromium without passing an hWnd (that is, not through the UI) ? Thanks.
    Last edited by SearchingDataOnly; Apr 13th, 2021 at 08:00 AM.

Posting Permissions

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



Click Here to Expand Forum to Full Width