Author Topic: COM Dictionary Example  (Read 619 times)

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 959
    • View Profile
COM Dictionary Example
« on: September 19, 2020, 10:24:06 PM »
I can't imagine when I would ever use a dictionary object but maybe someone else can use this BCX code as a jumping off point.


DIM oDict AS OBJECT
DIM DictSize
DIM Index$
DIM Value AS BSTR

oDict = COM ("Scripting.Dictionary")

oDict.Add "A", "Adam"
oDict.Add "B", "Bill"
oDict.Add "C", "Chuck"
oDict.Add "D", "Dave"
oDict.Add "E", "Ernie"
oDict.Add "F", "Frank"
oDict.Add "G", "Greg"
oDict.Add "H", "Harry"
oDict.Add "I", "Ian"
oDict.Add "J", "John"
oDict.Add "K", "Kevin"

DictSize = oDict.Count

FOR INT j = 0 TO DictSize - 1
  Index$ = CHR$ ( 65 + j )
  Value = oDict.Item (Index$)
  PRINT WIDETOANSI$ (Value)
NEXT

UNCOM(oDict)

PAUSE


OUTPUT

Adam
Bill
Chuck
Dave
Ernie
Frank
Greg
Harry
Ian
John
Kevin

Press any key to continue . . .


rexxitall

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: COM Dictionary Example
« Reply #1 on: June 15, 2021, 05:00:44 PM »
Well, to get familar with dictionarys you has to use them for a while :)
I use them as a micro database.
On larger Datasets you will not run over and over some kind of array.
I have used them for example for syntax parser where i just want to know if there is a thing a variable or a BASIC statement. Or you want ensure that things are just ONE times inside something. I have some kind of triangulation routine in my CAD. This ones really hate it if there are 3d Points twice in the dataset. If you has let say 20.000 points you will not run with a distance function over all points and find out if the distance is zero. So i just use STR(x) & " " & STR(y) & " " & STR(z)  on each point in the set and store them in such a dictionary. So on each new point i try to get such a thing and if i do not have then i add the point to the new dataset as well as to the dictionary. Colornames and RGB values are also a classic ones for a dictionary. Colorname as Key and you can easy get the rgb values. And what you guys usually do with ini files i do with a dictionary. Textfile, First word is the key and i have a very fast setup routine :) So... They are not that useless :)

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 959
    • View Profile
Re: COM Dictionary Example
« Reply #2 on: June 15, 2021, 05:08:50 PM »
I never suggested that dictionaries were useless, only that I have a limited imagination for them.

rexxitall

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: COM Dictionary Example
« Reply #3 on: June 15, 2021, 05:50:08 PM »
*grin* They becomes always handy if you has strings as a index or something which you can not calculate directly. Even a statement like Keyword.exists("For") can tell you syntax highlighter that he has to change its color. And dictionarys are fast. In my bastool i didnt know about dictionarys. So i use a ordered list and bisection to find things. Was also not that slow. But you has to keep the list sorted. Not to forget my tryouts with double chained lists or even binary trees :) SQL eats the power by the call to the SQL interpreter and so on and so on. At the end you waste more time to organize the things then you use them.  A lot of programming languages have them meanwhile build in. Rexx, JS, PHP... In Basic they somehow are not that liked. Imagine you write a game with different monsters. So for the inventory the dictionary is your best and flexible friend :) And it does not have to be complete. Some monsters just may have a few propertys or items and others have a lot. A dictionary does not care :) You may have a form with a lot of gadgets. One dirctionary for the gadget name as index and a array of dictionarys for the gadget propertys.... Funny nice thing by that solution, you may alter the amount of propertys by the next gadget generation. The routine for retriving and store those new tricks is already there. All you has to do is to feed the dirctionary on init time with all of those nice things you want to play with :) No need even for a resource compiler. A ini file in plain text will do the whole trick. :) I really love them :) BTW the MS API how to use them is quite short :) If you use COM you can also abuse them to do nice IP Communication. They bridge also 64 and 32 bit via COM.

jcfuller

  • Sr. Member
  • ****
  • Posts: 313
    • View Profile
Re: COM Dictionary Example
« Reply #4 on: June 16, 2021, 06:27:22 AM »
Kevin,
My memory is hazy on this but I remember Paul Squires touting  the speed of hash table code he wrote (Pb I'm pretty sure.)
I wrote a little ditty using iDictionary and it was many times faster.

I also wrote a cBcxDic class wrapper for iDictionary back in the bc9 days I need to investigate again.

James

rexxitall

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: COM Dictionary Example
« Reply #5 on: June 16, 2021, 06:44:33 AM »
Do not slay me but a few weeks ago i was playing with this here
https://github.com/XusinboyBekchanov/VisualFBEditor/tree/master/Tools/COMWrapperBuilder
So finally i was able in FB to get access to Windows COM Dictionary as well to the VBS interpreter. Which might be also useful for BCX. Only problem i could not really solve was that some COM objects return ARRAYS by a function. CODE for Freebasic. At the moment i stuck that full with work, that i can not even work on this :( BTW: The code has some nice tricks under the hood :)


   'without this the string mangeling wont work correctly
   'that means you can not add valid source code to the script CONTROL
   'and get the error that "ADD" does not work    o
   'For Variables it is the same
   'A error like "unknown name" also indicated that something was not given by a vbVariant
   
   'as a general "rule of the thumb" everything which you send
   'to COM has to be stored first in a vbVariant.
   'Then you has to call it with the vbVariant
   
   'even constant strings. COM Object uses the so called BSTR string convention
   'By this direct string literals like "scriptcontrol" will not work
   'until the com wrapper does something automagically with them
   
   #include once "vbcompat.bi"
   #include once "windows.bi"
   #include once "win/ole2.bi"
   #include once "crt/string.bi"
    #include "SimpleVariantPlus.bi"

    'basicly its all the time the same:

    'UTILZE THE WIONDOWS SCRIPTING HOST
    '-----------------------------------
    'create some variables
     Dim WSHName As vbVariant   'The name of the COM Object
     Dim WSHObject As  vbVariant 'in fact should be a object aka Pointer or LongPointer depends osn OS version

    'assign the variables
     WSHName="Wscript.shell" 'the Windows VBS engine (has to be stored to a variant ! )
     WSHObject = CreateObject("Wscript.shell")

    'now we have a Windows Scripting host object aka VBS
    'as you may have recognized we do not have had to deal with the WIN Api ans its parameters

    'same for some other Objects

    'UTILZE THE SCRIPT CONTROL
    '-----------------------------------
    Dim ScriptControlName As vbVariant
    Dim ScriptControl As vbVariant
    'this has been comented ot cuase it will break the sample here in 64bit Windows
    'without Tablacus Script Control installed

    ScriptControlName="scriptcontrol"
    ScriptControl = CreateObject(ScriptControlName)

    'UTILZE THE FILE SYSTEM OBJECT
    '-----------------------------------
    Dim FilesystemControlName As String
    Dim FilesystemControl As vbVariant
    FilesystemControl = CreateObject(ScriptControlName)


    'SETUP THE OBJECTS
    '--------------------
    'note the setup for the WSH Object and the Scriptcontrol are the same
    'but be careful, the internal things are sometimes different.
    'Input and output statemenets for example

    'First we set the language of the used (interpreter) aka script control
     Dim Lang As vbVariant
     LANG="VBScript" 'JScript would be another choice and means JAVASCRIPT !
     ScriptControl.Language = Lang ' (BTW: perfect for the use of JSON )

    'let us add some VBS code. For those who are not familar with VBS
    'VBS is typeless so everything is a Variant

   
   'to make the code a bit better understandeable for the first reader
   'I add this dynamically so you do not have to deal with two files
   
   'no one is hindering you to read it from a text file.
   'but be aware that the COM Objects usually use ANSI code
   'unicode is usally not supported. At those days as they invent com
   'unicode was not invented (what lucky days they have had)

   'Some variables to be later used
   Dim I As Long
   Dim FBRES As vbVariant
   Dim FX As vbVariant
   Dim FBMSG As vbVariant
   Dim EVCODE As vbVariant
   Dim RUNARGS As vbVariant
   Dim NIX As vbVariant 'NIX is german slang and means somehow "nothing", its just a var name
   

   'some important ones ;)
    Dim CODE As vbVariant
    Dim LF As vbVariant
   'DIM TAB as vbVariant
   
    LF=vblf
      
   'Note: the code provided here is just for the sake of demonstration
   '      and ease of understanding. Therefore he has not to make any sense
   '      or show best practice or is optimized or has bullet proof error handling
   
   
   CODE=""
   CODE=CODE & "DIM RESULT" & LF          'NO TYPE !!! NEVER !!! Just DIm and Name
   CODE=CODE & "DIM FKT" & LF             'NO TYPE !!! NEVER !!! Just DIm and Name
   CODE=CODE & "DIM ARR()" & LF           'NO TYPE !!! NEVER !!! Just DIm and Name
   CODE=CODE & LF

   CODE=CODE & "FKT=22" & LF              'NO TYPE !!! NEVER !!! Just DIm and Name

    CODE=CODE & "SUB MSG(S)" & LF          'add a message box function
    CODE=CODE & "  MSGBOX S" & LF
    CODE=CODE & "END SUB" & LF
    CODE=CODE & LF


    CODE=CODE & "FUNCTION INP(PROMPT)"  & LF 'add a input box function
   CODE=CODE & "  INP= InputBox(PROMPT)"  & LF
    CODE=CODE & "END FUNCTION" & LF

    CODE=CODE & "FUNCTION ADD(A,B)" & LF
    CODE=CODE & "  RETURN = A*1 + B*1 " & LF 'I multiply to force a internal type cast to a number
    CODE=CODE & "END FUNCTION" & LF          'a common pitfall. Very often it might return a string
                                          'so "1+1" will becomes "11" ....
    CODE=CODE & LF                           'you can alsoe add & "" a internal type cast to a string
                                             'VBS has also Cstr(), Clng() and friends to do more type casting
    CODE=CODE & "SUB EVALUATE(S)" & LF
    CODE=CODE & "   EVALUATE=EVAL(S)" & LF
    CODE=CODE & "END SUB" & LF
    CODE=CODE & LF

   CODE=CODE & "SUB ASSIGN(A)" & LF        'assign a variable the direct way
    CODE=CODE & "  FKT= A"  & LF
    CODE=CODE & "END SUB" & LF

   CODE=CODE & "SUB EXEC(A)" & LF           'assign a variable the direct way
   CODE = CODE & "  DIM STATEMENTS" & LF      'NOTE SPLIT WILL REASSIGN it to a array byselv!
   CODE=CODE & "  DIM STATEMENT"  & LF
   CODE=CODE & "  STATEMENTS=SPLIT(A,chr(13))"  & LF
   CODE = CODE & "  FOR EACH STATEMENT IN STATEMENTS"  & LF
   CODE=CODE & "     EXECUTE STATEMENT"  & LF
   CODE=CODE & "  NEXT"  & LF
   CODE=CODE & "END SUB" & LF
   
   CODE=CODE & "RESULT=ADD(1,3)" & LF
    CODE=CODE & "" & LF
   
   CODE=CODE & "SUB MAIN 'hast to be there and executet !" & LF
   CODE=CODE & "END SUB" & LF
   
   Color 2
   Print code
   Color 15
   
   Print "----------------"
   
   'lets add the fine code to the control
    ScriptControl.AddCode CODE
   
   'just because i am a bit old school guy and have used "eval" for years in dieffernt languages
   'in VBS EVAL just evaluates a variable or a single statetement
   'to run vbs code which is stored  in a variable you has to use EXECUTE
   
   NIX="MAIN"
   ScriptControl.run(NIX) '            'you can invoke the script either by a vbVariant
   'ScriptControl.run("MAIN")          or directly by text string - this would do the same as the line above
   
   FX="MSG"                            'Sub to be called
   RUNARGS ="HELLO WORLD"              'Prepare argument
   ScriptControl.run("MSG"   ,"Hello Xusing")       'Note that the arguments you want to pass
                                 'has to be placed as second parameter !
   'lets get a variable back
   
   NIX="FKT"                           'store the string to a vbVariant
   Print  ScriptControl.eval(NIX)      'it is the same as with the run method
                               'otherwise it will not work.
                              
    'We now give some more steam to the engine

   Print fbres
    Print "F(x)=x*x"
    For I=-3 To 3
        FX=Str(i) & "*" & Str(i)
        FBRES= ScriptControl.eval(FX)
        Print I,FBRES
     Next

   'Ok that was fine but...
   'we assign a function as string to a script value
   Print

   FX="ASSIGN"                         'Sub to be called
   RUNARGS ="Y=X*X+3"                  'Prepare argument
   ScriptControl.run(FX,RUNARGS)       'Note that the arguments you want to pass

    Print "FKT is now:"
   NIX="FKT"
   Print  ScriptControl.eval(NIX)
   
   
   
   Color 6
   Print "Let's do some civil engineering"
   Dim STRARG As String
   STRARG=""                                                             'Sub to be called
   STRARG =STRARG & "FKT="  & Chr(34) & "WILLY the engineer is killed by the formula"         & Chr(34) & LF   'Just put some garbage which will be redefined
   STRARG =STRARG & "FKT="  & Chr(34) & "M=0.125*Q*L*L" & Chr(34) & LF   'Beam formula
   
   'NOTE FKT holds now the beam formula
   STRARG =STRARG & "L=5.0" & LF   'Length of beam
   STRARG =STRARG & "Q=2.0" & LF   'load of beam
   'time to calculate the formula
   STRARG = STRARG & "EXECUTE FKT" 'forces the script to execute what is inside the FKT variable
   Color 15
   Print "TEST ARGUMENTS -----------------------------"
   Color 4
   Print STRARG
   Color 15
   Print "END ARGUMENTS -----------------------------"

   'run our litle program in a program
   FX="EXEC"
   RUNARGS =STRARG
   ScriptControl.run(FX,RUNARGS)              'Note that the arguments you want to pass

   Print
    Print "VAR FKT is now:"
   NIX="FKT"
   Color 4
   Print  ScriptControl.eval(NIX)
   
   Print
   Color 15
   Print "M as the function result is now:"
   NIX="M"
   Color 6
   
   Print  ScriptControl.eval(NIX)
   Color 15
   
   
   
   
   
   ' ScriptControl.RUN "MSG(RESULT)" 'Mesgbox should show "4"
    End
     'Return the VBS variable to Freebasic




MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 959
    • View Profile
Re: COM Dictionary Example
« Reply #6 on: June 16, 2021, 08:02:49 AM »
Kevin,
My memory is hazy on this but I remember Paul Squires touting  the speed of hash table code he wrote (Pb I'm pretty sure.)
I wrote a little ditty using iDictionary and it was many times faster.

I also wrote a cBcxDic class wrapper for iDictionary back in the bc9 days I need to investigate again.

James

James ... I'm still not interested in Dictionary code but Herr Rexxitall might find your BCX code useful.
« Last Edit: June 16, 2021, 11:52:23 AM by MrBcx »

rexxitall

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: COM Dictionary Example
« Reply #7 on: June 16, 2021, 03:27:09 PM »
Yes MrBCX, i am interested in any code to call such things from BCX, especially if they compile and run in a 64bit environment :) I need to know how to create and call a 64bit DLL via COM to make Autocad a bit more clever :) But this week i guess i will be busy with things like a parser engine *grin* 
Pure fun i would like to say:
If someones is interested and doesnt has enough problems to solve -> http://goldparser.org  ...

00026 000 ^ 012 :>


00027 000 ^ 013 :>

00000 000 ^ 009 :> <GlobalStmtList> ::= <GlobalStmt> <GlobalStmtList>

00000 000 ^ 011 :> <AccessModifierOpt> ::=
00028 000 ^ 011 :> Sub
00000 000 ^ 011 :> <SubID> ::= ID
00028 004 ^ 012 :> CGISET
00000 000 ^ 011 :> <MethodArgList> ::= '(' <ArgList> ')'
00028 010 ^ 012 :> (
00000 000 ^ 012 :> <ArgList> ::= <Arg> ',' <ArgList>
00000 000 ^ 013 :> <Arg> ::= <ArgModifierOpt> <ExtendedID>
00000 000 ^ 014 :> <ArgModifierOpt> ::=
00000 000 ^ 014 :> <ExtendedID> ::= ID
00028 012 ^ 015 :> KEY
00028 015 ^ 013 :> ,
00000 000 ^ 013 :> <Arg> ::= <ArgModifierOpt> <ExtendedID>
00000 000 ^ 014 :> <ArgModifierOpt> ::=
00000 000 ^ 014 :> <ExtendedID> ::= ID
00028 016 ^ 015 :> VALUE
00028 021 ^ 012 :> )

I hope i can craft some kind of transpiler ....

jcfuller

  • Sr. Member
  • ****
  • Posts: 313
    • View Profile
Re: COM Dictionary Example
« Reply #8 on: June 16, 2021, 05:24:49 PM »
Kevin,
   I took at a look at the "c" code produced by your demo and I must say I am very impressed.
Did Ljubisa Knezevic add all the COM work?
I compiled the "c" code with TDM, Nuwen, and Clang as 64 bit using Mikes InsertOptArg.
I tried COM with "c" a bit but I was primarily using PB at the time and there was little need.
When I tried it again it was with bc9/c++ so there was no need to use any work-a-rounds. Just build and use BCX/c++ classes.


James

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 959
    • View Profile
Re: COM Dictionary Example
« Reply #9 on: June 16, 2021, 06:42:53 PM »
Kevin,
   I took at a look at the "c" code produced by your demo and I must say I am very impressed.
Did Ljubisa Knezevic add all the COM work?
I compiled the "c" code with TDM, Nuwen, and Clang as 64 bit using Mikes InsertOptArg.
I tried COM with "c" a bit but I was primarily using PB at the time and there was little need.
When I tried it again it was with bc9/c++ so there was no need to use any work-a-rounds. Just build and use BCX/c++ classes.

James
James,

Ljubisa Knezevic gets most of the credit, along with big kudos for Wayne Halsdorf, Mike Henning, et al for improving and supplementing Ljubisa's work.  I spent many hours last year compressing variable names, creating wrappers, and adding a few functions of my own.  I also made modifications to BCX that results in COM output that one can actually study, learn from, and not go cross-eyed.   ;D

So ... thank you for noticing.

rexxitall

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: COM Dictionary Example
« Reply #10 on: July 06, 2021, 06:32:58 PM »
Hello, is there a hint to find those wrappers ?
It would be a starting point with my 64bit COM BCX dlls :)
Its nice to call very easy COM dlls in BCX. In fact it looks too simple as that it could be true :)
But in fact most peoples would get a bigger benefit to be able to create such com dlls byselv.
In Excel and ACAD this would be a real weapon. Cause now you could outsource whatever was still way too slow. ODBC database calls are such a pain in the ass. Last year i was in the need to feed a lot of big binary data (ACAD blocks) into a sqlite database. First i try it with plain VBA and the VBA com wrapper for sqlite. Works in general but was way too slow.In fact it was not possible to work serious with it. Problem was the database calls and the needed base64 transformation of the binary data. Then i feed a dll with the raw data  and let the dll do all the things i want. It was "some" times faster. In fact i wrote something which act as com server in VB.net, which also did some multithreading there and calls a freebasic dll to do the rest. its working quine nice cause VB.NET did the COM interface and mutithreading stuff and FB does the heavy work. (VB.NET and C# are slow). But it is a awful construct. At that times also the 64bit Sqlite interface was broken, so some more fun. I have had to write a new interface to tell FB how to call the 64bit Sqlite dll... If i remember right i wasted one month to get this up and running. According what i read til now in the docs this could be done way more with BCX.

Robert

  • Hero Member
  • *****
  • Posts: 710
    • View Profile
Re: COM Dictionary Example
« Reply #11 on: July 06, 2021, 06:56:13 PM »
Hello, is there a hint to find those wrappers ?
It would be a starting point with my 64bit COM BCX dlls :)
Its nice to call very easy COM dlls in BCX. In fact it looks too simple as that it could be true :)
But in fact most peoples would get a bigger benefit to be able to create such com dlls byselv.
In Excel and ACAD this would be a real weapon. Cause now you could outsource whatever was still way too slow. ODBC database calls are such a pain in the ass. Last year i was in the need to feed a lot of big binary data (ACAD blocks) into a sqlite database. First i try it with plain VBA and the VBA com wrapper for sqlite. Works in general but was way too slow.In fact it was not possible to work serious with it. Problem was the database calls and the needed base64 transformation of the binary data. Then i feed a dll with the raw data  and let the dll do all the things i want. It was "some" times faster. In fact i wrote something which act as com server in VB.net, which also did some multithreading there and calls a freebasic dll to do the rest. its working quine nice cause VB.NET did the COM interface and mutithreading stuff and FB does the heavy work. (VB.NET and C# are slow). But it is a awful construct. At that times also the 64bit Sqlite interface was broken, so some more fun. I have had to write a new interface to tell FB how to call the 64bit Sqlite dll... If i remember right i wasted one month to get this up and running. According what i read til now in the docs this could be done way more with BCX.

Hi Thomas:

The wrappers are in the BCX source code. You do not want to go there, yet, maybe later after you become a bit more familiar with BCX.

A better place to start would be with the BCX Help file. Specifically go to the Help file index and double click on the Com Interfaces Procedures entry. That will take you to a listing of many of the COM wrappers in BCX.

You mentioned Excel. Here's a BCX example

Code: [Select]


CLS
 
  DIM app AS OBJECT
 
  SET app = CREATEOBJECT("Excel.Application")
 
  IF BCX_COM_ERROR THEN
  PRINT BCX_GET_COM_ERROR_DESC$
  END
  END IF
 
  app.visible = true
 
  Sleep(2000) ' Excel will be visible for 2 sec, and than it will close.
 
  app.activeworkbook.saved = true ' don't prompt to save workbook
 
  app.quit
 
  SET app = NOTHING ' remember to call Set xxx = Nothing to release resources used by COM object!!!


Translate it and check out the C emitted code. Do that with some of the other COM examples and you should begin to get an understanding of what must be done to get to where you want to go.

Robert

  • Hero Member
  • *****
  • Posts: 710
    • View Profile
Re: COM Dictionary Example
« Reply #12 on: July 06, 2021, 07:05:00 PM »
Hi Thomas:

And here is a simple sqlite demo to get you going.

Code: [Select]

' SQLITE demo
' By Jef Rozenski JAN 2004
'
' Simplified to console mode by Jeff Shollenberger SEP 2004
'
' Updated to sqlite3 by Jeff Shollenberger MAY 2005
'
' Needs sqlite3.dll
' See http://www.sqlite.org/

DIM astring$
DIM rc
DIM dbHandle AS LONG

astring$ = sqlite3_libversion(LIB "sqlite3.dll")
PRINT "DLL version: " & astring$

PRINT "Opening database"
rc = sqlite3_open(LIB "sqlite3.dll","sq3.db", &dbHandle) ' open a database

IF NOT dbHandle THEN
  PRINT "Could not open database"
ELSE
  PRINT "Database opened successfully"
END IF

astring$ = "CREATE TABLE test (item varchar primary key, color text, price real);"
rc = sqlite3_exec(LIB "sqlite3.dll",dbHandle,astring$,NULL,NULL,NULL)
IF rc = 0 THEN ' Add some data (one time)
  PRINT "Adding Data To Table 'test'"
  astring$ = "INSERT INTO test VALUES ('apple1','green',0.95);"
  rc = sqlite3_exec(LIB "sqlite3.dll",dbHandle,astring$,NULL,NULL,NULL)
  astring$ = "INSERT INTO test VALUES ('apple2','red',0.85);"
  rc = sqlite3_exec(LIB "sqlite3.dll",dbHandle,astring$,NULL,NULL,NULL)
  astring$ = "INSERT INTO test VALUES ('tomato','red',0.65);"
  rc = sqlite3_exec(LIB "sqlite3.dll",dbHandle,astring$,NULL,NULL,NULL)
  astring$ = "INSERT INTO test VALUES ('strawberry','red',0.75);"
  rc = sqlite3_exec(LIB "sqlite3.dll",dbHandle,astring$,NULL,NULL,NULL)
  astring$ = "INSERT INTO test VALUES ('banana','yellow',1.25);"
  rc = sqlite3_exec(LIB "sqlite3.dll",dbHandle,astring$,NULL,NULL,NULL)
  astring$ = "INSERT INTO test VALUES ('pineapple','yellow',1.95);"
  rc = sqlite3_exec(LIB "sqlite3.dll",dbHandle,astring$,NULL,NULL,NULL)
  astring$ = "INSERT INTO test VALUES ('beans1','green',0.35);"
  rc = sqlite3_exec(LIB "sqlite3.dll",dbHandle,astring$,NULL,NULL,NULL)
  astring$ = "INSERT INTO test VALUES ('beans2','yellow',0.40);"
  rc = sqlite3_exec(LIB "sqlite3.dll",dbHandle,astring$,NULL,NULL,NULL)
ELSE
  PRINT "Table 'test' exists"
END IF
PRINT "Displaying data"
astring$ = "SELECT * FROM test"
ExecSQL(astring$)

PRINT "Closing Database"
sqlite3_close(LIB "sqlite3.dll",dbHandle) ' close the database



FUNCTION MyCallback(lpv AS LPVOID,cols AS INT,lpdata[] AS LPSTR,colnames[] AS LPSTR) AS INTEGER
  ' this function is executed for each hit from an sqlite3_exec call
  DIM sOutput$
  FOR INTEGER i = 0 TO cols-1
    sOutput$ = sOutput$ & lpdata[i] & SPACE$(11 - LEN(lpdata[i])) & "| "
  NEXT
  PRINT sOutput$
  FUNCTION = 0
END FUNCTION


FUNCTION ExecSQL(SQLstring$) AS INTEGER ' execute SQL command with Callback
  FUNCTION = sqlite3_exec(LIB "sqlite3.dll",dbHandle,SQLstring$,MyCallback,NULL,NULL)
END FUNCTION



rexxitall

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: COM Dictionary Example
« Reply #13 on: July 07, 2021, 06:57:55 AM »
Thank you both very much :)
Just to be sure that you understand what i need. I have a really massive amount of VBA code to drive autocad. More then half a million lines of code. The thing can meanwhile everything - except serve coffee :) Fastest way to do something automatically in Autocad is to write it in VBA. To write a module which generates whatever 3d staircase as precast element in whatever shape took me for example two days. A complete 3D rail road steel bow bridge around a week. Ok just in draft quality but that is what you need first. So i can fiddle with its parameter and my 3d terrain module to get a solution which fits best. And if something goes wrong you can edit it in a few minutes even during run time. So whatever i do it goes first the VBA way.It interfaces via COM in both directions. So i do not just call COM dlls, i create COM dlss to be called. To call com DLLs is way more easy as to create a com dll which can be called. That is due their interface which they have to provide to get registered in the registry and how they show the functions they provide. Currently i write VB.NET function stubs which calls a freebasic dll. VB.NET has a nice feature to create all those com related things more or less automatically. To ease my life ive written som VBA macros which emit all the funny interfaces and are also able to make export VBA code to Freebasic way more easy. I found a sample how i can write a com server class in freebasic on github https://github.com/zamabuvaraeu/TestCOMServer.  That is my goal, to make such DLLs a breeze. Another goal is not to get rid the VBA code, i want to get rid the VB.Net code *laugh*. BCX is able to embed native C and C++code which also makes me highly interested. ACADs ultimative API is written in C++ . Very often you just need a tiny function and then you ha the fun to convert a tiny pice of C++ to BASIC. And i am not the C,C++ Hero still :) So i do not drive ACAd with a application like some does, i enhance the functions of autocad by creating specialized dlls :) So i still can still use VBA as a rapid development tool. Construction sites loves to get paper drawings and hate to wait until you get some strange compiler issues fixed or solved. Aside my programming work i do a few times per year real bridge projects. Either for the first design or as a detail designer afterwards. Usually with a impatient construction site in the neck ;). For those who do not love bridge engineering so much there is another scenario where such com DLLs pays of. A game engine could be written as a com dll. Now you are able to control this engine with Pascal, VBS, Whatever.net or any other programming language which is com ready. The program main logic usually does not need to be fast. But the core working routines does. Same as for most applications. usally they need to read ini files, save and store text files, has susally all the same menu thing in it. If you get such a framework up and running its easy to derive applications from it. (without rewriting the same code again and again).  With VBS you could bring together the best of two worlds. I do not want you to make my job. :) But i am happy that you try to help me to get the first steps moving on. As written before. THIS weekend i try to learn how to compile normal DLLs or maybe call VBS via COM :) . During this week i will be a bit busy to finalize my tool which brings rusty VBA code in a way better standardized easy to parse shape. I got also a idea how to bring those "[" array braces into the emitted code, solve the need to be case sensitive or replace "MID(" by "MID$" ;). Last two things are rather trivial using dictionarys. The braces are a bit more tricky, you has first to figure out what was defined as array and then find the places in the code where they be used. 15 Years ago i wrote a tool to convert old BASIC programs with line numbers to get refactored for freebasic. This tool has had also to find out whats is a variable and to guess which kind of variable its might be. Works quite well. Just a few lines you has to convert by hand afterwards :). Thanks again and have a nice day :)