目的:实现一个TComboBox可以对选项进行多选
简单组了一个控件,发现点击下拉框后在点窗体下拉框不会自动收缩。
不知道为什么鼠标事件捕获无效了。代码如下:unit uCheckComboBox;interface
uses
Windows, Classes, StdCtrls, DB, Controls, Messages, SysUtils,checklst,RzPanel,RzCommon,
Forms, Graphics, Menus, Buttons,Dialogs,RzLstBox, RzChkLst,RzCmboBx, Mask, RzEdit, RzBtnEdt;type
TCheckComboBox = class(TWinControl)
private
FMarkchar :Char;
FItems :TStrings;
FComBoSel :TRzButtonEdit;
FDropList :TCheckListBox;
FCapturedMouse :Boolean;
function GetFitems: Tstrings;
procedure SetFitems(const Value: Tstrings);
function GetChecked(idx: Integer): Boolean;
procedure SetChecked(idx: Integer; const Value: Boolean);
protected
procedure SetDropListVisual(AVisual :Boolean);
procedure OnDropDownEvent(Sender:TObject);
procedure OnItemChange(Sender: TObject);
function GetRealValue(Value :String):String;
procedure OnDoDropListExit(Sender:Tobject);
procedure OnDropListMouseUp(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy;override; property Checked[idx: Integer]:Boolean read GetChecked write SetChecked;
published
property Items:Tstrings read GetFitems write SetFitems;
property Markchar :Char read FMarkchar write FMarkchar;
end;implementation
constructor TCheckComboBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCapturedMouse := false;
FItems:=TStringList.Create;
FComBoSel := TRzButtonEdit.Create(self);
FComBoSel.Parent := self;
FComBoSel.Align := alTop;
FComBoSel.ButtonKind :=bkDropDown;
FComBoSel.AllowKeyEdit := false;
FDropList :=TCheckListBox.Create(self);
FDropList.Parent :=self;
FDropList.Align := alClient;
FDropList.Visible := true;
FMarkchar :='|';
self.Top :=20;
self.Left :=50;
self.Visible := true;
self.Height :=100;
self.Width :=100;
SetDropListVisual(false);
FComBoSel.OnButtonClick := OnDropDownEvent;
FDropList.OnClickCheck :=OnItemChange;
FDropList.OnExit := OnDoDropListExit;
FDropList.OnMouseUp := OnDropListMouseUp;
end;destructor TCheckComboBox.Destroy;
begin
FComBoSel.Free;
FDropList.Free;
FItems.Free;
inherited;
end;function TCheckComboBox.GetChecked(idx: Integer): Boolean;
begin
result :=FDropList.Checked[idx];
end;function TCheckComboBox.GetFitems: Tstrings;
begin
result := FDropList.Items;
end;function TCheckComboBox.GetRealValue(Value: String): String;
var
idx :integer;
begin
result :='';
idx := Pos(FMarkchar,Value);
if idx > 0 then
result :=Copy(Value,1,idx-1);
end;procedure TCheckComboBox.OnDropDownEvent(Sender: TObject);
begin
SetDropListVisual(not FDropList.Visible);
end;procedure TCheckComboBox.OnDoDropListExit(Sender: Tobject);
begin
SetDropListVisual(false);
end;procedure TCheckComboBox.OnItemChange(Sender: TObject);
var
s :string;
begin if FDropList.Checked[FDropList.ItemIndex] then
begin
if Trim(FComBoSel.Text)='' then
FComBoSel.Text :=GetRealValue(FDropList.Items.Strings[FDropList.ItemIndex])
else
FComBoSel.Text :=FComBoSel.Text+','+ GetRealValue(FDropList.Items.Strings[FDropList.ItemIndex]);
end
else
begin
s :=FComBoSel.Text ;
s :=','+s+',';
s:=StringReplace(s,','+GetRealValue(FDropList.Items[FDropList.ItemIndex])+',',',',[rfReplaceAll, rfIgnoreCase]);
FComBoSel.Text := Copy(s,2,Length(s)-2);
end;
end;procedure TCheckComboBox.SetChecked(idx: Integer;
const Value: Boolean);
begin
FDropList.Checked[idx] := Value;
end;procedure TCheckComboBox.SetDropListVisual(AVisual: Boolean);
begin
if AVisual then
begin
if not FCapturedMouse then
SetCapture(FDropList.Handle);
FCapturedMouse := true;
height := FDropList.Count*FComBoSel.Height+ FComBoSel.Height+2 ;
FDropList.Visible := true;
FDropList.SetFocus;
end
else
begin
if FCapturedMouse then
begin
ReleaseCapture;
FCapturedMouse := false;
end;
FDropList.Visible := false;
height :=FComBoSel.Height+2 ;
end;
end;procedure TCheckComboBox.SetFitems(const Value: Tstrings);
begin
FDropList.Items.Assign(Value);
end;procedure TCheckComboBox.OnDropListMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
p : TPoint;
begin p.X :=x;
P.Y :=y;
if not PtInRect(FDropList.ClientRect,p) then
SetDropListVisual(false);
inherited;
end;end.调用示范
Box :TCheckComboBox; Box :=TCheckComboBox.Create(self);
Box.Parent := self;
Box.Visible := true;
Box.Items.Add('A|北京');
Box.Items.Add('B|上京');
Box.Items.Add('C|南京');
简单组了一个控件,发现点击下拉框后在点窗体下拉框不会自动收缩。
不知道为什么鼠标事件捕获无效了。代码如下:unit uCheckComboBox;interface
uses
Windows, Classes, StdCtrls, DB, Controls, Messages, SysUtils,checklst,RzPanel,RzCommon,
Forms, Graphics, Menus, Buttons,Dialogs,RzLstBox, RzChkLst,RzCmboBx, Mask, RzEdit, RzBtnEdt;type
TCheckComboBox = class(TWinControl)
private
FMarkchar :Char;
FItems :TStrings;
FComBoSel :TRzButtonEdit;
FDropList :TCheckListBox;
FCapturedMouse :Boolean;
function GetFitems: Tstrings;
procedure SetFitems(const Value: Tstrings);
function GetChecked(idx: Integer): Boolean;
procedure SetChecked(idx: Integer; const Value: Boolean);
protected
procedure SetDropListVisual(AVisual :Boolean);
procedure OnDropDownEvent(Sender:TObject);
procedure OnItemChange(Sender: TObject);
function GetRealValue(Value :String):String;
procedure OnDoDropListExit(Sender:Tobject);
procedure OnDropListMouseUp(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy;override; property Checked[idx: Integer]:Boolean read GetChecked write SetChecked;
published
property Items:Tstrings read GetFitems write SetFitems;
property Markchar :Char read FMarkchar write FMarkchar;
end;implementation
constructor TCheckComboBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCapturedMouse := false;
FItems:=TStringList.Create;
FComBoSel := TRzButtonEdit.Create(self);
FComBoSel.Parent := self;
FComBoSel.Align := alTop;
FComBoSel.ButtonKind :=bkDropDown;
FComBoSel.AllowKeyEdit := false;
FDropList :=TCheckListBox.Create(self);
FDropList.Parent :=self;
FDropList.Align := alClient;
FDropList.Visible := true;
FMarkchar :='|';
self.Top :=20;
self.Left :=50;
self.Visible := true;
self.Height :=100;
self.Width :=100;
SetDropListVisual(false);
FComBoSel.OnButtonClick := OnDropDownEvent;
FDropList.OnClickCheck :=OnItemChange;
FDropList.OnExit := OnDoDropListExit;
FDropList.OnMouseUp := OnDropListMouseUp;
end;destructor TCheckComboBox.Destroy;
begin
FComBoSel.Free;
FDropList.Free;
FItems.Free;
inherited;
end;function TCheckComboBox.GetChecked(idx: Integer): Boolean;
begin
result :=FDropList.Checked[idx];
end;function TCheckComboBox.GetFitems: Tstrings;
begin
result := FDropList.Items;
end;function TCheckComboBox.GetRealValue(Value: String): String;
var
idx :integer;
begin
result :='';
idx := Pos(FMarkchar,Value);
if idx > 0 then
result :=Copy(Value,1,idx-1);
end;procedure TCheckComboBox.OnDropDownEvent(Sender: TObject);
begin
SetDropListVisual(not FDropList.Visible);
end;procedure TCheckComboBox.OnDoDropListExit(Sender: Tobject);
begin
SetDropListVisual(false);
end;procedure TCheckComboBox.OnItemChange(Sender: TObject);
var
s :string;
begin if FDropList.Checked[FDropList.ItemIndex] then
begin
if Trim(FComBoSel.Text)='' then
FComBoSel.Text :=GetRealValue(FDropList.Items.Strings[FDropList.ItemIndex])
else
FComBoSel.Text :=FComBoSel.Text+','+ GetRealValue(FDropList.Items.Strings[FDropList.ItemIndex]);
end
else
begin
s :=FComBoSel.Text ;
s :=','+s+',';
s:=StringReplace(s,','+GetRealValue(FDropList.Items[FDropList.ItemIndex])+',',',',[rfReplaceAll, rfIgnoreCase]);
FComBoSel.Text := Copy(s,2,Length(s)-2);
end;
end;procedure TCheckComboBox.SetChecked(idx: Integer;
const Value: Boolean);
begin
FDropList.Checked[idx] := Value;
end;procedure TCheckComboBox.SetDropListVisual(AVisual: Boolean);
begin
if AVisual then
begin
if not FCapturedMouse then
SetCapture(FDropList.Handle);
FCapturedMouse := true;
height := FDropList.Count*FComBoSel.Height+ FComBoSel.Height+2 ;
FDropList.Visible := true;
FDropList.SetFocus;
end
else
begin
if FCapturedMouse then
begin
ReleaseCapture;
FCapturedMouse := false;
end;
FDropList.Visible := false;
height :=FComBoSel.Height+2 ;
end;
end;procedure TCheckComboBox.SetFitems(const Value: Tstrings);
begin
FDropList.Items.Assign(Value);
end;procedure TCheckComboBox.OnDropListMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
p : TPoint;
begin p.X :=x;
P.Y :=y;
if not PtInRect(FDropList.ClientRect,p) then
SetDropListVisual(false);
inherited;
end;end.调用示范
Box :TCheckComboBox; Box :=TCheckComboBox.Create(self);
Box.Parent := self;
Box.Visible := true;
Box.Items.Add('A|北京');
Box.Items.Add('B|上京');
Box.Items.Add('C|南京');
解决方案 »
- ‘Delphi 实现网络驱动器的映射及断开’为何不能实现?
- OpenDialog如何取多个记录名呀
- 如何 捕捉 程序或所有控件 发出的所有异常 信息 , 并 屏闭这些信息 换成 自己的信息 ??????????? 急!!!!!!!!!!
- 高分求教sql语句中的乱码问题,很急,在线等!!!
- 关于动态库的问题,哪位哥哥能出面救救我?--------UP有礼!
- 我的提问
- 属性编辑器如何返回值?
- 如何在DELPHI中操作word?请各位高手指教。
- 如何设置TabControl1.Tabs.InsertObject(index:integer;const s:string;AObject:TObject)中的TObject参数
- delphi与c#
- 关于使用Dev Express控件包中 dxdbExtlookupEdit控件的疑问
- 如何修改与删除记录型文件里的记录
Begin
RegisterComponents('MyControl', [TCheckComboBox]);
End;
然后放到窗体里,运行,没有问题