CbAutoComplete - Auto-completes typed values in a ComboBox

Post your working scripts, libraries and tools
User avatar
Pulover
Posts: 366
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

CbAutoComplete - Auto-completes typed values in a ComboBox

16 Mar 2016, 15:34

I have found a few scripts out there to accomplish this task, but all of them had some bug. So I decided to make my own and share it here.

Code: Select all

;=======================================================================================
;
; Function:      CbAutoComplete
; Description:   Auto-completes typed values in a ComboBox.
;
; Author:        Pulover [Rodolfo U. Batista]
; Usage:         Call the function from the Combobox's gLabel.
;
;=======================================================================================
CbAutoComplete()
{	; CB_GETEDITSEL = 0x0140, CB_SETEDITSEL = 0x0142
	If ((GetKeyState("Delete", "P")) || (GetKeyState("Backspace", "P")))
		return
	GuiControlGet, lHwnd, Hwnd, %A_GuiControl%
	SendMessage, 0x0140, 0, 0,, ahk_id %lHwnd%
	MakeShort(ErrorLevel, Start, End)
	GuiControlGet, CurContent,, %lHwnd%
	GuiControl, ChooseString, %A_GuiControl%, %CurContent%
	If (ErrorLevel)
	{
		ControlSetText,, %CurContent%, ahk_id %lHwnd%
		PostMessage, 0x0142, 0, MakeLong(Start, End),, ahk_id %lHwnd%
		return
	}
	GuiControlGet, CurContent,, %lHwnd%
	PostMessage, 0x0142, 0, MakeLong(Start, StrLen(CurContent)),, ahk_id %lHwnd%
}

MakeLong(LoWord, HiWord)
{
	return (HiWord << 16) | (LoWord & 0xffff)
}

MakeShort(Long, ByRef LoWord, ByRef HiWord)
{
	LoWord := Long & 0xffff
,   HiWord := Long >> 16
}
I only wish there was a better way to detect when the user is deleting content. Checking key state of bs and del keys doesn't work with Right-Click > Delete or with simulated keystrokes. But I'm not going to try OnMessage either...

:arrow: Sources and examples on GitHub

Feedback and improvements are welcome.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
guresicpark
Posts: 1
Joined: 01 Nov 2017, 07:40
GitHub: guresicpark

Re: CbAutoComplete - Auto-completes typed values in a ComboBox

01 Nov 2017, 07:43

Hey Pulover,
great stuff, thanks!
burque505
Posts: 859
Joined: 22 Jan 2017, 19:37

Re: CbAutoComplete - Auto-completes typed values in a ComboBox

01 Nov 2017, 20:03

Pulover, I can't believe I found this at the very moment I needed it. What a gift. Very nice indeed!
I was just about to try a ListBox and Sift, but this will certainly get me going faster.
Regards,
burque505
User avatar
Delta Pythagorean
Posts: 449
Joined: 13 Feb 2017, 13:44
GitHub: DelPyth
Location: Equestria

Re: CbAutoComplete - Auto-completes typed values in a ComboBox

02 Nov 2017, 07:05

If you want to detect if the user is deleting content, try checking the current string with the previous string that was captured.
five
Posts: 2
Joined: 31 Jan 2018, 16:00

Re: CbAutoComplete - Auto-completes typed values in a ComboBox

02 Feb 2018, 08:46

Great script. Once I've made my selection, how do I get the current selection into a variable that I can do something with. My source is a csv file.

Some sample code that I put online:
https://p.ahkscript.org/?p=6493c881

I realized after the fact that I had the sample csv backwards. It is actually computer name, ip address.

Code: Select all

csv =
(
CMJ8023, 192.168.1.1
CMK3689, 192.168.1.2 
C0I739H, 192.168.1.3
A20JK29, 192.168.1.4
RT9HJ90, 192.168.1.5 
F0MSSH4, 192.168.1.6
EBSDUNM, 192.168.1.7 
84LHXKX, 192.168.1.8 
NREP2LX, 192.168.1.9 
I6D3C3Q, 192.168.1.10 
24UL3Q1, 192.168.1.11 
SV62S85, 192.168.1.12 
EQCNAUU, 192.168.1.13 
68UZGK3, 192.168.1.14 
C4XNBY5, 192.168.1.15 
1MDVV9K, 192.168.1.16 
L750VIV, 192.168.1.17 
N068R9H, 192.168.1.18 
NT6NN8Z, 192.168.1.19 
6QVFJPS, 192.168.1.20
FWWSLSN, 192.168.1.21 
28SM0M1, 192.168.1.22 
GWHL7NB, 192.168.1.23 
4VJ7LCM, 192.168.1.24 
LBVJV30, 192.168.1.25 
)
And while I am asking questions. How hard would it be to change this code from search as you type to fuzzy search? Where you can type any part of the string and it would display the applicable results.
User avatar
SL5
Posts: 712
Joined: 12 May 2015, 02:10
GitHub: sl5net
Contact:

Re: CbAutoComplete - Auto-completes typed values in a ComboBox

28 Apr 2018, 11:27

five wrote:Great script. Once I've made my selection, how do I get the current selection into a variable that I can do something with. My source is a csv file.
...
And while I am asking questions. How hard would it be to change this code from search as you type to fuzzy search? Where you can type any part of the string and it would display the applicable results.
i dont know if this helps: https://autohotkey.com/boards/viewtopic ... 67#p215367
DRocks
Posts: 387
Joined: 08 May 2018, 10:20

Re: CbAutoComplete - Auto-completes typed values in a ComboBox

11 Sep 2018, 07:32

Thanks alot for this. And also for your macro recorder. It has taught me some of the hardest things to understand since its able to write code and give real-life examples
DRocks
Posts: 387
Joined: 08 May 2018, 10:20

Re: CbAutoComplete - Auto-completes typed values in a ComboBox

22 Sep 2018, 08:10

Hi Rodolfo,

EDIT: I have noticed after posting that you were aware of that complexity. I'll try some stuff but I'm out of solutions thats why I requested. :)

If by any chance you fall on this post, would it be possible to add a feature to autocomplete also AFTER a backspaceor deletekey was pressed?
What I mean by this is that when you type a word and it doesnt currently match because you make a mistake, you will most probably backspaceor deletea couple of letters until you cleaned your mistake - but then it stops there rather than re-choosing automatically a string that matches.
How would you make it re-analyze the new and cleaned current string AFTER the backspace/delete? But also considering that the user did not type any new letter or press space

Why it would be nice, I think, is that it would re-choose the matching string automatically.
So if you then press Tabor clickaway from the ComboBox, the cleaned string will automatically be matched to a string rather than wait a new input.
Currently when you backspace/delete, it will require the user to re-trigger the function manually with any lettersor a spacebefore it chooses a string.

For example: In this adapted version of your function I'm trying to add a non matching string to the user list of names and I have tried to loop back to the top of the function to auto-update on delete/backspace but it prevents from deleting the last matching string.

Code: Select all

cbAutoComplete() 
{ ; CB_GETEDITSEL = 0x0140, CB_SETEDITSEL = 0x0142
	Global NOM_Nouveau_Ajouter											; addition
	;cbAutoComplete:
	If ((GetKeyState("Delete", "P")) || (GetKeyState("Backspace", "P")))
	{
		;Goto, cbAutoComplete
		return
	}
	GuiControlGet, cbHwnd, Hwnd, %A_GuiControl%
	SendMessage, 0x0140, 0, 0,, ahk_id %cbHwnd%
	MakeShort(ErrorLevel, Start, End)
	GuiControlGet, cbCurContent,, %cbHwnd%
	GuiControl, ChooseString, %A_GuiControl%, %cbCurContent%
	If (ErrorLevel)
	{
		ControlSetText,, %cbCurContent%, ahk_id %cbHwnd%
		PostMessage, 0x0142, 0, MakeLong(Start, End),, ahk_id %cbHwnd%
		NOM_Nouveau_Ajouter:=True										; addition
		SetTimer, NOM_Nouveau_Ajouter, -10								; addition 
		return
	}
	NOM_Nouveau_Ajouter:=False											; addition
	GuiControl, Hide, NOM_Nouveau_Text									; addition
	GuiControlGet, cbCurContent,, %cbHwnd%
	PostMessage, 0x0142, 0, MakeLong(Start, StrLen(cbCurContent)),, ahk_id %cbHwnd%
}
Hope I was able to make myself understandable, if not the case please let me know.

In the waiting, thanks in advance.
Alex
A_AhkUser
Posts: 970
Joined: 06 Mar 2017, 16:18
Location: France

Re: CbAutoComplete - Auto-completes typed values in a ComboBox

23 Sep 2018, 09:13

Hi DRocks,

Try this:

Code: Select all

#NoEnv
#Warn
#SingleInstance Force
; #Include ..\CbAutoComplete.ahk

; from https://raw.githubusercontent.com/Pulover/CbAutoComplete/master/Examples/CbAutoCompleteDemo.ahk
list := ""
Loop, Files, C:\Windows\System32\*.exe
	list .= A_LoopFileName . "|"
f := Func("CbAutoComplete")
Gui, Add, Combobox, w300 vcb, % list
Gui, Add, Combobox, w300 vcb2, % list
GuiControl, +g, cb, % f
GuiControl, +g, cb2, % f
Gui, Show,, CbAutoComplete Demo
return

CbAutoComplete(_lHwnd) { ; from https://github.com/Pulover/CbAutoComplete/blob/master/CbAutoComplete.ahk
	static CB_GETEDITSEL := 0x0140, CB_SETEDITSEL := 0x0142
	static _f := "", _hwnd := ""
	if ((GetKeyState("Delete", "P")) || (GetKeyState("Backspace", "P"))) {
		((_lHwnd = _hwnd) || _f:=Func(A_ThisFunc).bind(_lHwnd))
		_hwnd := _lHwnd
		SetTimer % _f, % -650 ; if the period is negative, the timer runs only once
	return
	}
	_ahkid := "ahk_id " . _lHwnd ; a shorthand for convinience
	SendMessage % CB_GETEDITSEL, 0, 0,, % _ahkid
	_start := ErrorLevel & 0xffff, _end := ErrorLevel >> 16
	GuiControlGet, _input,, %_lHwnd%
	GuiControl, ChooseString, % _lHwnd, % _input
	if (ErrorLevel)
	{
		ControlSetText,, % _input, % _ahkid
		PostMessage, CB_SETEDITSEL, 0, % (_start << 16) | (_end & 0xffff),, % _ahkid
	return
	}
	GuiControlGet, _input,, %_lHwnd%
	PostMessage, 0x0142, 0, (_start << 16) | (StrLen(_input) & 0xffff),, % _ahkid
}
Hope this helps
DRocks
Posts: 387
Joined: 08 May 2018, 10:20

Re: CbAutoComplete - Auto-completes typed values in a ComboBox

25 Sep 2018, 07:23

thank you very much!

I had few time to thouroughly study the example. But it actually works and seems brilliant.
I like that multiple backspaces will not trigger autocomplete until a timer is past-due-time.

Thanks alot, I'll be studying it more.. !

EDIT: holy sh -- your eAutoComplete is crazy!! good job
DRocks
Posts: 387
Joined: 08 May 2018, 10:20

Re: CbAutoComplete - Auto-completes typed values in a ComboBox

15 Oct 2018, 14:15

Hello,

So after receiving help from A_AhkUser, I found myself in front of two functions that I did not fully understand - (first from Pulover and second from User). So I thought it was not acceptable to rely fully on them before I try to get my head around the way they work.

In this exercice, I think I found another way to solve the Backspace and Delete problem and I like the behavior.
To do this, I've reused Pulover's codelines and reordered them by trial and error inside the GetKeyState Condition check { }.
Then, the little modification that made it all finally work was to add -1 to the Start pos of the CB_SETEDITSEL

I hope this can be useful for someone else and If you have better ways to do this please let me know I'd really appreciate it :)

Code: Select all

;=======================================================================================
; https://github.com/pulover/cbautocomplete
;
; Function:      CbAutoComplete
; Description:   Auto-completes typed values in a ComboBox.
;
; Author:        Pulover [Rodolfo U. Batista]
; Usage:         Call the function from the Combobox's gLabel.
;
;=======================================================================================
CbAutoComplete()	{	
	global
	;CB_GETEDITSEL = 0x0140, CB_SETEDITSEL = 0x0142
	If ((GetKeyState("Delete", "P")) || (GetKeyState("Backspace", "P"))) {
		SendMessage, 0x0140, 0, 0,, ahk_id %lHwnd%
		MakeShort(ErrorLevel, Start, End)
		GuiControl, ChooseString, %A_GuiControl%, %cbCurContent%
		GuiControlGet, cbCurContent,, %lHwnd%
		PostMessage, 0x0142, 0, MakeLong(Start-1, StrLen(cbCurContent)),, ahk_id %lHwnd%
		return
	}
	GuiControlGet, lHwnd, Hwnd, %A_GuiControl%
	SendMessage, 0x0140, 0, 0,, ahk_id %lHwnd%
	MakeShort(ErrorLevel, Start, End)
	GuiControlGet, cbCurContent,, %lHwnd%
	GuiControl, ChooseString, %A_GuiControl%, %cbCurContent%
	If (ErrorLevel) {
		ControlSetText,, %cbCurContent%, ahk_id %lHwnd%
		PostMessage, 0x0142, 0, MakeLong(Start, End),, ahk_id %lHwnd%
		return
	}
	GuiControlGet, cbCurContent,, %lHwnd%
	PostMessage, 0x0142, 0, MakeLong(Start, StrLen(cbCurContent)),, ahk_id %lHwnd%
}
MakeLong(LoWord, HiWord)	{
	return (HiWord << 16) | (LoWord & 0xffff)
}
MakeShort(Long, ByRef LoWord, ByRef HiWord)	{
	LoWord := Long & 0xffff
   , HiWord := Long >> 16
}

Return to “Scripts and Functions”

Who is online

Users browsing this forum: robodesign and 28 guests