[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.vb.general.discussion

update combo dropdown list while typing

mm

7/22/2012 12:58:00 AM

I'm trying to achieve something similar like FireFox and other programs do
(Google in the search box), of making available on the combo dropdown list
just items that are relevant to what the user is typing.

I have several problems.

1) The mouse pointer disappears.
2) The list is not properly refreshed and the bottom part of the previous
list remains on the screen.
3) I don't know why the fist matching item is selected with the first
keystroke.

This is the code:

Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg _
As Long, ByVal wParam As Long, lParam As Any) As Long

Private Const CB_GETDROPPEDSTATE As Long = &H157
Private Const CB_SHOWDROPDOWN As Long = &H14F

Private mList(9) As String

Private Sub Form_Load()
mList(0) = "aaa"
mList(1) = "aa"
mList(2) = "abbbba"
mList(3) = "lla"
mList(4) = "lfaa"
mList(5) = "adffkaaa"
mList(6) = "baa"
mList(7) = "bbba"
mList(8) = "baba"
mList(9) = "baa"
End Sub

Private Sub Combo1_Change()
If Trim (Combo1.Text) <> "" Then
FillCombo
If Not ComboIsDropped(Combo1) Then
If Combo1.ListCount > 0 Then
DropDownCombo Combo1
End If
End If
Else
DropUpCombo Combo1
End If
End Sub

Private Sub FillCombo()
Dim c As Long
Dim iStr As String

iStr = Trim (Combo1.Text)
Do Until Combo1.ListCount = 0
Combo1.RemoveItem 0
Loop
For c = 0 To UBound(mList)
If InStr(mList(c), iStr) > 0 Then
Combo1.AddItem mList(c)
End If
Next c
End Sub

Public Function ComboIsDropped(nCombo As ComboBox) As Boolean
ComboIsDropped = CBool(SendMessage(nCombo.hwnd, _
CB_GETDROPPEDSTATE, 0&, 0&))
End Function

Public Sub DropDownCombo(nCombo As ComboBox)
SendMessage nCombo.hwnd, CB_SHOWDROPDOWN, _
True, ByVal 0
End Sub

Public Sub DropUpCombo(nCombo As ComboBox)
SendMessage nCombo.hwnd, CB_SHOWDROPDOWN, _
False, ByVal 0
End Sub


18 Answers

mm

7/22/2012 2:37:00 AM

0


"Eduardo" <mm@mm.com> escribió en el mensaje
news:jufj6n$p35$1@speranza.aioe.org...
> I'm trying to achieve something similar like FireFox and other programs do
> (Google in the search box), of making available on the combo dropdown list
> just items that are relevant to what the user is typing.
>
> I have several problems.
>
> 1) The mouse pointer disappears.
> 2) The list is not properly refreshed and the bottom part of the previous
> list remains on the screen.
> 3) I don't know why the first matching item is selected with the first
> keystroke.

I fixed the 1) and 2), but I still don't like the way the 3) was "fixed":

Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg _
As Long, ByVal wParam As Long, lParam As Any) As Long

Private Const CB_GETDROPPEDSTATE As Long = &H157
Private Const CB_SHOWDROPDOWN As Long = &H14F
Private Const CB_GETCOMBOBOXINFO As Long = &H164

Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Private Type COMBOBOXINFO
cbSize As Long
rcItem As RECT
rcButton As RECT
stateButton As Long
hwndCombo As Long
hwndItem As Long
hwndList As Long
End Type

Private Declare Function ShowWindow Lib "user32" _
(ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Private Const SW_HIDE As Long = 0
Private Const SW_SHOW As Long = 1

Private mList(9) As String

Private Sub Combo1_Change()
Dim iStr As String
Dim iSS As Long

If Trim(Combo1.Text) <> "" Then
FillCombo
If Not ComboIsDropped(Combo1) Then
If Combo1.ListCount > 0 Then
iSS = Combo1.SelStart
iStr = Combo1.Text
DropDownCombo Combo1
Combo1.Text = iStr
Combo1.SelStart = iSS
Combo1.MousePointer = 1
Combo1.MousePointer = 0
End If
End If
Else
DropUpCombo Combo1
End If
End Sub

Private Sub Form_Load()
mList(0) = "aaa"
mList(1) = "aa"
mList(2) = "abbbba"
mList(3) = "lla"
mList(4) = "lfaa"
mList(5) = "adffkaaa"
mList(6) = "baa"
mList(7) = "bbba"
mList(8) = "baba"
mList(9) = "baa"
End Sub

Private Sub FillCombo()
Dim c As Long
Dim iStr As String

If ComboIsDropped(Combo1) Then
ShowComboList Combo1, False
End If
iStr = Trim(Combo1.Text)
Do Until Combo1.ListCount = 0
Combo1.RemoveItem 0
Loop
For c = 0 To UBound(mList)
If InStr(mList(c), iStr) > 0 Then
Combo1.AddItem mList(c)
End If
Next c
If ComboIsDropped(Combo1) Then
ShowComboList Combo1, True
End If
End Sub

Public Function ComboIsDropped(nCombo As ComboBox) As Boolean
ComboIsDropped = CBool(SendMessage(nCombo.hwnd, _
CB_GETDROPPEDSTATE, 0&, 0&))
End Function

Public Sub DropDownCombo(nCombo As ComboBox)
SendMessage nCombo.hwnd, CB_SHOWDROPDOWN, _
True, ByVal 0
End Sub

Public Sub DropUpCombo(nCombo As ComboBox)
SendMessage nCombo.hwnd, CB_SHOWDROPDOWN, _
False, ByVal 0
End Sub

Private Sub ShowComboList(nCombo As ComboBox, _
nShow As Boolean)

Dim iCbInfo As COMBOBOXINFO

iCbInfo.cbSize = Len(iCbInfo)
SendMessage nCombo.hwnd, CB_GETCOMBOBOXINFO, _
0&, iCbInfo
ShowWindow iCbInfo.hwndList, Abs(CLng(nShow))
End Sub



Dee Earley

7/25/2012 2:37:00 PM

0

On 22/07/2012 01:58, Eduardo wrote:
> I'm trying to achieve something similar like FireFox and other programs do
> (Google in the search box), of making available on the combo dropdown list
> just items that are relevant to what the user is typing.

I'm sorry but any answer I give will be tainted by gay and be inherently
evil.

--
Deanna Earley (dee.earley@icode.co.uk)
i-Catcher Development Team
http://www.icode.co.uk...

iCode Systems

(Replies direct to my email address will be ignored. Please reply to the
group.)

mm

7/25/2012 3:00:00 PM

0


"Deanna Earley" <dee.earley@icode.co.uk> escribió en el mensaje
news:jup0an$uph$1@speranza.aioe.org...
> On 22/07/2012 01:58, Eduardo wrote:
>> I'm trying to achieve something similar like FireFox and other programs
>> do
>> (Google in the search box), of making available on the combo dropdown
>> list
>> just items that are relevant to what the user is typing.
>
> I'm sorry but any answer I give will be tainted by gay and be inherently
> evil.

I already made it to work fairly well.

Anyway I discarded the idea to offer to enter data that way in the screen I
was working on. It's a simple combo now.

What were you going to say?

I couldn't find a way to tell the combo not to select the first matching
element in the list when the first character is entered.


mm

7/25/2012 3:07:00 PM

0

This is the last code:

Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg _
As Long, ByVal wParam As Long, lParam As Any) As Long

Private Const CB_GETDROPPEDSTATE As Long = &H157
Private Const CB_SHOWDROPDOWN As Long = &H14F
Private Const CB_GETCOMBOBOXINFO As Long = &H164
Private Const CB_SETEXTENDEDUI As Long = &H155

Private Const CB_FINDSTRINGEXACT = &H158
Private Const CB_FINDSTRING = &H14C
Private Const CB_SELECTSTRING = &H14D

Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Private Type COMBOBOXINFO
cbSize As Long
rcItem As RECT
rcButton As RECT
stateButton As Long
hwndCombo As Long
hwndItem As Long
hwndList As Long
End Type

Private Declare Function ShowWindow Lib "user32" _
(ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Private mLastCombo1Text As String


Private mList(9) As String

Private Sub Combo1_Change()
Dim iStr As String
Dim iSS As Long

FillCombo
If Trim(Combo1.Text) <> "" Then
If Not ComboIsDropped(Combo1) Then
If Combo1.ListCount > 0 Then
iSS = Combo1.SelStart
iStr = Combo1.Text
DropDownCombo Combo1
Combo1.Text = iStr
Combo1.SelStart = iSS
Combo1.MousePointer = 1
Combo1.MousePointer = 0
End If
End If
End If
mLastCombo1Text = Combo1.Text
End Sub

Private Sub Combo1_Click()
If Combo1.ItemData(Combo1.ListIndex) = -1 Then
Combo1.Tag = "1"
Combo1.Clear
FillCombo
Combo1.Text = mLastCombo1Text
DropDownCombo Combo1
Else
If Combo1.ItemData(Combo1.ListIndex) = -2 Then
Combo1.Text = mLastCombo1Text
End If
End If
End Sub

Private Sub Combo1_DropDown()
FillCombo
End Sub

Private Sub Form_Load()
mList(0) = "aaa"
mList(1) = "aa"
mList(2) = "abbbba"
mList(3) = "lla"
mList(4) = "lfaa"
mList(5) = "adffkaaa"
mList(6) = "baa"
mList(7) = "bbba"
mList(8) = "baba"
mList(9) = "baa2"

SendMessage Combo1.hwnd, CB_SETEXTENDEDUI, 1, ByVal 0

End Sub

Private Sub FillCombo()
Dim c As Long
Dim iStr As String
Dim iStr2 As String
Dim iSDD As Boolean
Dim L As Long
Dim iSS As Long

If Combo1.Tag = "2" Then Exit Sub

iStr2 = Combo1.Text
iStr = Trim(iStr2)
iSS = Combo1.SelStart
iSDD = ComboIsDropped(Combo1)
If iSDD Then
ShowComboList Combo1, False
End If
Do Until Combo1.ListCount = 0
Combo1.RemoveItem 0
Loop
If Combo1.Tag = "1" Then
If Combo1.ListCount < 2 Then
For c = 0 To UBound(mList)
Combo1.AddItem mList(c)
Next c
End If
Combo1.Tag = "2"
Exit Sub
If iSDD Then
ShowComboList Combo1, True
End If
End If
For c = 0 To UBound(mList)
If InStr(mList(c), iStr) > 0 Then
Combo1.AddItem mList(c)
End If
Next c

If Combo1.ListCount < 2 Then
For c = 0 To UBound(mList)
Combo1.AddItem mList(c)
Next c
End If

If Combo1.ListCount < UBound(mList) + 1 Then
Combo1.AddItem "----------------"
Combo1.ItemData(Combo1.NewIndex) = -2
Combo1.AddItem "Show all"
Combo1.ItemData(Combo1.NewIndex) = -1
End If
If iSDD Then
ShowComboList Combo1, True
End If
If iStr2 <> "" Then
L = SendMessage(Combo1.hwnd, CB_FINDSTRINGEXACT, _
-1, ByVal iStr2)
Combo1.ListIndex = L
Combo1.SelStart = iSS
End If
End Sub

Public Function ComboIsDropped(nCombo As ComboBox) As Boolean
ComboIsDropped = CBool(SendMessage(nCombo.hwnd, _
CB_GETDROPPEDSTATE, 0&, 0&))
End Function

Public Sub DropDownCombo(nCombo As ComboBox)
SendMessage nCombo.hwnd, CB_SHOWDROPDOWN, _
True, ByVal 0
End Sub

Private Sub ShowComboList(nCombo As ComboBox, _
nShow As Boolean)

Dim iCbInfo As COMBOBOXINFO

iCbInfo.cbSize = Len(iCbInfo)
SendMessage nCombo.hwnd, CB_GETCOMBOBOXINFO, _
0&, iCbInfo
ShowWindow iCbInfo.hwndList, Abs(CLng(nShow))
End Sub



mm

7/25/2012 3:31:00 PM

0


"Deanna Earley" <dee.earley@icode.co.uk> escribió en el mensaje
news:jup0an$uph$1@speranza.aioe.org...

> and be inherently evil.

The only "evil" so far was to defend so much Mr. Chen position of not using
LockWindowUpdate when there is not other alternative for some scenarios.
But that wasn't really evil, just a bit annoying.


Dee Earley

7/25/2012 3:36:00 PM

0

On 25/07/2012 16:00, Eduardo wrote:
> "Deanna Earley" <dee.earley@icode.co.uk> escribió en el mensaje
> news:jup0an$uph$1@speranza.aioe.org...
>> On 22/07/2012 01:58, Eduardo wrote:
>>> I'm trying to achieve something similar like FireFox and other programs
>>> do
>>> (Google in the search box), of making available on the combo dropdown
>>> list
>>> just items that are relevant to what the user is typing.
>>
>> I'm sorry but any answer I give will be tainted by gay and be inherently
>> evil.
>
> I already made it to work fairly well.
>
> Anyway I discarded the idea to offer to enter data that way in the screen I
> was working on. It's a simple combo now.
>
> What were you going to say?

The auto complete api is a good start.
http://msdn.microsoft.com/en-us/library/windows/deskto...(v=vs.85).aspx

--
Deanna Earley (dee.earley@icode.co.uk)
i-Catcher Development Team
http://www.icode.co.uk...

iCode Systems

(Replies direct to my email address will be ignored. Please reply to the
group.)

Dee Earley

7/25/2012 3:40:00 PM

0

On 25/07/2012 16:31, Eduardo wrote:
> "Deanna Earley" <dee.earley@icode.co.uk> escribió en el mensaje
> news:jup0an$uph$1@speranza.aioe.org...
>
>> and be inherently evil.
>
> The only "evil" so far was to defend so much Mr. Chen position of not using
> LockWindowUpdate when there is not other alternative for some scenarios.
> But that wasn't really evil, just a bit annoying.

Oh, I missed that in the list of deadly sins.

--
Deanna Earley (dee.earley@icode.co.uk)
i-Catcher Development Team
http://www.icode.co.uk...

iCode Systems

(Replies direct to my email address will be ignored. Please reply to the
group.)

Coder X

7/25/2012 3:51:00 PM

0

Raymond Chen? Good grief, what did he say now?


"Eduardo" <mm@mm.com> wrote in message
news:jup3fq$8b8$1@speranza.aioe.org...
> The only "evil" so far was to defend so much Mr. Chen position of not
> using LockWindowUpdate when there is not other alternative for some
> scenarios.
> But that wasn't really evil, just a bit annoying.
>


mm

7/25/2012 4:19:00 PM

0


"Coder X" <coder@x.com> escribió en el mensaje
news:jup4l0$vcg$1@dont-email.me...
> Raymond Chen? Good grief, what did he say now?

The discussion:
https://groups.google.com/group/microsoft.public.vb.general.discussion/browse_frm/thread/2620c15c50516797/d6ce6a8c8a0d57ff?hl=en&tvc=1#d6ce6a...

Mr Chen articles:

What does LockWindowUpdate do?
http://blogs.msdn.com/b/oldnewthing/archive/2007/02/19/17...

With what operations is LockWindowUpdate meant to be used?
http://blogs.msdn.com/b/oldnewthing/archive/2007/02/21/17...

With what operations is LockWindowUpdate not meant to be used?
http://blogs.msdn.com/b/oldnewthing/archive/2007/02/22/1742084.as...

Final remarks on LockWindowUpdate
http://blogs.msdn.com/b/oldnewthing/archive/2007/02/23/17...

And perhaps this article:
http://fgaillard.com/2011/02/the-unfortunate-effect-of-wm_...


mm

7/25/2012 4:22:00 PM

0


"Deanna Earley" <dee.earley@icode.co.uk> escribió en el mensaje
news:jup3ob$949$1@speranza.aioe.org...

> The auto complete api is a good start.
> http://msdn.microsoft.com/en-us/library/windows/deskto...(v=vs.85).aspx

I don't know, it didn't work.
My test project crashed (it were not saved) the second time I called
CoUninitialize from the Form_Terminate event.

It seems to be intended to work with system files and URLs.