(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.
(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
Originally Posted by SearchingDataOnly
(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).
Originally Posted by SearchingDataOnly
(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)
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.
Originally Posted by Schmidt
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
Originally Posted by Schmidt
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.
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.
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.
Originally Posted by SearchingDataOnly
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...)
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.
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
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.
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.
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.
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.
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.
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.
...
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"
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?
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.
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.
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.
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.
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:
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:
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.
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
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.
(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.
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.