Main Menu

CDicObj

Started by Richard Kelly, May 02, 2026, 04:21:59 AM

Previous topic - Next topic

Richard Kelly

I have a custom TYPE I want to put into a dictionary with a string key. Are any examples available?

hajubu

#1
Hi Richard, here my Tip for an short example , show in J.R. docs folder of AfxNova-Main (Github)

CDicObj

can be  found in ..\docs\Windows\Windows Script\CDicObj Class.md

b.r. Hans (hajubu)

PS: see also the full .md collection as an HTML-Webview , which can be integrated in the Tiko as an help tool.

docs-as-Html for Tiko1.3/AfxNova

find it here in this  Support Forum -- PlanetSquires Software --# Tiko 1.3 and AfxNova Docs as integrated HelpTool   #10
--> CDicObj Class
-->
CDicObj is an associative array of variants. Each item is associated with a unique key. The key is used to retrieve an individual item.

Example
' // Creates an instance of the CDicObj class
DIM pDic AS CDicObj

' // Adds some key, value pairs
pDic.Add "a", "Athens"
pDic.Add "b", "Belgrade"
pDic.Add "c", "Cairo" ..........and so on .....

Richard Kelly

#2
I'll study things a bit. I've reached way back to PowerBasic days and I'm looking for replacements for LinkListCollection and PowerCollection.

What I'm trying to figure out is how to add a custom type like:

Type FontDescriptor
    FontName                As ZSTRING * 30
    FontID                  As Long
    FontStyle               As Long
    FontReferenced          As Long
    FontAscent              As Long
    FontCapHeight           As Long
    FontDescent             As Long
    FontFlags               As Long
    FontRectLeft            As Long
    FontRectTop             As Long
    FontRectRight           As Long
    FontRectBottom          As Long
    FontItalicAngle         As Double
    FontStemV               As Long
    FontWeight              As Long
    FontUnderlineThickness  As Long
    FontUnderlinePosition   As Long
    FontObject              As Long
    FontWidthObject         As Long
    FontDescriptorObject    As Long
 End Type

Richard Kelly

I'm getting a little closer using:

DIM uDescriptor       As FontDescriptor
 DIM uDescriptor1       As FontDescriptor
 DIM oDicObj            AS CDicObj
 DIM sDescriptor AS STRING * LEN(UDescriptor)
 DIM sDescriptor1 AS STRING
 
    uDescriptor.FontName = "Arial"
    uDescriptor.FontID = 1
    uDescriptor.FontStyle = 1
    uDescriptor.FontReferenced = 0
    uDescriptor.FontAscent = 905
    uDescriptor.FontCapHeight = 728
    uDescriptor.FontDescent = -210
    uDescriptor.FontFlags = 32
    uDescriptor.FontRectLeft = -666
    uDescriptor.FontRectTop = -210
    uDescriptor.FontRectRight = 2000
    uDescriptor.FontRectBottom = 728
    uDescriptor.FontItalicAngle = 0
    uDescriptor.FontStemV = 44
    uDescriptor.FontWeight = 400
    uDescriptor.FontUnderlineThickness = 73
    uDescriptor.FontUnderlinePosition = -106
   
    memcpy (StrPtr(sDescriptor), @uDescriptor, LEN(UDescriptor))
   
    oDicObj.Add("F1",sDescriptor)
    sDescriptor1 = oDicObj.Item("F1")
   
    memcpy (@uDescriptor1, StrPtr(sDescriptor1), LEN(uDescriptor1))
   
    print uDescriptor1.FontName
    print str(uDescriptor1.FontID)
    print str(uDescriptor1.FontStyle)
    print str(uDescriptor1.FontReferenced)
    print str(uDescriptor1.FontAscent)
    print str(uDescriptor1.FontCapHeight)
    print str(uDescriptor1.FontDescent)
    print str(uDescriptor1.FontFlags)
    print str(uDescriptor1.FontRectLeft)
    print str(uDescriptor1.FontRectTop)
    print str(uDescriptor1.FontRectRight)
    print str(uDescriptor1.FontRectBottom)
    print str(uDescriptor1.FontItalicAngle)
    print str(uDescriptor1.FontStemV)
    print str(uDescriptor1.FontWeight)
    print str(uDescriptor1.FontUnderlineThickness)
    print str(uDescriptor1.FontUnderlinePosition)

I'm not getting back what I sent in. More analysis needed.

hajubu

#4
hi,
I just added a 'Little'  and had working output result:
'REMARK I did not use #cmdline option in Tiko !!! do NOT use -'s gui' for an ' -s console'
'I prefer to set the pref. to win console64  (shift-f7 ....) and in the basic - env - compiler pref  to ' using cmd windows '

'!!!!!! IF you did (-s gui) on a console  -check- you have to kill the running application manually via Taskmanager
' ALSO with the  'SLEEP at the end - do not forget to close it manually.
----------------
Arial
42926416
0
1662031610
29243
42926416
0
42934288
0
... and_eight_more_zeros
-------------------------
'CdicObj_RK_sample_onConsole
'REMARK I did not use #cmdline option in Tiko !!! do NOT use -'s gui' for an ' -s console'

'#cmdline "-s console"   ' console application
''''''''''''''''''''''''''''''#cmdline "-s gui"       ' gui application
'#cmdline "resource.rc"  ' resource file
'REMARK
#include once "AfxNova\CdicObj.inc"
'
' then the Type...End section/region
Type FontDescriptor
.......................................
Type End
'
'then a copy of your 'code' region p to the last print statement
DIM uDescriptor      As FontDescriptor
DIM uDescriptor1      As FontDescriptor
DIM oDicObj            AS CDicObj
DIM sDescriptor AS STRING * LEN(UDescriptor)
DIM sDescriptor1 AS STRING

    uDescriptor.FontName = "Arial"
    uDescriptor.FontID = 1
'......up_to....
print str(uDescriptor1.FontUnderlinePosition)
'
'THEN a
SLEEP
' to ensure halting the console output ... waiting for a needed key <Enter>




Richard Kelly

#5
Quote from: hajubu on May 02, 2026, 06:45:56 PMArial
42926416
0
1662031610
29243
42926416
0
42934288
0
... and_eight_more_zeros

That doesn't match up with what I sent into CDicObj. I think presence of x'00' s might in play. If I populate my first type, memcpy it to a string then memcpy from that string to a second type, the second type is equal to the first.

Richard Kelly

Problem solved....for now unless someone has a better idea. I just used AfxBase64EncodeA passed in and AfxBase64DecodeA on what came out with memcpy along the way.

José Roca

The correct way is to use the IRecordInfo interface and assign the pointer to a variant of the type VT_RECORD. I will have to write a class to wrap the IRecordInfo interface. And please, when using COM forget ansi. Use WSTRING instead of ZSTRING. Using AfxNova, you better forget ansi forever.

Richard Kelly

I didn't know about IRecordInfo. The Zstring reference in that font UDT was what I just copied over from the old PowerBasic code I am looking to port. I can easily change that to WSTRING. I tried both the "W" and "A" versions of B24 calls any only the "A" version worked. I look forward to a more direct way to handle UDT's with CDicObj which is a great replacement for the PB PowerCollection.

José Roca

Forget IRecordInfo. It is an interface added for Automation languages like VB6 and needs the use of a type library.

Regarding PowerBasic, it is using the trick of converting the udt to a string. This can work if the udt only contains primitive types, not objects or variants.

José Roca

#10
After thinking it over, this is the solution I've come up with. It stores the UDT as an array of unsigned bytes (a VT_ARRRAY OR VT_UI1 variant).. Works with ZSTRING too.

#cmdline "-s console"
#INCLUDE ONCE "AfxNova/CDicObj.inc"
USING AfxNova

TYPE Foo
  x AS long
  y as long
  b as WSTRING * 260
END type
 

' // Creates an instance of the CDicObj class
DIM pDic AS CDicObj

' // Creates an instance of the Foo type
DIM t AS Foo = (12345, 72727, "Test string")
' // Assigns it to a DVARIANT
DIM dv AS DVARIANT
dv.PutBuffer(@t, SIZEOF(t))
' // Adds the type to the dictionary
pDic.Add "Foo1", dv

' // Creates another instance of the Foo type
DIM t2 AS Foo = (111111, 22222, "Test string 2")
' // Assigns it to a DVARIANT
DIM dv2 AS DVARIANT
dv2.PutBuffer(@t2, SIZEOF(t2))
' // Adds the type to the dictionary
pDic.Add "Foo2", dv2

' // Gets Foo1 from the dictionary
DIM dvFoo1 AS DVARIANT
dvFoo1 = pDic.Item("Foo1")
' // Assigns it to a Foo structure
DIM tFoo1 AS Foo
dvFoo1.ToBuffer(@tFoo1, SIZEOF(tFoo1))
' // DIsplays the values
print tFoo1.x
print tFoo1.y
print tFoo1.b

' // Gets Foo2 from the dictionary
DIM dvFoo2 AS DVARIANT
dvFoo2 = pDic.Item("Foo2")
' // Assigns it to a Foo structure
DIM tFoo2 AS Foo
dvFoo2.ToBuffer(@tFoo2, SIZEOF(tFoo2))
' // DIsplays the values
print tFoo2.x
print tFoo2.y
print tFoo2.b

PRINT
PRINT "Press any key..."
SLEEP