我想实现把TImage和TLabel合并成一个控件,即在Image边上附有Label说明的控件。但label 始终看不见。以下是我的代码,请帮忙看看。unit LabelImage;interface uses
Windows, Messages, SysUtils, Classes, Controls, ExtCtrls, StdCtrls;type
TLabelPosition = (lpAbove, lpBelow, lpLeft, lpRight);
TLableImage = class(TImage)
private
FImageLabel : TCustomLabel;
FLabelPosition : TLabelPosition;
FLabelSpacing: Integer;
procedure SetLabelPosition(const Value: TLabelPosition);
procedure SetLabelSpacing(const Value: Integer);
{ Private declarations }
protected
procedure SetName(const Value: TComponentName);
procedure SetParent(AParent: TWinControl);
{ Protected declarations }
public
constructor Create(AOwner: TComponent); override;
destructor Destroy;override;
procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;
procedure SetupInternalLabel; { Public declarations }
published
property ImageLabel:TCustomLabel read FImageLabel ;
property LabelPosition: TLabelPosition read FLabelPosition write SetLabelPosition;
property LabelSpacing: Integer read FLabelSpacing write SetLabelSpacing;
{ Published declarations }
end;procedure Register;implementationconstructor TLableImage.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FLabelPosition := lpBelow;
FLabelSpacing := 3;
SetupInternalLabel;
end;destructor TLableImage.Destroy;
begin
FImageLabel.Free;
inherited Destroy;
end;procedure TLableImage.SetLabelPosition(const Value: TLabelPosition);
var
P: TPoint;
begin
if FImageLabel = nil then exit;
FLabelPosition := Value;
case Value of
lpAbove: P := Point(Left, Top - FImageLabel.Height - FLabelSpacing);
lpBelow: P := Point(Left, Top + Height + FLabelSpacing);
lpLeft : P := Point(Left - FImageLabel.Width - FLabelSpacing,
Top + ((Height - FImageLabel.Height) div 2));
lpRight: P := Point(Left + Width + FLabelSpacing,
Top + ((Height - FImageLabel.Height) div 2));
end;
FImageLabel.SetBounds(P.x, P.y, FImageLabel.Width, FImageLabel.Height);
end;procedure TLableImage.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
SetLabelPosition(FLabelPosition);
end;procedure TLableImage.SetLabelSpacing(const Value: Integer);
begin
FLabelSpacing := Value;
SetLabelPosition(FLabelPosition);
end;procedure TLableImage.SetName(const Value: TComponentName);
begin
if (csDesigning in ComponentState) and ((FImageLabel.GetTextLen = 0) or
(CompareText(FImageLabel.Caption, Name) = 0)) then
FImageLabel.Caption := Value;
inherited SetName(Value);
if csDesigning in ComponentState then
Text := '';
end;procedure TLableImage.SetParent(AParent: TWinControl);
begin
inherited SetParent(AParent);
if FImageLabel = nil then exit;
FImageLabel.Parent := AParent;
FImageLabel.Visible := True;
end;procedure TLableImage.SetupInternalLabel;
begin
if Assigned(FImageLabel) then exit;
FImageLabel := TBoundLabel.Create(Self);
//FImageLabel.FocusControl := Self;
end;procedure Register;
begin
RegisterComponents('LJ', [TLableImage]);
end;end.
Windows, Messages, SysUtils, Classes, Controls, ExtCtrls, StdCtrls;type
TLabelPosition = (lpAbove, lpBelow, lpLeft, lpRight);
TLableImage = class(TImage)
private
FImageLabel : TCustomLabel;
FLabelPosition : TLabelPosition;
FLabelSpacing: Integer;
procedure SetLabelPosition(const Value: TLabelPosition);
procedure SetLabelSpacing(const Value: Integer);
{ Private declarations }
protected
procedure SetName(const Value: TComponentName);
procedure SetParent(AParent: TWinControl);
{ Protected declarations }
public
constructor Create(AOwner: TComponent); override;
destructor Destroy;override;
procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;
procedure SetupInternalLabel; { Public declarations }
published
property ImageLabel:TCustomLabel read FImageLabel ;
property LabelPosition: TLabelPosition read FLabelPosition write SetLabelPosition;
property LabelSpacing: Integer read FLabelSpacing write SetLabelSpacing;
{ Published declarations }
end;procedure Register;implementationconstructor TLableImage.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FLabelPosition := lpBelow;
FLabelSpacing := 3;
SetupInternalLabel;
end;destructor TLableImage.Destroy;
begin
FImageLabel.Free;
inherited Destroy;
end;procedure TLableImage.SetLabelPosition(const Value: TLabelPosition);
var
P: TPoint;
begin
if FImageLabel = nil then exit;
FLabelPosition := Value;
case Value of
lpAbove: P := Point(Left, Top - FImageLabel.Height - FLabelSpacing);
lpBelow: P := Point(Left, Top + Height + FLabelSpacing);
lpLeft : P := Point(Left - FImageLabel.Width - FLabelSpacing,
Top + ((Height - FImageLabel.Height) div 2));
lpRight: P := Point(Left + Width + FLabelSpacing,
Top + ((Height - FImageLabel.Height) div 2));
end;
FImageLabel.SetBounds(P.x, P.y, FImageLabel.Width, FImageLabel.Height);
end;procedure TLableImage.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
SetLabelPosition(FLabelPosition);
end;procedure TLableImage.SetLabelSpacing(const Value: Integer);
begin
FLabelSpacing := Value;
SetLabelPosition(FLabelPosition);
end;procedure TLableImage.SetName(const Value: TComponentName);
begin
if (csDesigning in ComponentState) and ((FImageLabel.GetTextLen = 0) or
(CompareText(FImageLabel.Caption, Name) = 0)) then
FImageLabel.Caption := Value;
inherited SetName(Value);
if csDesigning in ComponentState then
Text := '';
end;procedure TLableImage.SetParent(AParent: TWinControl);
begin
inherited SetParent(AParent);
if FImageLabel = nil then exit;
FImageLabel.Parent := AParent;
FImageLabel.Visible := True;
end;procedure TLableImage.SetupInternalLabel;
begin
if Assigned(FImageLabel) then exit;
FImageLabel := TBoundLabel.Create(Self);
//FImageLabel.FocusControl := Self;
end;procedure Register;
begin
RegisterComponents('LJ', [TLableImage]);
end;end.
unit BcImgLabel;interfaceuses
Windows, Messages, SysUtils, StdCtrls, ExtCtrls, Classes, Controls;type
TBcBoundLabel = class(TBoundLabel)
private
FOwnerControl: TControl;
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
published
property OnMouseEnter;
property OnMouseLeave;
end; TBcImgLabel = class(TImage)
private
{ Private declarations }
FLabel: TBcBoundLabel;
FLabelSpacing: Integer;
FLabelPosition: TLabelPosition;
FMouseLeave: TNotifyEvent;
FMouseEnter: TNotifyEvent;
procedure SetLabelPosition(const Value: TLabelPosition);
procedure SetLabelSpacing(const Value: Integer);
protected
{ Protected declarations }
procedure MouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure MouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
procedure SetParent(AParent: TWinControl); override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure SetName(const Value: TComponentName); override;
procedure CMVisiblechanged(var Message: TMessage);
message CM_VISIBLECHANGED;
procedure CMEnabledchanged(var Message: TMessage);
message CM_ENABLEDCHANGED;
procedure CMBidimodechanged(var Message: TMessage);
message CM_BIDIMODECHANGED;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;
procedure SetupInternalLabel;
published
{ Published declarations }
property EditLabel: TBcBoundLabel read FLabel;
property LabelPosition: TLabelPosition read FLabelPosition write SetLabelPosition;
property LabelSpacing: Integer read FLabelSpacing write SetLabelSpacing;
property OnMouseEnter: TNotifyEvent read FMouseEnter write FMouseEnter;
property OnMouseLeave: TNotifyEvent read FMouseLeave write FMouseLeave;
end;implementation
{ TBcImgLabel }procedure TBcImgLabel.CMBidimodechanged(var Message: TMessage);
begin
FLabel.BiDiMode := BiDiMode;
end;procedure TBcImgLabel.CMEnabledchanged(var Message: TMessage);
begin
FLabel.Enabled := Enabled;
end;procedure TBcImgLabel.CMVisiblechanged(var Message: TMessage);
begin
FLabel.Visible := Visible;
end;constructor TBcImgLabel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Width := 24;
Height := 24;
FLabelSpacing := 1;
FLabelPosition := lpRight;
SetupInternalLabel;
end;destructor TBcImgLabel.Destroy;
begin
FLabel.Free;
inherited;
end;procedure TBcImgLabel.MouseEnter(var Message: TMessage);
begin
inherited;
if Assigned(FMouseEnter) then
FMouseEnter(Self);
end;procedure TBcImgLabel.MouseLeave(var Message: TMessage);
begin
inherited;
if Assigned(FMouseLeave) then
FMouseLeave(Self);
end;procedure TBcImgLabel.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited;
if (AComponent = FLabel) and (Operation = opRemove) then
FLabel := nil;
end;procedure TBcImgLabel.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
SetLabelPosition(FLabelPosition);
end;procedure TBcImgLabel.SetLabelPosition(const Value: TLabelPosition);
var
P: TPoint;
begin
if FLabel = nil then
exit;
FLabelPosition := Value;
case Value of
lpAbove: P := Point(Left + (Width - FLabel.Width) div 2 - 1,
Top - FLabel.Height - FLabelSpacing);
lpBelow: P := Point(Left + (Width - FLabel.Width) div 2 - 1,
Top + Height + FLabelSpacing);
lpLeft: P := Point(Left - FLabel.Width - FLabelSpacing,
Top + ((Height - FLabel.Height) div 2));
lpRight: P := Point(Left + Width + FLabelSpacing,
Top + ((Height - FLabel.Height) div 2));
end;
FLabel.SetBounds(P.X, P.Y, FLabel.Width, FLabel.Height);
end;procedure TBcImgLabel.SetLabelSpacing(const Value: Integer);
begin
FLabelSpacing := Value;
SetLabelPosition(FLabelPosition);
end;procedure TBcImgLabel.SetName(const Value: TComponentName);
begin
if (csDesigning in ComponentState) and ((Flabel.GetTextLen = 0) or
(CompareText(FLabel.Caption, Name) = 0)) then
FLabel.Caption := Value;
inherited SetName(Value);
if csDesigning in ComponentState then
Text := '';
end;procedure TBcImgLabel.SetParent(AParent: TWinControl);
begin
inherited SetParent(AParent);
if FLabel = nil then
exit;
FLabel.Parent := AParent;
FLabel.Visible := True;
end;procedure TBcImgLabel.SetupInternalLabel;
begin
if Assigned(FLabel) then Exit;
FLabel := TBcBoundLabel.Create(Self);
FLabel.FOwnerControl := Self;
FLabel.FreeNotification(Self);
end;{ TBcBoundLabel }procedure TBcBoundLabel.CMFontChanged(var Message: TMessage);
begin
inherited;
if Assigned(FOwnerControl) then
with FOwnerControl do
SetBounds(Left, Top, Width, Height);
end;procedure TBcBoundLabel.CMTextChanged(var Message: TMessage);
begin
inherited;
if Assigned(FOwnerControl) then
with FOwnerControl do
SetBounds(Left, Top, Width, Height);
end;end.
procedure SetParent(AParent: TWinControl);
改为
procedure SetName(const Value: TComponentName);override;
procedure SetParent(AParent: TWinControl);override
Win2000+D7通过
但是FImageLabel.parent必须是Twincontrol,所以这个组件设计有问题。
TLableImage = class(TImage) //这个基类应该是twincontrol(或它的派生类)。
在create函数中:
FImageLabel:=tcustomlable.create(self);
FImageLabel.parent:=self;
Fimage:=Timage.create(self); //多定义一个Fiamge(Timage类型的)
FImage.parent:=self;
这样你做的控件才是 lable + image的组合。