我想实现把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.

解决方案 »

  1.   

    你看看我写的这段代码吧,看和你的有什么不一样。我的是调试成功的
    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.
      

  2.   

    procedure SetName(const Value: TComponentName);
    procedure SetParent(AParent: TWinControl);
    改为
    procedure SetName(const Value: TComponentName);override;
    procedure SetParent(AParent: TWinControl);override
    Win2000+D7通过
      

  3.   

    在create中应该指明FImageLabel.parent:=self;
    但是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的组合。
      

  4.   

    FImageLabel的parent没有指定,指定和TLableImage一个parent的吧