在delphi 7 自带的控件中有一个ExtCtrls.pas单元!
该单元中有两个控件,分别为TBoundLabel和TCustomLabeledEdit,
我们来分析第二个控件:TCustomLabeledEdit
两个控件在ExtCtrls.pas中定义如下: { TBoundLabel }
TBoundLabel = class(TCustomLabel)
private
function GetTop: Integer;
function GetLeft: Integer;
function GetWidth: Integer;
function GetHeight: Integer;
procedure SetHeight(const Value: Integer);
procedure SetWidth(const Value: Integer);
protected
procedure AdjustBounds; override;
public
constructor Create(AOwner: TComponent); override;
published
property BiDiMode;
property Caption;
property Color;
property DragCursor;
property DragKind;
property DragMode;
property Font;
property Height: Integer read GetHeight write SetHeight;
property Left: Integer read GetLeft;
property ParentBiDiMode;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowAccelChar;
property ShowHint;
property Top: Integer read GetTop;
property Transparent;
property Layout;
property WordWrap;
property Width: Integer read GetWidth write SetWidth;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
end; TLabelPosition = (lpAbove, lpBelow, lpLeft, lpRight); { TCustomLabeledEdit } TCustomLabeledEdit = class(TCustomEdit)
private
FEditLabel: TBoundLabel; //注意此处为私有成员;
FLabelPosition: TLabelPosition;
FLabelSpacing: Integer;
procedure SetLabelPosition(const Value: TLabelPosition);
procedure SetLabelSpacing(const Value: Integer);
protected
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;
procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;
procedure SetupInternalLabel;
property EditLabel: TBoundLabel read FEditLabel;
property LabelPosition: TLabelPosition read FLabelPosition write SetLabelPosition;
property LabelSpacing: Integer read FLabelSpacing write SetLabelSpacing;
end;其它的代码我们暂且不看!
我们来看看public中SetupInternalLabel的源码为:procedure TCustomLabeledEdit.SetupInternalLabel;
begin
if Assigned(FEditLabel) then exit;
FEditLabel := TBoundLabel.Create(Self);
FEditLabel.FreeNotification(Self);
FEditLabel.FocusControl := Self; //大家注意这句话;我感觉有问题!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end;
FocusControl属性在TBoundLabel中并未进行定义
而是在其父类中进行定义的
并且在其父类中为保护区域!TBoundLabel其父类为TCustomLabel,在StdCtrls.pas单元!
定义如下: TTextLayout = (tlTop, tlCenter, tlBottom); TCustomLabel = class(TGraphicControl)
private
FFocusControl: TWinControl;
FAlignment: TAlignment;
FAutoSize: Boolean;
FLayout: TTextLayout;
FWordWrap: Boolean;
FShowAccelChar: Boolean;
FOnMouseLeave: TNotifyEvent;
FOnMouseEnter: TNotifyEvent;
FTransparentSet: Boolean;
function GetTransparent: Boolean;
procedure SetAlignment(Value: TAlignment);
procedure SetFocusControl(Value: TWinControl);
procedure SetShowAccelChar(Value: Boolean);
procedure SetTransparent(Value: Boolean);
procedure SetLayout(Value: TTextLayout);
procedure SetWordWrap(Value: Boolean);
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
protected
procedure AdjustBounds; dynamic;
procedure DoDrawText(var Rect: TRect; Flags: Longint); dynamic;
function GetLabelText: string; virtual;
procedure Loaded; override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
procedure Paint; override;
procedure SetAutoSize(Value: Boolean); override;
property Alignment: TAlignment read FAlignment write SetAlignment
default taLeftJustify;
property AutoSize: Boolean read FAutoSize write SetAutoSize default True;
property ShowAccelChar: Boolean read FShowAccelChar write SetShowAccelChar default True;
property Transparent: Boolean read GetTransparent write SetTransparent stored FTransparentSet;
property FocusControl: TWinControl read FFocusControl write SetFocusControl; //FocusControl中是定义在protected区域中;
property Layout: TTextLayout read FLayout write SetLayout default tlTop;
property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
public
constructor Create(AOwner: TComponent); override;
property Caption;
property Canvas;
property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
end;============================================================================================================================
现在的问题是:在TCustomLabeledEdit类中,
为什么能访问到FEditLabel.FocusControl属性?
TCustomLabeledEdit类在ExtCtrls.pas单元中定义;
TCustomLabel类在StdCtrls.pas单元中定义;
它们不能够成友元类!在不是友元类的情况下,为什么TCustomLabeledEdit类中却可以访问其成员FEditLabel
(该成员国为TBoundLabel类的实例,TBoundLabel类从TCustomLabel类派生)
下的FocusControl属性(该属性在TCustomLabel类中定义在保护区域)????
该单元中有两个控件,分别为TBoundLabel和TCustomLabeledEdit,
我们来分析第二个控件:TCustomLabeledEdit
两个控件在ExtCtrls.pas中定义如下: { TBoundLabel }
TBoundLabel = class(TCustomLabel)
private
function GetTop: Integer;
function GetLeft: Integer;
function GetWidth: Integer;
function GetHeight: Integer;
procedure SetHeight(const Value: Integer);
procedure SetWidth(const Value: Integer);
protected
procedure AdjustBounds; override;
public
constructor Create(AOwner: TComponent); override;
published
property BiDiMode;
property Caption;
property Color;
property DragCursor;
property DragKind;
property DragMode;
property Font;
property Height: Integer read GetHeight write SetHeight;
property Left: Integer read GetLeft;
property ParentBiDiMode;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowAccelChar;
property ShowHint;
property Top: Integer read GetTop;
property Transparent;
property Layout;
property WordWrap;
property Width: Integer read GetWidth write SetWidth;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
end; TLabelPosition = (lpAbove, lpBelow, lpLeft, lpRight); { TCustomLabeledEdit } TCustomLabeledEdit = class(TCustomEdit)
private
FEditLabel: TBoundLabel; //注意此处为私有成员;
FLabelPosition: TLabelPosition;
FLabelSpacing: Integer;
procedure SetLabelPosition(const Value: TLabelPosition);
procedure SetLabelSpacing(const Value: Integer);
protected
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;
procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;
procedure SetupInternalLabel;
property EditLabel: TBoundLabel read FEditLabel;
property LabelPosition: TLabelPosition read FLabelPosition write SetLabelPosition;
property LabelSpacing: Integer read FLabelSpacing write SetLabelSpacing;
end;其它的代码我们暂且不看!
我们来看看public中SetupInternalLabel的源码为:procedure TCustomLabeledEdit.SetupInternalLabel;
begin
if Assigned(FEditLabel) then exit;
FEditLabel := TBoundLabel.Create(Self);
FEditLabel.FreeNotification(Self);
FEditLabel.FocusControl := Self; //大家注意这句话;我感觉有问题!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end;
FocusControl属性在TBoundLabel中并未进行定义
而是在其父类中进行定义的
并且在其父类中为保护区域!TBoundLabel其父类为TCustomLabel,在StdCtrls.pas单元!
定义如下: TTextLayout = (tlTop, tlCenter, tlBottom); TCustomLabel = class(TGraphicControl)
private
FFocusControl: TWinControl;
FAlignment: TAlignment;
FAutoSize: Boolean;
FLayout: TTextLayout;
FWordWrap: Boolean;
FShowAccelChar: Boolean;
FOnMouseLeave: TNotifyEvent;
FOnMouseEnter: TNotifyEvent;
FTransparentSet: Boolean;
function GetTransparent: Boolean;
procedure SetAlignment(Value: TAlignment);
procedure SetFocusControl(Value: TWinControl);
procedure SetShowAccelChar(Value: Boolean);
procedure SetTransparent(Value: Boolean);
procedure SetLayout(Value: TTextLayout);
procedure SetWordWrap(Value: Boolean);
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
protected
procedure AdjustBounds; dynamic;
procedure DoDrawText(var Rect: TRect; Flags: Longint); dynamic;
function GetLabelText: string; virtual;
procedure Loaded; override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
procedure Paint; override;
procedure SetAutoSize(Value: Boolean); override;
property Alignment: TAlignment read FAlignment write SetAlignment
default taLeftJustify;
property AutoSize: Boolean read FAutoSize write SetAutoSize default True;
property ShowAccelChar: Boolean read FShowAccelChar write SetShowAccelChar default True;
property Transparent: Boolean read GetTransparent write SetTransparent stored FTransparentSet;
property FocusControl: TWinControl read FFocusControl write SetFocusControl; //FocusControl中是定义在protected区域中;
property Layout: TTextLayout read FLayout write SetLayout default tlTop;
property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
public
constructor Create(AOwner: TComponent); override;
property Caption;
property Canvas;
property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
end;============================================================================================================================
现在的问题是:在TCustomLabeledEdit类中,
为什么能访问到FEditLabel.FocusControl属性?
TCustomLabeledEdit类在ExtCtrls.pas单元中定义;
TCustomLabel类在StdCtrls.pas单元中定义;
它们不能够成友元类!在不是友元类的情况下,为什么TCustomLabeledEdit类中却可以访问其成员FEditLabel
(该成员国为TBoundLabel类的实例,TBoundLabel类从TCustomLabel类派生)
下的FocusControl属性(该属性在TCustomLabel类中定义在保护区域)????
这儿不存在子类与父类的关系!TCustomLabeledEdit = class(TCustomEdit) //TCustomLabeledEdit 类是从 TCustomEdit派生的!FEditLabel: TBoundLabel; //FEditLabel只是TCustomLabeledEdit 类中定义的一个成员,FocusControl属性在TBoundLabel类中是属于保护区域的!而在
procedure TCustomLabeledEdit.SetupInternalLabel;
begin
if Assigned(FEditLabel) then exit;
FEditLabel := TBoundLabel.Create(Self);
FEditLabel.FreeNotification(Self);
FEditLabel.FocusControl := Self; //注意:在TCustomLabeledEdit类中可以访问其成员的保护属性!而不是其父类的保护属性!
end;
现在确出现了在TCustomLabeledEdit中可以访问其成员的保护属性的情况?
现在我自己定了一个控件,和TCustomLabeledEdit完全一样,
只是从TDBEditEh类派生!
其它代码都一模一样!
就在FEditLabel.FocusControl := Self;这句话上出了问题,说没有定义FocusControl属性!
然后我在StdCtrls.pas单元中,将 property FocusControl: TWinControl read FFocusControl write SetFocusControl;这行代码放到public中,也出现一样的问题!
我想是因为没有将StdCtrls.pas单元重新编译的原故!我在改了DELPHI自带的控件单元后,怎么重新编译呢?听同事说把原来的StdCtrls.dcu文件删除,然后重新编译就行,但我试了也不行!怎么办?
procedure TCustomLabeledEdit.SetupInternalLabel;
begin
if Assigned(FEditLabel) then exit;
FEditLabel := TBoundLabel.Create(Self);
FEditLabel.FreeNotification(Self);
FEditLabel.FocusControl := Self; //注意:在TCustomLabeledEdit类中可以访问其成员的保护属性!而不是其父类的保护属性!
end;
现在确出现了在TCustomLabeledEdit中可以访问其成员的保护属性的情况?
他们是友元类,
不仅可以访问对方的保护成员,
还可以访问私有成员。
但TBoundLabel的父类TCustomLabel确是在另一个单元,而FocusControl是属于TCustomLabel下的一个属性!
这样TCustomLabeledEdit类也能和TCustomLabel类构成友元吗?
好像不对吧!
如果真是友元类的话,如果这也成了友元的话,友元的概念不就成了:不但可以访问本单元内其它类的属性,还可以访问本单元内其它类的父类的成员,
这样一来,整个DELPHI中的类全都成了友元类了!====================================================================================
现在的问题是:在TCustomLabeledEdit类中,
为什么能访问到FEditLabel.FocusControl属性?
TCustomLabeledEdit类在ExtCtrls.pas单元中定义;
TCustomLabel类在StdCtrls.pas单元中定义;
它们不能够成友元类!在不是友元类的情况下,为什么TCustomLabeledEdit类中却可以访问其成员FEditLabel
(该成员国为TBoundLabel类的实例,TBoundLabel类从TCustomLabel类派生)
下的FocusControl属性(该属性在TCustomLabel类中定义在保护区域)????