TmyShape = class(TShape)
published
canvas:TCanvas;
end;
但是后来当我调用到这个类的TextOut方法时出错了,是不是与它的只读属性有关呢?应该如何解决?
myShape1.canvas.TextOut(0,0,'hello'); //这一句就出错了。
9 个解决方案
#1
如果想继承TShape的Canvas属性的话,应该写成:
TmyShape = class(TShape)
published
property canvas:TCanvas;
end;
但是刚才我试了一下,这样是编译不通过的,然后我看了一下它的两个父类,
TShape中没有定义过Canvas属性,TGraphicControl中有Canvas属性,但是它是Protected的,
照理来说,在TMyShape中只有将Canvas属性重新定义为public的,才可以给外部使用,但是,后来我将TMyShape改为:
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
后,TMyShape的Canvas属性就可以正常使用了,
然而,如果直接想使用TShape的Canvas属性则又不可,不知道何故。。。?
TmyShape = class(TShape)
published
property canvas:TCanvas;
end;
但是刚才我试了一下,这样是编译不通过的,然后我看了一下它的两个父类,
TShape中没有定义过Canvas属性,TGraphicControl中有Canvas属性,但是它是Protected的,
照理来说,在TMyShape中只有将Canvas属性重新定义为public的,才可以给外部使用,但是,后来我将TMyShape改为:
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
后,TMyShape的Canvas属性就可以正常使用了,
然而,如果直接想使用TShape的Canvas属性则又不可,不知道何故。。。?
#2
刚刚看了一下,果然漏写了property。但是就像tonylk(=www.tonixsoft.com=) 说的,这样编译是通不过的,反而是published之后什么都没写就一切OK。但这样的类定义有什么意义?
#3
TMyShape = class(TShape)
public
property Canvas;
end;
这个能编译通过。如果你在form的OnCreate事件中加入:
MyShape.canvas.textout(0,0,'123');
你是不会在MyShape中看见任何东西的,因为执行了这一句之后在Form Paint是会自动调用TMyShape里的Paint函数来重画组件,这时候TMyShape的父类会调用自己的Paint方法来重画组件,因此‘123’会被覆盖掉,要想在TMyShape中显示字体应该重载TShape的Paint方法而不是将它的Canvas属性公开。
public
property Canvas;
end;
这个能编译通过。如果你在form的OnCreate事件中加入:
MyShape.canvas.textout(0,0,'123');
你是不会在MyShape中看见任何东西的,因为执行了这一句之后在Form Paint是会自动调用TMyShape里的Paint函数来重画组件,这时候TMyShape的父类会调用自己的Paint方法来重画组件,因此‘123’会被覆盖掉,要想在TMyShape中显示字体应该重载TShape的Paint方法而不是将它的Canvas属性公开。
#4
TCustomShape = class(TShape)
private
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
protected
procedure Paint; override;
public
property Text;
property Color;
property Font;
end;
procedure TCustomShape.CMTextChanged(var Message: TMessage);
begin
Invalidate
end;
procedure TCustomShape.Paint;
begin
Brush.Color := Color;
inherited;
Canvas.Font := Font;
Canvas.TextOut(2, 2, Text);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with Shape do
begin
Color := clWhite;
Font.Color := clRed;
Text := 'WGYKING'
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Shape := TCustomShape.Create(nil);
Shape.Parent := Self
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeAndNil(Shape);
end;
private
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
protected
procedure Paint; override;
public
property Text;
property Color;
property Font;
end;
procedure TCustomShape.CMTextChanged(var Message: TMessage);
begin
Invalidate
end;
procedure TCustomShape.Paint;
begin
Brush.Color := Color;
inherited;
Canvas.Font := Font;
Canvas.TextOut(2, 2, Text);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with Shape do
begin
Color := clWhite;
Font.Color := clRed;
Text := 'WGYKING'
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Shape := TCustomShape.Create(nil);
Shape.Parent := Self
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeAndNil(Shape);
end;
#5
CareYouOnly(只在乎你)和WGYKING(修罗是谁?!) 的方法是通过重载paint方法来调用canvas,我试了一下已经OK了,谢谢!
不过我还有一点疑问,那就是为什么
TMyShape = class(TShape)
public
property Canvas;
end;
这样声明(公开属性时少写了属性的类型)就可以?
或者
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
这样声明的时候,在published部分根本就什么代码都没有,也能调用Canvas,这是什么原因?
不过我还有一点疑问,那就是为什么
TMyShape = class(TShape)
public
property Canvas;
end;
这样声明(公开属性时少写了属性的类型)就可以?
或者
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
这样声明的时候,在published部分根本就什么代码都没有,也能调用Canvas,这是什么原因?
#6
你是在同一单元申明这个类的吧?
如果是
他们为友元类
任何域字段的字段值都可以访问
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
这种声明是错误的
因为canvas是TMyShape的父类TShape的父类TGraphicControl类protected域的属性
如果再子类中公布
应该不加属性的类型
否则就是一个新的属性
父类同名属性被覆盖
如果是
他们为友元类
任何域字段的字段值都可以访问
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
这种声明是错误的
因为canvas是TMyShape的父类TShape的父类TGraphicControl类protected域的属性
如果再子类中公布
应该不加属性的类型
否则就是一个新的属性
父类同名属性被覆盖
#7
你看看TPaintBox类
他们父类相同
这是另一种实现方式^_^
TPaintBox = class(TGraphicControl)
private
FOnPaint: TNotifyEvent; //定义事件
protected
procedure Paint; override;//重载Paint过程
public
constructor Create(AOwner: TComponent); override;
property Canvas; //公布Canvas属性
published
property Align;
property Anchors;
property Color;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Visible;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnPaint: TNotifyEvent read FOnPaint write FOnPaint; //公布事件属性
property OnStartDock;
property OnStartDrag;
end;
~~~~~~~~~~~~~~~~~~~
procedure TPaintBox.Paint;
begin
Canvas.Font := Font;
Canvas.Brush.Color := Color;
if csDesigning in ComponentState then
with Canvas do
begin
Pen.Style := psDash;
Brush.Style := bsClear;
Rectangle(0, 0, Width, Height);
end;
if Assigned(FOnPaint) then FOnPaint(Self); //如果你指定了事件,在画玩外框后执行他
end;
他们父类相同
这是另一种实现方式^_^
TPaintBox = class(TGraphicControl)
private
FOnPaint: TNotifyEvent; //定义事件
protected
procedure Paint; override;//重载Paint过程
public
constructor Create(AOwner: TComponent); override;
property Canvas; //公布Canvas属性
published
property Align;
property Anchors;
property Color;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Visible;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnPaint: TNotifyEvent read FOnPaint write FOnPaint; //公布事件属性
property OnStartDock;
property OnStartDrag;
end;
~~~~~~~~~~~~~~~~~~~
procedure TPaintBox.Paint;
begin
Canvas.Font := Font;
Canvas.Brush.Color := Color;
if csDesigning in ComponentState then
with Canvas do
begin
Pen.Style := psDash;
Brush.Style := bsClear;
Rectangle(0, 0, Width, Height);
end;
if Assigned(FOnPaint) then FOnPaint(Self); //如果你指定了事件,在画玩外框后执行他
end;
#8
To:alexanda2000(期待Delphi9 ^_^)
WGYKING(修罗是谁?!) 已经讲得很清楚,呵呵。
WGYKING(修罗是谁?!) 已经讲得很清楚,呵呵。
#9
呵呵,明白了。多谢!!
#1
如果想继承TShape的Canvas属性的话,应该写成:
TmyShape = class(TShape)
published
property canvas:TCanvas;
end;
但是刚才我试了一下,这样是编译不通过的,然后我看了一下它的两个父类,
TShape中没有定义过Canvas属性,TGraphicControl中有Canvas属性,但是它是Protected的,
照理来说,在TMyShape中只有将Canvas属性重新定义为public的,才可以给外部使用,但是,后来我将TMyShape改为:
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
后,TMyShape的Canvas属性就可以正常使用了,
然而,如果直接想使用TShape的Canvas属性则又不可,不知道何故。。。?
TmyShape = class(TShape)
published
property canvas:TCanvas;
end;
但是刚才我试了一下,这样是编译不通过的,然后我看了一下它的两个父类,
TShape中没有定义过Canvas属性,TGraphicControl中有Canvas属性,但是它是Protected的,
照理来说,在TMyShape中只有将Canvas属性重新定义为public的,才可以给外部使用,但是,后来我将TMyShape改为:
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
后,TMyShape的Canvas属性就可以正常使用了,
然而,如果直接想使用TShape的Canvas属性则又不可,不知道何故。。。?
#2
刚刚看了一下,果然漏写了property。但是就像tonylk(=www.tonixsoft.com=) 说的,这样编译是通不过的,反而是published之后什么都没写就一切OK。但这样的类定义有什么意义?
#3
TMyShape = class(TShape)
public
property Canvas;
end;
这个能编译通过。如果你在form的OnCreate事件中加入:
MyShape.canvas.textout(0,0,'123');
你是不会在MyShape中看见任何东西的,因为执行了这一句之后在Form Paint是会自动调用TMyShape里的Paint函数来重画组件,这时候TMyShape的父类会调用自己的Paint方法来重画组件,因此‘123’会被覆盖掉,要想在TMyShape中显示字体应该重载TShape的Paint方法而不是将它的Canvas属性公开。
public
property Canvas;
end;
这个能编译通过。如果你在form的OnCreate事件中加入:
MyShape.canvas.textout(0,0,'123');
你是不会在MyShape中看见任何东西的,因为执行了这一句之后在Form Paint是会自动调用TMyShape里的Paint函数来重画组件,这时候TMyShape的父类会调用自己的Paint方法来重画组件,因此‘123’会被覆盖掉,要想在TMyShape中显示字体应该重载TShape的Paint方法而不是将它的Canvas属性公开。
#4
TCustomShape = class(TShape)
private
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
protected
procedure Paint; override;
public
property Text;
property Color;
property Font;
end;
procedure TCustomShape.CMTextChanged(var Message: TMessage);
begin
Invalidate
end;
procedure TCustomShape.Paint;
begin
Brush.Color := Color;
inherited;
Canvas.Font := Font;
Canvas.TextOut(2, 2, Text);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with Shape do
begin
Color := clWhite;
Font.Color := clRed;
Text := 'WGYKING'
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Shape := TCustomShape.Create(nil);
Shape.Parent := Self
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeAndNil(Shape);
end;
private
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
protected
procedure Paint; override;
public
property Text;
property Color;
property Font;
end;
procedure TCustomShape.CMTextChanged(var Message: TMessage);
begin
Invalidate
end;
procedure TCustomShape.Paint;
begin
Brush.Color := Color;
inherited;
Canvas.Font := Font;
Canvas.TextOut(2, 2, Text);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with Shape do
begin
Color := clWhite;
Font.Color := clRed;
Text := 'WGYKING'
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Shape := TCustomShape.Create(nil);
Shape.Parent := Self
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeAndNil(Shape);
end;
#5
CareYouOnly(只在乎你)和WGYKING(修罗是谁?!) 的方法是通过重载paint方法来调用canvas,我试了一下已经OK了,谢谢!
不过我还有一点疑问,那就是为什么
TMyShape = class(TShape)
public
property Canvas;
end;
这样声明(公开属性时少写了属性的类型)就可以?
或者
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
这样声明的时候,在published部分根本就什么代码都没有,也能调用Canvas,这是什么原因?
不过我还有一点疑问,那就是为什么
TMyShape = class(TShape)
public
property Canvas;
end;
这样声明(公开属性时少写了属性的类型)就可以?
或者
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
这样声明的时候,在published部分根本就什么代码都没有,也能调用Canvas,这是什么原因?
#6
你是在同一单元申明这个类的吧?
如果是
他们为友元类
任何域字段的字段值都可以访问
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
这种声明是错误的
因为canvas是TMyShape的父类TShape的父类TGraphicControl类protected域的属性
如果再子类中公布
应该不加属性的类型
否则就是一个新的属性
父类同名属性被覆盖
如果是
他们为友元类
任何域字段的字段值都可以访问
TmyShape = class(TShape)
published
//property canvas:TCanvas;
end;
这种声明是错误的
因为canvas是TMyShape的父类TShape的父类TGraphicControl类protected域的属性
如果再子类中公布
应该不加属性的类型
否则就是一个新的属性
父类同名属性被覆盖
#7
你看看TPaintBox类
他们父类相同
这是另一种实现方式^_^
TPaintBox = class(TGraphicControl)
private
FOnPaint: TNotifyEvent; //定义事件
protected
procedure Paint; override;//重载Paint过程
public
constructor Create(AOwner: TComponent); override;
property Canvas; //公布Canvas属性
published
property Align;
property Anchors;
property Color;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Visible;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnPaint: TNotifyEvent read FOnPaint write FOnPaint; //公布事件属性
property OnStartDock;
property OnStartDrag;
end;
~~~~~~~~~~~~~~~~~~~
procedure TPaintBox.Paint;
begin
Canvas.Font := Font;
Canvas.Brush.Color := Color;
if csDesigning in ComponentState then
with Canvas do
begin
Pen.Style := psDash;
Brush.Style := bsClear;
Rectangle(0, 0, Width, Height);
end;
if Assigned(FOnPaint) then FOnPaint(Self); //如果你指定了事件,在画玩外框后执行他
end;
他们父类相同
这是另一种实现方式^_^
TPaintBox = class(TGraphicControl)
private
FOnPaint: TNotifyEvent; //定义事件
protected
procedure Paint; override;//重载Paint过程
public
constructor Create(AOwner: TComponent); override;
property Canvas; //公布Canvas属性
published
property Align;
property Anchors;
property Color;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Visible;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnPaint: TNotifyEvent read FOnPaint write FOnPaint; //公布事件属性
property OnStartDock;
property OnStartDrag;
end;
~~~~~~~~~~~~~~~~~~~
procedure TPaintBox.Paint;
begin
Canvas.Font := Font;
Canvas.Brush.Color := Color;
if csDesigning in ComponentState then
with Canvas do
begin
Pen.Style := psDash;
Brush.Style := bsClear;
Rectangle(0, 0, Width, Height);
end;
if Assigned(FOnPaint) then FOnPaint(Self); //如果你指定了事件,在画玩外框后执行他
end;
#8
To:alexanda2000(期待Delphi9 ^_^)
WGYKING(修罗是谁?!) 已经讲得很清楚,呵呵。
WGYKING(修罗是谁?!) 已经讲得很清楚,呵呵。
#9
呵呵,明白了。多谢!!