制作象 TLabel 一样的控件(100分)

  • 主题发起人 主题发起人 沧海
  • 开始时间 开始时间

沧海

Unregistered / Unconfirmed
GUEST, unregistred user!
请问怎样从 TGraphicControl 继承,做一个象 TLabel 或 TEdit 一样的控件,只要可以画
出来(具体属性与方法不管),具体画什么在控件内部定义,比如说画一条直线。拉出来的
时候最好不是 矩形的(是原来画的样子)。

请高手多多发言。
 
从TShape继承一个不就行了?
 
杜保兄,你的方法能详细一点吗?我的资质比较低!!!
不过其实我是想从 TGraphicControl 这样可以了解到更多的东东。
谢了!
 
你把tlable的原代码拿出来看看就知道了

可以改动它啊
 
各位高手,帮帮忙呀!
 
在新控件的OnPaint事件中用Canvas对象绘制所需图形即可

...
with Canvas do
begin
...
end;
...
 
更正:不是OnPaint事件,是重载(override)Paint方法
 
不好意思,网络有问题,全部程序贴不上来。
type
TLine = class(TGraphicControl)
private
FStart_Point:TPoint;
FEnd_Point:TPoint;
procedure WMPaint(var Message: TWMPaint);message WM_PAINT;
protected
public
constructor Create(AOwner: TComponent);override;
destructor Destory;//override;
procedure Paint; override;
published
property Start_Point:TPoint read FStart_Point write FStart_Point;
property End_Point:TPoint read FEnd_Point write FEnd_Point;
procedure DrawLine(); //每次paint调用画线
......
 
constructor TLine.Create(AOwner: TComponent);
begin
inherited Create(AOwner);

ControlStyle := ControlStyle ;
Parent := TWinControl(AOWner);
Start_Point.x:=10; //出错
Start_Point.y:=10; //出错
End_Point.x:=100; //出错
End_Point.y:=100; //出错

DrawLine();

end;
...........
因为Start_Point;End_Point 负初值出错,所以什么也没画出来!
各位高手多多帮忙呀 !
 
destructor TLine.Destory;
begin
inherited Destroy;
end;

procedure TLine.WMPaint(var Message: TWMPaint);
begin
inherited;
end;

procedure TLine.Paint;
begin
inherited Paint;
DrawLine;
end;

procedure TLine.DrawLine();
begin
with Canvas do
begin
MoveTo (Start_Point.x,Start_Point.y);
LineTo (End_Point.x,End_Point.y);
end;
end;

end.

 
我的问题很没有意思吗?怎么各位大虾都不屑于回答呀!
 
把出错的代码改成
fStart_Point.x:=10;
fStart_Point.y:=10;
fEnd_Point.x:=100;
fEnd_Point.y:=100;
试试
 
sonie,兄,我试过了,好象没反映也
 
先说说你的源代码(当然这是我个人的观点,不妥之处,勿请各位手下留情):

type
TLine = class(TGraphicControl)
private
FStart_Point:TPoint;
FEnd_Point:TPoint;
procedure WMPaint(var Message: TWMPaint);message WM_PAINT;
protected
public
constructor Create(AOwner: TComponent);override;
destructor Destory;//override;
procedure Paint; override;
published
property Start_Point:TPoint read FStart_Point write FStart_Point;
property End_Point:TPoint read FEnd_Point write FEnd_Point;
......

1)Start_Point属性不能出现在 published 中。
published 要求是基本类型,应该改为:
published
property Start_PointX: Longint read FStart_Point.X write SetStart_PointX;
property Start_PointY: Longint read FStart_Point.Y write SetStart_PointY;
...

用 Set 过程是因为如果有坐标点变化就可以立即更新组件状态。
procedure SetStart_PointX(V: Longint);
begin
FStart_Point.x := V;
DrawLine();
end;

2)作为子件,DrawLine() 过程最好设置为受保护的过程:
protected
procedure DrawLine(); dynamic;
这样以后如果有类似的派生子件可以覆盖该方法。

3)声名一个事件:OnDrawLine;
published
property OnDrawLine: TNotifyEvent read FOnDrawLine write FOnDrawLine;

然后在 DrawLine() 过程中:
if Assigned(FOnDrawLine) then
FOnDrawLine(Self)
else
//your default drawing code here.

4)WM_PAINT消息不用处理了,因为是 TGraphicControl 有默认的
可覆盖例程:Paint()。override 就是了。
procedure TLine.Paint;
begin
Canvas.Lock;
try
DrawLine;
finally
Canvas.UnLock;
end;
end;


5)构造函数
constructor TLine.Create(AOwner: TComponent);
begin
inherited Create(AOwner);

//ControlStyle := ControlStyle ;
//Parent := TWinControl(AOWner);
//这两句如果没有特殊处理,是多余的。

FStart_Point.x:=10; //出错
FStart_Point.y:=10; //出错
FEnd_Point.x:=100; //出错
FEnd_Point.y:=100; //出错

//DrawLine();
//不能在这儿画!必须在 Paint() 过程中实现!

end;

...唉,要说得太多了,慢慢来吧。
 
首先要向大家道歉,由于网络原因很久没上来了。

不是因为我的问题太烂了把?怎么人气这么差呀!
 
unit MyLabel;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type

TMyShape=(msLine,msRect,msEllipse);

TMyLabel = class(TGraphicControl)
private
FMyShape:TMyShape;
procedure SetShape(value:TMyShape);
protected
Constructor Create(AOwner:TComponent);override;

public
procedure paint;override;
published
property MyShape:TMyShape read FMyShape write SetShape Default msLine;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Expand', [TMyLabel]);
end;

{ TMyLabel }

constructor TMyLabel.Create(AOwner: TComponent);
begin
inherited;
height:=50;
width:=50;
FMyShape:=msLine;
end;

procedure TMyLabel.paint;
begin
inherited;
with Canvas do begin
case FMyShape of
msline: begin
Moveto(height div 2,0);
lineto(height div 2,width);
end;
msRect:
Rectangle(0,0,width,height);
msEllipse:
Ellipse(0,0,width,height);
end;
end;


end;

procedure TMyLabel.SetShape(value: TMyShape);
begin
if FmyShape<>value then
FMyShape:=value;
end;

end.
 
同意DiamondKing, 和ddev,
to 沧海:
没显示是因为创建的控件没有大小,默认width,height := 0,当然画不出线了

如果只是为了显示,以下代码足够了
作控件参考ddev说的,找本书看看

procedure TForm1.Button1Click(Sender: TObject);
var
myline : TLine;
begin
myline := TLine.Create(Self);
myline.Parent := self;
//指定位置
myline.Left := 100;
myline.Top := 100;
//指定大小,否则没了显示区
myline.Width := 200;
myline.Height := 200;

end;


unit Unit2;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
TLine = class(TGraphicControl)
private
FStart_Point:TPoint;
FEnd_Point:TPoint;
protected
procedure DrawLine(); //每次paint调用画线
public
constructor Create(AOwner: TComponent);override;
procedure Paint; override;
published
property Start_Point:TPoint read FStart_Point write FStart_Point;
property End_Point:TPoint read FEnd_Point write FEnd_Point;

end;

implementation

{ TLine }

constructor TLine.Create(AOwner: TComponent);
begin
inherited Create(AOwner);

FStart_Point.x:=10;
FStart_Point.y:=10;
FEnd_Point.x:=100;
FEnd_Point.y:=100;

end;

procedure TLine.DrawLine;
begin
Canvas.MoveTo(FStart_Point.x,FStart_Point.y);
Canvas.LineTo(FEnd_Point.x,FEnd_Point.y);
end;

procedure TLine.Paint;
begin
DrawLine;
end;


end.
 
DiamondKing, 兄的程序还没时间调试,不过估计也是正确的,
yidaoh, 兄的程序完全符合我的希望(呵呵,我的要求不高的),
至于高手 ddev 的答案已经超出了我的要求,我会努力学习的。
谢谢各位对我的帮助,不过我想等几天在放分,再看看其他人的意见,
几位大虾不会介意把! :)
 
还不结束?
 
To Yidaoh: property Start_Point:TPoint read FStart_Point write FStart_Point;
property End_Point:TPoint read FEnd_Point write FEnd_Point;
这两句我觉得不很完善。因为当你更改FStart_Point,FEnd_Point,的时候你的
组件肯定不能重绘,无法更新到你需要的形状。 最好给出SetStartPoint过程。并在该过程中
Notify组件重绘。 还有就是建议Override Paint. SetStartPoint可以用Invalidate.
好象没有TLine,这个类。
 
后退
顶部