我在做一个自定义组件,到处是错误?
我还是照着书上来的!
那位高手,帮我看看!
unit MyButton;interfaceuses
SysUtils, Classes, Controls, StdCtrls,Graphics,Messages,Types;type
TMyButton = class(TButton)
private
FColor:TColor;
FCanvas:TCanvas;
IsFocused:Boolean;
SetColor:TColor;
procedure CNDrawItem(var CMessage: TWMDrawItem); message WM_DRAWITEM;
{ Private declarations }
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure SetButton(var ADefault:Boolean);
{ Protected declarations }
public
procedure Create(AOwner:TComponent);override;
procedure Destroy;override;
{ Public declarations }
published
property Color:TColor read FColor write SetColor default clWhite;
{ Published declarations }
end;procedure Register;implementation
procedure CNDrawItem(var CMessage: TWMDrawItem); message WM_DRAWITEM;
var
IsDown, IsDefault: Boolean;
ARect: TRect;
Flags: Longint;
DrawItemStruct: TDrawItemStruct;
wh:TSize;
begin
DrawItemStruct:=CMessage.DrawItemStruct^;
FCanvas.Handle := DrawItemStruct.hDC;
ARect := ClientRect;
with DrawItemStruct do
begin
IsDown := itemState and ODS_SELECTED <> 0;
IsDefault := itemState and ODS_FOCUS <> 0;
end; Flags := DFCS_BUTTONPUSH or DFCS_ADJUSTRECT;
if IsDown then Flags := Flags or DFCS_PUSHED;
if DrawItemStruct.itemState and ODS_DISABLED <> 0 then
Flags := Flags or DFCS_INACTIVE; if IsFocused or IsDefault then
begin
//按钮得到焦点时的状态绘制
FCanvas.Pen.Color := clWindowFrame;
FCanvas.Pen.Width := 1;
FCanvas.Brush.Style := bsClear;
FCanvas.Rectangle(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
InflateRect(ARect, -1, -1);
end; FCanvas.Pen.Color := clBtnShadow;
FCanvas.Pen.Width := 1;
FCanvas.Brush.Color := FColor;
if IsDown then begin
//按钮被按下时的状态绘制
FCanvas.Rectangle(ARect.Left , ARect.Top, ARect.Right, ARect.Bottom);
InflateRect(ARect, -1, -1);
end else
//绘制一个未按下的按钮
DrawFrameControl(DrawItemStruct.hDC, ARect, DFC_BUTTON, Flags);
FCanvas.FillRect(ARect); //绘制Caption文本内容
FCanvas.Font := Self.Font;
ARect:=ClientRect;
wh:=FCanvas.TextExtent(Caption);
FCanvas.Pen.Width := 1;
FCanvas.Brush.Style := bsClear;
if not Enabled then
begin //按钮失效时应多绘一次Caption文本
FCanvas.Font.Color := clBtnHighlight;
FCanvas.TextOut((Width div 2)-(wh.cx div 2)+1,
(height div 2)-(wh.cy div 2)+1,
Caption);
FCanvas.Font.Color := clBtnShadow;
end;
FCanvas.TextOut((Width div 2)-(wh.cx div 2),(height div 2)-(wh.cy div 2),Caption); //绘制得到焦点时的内框虚线
if IsFocused and IsDefault then
begin
ARect := ClientRect;
InflateRect(ARect, -4, -4);
FCanvas.Pen.Color := clWindowFrame;
FCanvas.Brush.Color := FColor;
DrawFocusRect(FCanvas.Handle, ARect);
end;
FCanvas.Handle := 0;end;
procedure SetButton(var ADefault:Boolean);
begin
if ADefault <> IsFocused then
begin
IsFocused := ADefault;
Refresh;
end;
end;
procedure CreateParams(var Params:TCreateParams);override;
begin
with Params do
Style=Style or BS_OWNERDRAW;
end;
procedure Create(AOwner:TComponent);override;
begin
inherited;
FCanvas:=TCanvas.Create;
end;
procedure Destroy;override;
begin
FCanvas.Free;
inherited;
end;
procedure Register;
begin
RegisterComponents('MyLib', [TMyButton]);
end;end.
我还是照着书上来的!
那位高手,帮我看看!
unit MyButton;interfaceuses
SysUtils, Classes, Controls, StdCtrls,Graphics,Messages,Types;type
TMyButton = class(TButton)
private
FColor:TColor;
FCanvas:TCanvas;
IsFocused:Boolean;
SetColor:TColor;
procedure CNDrawItem(var CMessage: TWMDrawItem); message WM_DRAWITEM;
{ Private declarations }
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure SetButton(var ADefault:Boolean);
{ Protected declarations }
public
procedure Create(AOwner:TComponent);override;
procedure Destroy;override;
{ Public declarations }
published
property Color:TColor read FColor write SetColor default clWhite;
{ Published declarations }
end;procedure Register;implementation
procedure CNDrawItem(var CMessage: TWMDrawItem); message WM_DRAWITEM;
var
IsDown, IsDefault: Boolean;
ARect: TRect;
Flags: Longint;
DrawItemStruct: TDrawItemStruct;
wh:TSize;
begin
DrawItemStruct:=CMessage.DrawItemStruct^;
FCanvas.Handle := DrawItemStruct.hDC;
ARect := ClientRect;
with DrawItemStruct do
begin
IsDown := itemState and ODS_SELECTED <> 0;
IsDefault := itemState and ODS_FOCUS <> 0;
end; Flags := DFCS_BUTTONPUSH or DFCS_ADJUSTRECT;
if IsDown then Flags := Flags or DFCS_PUSHED;
if DrawItemStruct.itemState and ODS_DISABLED <> 0 then
Flags := Flags or DFCS_INACTIVE; if IsFocused or IsDefault then
begin
//按钮得到焦点时的状态绘制
FCanvas.Pen.Color := clWindowFrame;
FCanvas.Pen.Width := 1;
FCanvas.Brush.Style := bsClear;
FCanvas.Rectangle(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
InflateRect(ARect, -1, -1);
end; FCanvas.Pen.Color := clBtnShadow;
FCanvas.Pen.Width := 1;
FCanvas.Brush.Color := FColor;
if IsDown then begin
//按钮被按下时的状态绘制
FCanvas.Rectangle(ARect.Left , ARect.Top, ARect.Right, ARect.Bottom);
InflateRect(ARect, -1, -1);
end else
//绘制一个未按下的按钮
DrawFrameControl(DrawItemStruct.hDC, ARect, DFC_BUTTON, Flags);
FCanvas.FillRect(ARect); //绘制Caption文本内容
FCanvas.Font := Self.Font;
ARect:=ClientRect;
wh:=FCanvas.TextExtent(Caption);
FCanvas.Pen.Width := 1;
FCanvas.Brush.Style := bsClear;
if not Enabled then
begin //按钮失效时应多绘一次Caption文本
FCanvas.Font.Color := clBtnHighlight;
FCanvas.TextOut((Width div 2)-(wh.cx div 2)+1,
(height div 2)-(wh.cy div 2)+1,
Caption);
FCanvas.Font.Color := clBtnShadow;
end;
FCanvas.TextOut((Width div 2)-(wh.cx div 2),(height div 2)-(wh.cy div 2),Caption); //绘制得到焦点时的内框虚线
if IsFocused and IsDefault then
begin
ARect := ClientRect;
InflateRect(ARect, -4, -4);
FCanvas.Pen.Color := clWindowFrame;
FCanvas.Brush.Color := FColor;
DrawFocusRect(FCanvas.Handle, ARect);
end;
FCanvas.Handle := 0;end;
procedure SetButton(var ADefault:Boolean);
begin
if ADefault <> IsFocused then
begin
IsFocused := ADefault;
Refresh;
end;
end;
procedure CreateParams(var Params:TCreateParams);override;
begin
with Params do
Style=Style or BS_OWNERDRAW;
end;
procedure Create(AOwner:TComponent);override;
begin
inherited;
FCanvas:=TCanvas.Create;
end;
procedure Destroy;override;
begin
FCanvas.Free;
inherited;
end;
procedure Register;
begin
RegisterComponents('MyLib', [TMyButton]);
end;end.
解决方案 »
- 部分计算机书籍转让(主要为Delphi和软考类,限深圳地区)
- FastReport的问题,frReport1.showreport闪一下就没咯,怎么回事。没有生成预览啊
- 我想做一个圆柱体,在上面精确的并列贴上一组图片,请问大家有无思路。
- 100分:如何在fastreport中某个memo中显示当前窗体中某个EDIT的TEXT?
- Delphi的函数在编译时是否能实现VC中Inline的效果?
- MDI应用程
- 图层信息的纪录问题!
- 请各位在职的程序员大哥指点一下方向
- 那位高手知道net send 在internet中是如何实现的?
- 关于FLASH控件问题
- 一个DELPHI的内嵌汇编的奇怪问题.....
- 如何实现客户端与服器之间数据的传输
前面的几个错为:
public
procedure Create(AOwner:TComponent);override; //1
procedure Destroy;override; //2
1. 你的控件基于TButton,它的Create定义为构造函数,所以要定义为:
constructor Create(AOwner:TComponent);override;
2.同理:
destructor Destroy;override;
implementation
procedure CNDrawItem(var CMessage: TWMDrawItem); message WM_DRAWITEM; //3
3.CNDrawItem是你类中的函数.所以要写成
procedure TMyButton.CNDrawItem(var CMessage: TWMDrawItem);
另外,message WM_DRAWITEM;是函数申明时用,实现(定义)时不能有
DrawItemStruct: TDrawItemStruct;
你的TDrawItemStruct在哪里定义的?
...
但是它提示:
IsDown := (itemState) and (ODS_SELECTED <> 0);
IsDefault := (itemState) and (ODS_FOCUS <> 0);
这个句出错.
提示:"Operator not applicable to this Operand type."
建议去看看windows程序设计.
system error. code:87
参数错误.怎回事?
unit MyButton;interfaceuses
SysUtils, Classes, Controls, StdCtrls,Graphics,Messages,Types,WINDOWS;type
TMyButton = class(TButton)
private
FColor:TColor;
FCanvas:TCanvas;
IsFocused:Boolean;
SetColor:TColor;
procedure CNDrawItem(var CMessage: TWMDrawItem); message WM_DRAWITEM;
{ Private declarations }
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure SetButton(var ADefault:Boolean);
{ Protected declarations }
public
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
{ Public declarations }
published
property Color:TColor read FColor write SetColor default clWhite;
{ Published declarations }
end;procedure Register;implementation
procedure TMyButton.CNDrawItem(var CMessage: TWMDrawItem); // message WM_DRAWITEM;
var
IsDown, IsDefault: Boolean;
ARect: TRect;
Flags: Longint;
DrawItemStruct: TDrawItemStruct;
wh:TSize;
begin
DrawItemStruct:=CMessage.DrawItemStruct^;
FCanvas.Handle := DrawItemStruct.hDC;
ARect := ClientRect;
with DrawItemStruct do
begin
IsDown := itemState and ODS_SELECTED <> 0;
IsDefault := itemState and ODS_FOCUS <> 0;
end; Flags := DFCS_BUTTONPUSH or DFCS_ADJUSTRECT;
if IsDown then Flags := Flags or DFCS_PUSHED;
if DrawItemStruct.itemState and ODS_DISABLED <> 0 then
Flags := Flags or DFCS_INACTIVE; if IsFocused or IsDefault then
begin
//按钮得到焦点时的状态绘制
FCanvas.Pen.Color := clWindowFrame;
FCanvas.Pen.Width := 1;
FCanvas.Brush.Style := bsClear;
FCanvas.Rectangle(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
InflateRect(ARect, -1, -1);
end; FCanvas.Pen.Color := clBtnShadow;
FCanvas.Pen.Width := 1;
FCanvas.Brush.Color := FColor;
if IsDown then begin
//按钮被按下时的状态绘制
FCanvas.Rectangle(ARect.Left , ARect.Top, ARect.Right, ARect.Bottom);
InflateRect(ARect, -1, -1);
end else
//绘制一个未按下的按钮
DrawFrameControl(DrawItemStruct.hDC, ARect, DFC_BUTTON, Flags);
FCanvas.FillRect(ARect); //绘制Caption文本内容
FCanvas.Font := Self.Font;
ARect:=ClientRect;
wh:=FCanvas.TextExtent(Caption);
FCanvas.Pen.Width := 1;
FCanvas.Brush.Style := bsClear;
if not Enabled then
begin //按钮失效时应多绘一次Caption文本
FCanvas.Font.Color := clBtnHighlight;
FCanvas.TextOut((Width div 2)-(wh.cx div 2)+1,
(height div 2)-(wh.cy div 2)+1,
Caption);
FCanvas.Font.Color := clBtnShadow;
end;
FCanvas.TextOut((Width div 2)-(wh.cx div 2),(height div 2)-(wh.cy div 2),Caption); //绘制得到焦点时的内框虚线
if IsFocused and IsDefault then
begin
ARect := ClientRect;
InflateRect(ARect, -4, -4);
FCanvas.Pen.Color := clWindowFrame;
FCanvas.Brush.Color := FColor;
DrawFocusRect(FCanvas.Handle, ARect);
end;
FCanvas.Handle := 0;end;
procedure TMyButton.SetButton(var ADefault:Boolean);
begin
if ADefault <> IsFocused then
begin
IsFocused := ADefault;
Refresh;
end;
end;
procedure TMyButton.CreateParams(var Params:TCreateParams);
begin
inherited CreateParams(Params);
with Params.WindowClass do
Style:=Style or BS_OWNERDRAW;
end;
constructor TMyButton.Create(AOwner:TComponent);
begin
inherited;
FCanvas:=TCanvas.Create;
end;
destructor TMyButton.Destroy;
begin
FCanvas.Free;
inherited;
end;
procedure Register;
begin
RegisterComponents('MyLib', [TMyButton]);
end;end.
我编译完成了,并已安装了.只是在使用时出错,我新建一个工程,当我把这个控件放到FORM中时出错:
system error. code:87
参数错误.怎回事?
最好将以期的代码改名备份重新编译
参考下面改进后的代码:unit MyButton;interfaceuses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls, Graphics;type
TMyButton = class(TButton)
private
FCanvas: TCanvas;
IsFocused: Boolean;
procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM; // 换成CN_DRAWITE不是WM_DRAWITE
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure SetButtonStyle(ADefault: Boolean); override; // 这条必须加,才能触发CN_DRAWITEM
public
constructor Create(AOwner: TComponent);override;
destructor Destroy; override;
published
property Color default clWhite; // Color在父类中已经有声明
end;procedure Register;implementationprocedure Register;
begin
RegisterComponents('MyLib', [TMyButton]);
end;procedure TMyButton.CNDrawItem(var Message: TWMDrawItem);
var
IsDown, IsDefault: Boolean;
ARect: TRect;
Flags: Longint;
DrawItemStruct: TDrawItemStruct;
wh: TSize;
begin
DrawItemStruct := Message.DrawItemStruct^;
FCanvas.Handle := DrawItemStruct.hDC;
ARect := ClientRect;
with DrawItemStruct do
begin
IsDown := itemState and ODS_SELECTED <> 0;
IsDefault := itemState and ODS_FOCUS <> 0;
end; Flags := DFCS_BUTTONPUSH or DFCS_ADJUSTRECT;
if IsDown then Flags := Flags or DFCS_PUSHED;
if DrawItemStruct.itemState and ODS_DISABLED <> 0 then
Flags := Flags or DFCS_INACTIVE; if IsFocused or IsDefault then
begin
//按钮得到焦点时的状态绘制
FCanvas.Pen.Color := clWindowFrame;
FCanvas.Pen.Width := 1;
FCanvas.Brush.Style := bsClear;
FCanvas.Rectangle(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
InflateRect(ARect, -1, -1);
end; FCanvas.Pen.Color := clBtnShadow;
FCanvas.Pen.Width := 1;
FCanvas.Brush.Color := Color;
if IsDown then
begin
//按钮被按下时的状态绘制
FCanvas.Rectangle(ARect.Left , ARect.Top, ARect.Right, ARect.Bottom);
InflateRect(ARect, -1, -1);
end else
//绘制一个未按下的按钮
DrawFrameControl(DrawItemStruct.hDC, ARect, DFC_BUTTON, Flags);
FCanvas.FillRect(ARect); //绘制Caption文本内容
FCanvas.Font.Assign(Font);
ARect := ClientRect;
wh := FCanvas.TextExtent(Caption);
FCanvas.Pen.Width := 1;
FCanvas.Brush.Style := bsClear;
if not Enabled then
begin //按钮失效时应多绘一次Caption文本
FCanvas.Font.Color := clBtnHighlight;
FCanvas.TextOut((Width div 2) - (wh.cx div 2) + 1,
(Height div 2) - (wh.cy div 2) + 1, Caption);
FCanvas.Font.Color := clBtnShadow;
end;
FCanvas.TextOut((Width div 2) - (wh.cx div 2),
(Height div 2) - (wh.cy div 2), Caption); //绘制得到焦点时的内框虚线
if IsFocused and IsDefault then
begin
ARect := ClientRect;
InflateRect(ARect, -4, -4);
FCanvas.Pen.Color := clWindowFrame;
FCanvas.Brush.Color := Color;
DrawFocusRect(FCanvas.Handle, ARect);
end;
FCanvas.Handle := 0;
end;procedure TMyButton.SetButtonStyle(ADefault: Boolean);
begin
if ADefault <> IsFocused then
begin
IsFocused := ADefault;
Refresh;
end;
end;procedure TMyButton.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do Style := Style or BS_OWNERDRAW; // 不是Params.WindowClass
end;constructor TMyButton.Create(AOwner: TComponent);
begin
inherited;
FCanvas := TCanvas.Create;
Color := clWhite; // 默认值需要在Create中设置
end;destructor TMyButton.Destroy;
begin
FCanvas.Free;
inherited;
end;end.
begin
inherited CreateParams(Params);
with Params.WindowClass do
Style:=Style or BS_OWNERDRAW;
end;另外,按zswang(伴水清清)(专家门诊清洁工)所说,重新编译
procedure SetButtonStyle(ADefault: Boolean); override;提示:Declaration of 'setbuttonstyle' differs from previous declaration.
是不是说定义出父类的不一样?
如果你用zswang(伴水清清)(专家门诊清洁工)的程序,头上和下面的SetButtonStyle都要改
不过有几个问题不明白:
1、procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM; // 换成CN_DRAWITEM不是WM_DRAWITE 为什么要换成CN_DRAWITEM ,WINDOWS消息不是WM_DRAWITEM,怎么变成CN_DRAWITEM。
2、 SetButtonStyle(ADefault: Boolean); 函数既然是父类的函数,在我DELPHI的帮助中TBUTTON类里找不到SetButtonStyle 这个函数?
看TBitBtn怎么封装就怎么封装,VCL是开源的
你学自定义组建最好的学习对象就是VCL的源代码2、
TButton = class(TButtonControl)
private
//。
protected
//。
procedure SetButtonStyle(ADefault: Boolean); virtual;
//。
end;
我要知道它为什么这样.
还有既然有CN_DRAWITEM,那有没有CN_LBUTTON等呢?