 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Laszlo
Joined: 14 Feb 2005 Posts: 4515 Location: Boulder, CO
|
Posted: Mon Jun 04, 2007 10:35 pm Post subject: |
|
|
| majkinetor wrote: | | The usage is not the problem. The problem is sharing. | Then I don't understand the problem: you have to pass the dictionary handle to a function as a parameter or make it global. The same is with the variable containing all of your constants. The later is faster and does not need includes or dll calls. |
|
| Back to top |
|
 |
toralf
Joined: 31 Jan 2005 Posts: 3906 Location: Bremen, Germany
|
Posted: Wed Jun 06, 2007 7:21 am Post subject: |
|
|
Is there any limitation on OS? Does it run on all windows versions? _________________ Ciao
toralf  |
|
| Back to top |
|
 |
hoppfrosch
Joined: 25 Jan 2006 Posts: 38 Location: Froschtümpel
|
Posted: Thu Aug 09, 2007 7:09 am Post subject: Question: Hash of Hashes? |
|
|
Hi,
got a question concerning "Hash of Hashes" (considering dictionaries as hashes).
What I try to do is putting dictionary items into a dictionary:
| Code: |
#include %A_ScriptDir%\Includes\CoHelper.ahk
#Include %A_ScriptDir%\Includes\Dic.ahk
CoInitialize()
pdic := Dictionary()
Add(pdic, "ATT1", "ATT1_1")
Add(pdic, "ATT2", "ATT2_1")
Add(pdic, "ATT3", "ATT3_1")
Add(pdic, "ATT4", "ATT4_1")
pdic2 := Dictionary()
Add(pdic2, "ENTRY1", pDic)
MsgBox, % "ENTRY1: " . "`n" . Enumerate(GetItem(pdic2, "ENTRY1"))
; Changing the contents of pDic
SetItem(pdic, "ATT1", "ATT1_2")
SetItem(pdic, "ATT2", "ATT2_2")
SetItem(pdic, "ATT3", "ATT3_2")
SetItem(pdic, "ATT4", "ATT4_2")
; Is pDic stored byVal or byRef? Unfortunately its stored byRef, so the old contents got lost ....
MsgBox, % "ENTRY1: " . "`n" . Enumerate(GetItem(pdic2, "ENTRY1"))
Release(pdic)
Release(pdic2)
CoUninitialize()
|
Doing the above - changing contents of pdic after inserting it into pdic2, also changes the inserted item in pdic2.
How can I store the contents of pdic in pdic2, instead of just storing the reference of pdic?
Thanks in advance
Hoppfrosch |
|
| Back to top |
|
 |
Azerty
Joined: 19 Dec 2006 Posts: 72 Location: France
|
Posted: Thu Aug 09, 2007 1:11 pm Post subject: |
|
|
| Chris wrote: | | Thanks for these great functions. I've linked to this topic from the bottom of the Arrays page. Does anyone know whether Windows 9x/NT supports Scripting.Dictionary? |
Hi
AFAIK, Scripting.Dictionary is implemented when WSH5.6 is installed. Since MS has a specific version for W98/NT4, it should be supported as well
Sean : thanks for this great work |
|
| Back to top |
|
 |
fade2gray
Joined: 21 Oct 2006 Posts: 18
|
Posted: Tue Oct 23, 2007 11:41 am Post subject: |
|
|
Hi, I arrived here by reading the help file on arrays.
I downloaded the Dictionary and CoHelper scripts, but running the example included in Dictionary.ahk results in:- | Quote: | Error at line63 in #include file "\path to\CoHelper.ahk ".
Line Text: Enumerate(penum, ByRef Result)
Error:Duplicate function definition |
The Enumerate() function has been defined in Dictionary.ahk as:-
| Code: | Enumerate(pdic)
{
DllCall(VTable(pdic, 20), "Uint", pdic, "UintP", penm)
VarSetCapacity(var, 8 * 2, 0)
Loop, % Count(pdic)
{
DllCall(VTable(penm, 3), "Uint", penm, "Uint", 1, "Uint", &var, "Uint", 0)
pKey := DecodeInteger(&var + 8)
DllCall(VTable(pdic, 9), "Uint", pdic, "Uint", &var, "Uint", &var)
pItm := DecodeInteger(&var + 8)
Unicode2Ansi(pKey, sKey)
Unicode2Ansi(pItm, sItm)
SysFreeString(pKey)
SysFreeString(pItm)
sKeys .= sKey . " : " . sItm . "`n"
}
DllCall(VTable(penm, 2), "Uint", penm)
Return sKeys
} |
and in CoHelper.ahk as:-
| Code: | Enumerate(penum, ByRef Result)
{
VarSetCapacity(varResult,16,0)
If (0 = hResult:=DllCall(NumGet(NumGet(1*penum)+12), "Uint", penum, "Uint", 1, "Uint", &varResult, "UintP", 0))
Result:=(vt:=NumGet(varResult,0,"Ushort"))=8||vt<0x1000&&DllCall("oleaut32\VariantChangeTypeEx","Uint",&varResult,"Uint",&varResult,"Uint",LCID,"Ushort",1,"Ushort",8)=0 ? Ansi4Unicode(bstr:=NumGet(varResult,8)) . SubStr(SysFreeString(bstr),1,0) : NumGet(varResult,8)
Return hResult
} |
Any comments please? |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4114 Location: Belgrade
|
Posted: Tue Oct 23, 2007 11:48 am Post subject: |
|
|
If i recall correctly COM.ahk replaced CoHelper.ahk. _________________
 |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 2204
|
Posted: Tue Oct 23, 2007 12:00 pm Post subject: |
|
|
| fade2gray wrote: | I downloaded the Dictionary and CoHelper scripts, but running the example included in Dictionary.ahk results in:- | Quote: | | Error at line63 in #include file "\path to\CoHelper.ahk ". |
|
Ah, recently I added Enumerate() to CoHelper.ahk while adding COM_Enumerate() to COM.ahk, completely forgetting about this Scripting.Dictionary (:yes, it's been deleted already from my HDD, all functions were replaced with Invoke()).
Are you gonna use it? I can safely remove Enumerate() from CoHelper.ahk.
However, I suggest to switch to Invoke()/COM_Invoke(). |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 2204
|
Posted: Tue Oct 23, 2007 12:40 pm Post subject: |
|
|
| fade2gray wrote: | | Error at line63 in #include file "\path to\CoHelper.ahk ". |
I commented out Enumerate() in CoHelper.ahk. So, you may redownload it.
BTW, I recommend using COM.ahk over CoHelper.ahk, and COM_Invoke() function over the script(s) Scripting.Dictionary etc. |
|
| Back to top |
|
 |
fade2gray
Joined: 21 Oct 2006 Posts: 18
|
Posted: Tue Oct 23, 2007 5:54 pm Post subject: |
|
|
Thanks for the prompt replies.
I was trying to find a method to return multiple variables from a function (believing an array was the way to go) and have just figured how to use StringSplit. |
|
| Back to top |
|
 |
Phoenix
Joined: 23 Sep 2005 Posts: 48
|
Posted: Sun Feb 24, 2008 1:36 am Post subject: |
|
|
| How do I loop through the whole dictionary the best way? |
|
| Back to top |
|
 |
Phoenix
Joined: 23 Sep 2005 Posts: 48
|
Posted: Mon Apr 21, 2008 6:36 pm Post subject: |
|
|
*bump* I would like to know how to loop through through it  |
|
| Back to top |
|
 |
Guest
|
Posted: Mon Apr 21, 2008 11:41 pm Post subject: |
|
|
| There is a function Enumerate in the script. |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 2179 Location: GERMANY
|
Posted: Mon Jun 22, 2009 9:05 pm Post subject: |
|
|
Many thanks for this great functionality, specially to Sean and Laszlo
I've tried to put in some more simplicity and functionality in it
I would love to get some feedback
EDIT:
Added action abbreviation characters: + (Add), - (Delete), = (Set)...
HowTo
| Code: | ;--------------------------------------------------------------------------------------------
;
; D D D D D D D D D D D D ; D I C T I O N A R Y D A T A B A S E
; D D D D D D ;
; D D D D D D ;
; D D D D D D ;
; D D D D D D D D ; B Y H O T K E Y I T
; D D D D D D ;
; D D D D D D ;
; D D D D D D ;
; D D D D D D D D D D D D ; http://www.autohotkey.com/forum/viewtopic.php?p=276927#276927
;
;---------------------------------------------------------------------------------------------
;
; Scripting.Dictionary - http://msdn.microsoft.com/en-us/library/x4k5wbx4.aspx
; - A Dictionary object is the equivalent of a PERL associative array.
; Items can be any form of data, and are stored in the array.
; Each item is associated with a unique key.
; The key is used to retrieve an individual item and is usually an integer or a string but can be anything else.
; THE ONLY CHARACTERS YOU SHOULD NOT USE ARE CHR(2) + CHR(3) - those are used in sort action
;
; Syntax
; DDB([database,action,key/option,itm/option,skip,limit])
;
;
; DDB() - ALL PARAMETERS ARE OPTIONAL - DDB() will destroy all databases and UNinitialise COM
;
;
; DDB uses offers following functions ( - Key is like a Var and Item like Value in AutoHotkey - )
;
;
; - Create/N ---> Initialises COM (if not already done so) and creates a new database.
; key can be used to set comparison mode: 0=Binary (default); 1=Text (case insensitive); 2=Database
; - DDB( "MyDB" , "create" , 1 ) ;Create a database named MyDB.
;
; - Count/C ---> Count items in Database
; - ItemsInDatabase := DDB( "MyDB" , "count" ) alternatively
;
; - Destroy/D ---> Destroy a database
; - DDB( "MyDB" , "destroy" )
;
; - DestroyAll/DA---> Destroy all databases (COM will be not UNinitialised, use DDB() therfore)
; - DDB( "MyDB" , "destroyall" )
;
; - GetCompMode ---> Find out compare mode of database
; - DDB( "MyDB" , "getcompmode" )
;
;
; - Add/+ ---> Adds a key and item pair to a database
; This is similar to var=value where var is the key and value is the itm.
; - DDB( "MyDB" , "add" , "Key" , "Item" )
;
; - Get/< ---> Retrieves an Item from database using a key
; - Item := DDB( "MyDB" , "get" , "Key" )
;
; - Set/= ---> Overwrites an existing Item to new value using a key
; - DDB( "MyDB" , "set" , "Key" , "New Value" )
;
; - Exists/? ---> Checks if a key exist and returns 1 if a key exists
; - If DDB( "MyDB" , "exists" , "Key" )
;
; - Delete/- ---> Delete a Key and its Item from Database
; - DDB( "MyDB" , "delete" , "Key" )
;
; - Rename/~ ---> Rename a key
; - DDB( "MyDB" , "rename" , "Key" , "NewKey" )
;
; - DeleteAll/_ ---> Delete all keys from database
; - DDB( "MyDB" , "deleteall" )
;
; - Hash ---> Return hash of key
; hash:=DDB( "MyDB" , "hash" , "key" )
;
;
; - FIND / MATCH / REGEX / GETALL
; - For item you can specify a different separator than default (`n)
; - Parameter skip can be used to ommit first found items
; - Parameter limit can be used to limit foundings
; Example: DDB("MyDB","find","au",".",20,100)
; = Find max 100 keys starting with "au" in "MyDB", ommit first 20 found and separate output by .
;
; - GetAll ---> Receives all keys from database
; - AllKeys:=DDB( "MyDB" , "getall" , A_Space ) ;So output here will be: Key1 Key2 Key3...
;
; - Find ---> Find keys starting with given characters and return Values of found keys
; Key can be used to
; - FoundKeys:=DDB( "MyDB" , "find" , "Ke" , A_Tab )
;
; - Match ---> Match keys containing given characters anywhere inside the key
; - FoundKeys:=DDB( "MyDB" , "match" , "ey" , A_Tab )
;
; - RegEx ---> Find keys using RegEx function
; - FoundKeys:=DDB( "MyDB" , "regex" , "i).*y$" , A_Tab )
;
;
;
; - Sort ---> Sort Database using delimiter Chr(3) !!! DUE TO THIS OPTION "D" IS NOT AVALIABLE !!!
; Parameter key can be used for sort options from AutoHotkey Sort command, only those are valid: C, CL, F, N, Pn, R
; - DDB( "MyDB" , "sort" , "N R" )
;
; - Copy ---> Copy a database to new database
; - DB( "MyDB" , "copy" , "MyDB" , "MyNewDB" )
;
; - Replace ---> Replace values from Items
; DDB( "MyDB" , "replace" , "SearchText" , "ReplaceText" , "A" ) ; A to replace all
;
; - RegExReplace ---> Replace values from Item using RegExReplace
; DDB( "MyDB" , "regexreplace" , "SearchText" , "ReplaceText" , "10" ) ;10->replace first 10 found
;
;
; - Enum/& ---> This action is used to loop trough keys in database
; Loop
; If (key:=DDB( "MyDB" , "enum" ))
; MsgBox % "Key: " . key . "`nValue: " . DDB( "MyDB" , "get" , key)
; else break
; Alternatively you can catch ErrorLevel to receive the EnumPointer and go "manually" trough the database
; - DDB( "MyDB" , "enum" ), pEnum:=ErrorLevel...
; - key := DDB( "MyDB" , "enum" , pEnum )
; To start manually from beginning (this is when you did not "Loop" trough the whole database)
; - DDB( "MyDB" , "enum" , 0 ) ;start from beginning and return first key in Database
;-------------------------------------------------------------------------------------------- |
Example
| Code: | #Include %A_ScriptDir%\DDB.ahk
SetBatchLines,-1
OnExit, Exit
DDB("MyDB","create",1) ;Same as DDB("MyDB","n",1)
;create 1000 keys and items
Loop 1000
DDB("MyDB","add",A_Index,A_Index) ;or DDB("MyDB","+"...
;enum trogh database
Loop % (20) {
If NextKey:=DDB("MyDB","enum"){ ;or DDB("MyDB","&")
pEnum:=ErrorLevel
ToolTip % "Key: " . NextKey . "`nValue: " . DDB("MyDB","get",NextKey) ;same as DDB("MyDB","<",NextKey)
Sleep, 100
} else break
}
ToolTip
MsgBox % "Change item 21:`nbefore: " . DDB("MyDB","get",21)
. "`nafter: " . DDB("MyDB","set",21,"Hello World!")
. DDB("MyDB","get",21)
MsgBox % "Item 21 recieved using pEnum: " . DDB("MyDB","get",DDB("MyDB","enum",pEnum))
MsgBox % "Find max 10 keys that start with character 2 and return their items separated by Tab`n" DDB("MyDB","find","2",A_Tab,0,10)
MsgBox % "Match 2 inside key, skip first 10 found and return max 20 items`n" DDB("MyDB","match",2,"",10,20)
MsgBox % "RegEx based search (^20.?$)`n" DDB("MyDB","regex","^20.?$","",0,10)
MsgBox % "Sort descending by number`n" . DDB("MyDB","sort","N R") . SubStr(DDB("MyDB","getAll"),1,100) . "`n…"
MsgBox % "Replace any 1 in Value by a`n" DDB("MyDB","replace",1,"a") DDB("MyDB","find","","|")
DDB("MyDB","sort","N")
MsgBox % "Rename Key 2 to AutoHotkey + Delete Key 3`n" DDB("MyDB","rename",2,"AutoHotkey") DDB("MyDB","delete",3) DDB("MyDB","getall","|")
MsgBox % "copy database to new database (remember 1 Item was deleted)`nItems in new Database: " DDB("MyDB","copy","new") DDB("new","count")
Exit:
DDB()
ExitApp |
Function
| Code: | DDB(pdic="",action="",Key="",Item="",skip=0,limit=4294967295,ByRef data=""){
static
local CLSID,IID,pKey,pItm,nLen,nLenItm,bExist,label,penum,result,nCompMode,wStr
static var1,var2, CLSIDString:="{EE09B103-97E0-11CF-978F-00A02463E06F}", IIDString:="{42C642C1-97E1-11CF-978F-00A02463E06F}"
If (label:="DDB" . action)
Goto % label
DDB<:
DDBGet:
Gosub,DDBAllocKey
DllCall(NumGet(NumGet(pDic%pdic%+0)+48), UInt,pDic%pdic%, UInt,&var1, IntP,bExist)
If bExist { ; to avoid creating an unwanted new entry
DllCall(NumGet(NumGet(pDic%pdic%+0)+36), UInt,pDic%pdic%, UInt,&var1, UInt,&var2)
pItm := NumGet(&var2+8)
nLen := DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pItm, Int,-1, UInt,0, Int,0, UInt,0, UInt,0)
VarSetCapacity(Item, nLen)
DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pItm, Int,-1, Str,Item, Int,nLen, UInt,0, UInt,0)
DllCall("oleaut32\SysFreeString", UInt,pItm)
}
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return Item
DDB+:
DDBAdd:
Gosub,DDBAllocItm
DllCall(NumGet(NumGet(pDic%pdic%+0)+40), UInt,pDic%pdic%, UInt,&var1, UInt,&var2)
DllCall("oleaut32\SysFreeString", UInt,pItm),DllCall("oleaut32\SysFreeString", UInt,pKey)
Return
DDB?:
DDBExists:
Gosub,DDBAllocKey
DllCall(NumGet(NumGet(pDic%pdic%+0)+48), UInt,pDic%pdic%, UInt,&var1, IntP,bExist)
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return bExist
DDBFind:
DDBMatch:
DDBRegEx:
DDBGetAll:
DDBCopy:
DDBSort:
DDBRegexReplace:
DDBReplace:
;label:=A_Thislabel
DllCall(NumGet(NumGet(pDic%pdic%+0)+80), UInt,pDic%pdic%, UIntP,penum) ; create key-list in penum
Loop % DDB(pdic,"count") {
If (InStr("Clear0",pDic%pdic%) || DllCall(NumGet(NumGet(penum+0)+12), UInt,penum, UInt,1, UInt,&var1, UInt,0)) {
DllCall(NumGet(NumGet(penum+0)+8), UInt,penum) ; END: destroy key-list
penum = ; signal end of list
break ; empty
}
pKey := NumGet(&var1 + 8)
nLen := DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pKey, Int,-1, UInt,0, Int,0, UInt,0, UInt,0)
VarSetCapacity(wStr, nLen)
DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pKey, Int,-1, Str,wStr, Int,nLen, UInt,0, UInt,0)
If (InStr("DDBFindDDBMatchDDBRegex",label) and (Key="" or (label="DDBFind"
? (InStr(wStr,Key)=1) : (label="DDBMatch" ? (InStr(wStr,Key)) : (RegExMatch(wStr,Key)))))){
bExist++
If (bExist>skip){
result.= DDB(pdic,"get",wStr) . (Item!="" ? Item : "`n")
nLenItm++
If (limit<=nLenItm){
DllCall("oleaut32\SysFreeString", UInt,pKey)
Break
}
}
} else if (label="DDBReplace"){
result:=DDB(pdic,"get",wStr)
StringReplace,result,result,%Key%,%Item%,% (Item ? Item : "")
DDB(pdic,"set",wStr,result)
} else if (label="DDBRegexReplace"){
result:=DDB(pdic,"get",wStr)
result:=RegExReplace(result,Key,Item,"",Item ? Item : -1)
DDB(pdic,"set",wStr,result)
} else if !InStr("DDBFindDDBMatchDDBRegex",label){
result.= wStr . (label="DDBGetAll" ? (Key!="" ? Key : "`n") : (Chr(2) . DDB(pdic,"get",wStr) . Chr(3)))
}
DllCall("oleaut32\SysFreeString", UInt,pKey)
}
If InStr("DDBGetAllDDBFindDDBMatchDDBRegEx",label)
Return result
else if (label="DDBReplace"){
Return
} else if (label="DDBCopy"){
Gosub, DDBGetCompMode
pdic:=Key
} else Sort,result,% "D" . Chr(3) . (Key ? Key : "")
Gosub, DDBDeleteAll
If (label="DDBCopy"){
Key:= nCompMode ? nCompMode : (Item ? Item : 1)
Gosub, DDBCreate
}
Loop,Parse,result,% Chr(3)
If (A_LoopField!="")
DDB(pdic,"add",SubStr(A_LoopField,1,InStr(A_LoopField,Chr(2))-1),SubStr(A_LoopField,InStr(A_LoopField,Chr(2))+1))
Return
DDB&:
DDBEnum:
If Key>0
penum%pdic%:=Key
else If (!penum%pdic% or Key="0")
DllCall(NumGet(NumGet(pDic%pdic%+0)+80), UInt,pDic%pdic%, UIntP,penum%pdic%) ; create key-list in penum
If (InStr("Clear0",pDic%pdic%) || DllCall(NumGet(NumGet(penum%pdic%+0)+12), UInt,penum%pdic%, UInt,1, UInt,&var1, UInt,0)) {
DllCall(NumGet(NumGet(penum%pdic%+0)+8), UInt,penum%pdic%) ; END: destroy key-list
penum%dic%= ; signal end of list
ErrorLevel= ; empty
Return
}
pKey := NumGet(&var1 + 8)
nLen := DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pKey, Int,-1, UInt,0, Int,0, UInt,0, UInt,0)
VarSetCapacity(wStr, nLen)
DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pKey, Int,-1, Str,wStr, Int,nLen, UInt,0, UInt,0)
DllCall("oleaut32\SysFreeString", UInt,pKey)
ErrorLevel:=penum%pdic%
Return wStr
DDB=:
DDBSet:
Gosub,DDBAllocItm
DllCall(NumGet(NumGet(pDic%pdic%+0)+32), UInt,pDic%pdic%, UInt,&var1, UInt,&var2) ; 8 (Set0 -> 7)
DllCall("oleaut32\SysFreeString", UInt,pKey)
DllCall("oleaut32\SysFreeString", UInt,pItm)
Return
DDBHash:
Gosub, DDBAllocKey
DllCall(NumGet(NumGet(pDic%pdic%+0)+48), UInt,pDic%pdic%, UInt,&var1, IntP,bExist)
DllCall(NumGet(NumGet(pDic%pdic%+0)+84), UInt,pDic%pdic%, UInt,&var1, UInt,&var2)
result := NumGet(&var2+8)
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return result
Return
DDB~:
DDBRename:
Gosub,DDBAllocItm
DllCall(NumGet(NumGet(pDic%pdic%+0)+56), UInt,pDic%pdic%, UInt,&var1, UInt,&var2)
DllCall("oleaut32\SysFreeString", UInt,pKey)
DllCall("oleaut32\SysFreeString", UInt,pItm)
Return
DDB-:
DDBDelete:
Gosub,DDBAllocKey
DllCall(NumGet(NumGet(pDic%pdic%+0)+64), UInt,pDic%pdic%, UInt,&var1)
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return
DDB_:
DDBDeleteAll:
Return DllCall(NumGet(NumGet(pDic%pdic%+0)+68), UInt,pDic%pdic%)
DDBC:
DDBCount:
DllCall(NumGet(NumGet(pDic%pdic%+0)+44), UInt,pDic%pdic%, IntP,result)
Return result
DDBD:
DDBDestroy:
DllCall(NumGet(NumGet(pDic%pdic%+0)+8), UInt,pDic%pdic%)
StringReplace,DDBAll,DDBAll,|pDic%pdic%|
Return
DDBN:
DDBCreate:
If !Init
DllCall("ole32\CoInitialize", UInt,0),Init:=1
,VarSetCapacity(var1, 16, 0),VarSetCapacity(var2, 16, 0),NumPut(8, var1),NumPut(8, var2)
DDBAll.="|" . pdic . "|"
VarSetCapacity(CLSID, 16)
VarSetCapacity(wStr, 79)
DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&CLSIDString, Int,-1, UInt,&wStr, Int,79)
DllCall("ole32\CLSIDFromString", Str,wStr, Str,CLSID)
VarSetCapacity(IID, 16)
DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&IIDString, Int,-1, UInt,&wStr, Int,79)
DllCall("ole32\CLSIDFromString", Str,wStr, Str,IID)
DllCall("ole32\CoCreateInstance", Str,CLSID, UInt,0, UInt,5, Str,IID, UIntP,pDic%pdic%) ; CLSCTX=5
DllCall(NumGet(NumGet(pDic%pdic%+0)+72), UInt,pDic%pdic%, Int,Key) ; Set compare mode
Return
DDBGetCompMode:
DllCall(NumGet(NumGet(pDic%pdic%+0)+76), UInt,pDic%pdic%, IntP,nCompMode)
return nCompMode
DDBDA:
DDBDestroyAll:
Loop,Parse,DDBAll,|
If (A_LoopField!="")
DllCall(NumGet(NumGet(A_LoopField+0)+8), UInt,A_LoopField)
DDBAll=
Return
DDB:
If DDBDestroyAll
Gosub, DDBDestroyAll
DllCall("ole32\CoUnInitialize")
Return
DDBAllocItm: ;Internal
VarSetCapacity(wStr, (StrLen(Item))*2 + 1)
DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&Item, Int,-1, UInt,&wStr, Int,StrLen(Item)+1)
pItm := DllCall("oleaut32\SysAllocString", Str,wStr)
NumPut(pItm,&var2+8)
DDBAllocKey: ;Internal
VarSetCapacity(wStr, (StrLen(Key))*2 + 1)
DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&Key, Int,-1, UInt,&wStr, Int,StrLen(Key)+1)
pKey := DllCall("oleaut32\SysAllocString", Str,wStr)
NumPut(pKey,&var1+8)
Return
} |
_________________ AutoHotFile - ToolTip(n,text,title,options)
Last edited by HotKeyIt on Sun Jun 28, 2009 6:33 pm; edited 2 times in total |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 2179 Location: GERMANY
|
Posted: Wed Jun 24, 2009 3:19 pm Post subject: |
|
|
Below you will find a test using DDB vs. COM vs. Laszlo vers. and vs. toralf version.
Edit:
Add and get are faster than com now
But DDB consumes still more memory, please help
| Code: |
#Include %A_ScriptDir%\Com.ahk
#Include %A_ScriptDir%\DDB.ahk
SetBatchLines,-1
;DDB create
DDB("DB","n",0)
;COM_Init() ; Initialized COM in DDB already
d := COM_CreateObject("Scripting.Dictionary") ; Create dictionary.
;Dic create by Toralf
Dic()
;Create Dictionary by Laszlo
dic:=CreateDictionary()
;how ofter to loop
LoopTimes:=10000
SplashTextOn,300,20,Creating %looptimes% items using DDB function
;Create 10000 Items
Start:=A_TickCount
Loop % LoopTimes
DDB("DB","+",A_Index,A_Index)
CreateDDB:=A_TickCount-Start
SplashTextOn,300,20,Creating %looptimes% items using COM function
Start:=A_TickCount
Loop % LoopTimes
COM_Invoke(d,"Item",A_Index,A_Index)
CreateCOM:=A_TickCount-Start
SplashTextOn,300,20,Creating %looptimes% items using Dic function
Start:=A_TickCount
Loop % LoopTimes
Dic_Add(A_Index,A_Index)
CreateDic:=A_TickCount-Start
SplashTextOn,300,20,Creating %looptimes% items using Add function
Start:=A_TickCount
Loop % LoopTimes
Add(dic,A_Index,A_Index)
CreateDict:=A_TickCount-Start
SplashTextOff
MsgBox % "Create " LoopTimes " items`nDDB: " CreateDDB "`nCOM: " CreateCOM "`nDic: " CreateDic "`nAdd: " CreateDict
SplashTextOn,300,20,Get %looptimes% items using DDB function
Start:=A_TickCount
Loop % LoopTimes
DDB("DB","<",A_Index,A_Index)
CreateDDB:=A_TickCount-Start
SplashTextOn,300,20,Get %looptimes% items using COM function
Start:=A_TickCount
Loop % LoopTimes
COM_Invoke(d,"Item",A_Index)
CreateCOM:=A_TickCount-Start
SplashTextOn,300,20,Get %looptimes% items using Dic function
Start:=A_TickCount
Loop % LoopTimes
Dic_Get(A_Index)
CreateDic:=A_TickCount-Start
SplashTextOn,300,20,Get %looptimes% items using Get function
Start:=A_TickCount
Loop % LoopTimes
Get(dic, A_Index)
CreateDict:=A_TickCount-Start
SplashTextOff
MsgBox % "Get " LoopTimes " items`nDDB: " CreateDDB "`nCOM: " CreateCOM "`nDic: " CreateDic "`nGet: " CreateDict
COM_Release(d) ; Done using dictionary d.
;COM_Term() ; Done using COM is done in DDB()
Dic(1)
Destroydictionary(dic)
DDB()
;###############################################################################
;### Scripting.Dictionary COM object Modul ###
;###############################################################################
Dic(Action=""){
static initialized, pdic
If (Action = "pdic") ;return pdic
Return pdic
Else If Action { ;exit - clean up
Dic_DestroyDictionary(pdic)
;DllCall("ole32\CoUninitialize")
}Else{ ;create a dictionary
;If !initialized {
; initialized := True
; DllCall("ole32\CoInitialize", UInt,0)
; }
pdic := Dic_CreateDictionary()
}
Return 1
}
Dic_Add(sKey, sItm) { ; If key exists: no effect (<--> Set)
pdic := Dic("pdic")
Dic_AllocBString(pKey, var1, sKey)
Dic_AllocBString(pItm, var2, sItm)
DllCall(Dic_VTable(pdic,10), UInt,pdic, UInt,&var1, UInt,&var2)
DllCall("oleaut32\SysFreeString", UInt,pKey)
DllCall("oleaut32\SysFreeString", UInt,pItm)
}
Dic_Set(sKey, sItm) { ; If key exists, update the item, Else create a new entry
pdic := Dic("pdic")
Dic_AllocBString(pKey, var1, sKey)
Dic_AllocBString(pItm, var2, sItm)
DllCall(Dic_VTable(pdic,8), UInt,pdic, UInt,&var1, UInt,&var2) ; 8 (Set0 -> 7)
DllCall("oleaut32\SysFreeString", UInt,pKey)
DllCall("oleaut32\SysFreeString", UInt,pItm)
}
Dic_Get(sKey) { ; empty if not exists
pdic := Dic("pdic")
Dic_AllocBString(pKey, var1, sKey)
DllCall(Dic_VTable(pdic,12), UInt,pdic, UInt,&var1, IntP,bExist)
If bExist { ; to avoid creating an unwanted new entry
VarSetCapacity(var2, 16, 0)
DllCall(Dic_VTable(pdic,9), UInt,pdic, UInt,&var1, UInt,&var2)
pItm := *(&var2+8) | *(&var2+9) << 8 | *(&var2+10) << 16 | *(&var2+11) << 24
Dic_Unicode2Ansi(pItm, sItm)
DllCall("oleaut32\SysFreeString", UInt,pItm)
}
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return sItm
}
Dic_NextKey(ByRef penum) { ; penum = "": create new list
pdic := Dic("pdic")
If penum = ; not static: allow multiple independent lists
DllCall(Dic_VTable(pdic,20), UInt,pdic, UIntP,penum) ; create key-list in penum
VarSetCapacity(var, 16, 0)
If DllCall(Dic_VTable(penum,3), UInt,penum, UInt,1, UInt,&var, UInt,0) {
DllCall(Dic_VTable(penum,2), UInt,penum) ; END: destroy key-list
penum = ; signal end of list
Return ; empty
}
pKey := Dic_UInt@(&var + 8)
Dic_Unicode2Ansi(pKey, sKey)
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return skey
}
Dic_Count() { ; #entries
pdic := Dic("pdic")
DllCall(Dic_VTable(pdic,11), UInt,pdic, IntP,nCount)
Return nCount
}
Dic_Exists(sKey) {
pdic := Dic("pdic")
Dic_AllocBString(pKey, var, sKey)
DllCall(Dic_VTable(pdic,12), UInt,pdic, UInt,&var, IntP,bExist)
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return bExist
}
Dic_Rename(sKeyFr, sKeyTo) {
pdic := Dic("pdic")
Dic_AllocBString(pKeyFr, var1, sKeyFr)
Dic_AllocBString(pKeyTo, var2, sKeyTo)
DllCall(Dic_VTable(pdic,14), UInt,pdic, UInt,&var1, UInt,&var2)
DllCall("oleaut32\SysFreeString", UInt,pKeyFr)
DllCall("oleaut32\SysFreeString", UInt,pKeyTo)
}
Dic_Remove(sKey) {
pdic := Dic("pdic")
Dic_AllocBString(pKey, var, sKey)
DllCall(Dic_VTable(pdic,16), UInt,pdic, UInt,&var)
DllCall("oleaut32\SysFreeString", UInt,pKey)
}
Dic_RemoveAll() {
pdic := Dic("pdic")
Return DllCall(Dic_VTable(pdic,17), UInt,pdic)
}
Dic_SetCompareMode(nCompMode = 1) { ; 0: Binary, 1: Text, 2: Database, n: LCID
pdic := Dic("pdic")
Modes = btd
Loop, Parse, Modes
If RegExMatch(nCompMode, "i)^" A_LoopField)
nCompMode := A_Index - 1
DllCall(Dic_VTable(pdic,18), UInt,pdic, Int,nCompMode)
}
Dic_GetCompareMode() {
pdic := Dic("pdic")
DllCall(Dic_VTable(pdic,19), UInt,pdic, IntP,nCompMode)
Return nCompMode
}
Dic_HashVal(sKey) {
pdic := Dic("pdic")
Dic_AllocBString(pKey, var1, sKey)
DllCall(Dic_VTable(pdic,12), UInt,pdic, UInt,&var1, IntP,bExist)
VarSetCapacity(var2, 16, 0)
DllCall(Dic_VTable(pdic,21), UInt,pdic, UInt,&var1, UInt,&var2)
nHashVal := *(&var2+8) | *(&var2+9) << 8 | *(&var2+10) << 16 | *(&var2+11) << 24
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return nHashVal
}
;######### PRIVATE FUNCTIONS ################################################
Dic_CreateDictionary() {
CLSID_Dictionary := "{EE09B103-97E0-11CF-978F-00A02463E06F}"
IID_IDictionary := "{42C642C1-97E1-11CF-978F-00A02463E06F}"
Return Dic_CreateObject(CLSID_Dictionary, IID_IDictionary)
}
Dic_DestroyDictionary(pdic) {
DllCall(Dic_UInt@(Dic_UInt@(pdic)+8), UInt,pdic)
}
Dic_AllocBString(ByRef Key, ByRef Var, sString) {
Dic_Ansi2Unicode(sString, wString)
Key := DllCall("oleaut32\SysAllocString", Str,wString)
VarSetCapacity(Var, 16, 0)
DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var, UInt,4, UInt,8)
DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var+8,UInt,4, UInt,Key)
}
Dic_UInt@(ptr) {
Return *ptr | *(ptr+1) << 8 | *(ptr+2) << 16 | *(ptr+3) << 24
}
Dic_CreateObject(ByRef CLSID, ByRef IID, CLSCTX = 5) {
If StrLen(CLSID) = 38
Dic_GUID4String(CLSID, CLSID)
If StrLen(IID) = 38
Dic_GUID4String(IID, IID)
DllCall("ole32\CoCreateInstance", Str,CLSID, UInt,0, UInt,CLSCTX, Str,IID, UIntP,ppv)
Return ppv
}
Dic_GUID4String(Byref CLSID, sString) {
VarSetCapacity(CLSID, 16)
Dic_Ansi2Unicode(sString, wString, 38)
DllCall("ole32\CLSIDFromString", Str,wString, Str,CLSID)
}
Dic_Ansi2Unicode(ByRef sString, ByRef wString, nLen = 0) {
If !nLen
nLen := DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&sString, Int,-1, UInt,0, Int,0)
VarSetCapacity(wString, nLen*2 + 1)
DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&sString, Int,-1, UInt,&wString, Int,nLen)
}
Dic_VTable(ppv, idx) {
Return Dic_UInt@(Dic_UInt@(ppv) + idx*4)
}
Dic_Unicode2Ansi(ByRef wString, ByRef sString, nLen = 0) {
pString := wString + 0 > 65535 ? wString : &wString
If !nLen
nLen := DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pString, Int,-1, UInt,0, Int,0, UInt,0, UInt,0)
VarSetCapacity(sString, nLen)
DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pString, Int,-1, Str,sString, Int,nLen, UInt,0, UInt,0)
}
;By Laszlo
CreateDictionary(nCompMode = 0) { ; Compare mode = 0: Binary, 1: Text, 2: Database, n: LCID
CLSID_Dictionary := "{EE09B103-97E0-11CF-978F-00A02463E06F}"
IID_IDictionary := "{42C642C1-97E1-11CF-978F-00A02463E06F}"
pdic := CreateObject(CLSID_Dictionary, IID_IDictionary)
DllCall(VTable(pdic,18), UInt,pdic, Int,nCompMode) ; Set compare mode
Return pdic
}
DestroyDictionary(pdic) {
DllCall(UInt@(UInt@(pdic)+8), UInt,pdic)
}
Add(pdic, sKey, sItm) { ; If key exists: no effect (<--> Set)
AllocBString(pKey, var1, sKey)
AllocBString(pItm, var2, sItm)
DllCall(VTable(pdic,10), UInt,pdic, UInt,&var1, UInt,&var2)
DllCall("oleaut32\SysFreeString", UInt,pKey)
DllCall("oleaut32\SysFreeString", UInt,pItm)
}
Set(pdic, sKey, sItm) { ; If key exists, update the item, Else create a new entry
AllocBString(pKey, var1, sKey)
AllocBString(pItm, var2, sItm)
DllCall(VTable(pdic,8), UInt,pdic, UInt,&var1, UInt,&var2) ; 8 (Set0 -> 7)
DllCall("oleaut32\SysFreeString", UInt,pKey)
DllCall("oleaut32\SysFreeString", UInt,pItm)
}
Get(pdic, sKey) { ; empty if not exists
AllocBString(pKey, var1, sKey)
DllCall(VTable(pdic,12), UInt,pdic, UInt,&var1, IntP,bExist)
If bExist { ; to avoid creating an unwanted new entry
VarSetCapacity(var2, 16, 0)
DllCall(VTable(pdic,9), UInt,pdic, UInt,&var1, UInt,&var2)
pItm := *(&var2+8) | *(&var2+9) << 8 | *(&var2+10) << 16 | *(&var2+11) << 24
Unicode2Ansi(pItm, sItm)
DllCall("oleaut32\SysFreeString", UInt,pItm)
}
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return sItm
}
Count(pdic) { ; #entries
DllCall(VTable(pdic,11), UInt,pdic, IntP,nCount)
Return nCount
}
Exists(pdic, sKey) {
AllocBString(pKey, var, sKey)
DllCall(VTable(pdic,12), UInt,pdic, UInt,&var, IntP,bExist)
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return bExist
}
Rename(pdic, sKeyFr, sKeyTo) {
AllocBString(pKeyFr, var1, sKeyFr)
AllocBString(pKeyTo, var2, sKeyTo)
DllCall(VTable(pdic,14), UInt,pdic, UInt,&var1, UInt,&var2)
DllCall("oleaut32\SysFreeString", UInt,pKeyFr)
DllCall("oleaut32\SysFreeString", UInt,pKeyTo)
}
Remove(pdic, sKey) {
AllocBString(pKey, var, sKey)
DllCall(VTable(pdic,16), UInt,pdic, UInt,&var)
DllCall("oleaut32\SysFreeString", UInt,pKey)
}
RemoveAll(pdic) {
Return DllCall(VTable(pdic,17), UInt,pdic)
}
GetCompareMode(pdic) {
DllCall(VTable(pdic,19), UInt,pdic, IntP,nCompMode)
Return nCompMode
}
HashVal(pdic,sKey) {
AllocBString(pKey, var1, sKey)
DllCall(VTable(pdic,12), UInt,pdic, UInt,&var1, IntP,bExist)
VarSetCapacity(var2, 16, 0)
DllCall(VTable(pdic,21), UInt,pdic, UInt,&var1, UInt,&var2)
nHashVal := *(&var2+8) | *(&var2+9) << 8 | *(&var2+10) << 16 | *(&var2+11) << 24
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return nHashVal
}
NextKey(ByRef penum, pdic="") { ; penum = "": create new list. pdic=0,"Clear": destroy list
If penum = ; not static: allow multiple independent lists
DllCall(VTable(pdic,20), UInt,pdic, UIntP,penum) ; create key-list in penum
VarSetCapacity(var, 16, 0)
If (InStr("Clear0",pdic) || DllCall(VTable(penum,3), UInt,penum, UInt,1, UInt,&var, UInt,0)) {
DllCall(VTable(penum,2), UInt,penum) ; END: destroy key-list
penum = ; signal end of list
Return ; empty
}
pKey := UInt@(&var + 8)
Unicode2Ansi(pKey, sKey)
DllCall("oleaut32\SysFreeString", UInt,pKey)
Return skey
}
AllocBString(ByRef Key, ByRef Var, sString) {
Ansi2Unicode(sString, wString)
Key := DllCall("oleaut32\SysAllocString", Str,wString)
VarSetCapacity(Var, 16, 0)
DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var, UInt,4, UInt,8)
DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var+8,UInt,4, UInt,Key)
}
UInt@(ptr) {
Return *ptr | *(ptr+1) << 8 | *(ptr+2) << 16 | *(ptr+3) << 24
}
;;; COM Helper functions
CreateObject(ByRef CLSID, ByRef IID, CLSCTX = 5) {
If StrLen(CLSID) = 38
GUID4String(CLSID, CLSID)
If StrLen(IID) = 38
GUID4String(IID, IID)
DllCall("ole32\CoCreateInstance", Str,CLSID, UInt,0, UInt,CLSCTX, Str,IID, UIntP,ppv)
Return ppv
}
GUID4String(Byref CLSID, sString) {
VarSetCapacity(CLSID, 16)
Ansi2Unicode(sString, wString, 38)
DllCall("ole32\CLSIDFromString", Str,wString, Str,CLSID)
}
Ansi2Unicode(ByRef sString, ByRef wString, nLen = 0) {
If !nLen
nLen := DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&sString, Int,-1, UInt,0, Int,0)
VarSetCapacity(wString, nLen*2 + 1)
DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&sString, Int,-1, UInt,&wString, Int,nLen)
}
VTable(ppv, idx) {
Return UInt@(UInt@(ppv) + idx*4)
}
Unicode2Ansi(ByRef wString, ByRef sString, nLen = 0) {
pString := wString + 0 > 65535 ? wString : &wString
If !nLen
nLen := DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pString, Int,-1, UInt,0, Int,0, UInt,0, UInt,0)
VarSetCapacity(sString, nLen)
DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pString, Int,-1, Str,sString, Int,nLen, UInt,0, UInt,0)
} |
_________________ AutoHotFile - ToolTip(n,text,title,options) |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|