Code: Alles auswählen
; http://www.purebasic.fr/english/viewtopic.php?f=12&t=24721&hilit=AutoComplete&start=60
; Peyman, 03.07.2013
; Generic Implementation of an IEnumString Interface.
; New_EnumString(StringArray(), ItemCount) will create a new IEnumString instance
; with a referencecount of 1. (this means you must call IEnumString\Release()
; to release this reference once you do not need it anymore.)
;
;
;
EnableExplicit
; To allow for the ::Clone() method without dublicating the buffer,
; the string buffer is kept separate, with its own reference count.
Structure EnumStringBuffer
RefCount.l
Strings.l[0]
; following is the literal string data
EndStructure
; IEnumString data
Structure EnumString
*Vtbl
RefCount.l
StringCount.l
Enumerator.l
*Buffer.EnumStringBuffer
EndStructure
Procedure IEnumString_QueryInterface(*THIS.EnumString, *IID.IID, *Object.Integer)
If *Object = 0
ProcedureReturn #E_INVALIDARG
ElseIf CompareMemory(*IID, ?IID_IUnknown, SizeOf(IID)) Or CompareMemory(*IID, ?IID_IEnumString, SizeOf(IID))
*Object\i = *THIS
*THIS\RefCount + 1
ProcedureReturn #S_OK
Else
*Object\i = 0
ProcedureReturn #E_NOINTERFACE
EndIf
EndProcedure
Procedure IEnumString_AddRef(*THIS.EnumString)
*THIS\RefCount + 1
ProcedureReturn *THIS\RefCount
EndProcedure
Procedure IEnumString_Release(*THIS.EnumString)
*THIS\RefCount - 1
If *THIS\RefCount = 0
*THIS\Buffer\RefCount - 1
If *THIS\Buffer\RefCount = 0
FreeMemory(*THIS\Buffer)
EndIf
FreeMemory(*THIS)
ProcedureReturn 0
Else
ProcedureReturn *THIS\RefCount
EndIf
EndProcedure
Procedure IEnumString_Next(*THIS.EnumString, celt, *rgelt.Integer, *pceltFetched.Integer)
Protected count.i, i.i
If *THIS\Enumerator + celt <= *THIS\StringCount
count = celt
Else
count = *THIS\StringCount - *THIS\Enumerator
EndIf
For i = 0 To count-1
*rgelt\i = *THIS\Buffer\Strings[*THIS\Enumerator + i]
*rgelt + 4
Next i
*THIS\Enumerator + count
If *pceltFetched
*pceltFetched\i = count
EndIf
If count = celt
ProcedureReturn #S_OK
Else
ProcedureReturn #S_FALSE
EndIf
EndProcedure
Procedure IEnumString_Skip(*THIS.EnumString, celt)
*THIS\Enumerator + celt
If *THIS\Enumerator <= *THIS\StringCount
ProcedureReturn #S_OK
Else
ProcedureReturn #S_FALSE
EndIf
EndProcedure
Procedure IEnumString_Reset(*THIS.EnumString)
*THIS\Enumerator = 0
ProcedureReturn #S_OK
EndProcedure
Procedure IEnumString_Clone(*THIS.EnumString, *ppenum.Integer)
Protected *Clone.EnumString
If *ppenum = 0
ProcedureReturn #E_INVALIDARG
Else
*Clone = AllocateMemory(SizeOf(EnumString))
If *Clone
CopyMemory(*THIS, *Clone, SizeOf(EnumString))
*Clone\RefCount = 1
*Clone\Buffer\RefCount + 1
*ppenum\i = *Clone
ProcedureReturn #S_OK
Else
*ppenum\i = 0
ProcedureReturn #E_OUTOFMEMORY
EndIf
EndIf
EndProcedure
Procedure New_EnumString(Array StringArray.s(1))
Protected *THIS.EnumString = 0, *StringBuffer.EnumStringBuffer
Protected StringCount.i, Size.i, i.i
Protected *Pointer
StringCount = ArraySize(StringArray())
Size = 4 + StringCount * 4
For i = 0 To StringCount - 1
Size + Len(StringArray(i)) * 2 + 2
Next i
*StringBuffer = AllocateMemory(Size)
If *StringBuffer
*StringBuffer\RefCount = 1
*Pointer = *StringBuffer + 4 + StringCount * 4
For i = 0 To StringCount - 1
*StringBuffer\Strings[i] = *Pointer
PokeS(*Pointer, StringArray(i), -1, #PB_Unicode)
*Pointer + Len(StringArray(i)) * 2 + 2
Next i
*THIS = AllocateMemory(SizeOf(EnumString))
If *THIS
*THIS\Vtbl = ?IEnumStringVtbl
*THIS\RefCount = 1
*THIS\StringCount = StringCount
*THIS\Enumerator = 0
*THIS\Buffer = *StringBuffer
Else
FreeMemory(*StringBuffer)
EndIf
EndIf
ProcedureReturn *THIS
EndProcedure
DataSection
IEnumStringVtbl:
Data.i @IEnumString_QueryInterface()
Data.i @IEnumString_AddRef()
Data.i @IEnumString_Release()
Data.i @IEnumString_Next()
Data.i @IEnumString_Skip()
Data.i @IEnumString_Reset()
Data.i @IEnumString_Clone()
IID_IUnknown: ; {00000000-0000-0000-C000-000000000046}
Data.l $00000000
Data.w $0000, $0000
Data.b $C0, $00, $00, $00, $00, $00, $00, $46
IID_IEnumString: ; {00000101-0000-0000-C000-000000000046}
Data.l $00000101
Data.w $0000, $0000
Data.b $C0, $00, $00, $00, $00, $00, $00, $46
CLSID_AutoComplete: ; {00BB2763-6A77-11D0-A535-00C04FD7D062}
Data.l $00BB2763
Data.w $6A77, $11D0
Data.b $A5, $35, $00, $C0, $4F, $D7, $D0, $62
IID_IAutoComplete: ; {00BB2762-6A77-11D0-A535-00C04FD7D062}
Data.l $00BB2762
Data.w $6A77, $11D0
Data.b $A5, $35, $00, $C0, $4F, $D7, $D0, $62
IID_IAutoComplete2: ; {EAC04BC0-3791-11D2-BB95-0060977B464C}
Data.l $EAC04BC0
Data.w $3791, $11D2
Data.b $BB, $95, $00, $60, $97, $7B, $46, $4C
EndDataSection
#CLSCTX_INPROC_SERVER = $1
#ACO_NONE = 0 ; No autocompletion.
#ACO_AUTOSUGGEST = $1 ; Enable the autosuggest drop-down list.
#ACO_AUTOAPPEND = $2 ; Enable autoappend.
#ACO_SEARCH = $4 ; Add a search item to the dropdown list of completed strings. If this is item is selected, you should launch a search engine to assist the user.
#ACO_FILTERPREFIXES = $8 ; Don't match common prefixes, such as "www.", "http://", and so on.
#ACO_USETAB = $10 ; Use the TAB key to select an item from the drop-down list. This flag is disabled by default.
#ACO_UPDOWNKEYDROPSLIST = $20 ; Use the UP ARROW and DOWN ARROW keys to display the autosuggest drop-down list.
#ACO_RTLREADING = $40 ; If ACO_RTLREADING is set, the text is read in the opposite direction from the text in the parent window.
;main.pb
#Window_0 = 0
#String_0 = 0
Dim Strings.s(17)
Strings(0) = "Else"
Strings(1) = "ElseIf"
Strings(2) = "EnableDebugger"
Strings(3) = "EnableExplicit"
Strings(4) = "End"
Strings(5) = "EndDataSection"
Strings(6) = "EndEnumeration"
Strings(7) = "EndIf"
Strings(8) = "EndImport"
Strings(9) = "EndInterface"
Strings(10) = "EndMacro"
Strings(11) = "EndProcedure"
Strings(12) = "EndSelect"
Strings(13) = "EndStructure"
Strings(14) = "EndStructureUnion"
Strings(15) = "EndWith"
Strings(16) = "Enumeration"
; Initialize the COM environment
CoInitialize_(0)
Define *AutoComplete.IAutoComplete2, *Enum.IEnumString
If OpenWindow(#Window_0, 323, 219, 600, 300, "AutoComplete", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
StringGadget(#String_0, 40, 40, 320, 20, "")
SetActiveGadget(#String_0)
; This creates the autocomplete object:
;
If CoCreateInstance_(?CLSID_AutoComplete, #Null, 1, ?IID_IAutoComplete2, @*AutoComplete) = #S_OK
; Lets change the options for autocomplete a bit:
; See the constant definitions above for the available options.
; There is a dropdown or in-place suggestion mode.
;
*AutoComplete\SetOptions(#ACO_AUTOSUGGEST|#ACO_USETAB)
; This creates the IEnumString interface from our string array:
;
*Enum = New_EnumString(Strings())
; This sets the autocomplet with our Enum object.
; If you want more info on the last 2 parameters, read here:
; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/ifaces/iautocomplete/Init.asp
; Note that these must be unicode strings if present!
;
; This also works for Comboboxes, you just need to get the handle to the edit
; control that is contained inside with the GetComboBoxInfo_() function.
;
*AutoComplete\Init(GadgetID(#String_0), *Enum, 0, 0)
; Release our own references to the objects to avoid a memory leak
;
*Enum\Release()
*AutoComplete\Release()
EndIf
EndIf
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Code: Alles auswählen
Procedure autocomplete(STR_Gadget, Array Auswahl(1))
If CoCreateInstance_(?CLSID_AutoComplete, #Null, 1, ?IID_IAutoComplete2, @*AutoComplete) = #S_OK
*AutoComplete\SetOptions(#ACO_AUTOSUGGEST|#ACO_USETAB)
*Enum = New_EnumString(Auswahl())
*AutoComplete\Init(GadgetID(Str_Gadget), *Enum, 0, 0)
*Enum\Release()
*AutoComplete\Release()
EndIf
EndProcedure
Kann mir einer erklären warum?
Und was bedeutet bitte schön ?CLSID_AutoComplete und @*AutoComplete ??