I got another problem.
I tried to use a long word list, and got a "Continuation section is too long" error. So I modified the sample code slightly, see below.
For the short word list, it works perfectly, however, for my full word list, the program stop working.
Code: Select all
; http://www.autohotkey.com/board/topic/96129-ahk-l-custom-autocompletion-for-edit-control-with-drop-down-list/
Gui, -Caption +AlwaysOnTop +Border +hwndhgui +LastFound +ToolWindow
Gui, Add, Edit, w300 hwndhedit
Gui, Show
Txt=0930-1208
txt=%txt%`n0930-1213
txt=%txt%`n0930-1612
txt=%txt%`nTC930-1208
txt=%txt%`nTC930-1213
txt=%txt%`nRPM-4840
txt=%txt%`nRPM-6420-40
txt=%txt%`nSF930-1213
AutoComplete(hedit, "init", txt, "`n")
AutoComplete(hedit, "option", "AUTOSUGGEST AUTOAPPEND USETAB", 0)
return
GuiClose:
GuiEscape:
ExitApp
/* Autocompletion
Function : Autocomplete(hwnd , action , p1=0 , p2=0)
Parameter
- hwnd : hwnd of edit control
- action : init, enable, disable, release, option
Usage:
1. Initializes the autocomplete object.
Function : Autocomplete(hwnd , "init" , txt , delim)
Parameter
- txt : Autocomplete list
- delim : delimiter seperate each item
2. Enables autocompletion.
Function : Autocomplete(hwnd , "enable" , 0 , 0)
3. Disables autocompletion.
Function : Autocomplete(hwnd , "disable" , 0 , 0)
4. Release autocompletion.
Function : Autocomplete(hwnd , "release" , 0 , 0)
5. Sets the current autocomplete options.
Function : Autocomplete(hwnd , "option" , mode , 0)
Parameter
- mode : options seperated by space
AUTOSUGGEST : Enable the autosuggest drop-down list.
AUTOAPPEND : Enable autoappend.
SEARCH : Add a search item to the list of completed strings. When the user selects this item, it launches a search engine.
FILTERPREFIXES : Do not match common prefixes, such as "www." or "http://".
USETAB : Use the TAB key to select an item from the drop-down list.
UPDOWNKEYDROPSLIST : Use the UP ARROW and DOWN ARROW keys to display the autosuggest drop-down list.
RTLREADING : read right-to-left (RTL).
WORD_FILTER : If set, the autocompleted suggestion is treated as a phrase for search purposes.
NOPREFIXFILTERING : Disable prefix filtering when displaying the autosuggest dropdown. Always display all suggestions.
*/
AutoComplete(self, celt, rgelt, pceltFetched)
{
static es:=[]
; =============================================================================================================================================================================
if (celt = "init") ; Initializes the autocomplete object.
{
sList:=[]
loop, parse, rgelt, %pceltFetched%, %A_Space%%A_Tab%
sList[A_Index] := A_LoopField
obj:=[]
obj.List := sList
obj.CurrentElement := 1
obj.hwnd := self
obj.SetCapacity("EnumString", A_PtrSize * 8)
pes := obj.GetAddress("EnumString")
,NumPut(pes + A_PtrSize, pes + 0)
,NumPut(RegisterCallback("_IUnknown_QueryInterface", "F"), pes + A_PtrSize * 1) ; IUnknown::QueryInterface http://msdn.com/library/ms682521(vs.85,en-us)
,NumPut(RegisterCallback("_IUnknown_AddRef", "F"), pes + A_PtrSize * 2) ; IUnknown::AddRef http://msdn.com/library/ms691379(vs.85,en-us)
,NumPut(RegisterCallback("_IUnknown_Release", "F"), pes + A_PtrSize * 3) ; IUnknown::Release http://msdn.com/library/ms682317(vs.85,en-us)
,NumPut(RegisterCallback(A_ThisFunc, "F"), pes + A_PtrSize * 4) ; IEnumString::Next http://msdn.com/library/ms693735(vs.85,en-us)
,NumPut(RegisterCallback("_IEnumString_Skip", "F"), pes + A_PtrSize * 5) ; IEnumString::Skip http://msdn.com/library/ms688527(vs.85,en-us)
,NumPut(RegisterCallback("_IEnumString_Reset", "F"), pes + A_PtrSize * 6) ; IEnumString::Reset http://msdn.com/library/ms686598(vs.85,en-us)
,NumPut(RegisterCallback("_IEnumString_Clone", "F"), pes + A_PtrSize * 7) ; IEnumString::Clone http://msdn.com/library/ms693436(vs.85,en-us)
/*
ObjIdl.h #ifdef COBJMACROS
#define IEnumString_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IEnumString_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IEnumString_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IEnumString_Next(This,celt,rgelt,pceltFetched) \
( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
#define IEnumString_Skip(This,celt) \
( (This)->lpVtbl -> Skip(This,celt) )
#define IEnumString_Reset(This) \
( (This)->lpVtbl -> Reset(This) )
#define IEnumString_Clone(This,ppenum) \
( (This)->lpVtbl -> Clone(This,ppenum) )
*/
pac2 := ComObjCreate("{00BB2763-6A77-11D0-A535-00C04FD7D062}", "{EAC04BC0-3791-11d2-BB95-0060977B464C}")
/*
IAutoComplete2 http://msdn.com/library/bb776288(vs.85,en-us)
CLSID_IAutoComplete = {00BB2763-6A77-11D0-A535-00C04FD7D062}
IID_IAutoComplete2 = {EAC04BC0-3791-11d2-BB95-0060977B464C}
*/
obj.pac := pac2
DllCall(NumGet(NumGet(pac2 + 0) + 3 * A_PtrSize), "Ptr", pac2, "Ptr", self, "Ptr", pes, "Ptr", 0, "Ptr", 0, "Int")
/*
IAutoComplete::Init http://msdn.com/library/bb776293(vs.85,en-us)
HRESULT Init(
[in] HWND hwndEdit,
[in] IUnknown *punkACL,
[in, optional] LPCWSTR pwszRegKeyPath,
[in, optional] LPCWSTR pwszQuickComplete
);
*/
es[pes] := obj
return 0
}
; =============================================================================================================================================================================
else if (celt = "enable") ; Enables autocompletion.
{
for k, v in es
{
if (v.hwnd = self)
return DllCall(NumGet(NumGet(v.pac + 0) + 4 * A_PtrSize), "Ptr", v.pac, "Int", 1, "Int")
/*
IAutoComplete::Enable http://msdn.com/library/bb776291(vs.85,en-us)
HRESULT Enable(
[in] BOOL fEnable
);
*/
}
return
}
; =============================================================================================================================================================================
else if (celt = "disable") ; Disables autocompletion.
{
for k, v in es
{
if (v.hwnd = self)
return DllCall(NumGet(NumGet(v.pac + 0) + 4 * A_PtrSize), "Ptr", v.pac, "Int", 0, "Int")
/*
IAutoComplete::Enable http://msdn.com/library/bb776291(vs.85,en-us)
HRESULT Enable(
[in] BOOL fEnable
);
*/
}
return
}
; =============================================================================================================================================================================
else if (celt = "release") ; Release autocompletion.
{
for k, v in es
{
if (v.hwnd = self)
ObjRelease(v.pac), es.remove(k)
}
return
}
; =============================================================================================================================================================================
else if (celt = "option") ; Sets the current autocomplete options.
{
if rgelt is Integer
{
if (rgelt < 0x200)
option := rgelt
else
return
}
else
{
mode := { AUTOSUGGEST: 0x1 ; Enable the autosuggest drop-down list.
, AUTOAPPEND: 0x2 ; Enable autoappend.
, SEARCH: 0x4 ; Add a search item to the list of completed strings. When the user selects this item, it launches a search engine.
, FILTERPREFIXES: 0x8 ; Do not match common prefixes, such as "www." or "http://".
, USETAB: 0x10 ; Use the TAB key to select an item from the drop-down list.
, UPDOWNKEYDROPSLIST: 0x20 ; Use the UP ARROW and DOWN ARROW keys to display the autosuggest drop-down list.
, RTLREADING: 0x40 ; read right-to-left (RTL).
, WORD_FILTER: 0x80 ; If set, the autocompleted suggestion is treated as a phrase for search purposes. The suggestion, Microsoft Office, would be treated as "Microsoft Office" (where both Microsoft AND Office must appear in the search results).
, NOPREFIXFILTERING: 0x100 } ; Disable prefix filtering when displaying the autosuggest dropdown. Always display all suggestions.
option := 0
loop, parse, rgelt, %A_Space%
if (mode[A_LoopField])
option |= mode[A_LoopField]
}
for k, v in es
{
if (v.hwnd = self)
return DllCall(NumGet(NumGet(v.pac + 0) + 5 * A_PtrSize), "Ptr", v.pac, "UInt", option, "Int")
/*
IAutoComplete2::SetOptions http://msdn.com/library/bb776290(vs.85,en-us)
HRESULT SetOptions(
[in] DWORD dwFlag
);
*/
}
return
}
; =============================================================================================================================================================================
else if !(es.haskey(self))
{
return 1
}
; =============================================================================================================================================================================
else if (celt = "reset") ; Resets the enumeration sequence to the beginning.
{
es[self].CurrentElement := 1
}
; =============================================================================================================================================================================
if !(celt)
celt := 1
i := 0
loop % celt ; IEnumString::Next http://msdn.com/library/ms693735(vs.85,en-us)
{
if (es[self].CurrentElement = es[self].List.maxindex() + 1)
break
string := es[self].List[es[self].CurrentElement]
NumPut(p := DllCall("ole32.dll\CoTaskMemAlloc", "UPtr", 2 * (StrPut(string, "UTF-16")), "Ptr"), rgelt + (A_Index - 1) * A_PtrSize) ; http://msdn.com/library/ms692727(vs.85,en-us)
StrPut(string, p, "UTF-16")
NumPut(NumGet(pceltFetched + 0, "UInt") + 1, pceltFetched, 0, "UInt")
es[self].CurrentElement := es[self].CurrentElement + 1
i++
}
return (i = celt) ? 0 : 1
}
; =================================================================================================================================================================================
_IUnknown_QueryInterface(self, riid, pObj) ; IUnknown::QueryInterface http://msdn.com/library/ms682521(vs.85,en-us)
{
DllCall("ole32.dll\StringFromCLSID", "Ptr", riid, "Ptr*", sz) ; http://msdn.com/library/ms683917(vs.85,en-us)
string := StrGet(sz, "UTF-16")
if (string = "{00000101-0000-0000-C000-000000000046}") ; IID_IEnumString = {00000101-0000-0000-C000-000000000046}
return NumPut(self, pObj + 0) * 0
else
return 0x80004002
}
; =================================================================================================================================================================================
_IUnknown_AddRef(self) ; IUnknown::AddRef http://msdn.com/library/ms691379(vs.85,en-us)
{
return 1
}
; =================================================================================================================================================================================
_IUnknown_Release(self) ; IUnknown::Release http://msdn.com/library/ms682317(vs.85,en-us)
{
return 0
}
; =================================================================================================================================================================================
_IEnumString_Skip(self, celt) ; IEnumString::Skip http://msdn.com/library/ms688527(vs.85,en-us)
{
return 0
}
; =================================================================================================================================================================================
_IEnumString_Reset(self) ; IEnumString::Reset http://msdn.com/library/ms686598(vs.85,en-us)
{
AutoComplete(self, "reset", 0, 0)
return 0
}
; =================================================================================================================================================================================
_IEnumString_Clone(self, ppenum) ; IEnumString::Clone http://msdn.com/library/ms693436(vs.85,en-us)
{
NumPut(self, ppenum + 0)
return 0
}
; =================================================================================================================================================================================