Page 2 of 3
Re: Combobox dropdown style - search
Posted: Tue Feb 17, 2009 12:04 pm
by demont frank
Otto wrote:Hello Frank,
As I can’t get working incremental search in combobox I would like to test your solution with xBrowse.
Would you be so kind to send me following functions:
MAKE2DIM
NM_ALFA
MAKEGETBOX
Thanks in advance
Otto
Ok , it was send
Frank
Re: Combobox dropdown style - search
Posted: Tue Feb 17, 2009 10:46 pm
by Antonio Linares
Dear Otto,
First, you have to remove CBS_SORT from the RC or the order in the aItems array is not the same as the displayed in the combobox.
Second, besides James suggestion to set oCbx:lIncSearch := .T., you have to set this line:
Code: Select all | Expand
REDEFINE COMBOBOX oCbx VAR cItem ITEMS aItems ;
ID 110 OF oDlg ;
ON CHANGE ( oSayItem:cTitle := oCbx:GetText() ) ;
VALID ( MsgBeep(), .t. )
oCbx:lIncSearch := .T.
oCbx:oGet:bKeyChar = { | nKey | oCbx:KeyChar( nKey ) } // this one!
As you are using a CBS_DROPDOWN (that uses a GET) instead of a CBS_DROPDOWNLIST (that does not uses a GET).
With these changes, your example is working fine here

Re: Combobox dropdown style - search
Posted: Tue Feb 17, 2009 11:20 pm
by Otto
Antonio,
I changed the code but it does not work.
The changes you suggest make a DROPDOWNLIST behavior out of the DROPDOWN box.
You can’t insert a new text.
I need the dropdown behavior this means you can select an item or you can insert a new one.
Thanks in advance
Otto
Re: Combobox dropdown style - search
Posted: Wed Feb 18, 2009 12:26 am
by Antonio Linares
Otto,
Ok, I see what you want. Please make this change in Class TComboBox Method KeyChar:
Code: Select all | Expand
...
if Empty( uItem )
if nNewAt == 0
nNewAt = AScan( ::aItems, {|x| Upper(x) = Upper( ::cSearchKey ) } )
// if nNewAt > 0 .and. Len( ::aItems ) <= nNewAt
// uItem = ::aItems[ nNewAt ]
// endif
uItem = If( nNewAt > 0, ::aItems[ nNewAt ], ::cSearchKey )
else
uItem = ::aItems[ Max( nNewAt, 1) ]
endif
endif
::Set( If( ValType( Eval( ::bSetGet ) ) == "N", AScan( ::aItems, uItem ), uItem ) )
::oGet:SetPos( Len( ::cSearchKey ) + 1 )
endif
...
Please keep this line:
oCbx:oGet:bKeyChar = { | nKey | oCbx:KeyChar( nKey ) }
We may need a new DATA to select this new behavior.
Please download the EXE from here to test it:
http://www.mediafire.com/?sharekey=f67b ... 6e282a0ee8Type "antonio" and see how it behaves. Then delete char by char

Re: Combobox dropdown style - search
Posted: Wed Feb 18, 2009 9:49 am
by Antonio Linares
> We may need a new DATA to select this new behavior.
We can avoid it if we check if oCbx:oGet is != nil
Re: Combobox dropdown style - search
Posted: Wed Feb 18, 2009 10:07 am
by Antonio Linares
Otto,
This modified Class TComboBox Method KeyChar() seems to work fine, respecting spaces and evaluating ON CHANGE

Code: Select all | Expand
METHOD KeyChar( nKey, nFlags ) CLASS TComboBox
local nNewAT := 0, nOldAT := ::nAT, uItem
if Len( ::aItems ) == 0
return 0
endif
if ::lIncSearch
do case
case nKey = 32 // VK_DELETE do not work!
if ::oGet == nil
::cSearchKey = ""
nNewAt = 1
uItem = ::aItems[ nNewAt ]
else
::cSearchKey += " "
endif
case nKey = VK_BACK
::cSearchKey = Left( ::cSearchKey, Len( ::cSearchKey ) - 1 )
case nKey = 190
nKey = 0
::cSearchKey += "."
otherwise
::cSearchKey += Chr( nKey )
endcase
if Empty( uItem )
if nNewAt == 0
nNewAt = AScan( ::aItems, {|x| x = ::cSearchKey } )
if ::oGet == nil
uItem = ::aItems[ If( nNewAt > 0, nNewAt, Max( ::nAT, 1 ) ) ]
else
uItem = If( nNewAt > 0, ::aItems[ nNewAt ], ::cSearchKey )
endif
else
uItem = ::aItems[ Max( nNewAt, 1) ]
endif
endif
::Set( If( ValType( Eval( ::bSetGet ) ) == "N", AScan( ::aItems, uItem ), uItem ) )
if ::oGet != nil
::oGet:SetPos( Len( ::cSearchKey ) + 1 )
endif
endif
if ::bChange != nil
if ::oGet != nil .or. ( nNewAT != nOldAt .and. nNewAt != 0 )
Eval( ::bChange, Self, ::VarGet() )
endif
endif
if nKey == VK_RETURN
return ::oWnd:GoNextCtrl( ::hWnd )
endif
return If( ::lIncSearch, 0, nil )
Here you have the EXE to test it:
http://www.mediafire.com/?sharekey=414c ... 0a1ae8665a
Re: Combobox dropdown style - search
Posted: Wed Feb 18, 2009 11:14 am
by Antonio Linares
To avoid case sensitive make this change in the proposed Method KeyChar():
Code: Select all | Expand
nNewAt = AScan( ::aItems, {|x| Upper( x ) = Upper( ::cSearchKey ) } )
Re: Combobox dropdown style - search
Posted: Wed Feb 18, 2009 4:21 pm
by James Bott
Antonio,
May I suggest also modifying TCombobox so that incremental searching works when the style is DROPDOWN (and lIncSearch=.t.). According to Otto, this is not working.
Regards,
James
Re: Combobox dropdown style - search
Posted: Wed Feb 18, 2009 5:23 pm
by Antonio Linares
James,
Thats is what we are doing. It only works when lIncSearch is .T. and the style is dropdown.
According to Otto tests, we are close to get it fully functional. Still there are some behaviors to solve.
Re: Combobox dropdown style - search
Posted: Wed Feb 18, 2009 7:42 pm
by Antonio Linares
Otto,
This is a modified Method KeyChar() that provides support for VK_TAB. Here it is working fine.
I appreciate your feedback, thanks

Code: Select all | Expand
METHOD KeyChar( nKey, nFlags ) CLASS TComboBox
local nNewAT := 0, nOldAT := ::nAT, uItem
if Len( ::aItems ) == 0
return 0
endif
if ::lIncSearch
do case
case nKey = 32 // VK_DELETE (DO NOT WORK!)
if ::oGet == nil
::cSearchKey = ""
nNewAt = 1
uItem = ::aItems[ nNewAt ]
else
::cSearchKey += " "
endif
case nKey = VK_BACK
::cSearchKey = Left( ::cSearchKey, Len( ::cSearchKey ) - 1 )
case nKey = 190
nKey = 0
::cSearchKey += "."
case ::oGet != nil .and. nKey = VK_TAB
if ! GetKeyState( VK_SHIFT )
::oWnd:GoNextCtrl( ::hWnd )
else
::oWnd:GoPrevCtrl( ::hWnd )
endif
return 0
otherwise
::cSearchKey += Chr( nKey )
endcase
if Empty( uItem )
if nNewAt == 0
nNewAt = AScan( ::aItems, {|x| x = ::cSearchKey } )
if ::oGet == nil
uItem = ::aItems[ If( nNewAt > 0, nNewAt, Max( ::nAT, 1 ) ) ]
else
uItem = If( nNewAt > 0, ::aItems[ nNewAt ], ::cSearchKey )
endif
else
uItem = ::aItems[ Max( nNewAt, 1) ]
endif
endif
::Set( If( ValType( Eval( ::bSetGet ) ) == "N", AScan( ::aItems, uItem ), uItem ) )
if ::oGet != nil
::oGet:SetPos( Len( ::cSearchKey ) + 1 )
endif
endif
if ::bChange != nil
if ::oGet != nil .or. ( nNewAT != nOldAt .and. nNewAt != 0 )
Eval( ::bChange, Self, ::VarGet() )
endif
endif
if nKey == VK_RETURN
return ::oWnd:GoNextCtrl( ::hWnd )
endif
return If( ::lIncSearch, 0, nil )
Re: Combobox dropdown style - search
Posted: Wed Feb 18, 2009 9:48 pm
by Otto
Hello Antonio,
VK_TAB is working now.
Thanks again,
Otto
Re: Combobox dropdown style - search
Posted: Thu Feb 19, 2009 4:11 pm
by Otto
Hello Antonio,
in your last change of the method you didn't include the change
//nNewAt = AScan( ::aItems, {|x| x = ::cSearchKey } )
nNewAt = AScan( ::aItems, {|x| Upper( x ) = Upper( ::cSearchKey ) } )
Best regards,
Otto
Re: Combobox dropdown style - search
Posted: Thu Feb 19, 2009 5:58 pm
by Otto
Antonio,
http://www.atzwanger.info/kartei2/kartei2.htmPlease help me with this problem. I want to edit the field "briefanrede". But the changes go away.
Thanks in advance
Otto
Re: Combobox dropdown style - search
Posted: Wed Mar 04, 2009 9:11 pm
by Otto
Hello Antonio,
As a workaround for I changed the KeyChar method in TGet.
I inserted a
return Super:KeyChar( nKey, nFlags )
at the beginning of the method.
Now search in combobox is working.
I take the original combobox without the suggested changes. The changes I made only in TGet.
As I don’t be aware what other disadvantages the change has I copied Tget and call from combobox the copy with the changes.
Best regards,
Otto
METHOD KeyChar( nKey, nFlags ) CLASS TGet
local nHi, nLo
local lAccept
local bKeyAction := SetKey( nKey )
local nDefButton
return Super:KeyChar( nKey, nFlags )
Re: Combobox dropdown style - search
Posted: Tue Mar 10, 2009 12:27 am
by Otto
Hello Antonio,
Why do we need a TGet with CBS_Dropdown? Is this only for the TAB order?
If I commend out the following lines searching works but the Tab order is false.
Regards,
Otto
Code: Select all | Expand
if lAnd( ::nStyle, CBS_DROPDOWN )
#ifdef __XPP__
#undef New
#endif
::oGet := TGet():ReDefine( nil, ; // ID not used
::bSetGet, ; // bSETGET(uVar)
Self, ; // oDlg
::nHelpID, ; // Help Context ID
cPict, ; // Picture
nil, ; // Valid is handled by the CBx
::nClrText,;
::nClrPane,;
::oFont, ; // <oFont>
nil, ; // <oCursor>
cMsg, ; // cMsg
nil, ; // <.update.>
nil, ; // <{uWhen}>
bEChange, ; // {|nKey,nFlags,Self| <uEChange>}
.F. ) // <.readonly.> )
::oGet:bKeyChar = { | nKey | If( ( nKey == VK_TAB .and. ! GetKeyState( VK_SHIFT ) ) .or. ;
nKey == VK_RETURN,;
( ::oWnd:GoNextCtrl( ::hWnd ), 0 ),;
If( nKey == VK_TAB .and. GetKeyState( VK_SHIFT ),;
( ::oWnd:GoPrevCtrl( ::hWnd ), 0 ),) ) }
endif