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. ************************* Combobox的自动完成 在Combobox的OnChange或者Key事件中,写如下代码,注意,没有处理删除的情况,请自己完成。 procedure TForm1.ComboBox1Change(Sender: TObject); var a:integer; Old:string; begin a:=-1; Old :=ComboBox1.Text; sendmessage(combobox1.handle,CB_SHOWDROPDOWN,1,0); a:=SendMessage(ComboBox1.Handle, CB_SELECTSTRING,integer(@a),integer(pchar(ComboBox1.Text))); ComboBox1.SelStart:=Length(Old); ComboBox1.SelLength:=Length(ComboBox1.Text)-Length(Old); ComboBox1.ItemIndex:=a; end; *********** unit unit1 .... private selectitem : boolean; ....
procedure TForm1.ComboBox1Change(Sender: TObject); var sinput, sselected : string; i, j : integer; begin j := 0; if not selectitem then begin selectitem := true; exit; end; sinput := copy(combobox1.text, 1, combobox1.SelStart); for i := 0 to combobox1.items.count - 1 do if copy(combobox1.items[i], 1, length(sinput)) = sinput then begin if j = 0 then sselected := combobox1.items[i]; j := j + 1; end; if j > 0 then combobox1.Text := sselected else combobox1.Text := sinput; combobox1.SelStart := length(sinput); combobox1.SelLength := length(combobox1.text) - length(sinput); end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin application.Terminate end;
procedure TForm1.ComboBox1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if key = 8 then selectitem := false; end;
procedure TForm1.FormShow(Sender: TObject); begin selectitem := true; end;
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; {继承 TComboBox :增加功能,类似IE的自动查询} type TComboBox = class(StdCtrls.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; type TForm1 = class(TForm) ComboBox1: TComboBox; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm} function TComboBox.GetTextCompletion: Boolean; begin Result := fTextCompletion; end;procedure TComboBox.SetTextCompletion(const Value: Boolean); begin fTextCompletion := Value; end;procedure TComboBox.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;procedure TForm1.FormCreate(Sender: TObject); begin combobox1.Items.Add('青霉素'); combobox1.Items.Add('脑白金'); combobox1.Items.Add('全部'); end;end.
如果是前者,TCommonBox自身就有这样的功能阿?
比如你输入‘青’,那么下拉框打开,并自动过滤出含‘青’或者以‘青’开头的项,其他项就不显示或者放到后面啊。默认象你那样选择第一个,只要回车即可确定。
这样实现比较人性化吧。不过好象已经有这样的控件了,不再需要你去实现了!
主要解答者: aiirii 提交人: RaulWhite
感谢: aiirii、miky
审核者: qxj 社区对应贴子: 查看
A : 我想把combobox改造成以下的样子:还是存入一些原始数据,然后可以在用户输入的时候在combobox的下拉筐里实现原始数据模糊查询的功能,然后让用户选中,各路高人有什么好的建议?
---------------------------------------------------------------
类似IE地址栏的自动完成的效果
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.
*************************
Combobox的自动完成
在Combobox的OnChange或者Key事件中,写如下代码,注意,没有处理删除的情况,请自己完成。
procedure TForm1.ComboBox1Change(Sender: TObject);
var
a:integer;
Old:string;
begin
a:=-1;
Old :=ComboBox1.Text;
sendmessage(combobox1.handle,CB_SHOWDROPDOWN,1,0);
a:=SendMessage(ComboBox1.Handle, CB_SELECTSTRING,integer(@a),integer(pchar(ComboBox1.Text)));
ComboBox1.SelStart:=Length(Old);
ComboBox1.SelLength:=Length(ComboBox1.Text)-Length(Old);
ComboBox1.ItemIndex:=a;
end;
***********
unit unit1
....
private
selectitem : boolean;
....
procedure TForm1.ComboBox1Change(Sender: TObject);
var
sinput, sselected : string;
i, j : integer;
begin
j := 0;
if not selectitem then
begin
selectitem := true;
exit;
end;
sinput := copy(combobox1.text, 1, combobox1.SelStart);
for i := 0 to combobox1.items.count - 1 do
if copy(combobox1.items[i], 1, length(sinput)) = sinput then
begin
if j = 0 then sselected := combobox1.items[i];
j := j + 1;
end;
if j > 0 then combobox1.Text := sselected
else combobox1.Text := sinput;
combobox1.SelStart := length(sinput);
combobox1.SelLength := length(combobox1.text) - length(sinput);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
application.Terminate
end;
procedure TForm1.ComboBox1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if key = 8 then selectitem := false;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
selectitem := true;
end;
end.
---------------------------------------------------------------
你是这个意思吧
procedure TForm1.ComboBox1Change(Sender: TObject);
var
S:string;
findResult:TStrings;
begin
S:= Combobox1.Text;
//调用你的模糊查找程序,找到一些内容
//FindResult:= 你找到的内容
Combobox1.Clear; //清空上次找到的内容
//Combobox1.Items := FindResult; 把你找到的内容放入ComboBox;
//恢复用户输入
Combobox1.Text := S;
Combobox1.SelStart := length(S);
end;
dear眼睛老大,我的要求是输入条件,然后combobox给出了符合模糊查询条件的下拉框,然后供用户选择谢谢,能不能再给点指点
先把Databases的相関数据全部読入内存(TlistString或TList)、
用户输入後按回车、在TlistString内查出数据、放入TCombobox...
也可在進入TCombobox時、把TlistString内容全部放入TCombobox、
在OnChange時、查出数据修正TCombobox内容。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
{继承 TComboBox :增加功能,类似IE的自动查询}
type
TComboBox = class(StdCtrls.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;
type
TForm1 = class(TForm)
ComboBox1: TComboBox;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}
function TComboBox.GetTextCompletion: Boolean;
begin
Result := fTextCompletion;
end;procedure TComboBox.SetTextCompletion(const Value: Boolean);
begin
fTextCompletion := Value;
end;procedure TComboBox.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;procedure TForm1.FormCreate(Sender: TObject);
begin
combobox1.Items.Add('青霉素');
combobox1.Items.Add('脑白金');
combobox1.Items.Add('全部');
end;end.
每次打开的时候就将ini文件里的内容作为combobox的备选项然后autocomplete属性设置为true
好了,这个功能基本满足,
只要你曾经输入过青霉素
那么你下次输入青的时候
程序就会自动完成了
在Combobox的OnChange事件中着样做,好像不行啊,因Combobox中内容一改变(Combobox1.Text:=S),又会产生该事件,这会形成循环
谢谢jinjazz(近身剪(N-P攻略))!