Title: Adding TextCompletion to a TComboBox
Question: This article describes how to add TextCompletion to a TComboBox by descending from TComboBox and creating a new visual component.
Answer:
The Netscape Communicator location box, The Windows 98 'Run' dialog, and other programs, have implemented a very user friendly feature known commonly as text completion. This document describes how to add similar functionality to a TComboBox. The most elegant and reusable way to add this functionality is by descending from TComboBox and overriding the ComboWndProc to handle the WM_KEYUP message. By adding a new property 'TextCompletion', the functionality can be toggled to act like a regular TComboBox. Below is the component unit that implements text completion in a TComboBox. This unit can be installed as is.
unit CompletingComboBox;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TCompletingComboBox = class(TComboBox)
private
FTextCompletion: Boolean;
function GetTextCompletion: Boolean;
procedure SetTextCompletion(const Value: Boolean);
protected
// override the WndProc() so that we can trap KeyUp events.
procedure ComboWndProc(var Message: TMessage; ComboWnd: HWnd;
ComboProc: Pointer); override;
public
{ Public declarations }
published
property TextCompletion: Boolean read GetTextCompletion
write SetTextCompletion;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Standard', [TCompletingComboBox]);
end;
{ TCompletingComboBox }
function TCompletingComboBox.GetTextCompletion: Boolean;
begin
Result := fTextCompletion;
end;
procedure TCompletingComboBox.SetTextCompletion(const Value: Boolean);
begin
fTextCompletion := Value;
end;
procedure TCompletingComboBox.ComboWndProc(var Message:TMessage;
ComboWnd: HWnd;
ComboProc: Pointer);
var
rc, len: Integer;
begin
inherited;
case Message.Msg of
WM_KEYUP:
begin
// test to see if its a character that should not be
// processed.
if (Message.WParam 8) and
(Message.WParam VK_DELETE) and
(Message.WParam VK_SHIFT) and
(FTextCompletion = True) then
begin
// Use CB_FINDSTRING to locate the string in the Items
// property
rc := Perform(CB_FINDSTRING, -1,
Integer(PChar(Caption)));
// if its in there then add the new string to the Text
// and select the portion that wasn't typed in by the
// user
if rc CB_ERR then
begin
// store the length of the current string
len := Length(Text);
// set the new string
ItemIndex := rc;
// highlight the rest of the text that was added.
SelStart := len;
SelLength := Length(Text) - len;
// return 0 to signify that the message has been
// handled.
Message.Result := 0;
end;
end;
end;
end; // case
end;
end.
from the Borland Community
Article ID: 20450