PickList弹出的下拉框是个ListBox,而不是ComboBox,所以如果要完成自动完成功能,包括
按某键等于按下拉按钮的功能。
1、按某键等于按按下拉按钮,假设按下箭头键,对于一个普通的ComboBox
procedure TForm1.ComboBox1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key=VK_DOWN then
begin
SendMessage(ComboBox1.Handle, CB_SHOWDROPDOWN, Integer(True), 0);
Key:=0;
end;
end;
2、作个自动完成的DBComboBox
unit CompletingDBComboBox;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls,DB,DBCtrls;
type
TCompletingComboBox = class(TDBComboBox)
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.
3、然后嵌进去,一个其他的例子
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
begin
//Regardless of cell, do we have input focus? Also,
//is the field we're on the same as the data field
//pointed to by the DBLookupComboBox? If so, then
//Move the component over the cell.
if ((gdFocused in State) AND
(Field.FieldName = DBLookupComboBox1.DataField)) then
with DBLookupComboBox1 do begin
Left := Rect.Left + DBGrid1.Left;
Top := Rect.Top + DBGrid1.Top;
Width := Rect.Right - Rect.Left;
if ((Rect.Bottom - Rect.Top) > Height) then
Height := Rect.Bottom - Rect.Top;
Visible := True;
end;
end;
procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
//Are we leaving the field in the grid that
//is also the data field for our lookup?
with DBGrid1, DBLookupComboBox1 do
if (SelectedField.FieldName = DataField) then
Visible := False;
end;
procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if (Key <> Chr(9)) then
with DBGrid1, DBLookupComboBox1 do
if (SelectedField.FieldName = DataField) then
begin
SetFocus;
SendMessage(Handle, WM_CHAR, Word(Key), 0);
end;
end;