话题0915735的标题是: 试着做了个控件,帮我看看 分类:控件-开发 Dk108 (2002-2-8 14:15:00) 刚做了个控件,想在DrawGrid的每一行的第一列加上一个CheckBox,但是编译以后每次添加 到一个Form上,在DrawGrid上都有闪烁,而且运行也看不到CheckBox,那位高手能帮我看看是什么 原因! unit XzlDrawGrid;interfaceuses windows,SysUtils,Classes,Grids,Graphics,Messages,Controls,StdCtrls,Forms; type TXzlDrawGrid=class(TDrawGrid) private fcolor:TColor; procedure setcolor(const value:TColor); public CheckBox:Array[1..100]of TCheckBox; constructor Create(AOwner:TComponent);override; destructor Destroy;override; procedure DrawCell(ACol,ARow:LongInt;ARect:TRect;AState:TGridDrawState);override; published property mycolor:TColor read fcolor write setcolor; end;procedure Register; implementationprocedure Register; begin RegisterComponents('Samples',[TXzlDrawGrid]); end;constructor TXzlDrawGrid.Create(AOwner:TComponent); var i:integer; begin inherited Create(AOwner); FColor := clBtnFace; for i:=1 to col do CheckBox[i]:=TCheckBox.create(Self); end;destructor TXzlDrawGrid.Destroy; begin inherited; end;procedure TXzlDrawGrid.setcolor(const value:TColor); begin Fcolor:=value; refresh; end;procedure TXzlDrawGrid.DrawCell(ACol,ARow:LongInt;ARect:TRect;AState:TGridDrawState); begin if (ACol=1)and(ARow<>0) then begin CheckBox[ACol].Parent:=Self; CheckBox[ACol].Left:=ARect.Left; CheckBox[ACol].Top:=ARect.Top; CheckBox[ACol].Height:=ARect.Bottom-ARect.Top; CheckBox[ACol].Show; end; inherited; end; end.
taozhiyu (2002-2-8 14:18:00) 你create的东西不用free的么?
tseug (2002-2-8 14:18:00) constructor TXzlDrawGrid.Create(AOwner:TComponent); var i:integer; begin inherited Create(AOwner); FColor := clBtnFace; for i:=1 to col do begin CheckBox[i]:=TCheckBox.create(Self); CheckBox[i].Parent := Self end; end
minikiller (2002-2-8 14:36:00) up
Dk108 (2002-2-8 14:41:00) to taozhiyu: 但是我要用到checkbox,怎么能free了呢?to tseug: Checkbox[i].parent我在DrawCell中附值了呀:)
Dk108 (2002-2-8 14:49:00) to tseug: 我试了一下,把checkbox[i].parent加在create里面后,控件出错,可能是self还没有 创建的原因吧,你试过吗?可以吗?有没有源码?
tseug (2002-2-8 15:55:00) 正在看,晚上告诉你。
LargeWang (2002-2-8 17:46:00) 想给你改也不行啊,我放假了
balaschen (2002-2-8 19:35:00) 你的控件存在以下问题: 1、CheckBox没有Free; 2、你在DrawCell中实际上只用到一个CheckBox,而你一下子定义了100个CheckBox, 简直是资源杀手; 3、你的处理思路根本性就是错误的,由于你都是用到同一个CheckBox来显示,所以当你的 显示下一行的时候CheckBox就相应的往下移动,这就是为什么在你要显示CheckBox的那一列 一直闪烁的原因。不改变你处理方式的话只能是每行用一个CheckBox,这将极大的浪费资源 你把if (ACol=1)and(ARow<>0) then改成if (ACol=1)and(ARow=1) then或者 改成: if (ACol=1)and(ARow<>0) then begin CheckBox[ARow].Parent:=Self; CheckBox[ARow].Left:=ARect.Left; CheckBox[ARow].Top:=ARect.Top; CheckBox[ARow].Height:=ARect.Bottom-ARect.Top; CheckBox[ARow].Show; end else inherited;再看看,但这不是解决之道,正确的方法是在DrawCell方法中自己画CheckBox,可以画 CheckBox样子的图片或利用DrawFrameControl函数来显示。
tseug (2002-2-8 19:52:00) 大概改了一下,你看看吧 unit abc;interfaceuses windows,SysUtils,Classes,Grids,Graphics,Messages,Controls,StdCtrls,Forms; type TXzlDrawGrid=class(TDrawGrid) private fcolor:TColor; procedure setcolor(const value:TColor); public CheckBox:Array[1..100]of TCheckBox; constructor Create(AOwner:TComponent);override; destructor Destroy;override; published property mycolor:TColor read fcolor write setcolor; end;procedure Register; implementationprocedure Register; begin RegisterComponents('Samples',[TXzlDrawGrid]); end;constructor TXzlDrawGrid.Create(AOwner:TComponent); var I : Integer; Rect : TRect; begin inherited Create(AOwner); Parent := TWinControl(AOWner); FColor := clBtnFace; for I := 1 to RowCount do begin Rect := CellRect(1, I); CheckBox[I]:=TCheckBox.Create(Self); with CheckBox[I] do begin Name := Format('CheckBox%d', [I]); Parent := Self; Left := Rect.Left; Top := Rect.Top; Width := Rect.Right - Rect.Left; Height := Rect.Bottom - Rect.Top; end; end; end;destructor TXzlDrawGrid.Destroy; var i : Integer; begin for i := 1 to col do begin CheckBox[i].Free; end; inherited; end;procedure TXzlDrawGrid.setcolor(const value:TColor); begin Fcolor:=value; refresh; end;end.
TStringGrid(DBGrid1).Options:=[goFixedVertLine,goFixedHorzLine,goVertLine,goHorzLine];这次总没问题了吧。
分类:控件-开发 Dk108 (2002-2-8 14:15:00)
刚做了个控件,想在DrawGrid的每一行的第一列加上一个CheckBox,但是编译以后每次添加
到一个Form上,在DrawGrid上都有闪烁,而且运行也看不到CheckBox,那位高手能帮我看看是什么
原因!
unit XzlDrawGrid;interfaceuses
windows,SysUtils,Classes,Grids,Graphics,Messages,Controls,StdCtrls,Forms;
type
TXzlDrawGrid=class(TDrawGrid)
private
fcolor:TColor;
procedure setcolor(const value:TColor);
public
CheckBox:Array[1..100]of TCheckBox;
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
procedure DrawCell(ACol,ARow:LongInt;ARect:TRect;AState:TGridDrawState);override;
published
property mycolor:TColor read fcolor write setcolor; end;procedure Register;
implementationprocedure Register;
begin
RegisterComponents('Samples',[TXzlDrawGrid]);
end;constructor TXzlDrawGrid.Create(AOwner:TComponent);
var
i:integer;
begin
inherited Create(AOwner);
FColor := clBtnFace;
for i:=1 to col do
CheckBox[i]:=TCheckBox.create(Self);
end;destructor TXzlDrawGrid.Destroy;
begin
inherited;
end;procedure TXzlDrawGrid.setcolor(const value:TColor);
begin
Fcolor:=value;
refresh;
end;procedure TXzlDrawGrid.DrawCell(ACol,ARow:LongInt;ARect:TRect;AState:TGridDrawState);
begin
if (ACol=1)and(ARow<>0) then
begin
CheckBox[ACol].Parent:=Self;
CheckBox[ACol].Left:=ARect.Left;
CheckBox[ACol].Top:=ARect.Top;
CheckBox[ACol].Height:=ARect.Bottom-ARect.Top;
CheckBox[ACol].Show;
end;
inherited;
end;
end.
taozhiyu (2002-2-8 14:18:00)
你create的东西不用free的么?
tseug (2002-2-8 14:18:00)
constructor TXzlDrawGrid.Create(AOwner:TComponent);
var
i:integer;
begin
inherited Create(AOwner);
FColor := clBtnFace;
for i:=1 to col do
begin
CheckBox[i]:=TCheckBox.create(Self);
CheckBox[i].Parent := Self
end;
end
minikiller (2002-2-8 14:36:00)
up
Dk108 (2002-2-8 14:41:00)
to taozhiyu:
但是我要用到checkbox,怎么能free了呢?to tseug:
Checkbox[i].parent我在DrawCell中附值了呀:)
tseug (2002-2-8 14:46:00)
我觉得在那里是有问题的。[:(],你试试吧,我这样做过没甚么问题。
Dk108 (2002-2-8 14:49:00)
to tseug:
我试了一下,把checkbox[i].parent加在create里面后,控件出错,可能是self还没有
创建的原因吧,你试过吗?可以吗?有没有源码?
tseug (2002-2-8 15:55:00)
正在看,晚上告诉你。
LargeWang (2002-2-8 17:46:00)
想给你改也不行啊,我放假了
balaschen (2002-2-8 19:35:00)
你的控件存在以下问题:
1、CheckBox没有Free;
2、你在DrawCell中实际上只用到一个CheckBox,而你一下子定义了100个CheckBox,
简直是资源杀手;
3、你的处理思路根本性就是错误的,由于你都是用到同一个CheckBox来显示,所以当你的
显示下一行的时候CheckBox就相应的往下移动,这就是为什么在你要显示CheckBox的那一列
一直闪烁的原因。不改变你处理方式的话只能是每行用一个CheckBox,这将极大的浪费资源
你把if (ACol=1)and(ARow<>0) then改成if (ACol=1)and(ARow=1) then或者
改成:
if (ACol=1)and(ARow<>0) then
begin
CheckBox[ARow].Parent:=Self;
CheckBox[ARow].Left:=ARect.Left;
CheckBox[ARow].Top:=ARect.Top;
CheckBox[ARow].Height:=ARect.Bottom-ARect.Top;
CheckBox[ARow].Show;
end
else
inherited;再看看,但这不是解决之道,正确的方法是在DrawCell方法中自己画CheckBox,可以画
CheckBox样子的图片或利用DrawFrameControl函数来显示。
tseug (2002-2-8 19:52:00)
大概改了一下,你看看吧
unit abc;interfaceuses
windows,SysUtils,Classes,Grids,Graphics,Messages,Controls,StdCtrls,Forms;
type
TXzlDrawGrid=class(TDrawGrid)
private
fcolor:TColor;
procedure setcolor(const value:TColor);
public
CheckBox:Array[1..100]of TCheckBox;
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
published
property mycolor:TColor read fcolor write setcolor; end;procedure Register;
implementationprocedure Register;
begin
RegisterComponents('Samples',[TXzlDrawGrid]);
end;constructor TXzlDrawGrid.Create(AOwner:TComponent);
var
I : Integer;
Rect : TRect;
begin
inherited Create(AOwner);
Parent := TWinControl(AOWner);
FColor := clBtnFace; for I := 1 to RowCount do
begin
Rect := CellRect(1, I);
CheckBox[I]:=TCheckBox.Create(Self);
with CheckBox[I] do
begin
Name := Format('CheckBox%d', [I]);
Parent := Self;
Left := Rect.Left;
Top := Rect.Top;
Width := Rect.Right - Rect.Left;
Height := Rect.Bottom - Rect.Top;
end;
end;
end;destructor TXzlDrawGrid.Destroy;
var
i : Integer;
begin
for i := 1 to col do
begin
CheckBox[i].Free;
end;
inherited;
end;procedure TXzlDrawGrid.setcolor(const value:TColor);
begin
Fcolor:=value;
refresh;
end;end.
zj_94yy (2002-2-8 19:55:00)
我觉得你可以自己画一个CheckBox,没有必要用CheckBox控件
liu_liu (2002-2-9 12:50:00)
同意balaschen,可以在DBGrid的OnDBGrid1DrawDataCell事件中获得位置来显示CheckBox如果是做控件的话,应该在DBGrid1DrawDataCell事件中进行控制
Dk108 (2002-2-13 17:29:00)
to tseug:我用你的方法试了,还是一样的闪烁不停to zh96yy:自己画一个CheckBox?怎么做?能详细点吗?谢谢 :)
我想把这一段代码改为花panel, 怎么做
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var P: TPanel;
begin
if Column.Title.caption='1' then
begin
P:=TPanel.Create(DBGrid1);
P.Left:=Rect.Left;
P.Top:=Rect.Top;
P.Width:=Rect.Right-Rect.Left;
P.Height:=Rect.Bottom-Rect.Top;
end;
end;
Panel[i].Left:=Rect.Left;
Panel[i].Top:=Rect.Top;
unit wfpDrawGrid;interfaceuses
Windows, Messages, SysUtils, Classes, Controls, Grids, QGraphics;type
TwfpDrawGrid = class(TDrawGrid)
private
FbCheck: Boolean; protected
procedure DrawCell(ACol, ARow: Longint; ARect: TRect;
AState: TGridDrawState); override;
procedure DrawCheck(ARect: TRect);
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
public
constructor Create(AOwner: TComponent); override;
{ Public declarations }
published
{ Published declarations }
end;procedure Register;implementationprocedure Register;
begin
RegisterComponents('Samples', [TwfpDrawGrid]);
end;{ TwfpDrawGrid }constructor TwfpDrawGrid.Create(AOwner: TComponent);
begin
inherited;
FbCheck := True;
end;procedure TwfpDrawGrid.DrawCell(ACol, ARow: Integer; ARect: TRect;
AState: TGridDrawState);
begin
if (ARow = 1) and (ACol = 1) then begin
DrawCheck(ARect);
end
else
inherited;
end;procedure TwfpDrawGrid.DrawCheck(ARect: TRect);
var
iCheckWidth: Integer;
iWidth, iHeight: Integer;
iTop, iLeft: Integer;
rctCheck: TRect;
clSave: TColor;
begin
iWidth := ARect.Right - ARect.Left;
iHeight := ARect.Bottom - ARect.Top;
if iWidth > iHeight then begin
iCheckWidth := iHeight;
end
else
iCheckWidth := iWidth;
if iCheckWidth > 16 then begin
iCheckWidth := 16;
end;
iTop := ARect.Top + (iHeight - iCheckWidth) shr 1;
iLeft := ARect.Left + (iWidth - iCheckWidth) shr 1;
rctCheck := Rect(iLeft, iTop, iLeft + iCheckWidth, iTop + iCheckWidth); clSave := Canvas.Pen.Color;
Canvas.Pen.Color := clBlack;
//画边框
Canvas.Rectangle(rctCheck);
if FbCheck then begin
//画勾
Canvas.Pen.Width := 2;
Canvas.MoveTo(iLeft + 2, iTop + (iCheckWidth shr 1) - 3);
Canvas.LineTo(iLeft + (iCheckWidth shr 1) - 3, rctCheck.Bottom - 2);
Canvas.LineTo(rctCheck.Right - 2, iTop + 2);
Canvas.Pen.Width := 1;
end;
Canvas.Pen.Color := clSave;
end;procedure TwfpDrawGrid.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
var
pCellHit: TGridCoord;
begin
//计算点击的格子位置
pCellHit := MouseCoord(X, Y);
if (pCellHit.X = 1) and (pCellHit.Y = 1) then begin
FbCheck := not FbCheck;
InvalidateCell(pCellHit.Y, pCellHit.X);
end;
inherited;
end;end.
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var R: TRect;
begin
if Column.Index=0 then
begin
R:=Rect;
R.Left:=R.Left;
R.Top:=R.Top;
R.Right:=R.Right;
R.Bottom:=R.Bottom;
DBGrid1.Canvas.Brush.Color:=clBtnFace;
DBGrid1.Canvas.FillRect(R);
DBGrid1.Canvas.Pen.Color:=clWhite;
DBGrid1.Canvas.MoveTo(R.Left,R.Bottom-1);
DBGrid1.Canvas.LineTo(R.Left,R.Top);
DBGrid1.Canvas.LineTo(R.Right-1,R.Top);
DBGrid1.Canvas.Pen.Color:=clGray;
DBGrid1.Canvas.MoveTo(R.Left,R.Bottom-1);
DBGrid1.Canvas.LineTo(R.Right-1,R.Bottom-1);
DBGrid1.Canvas.LineTo(R.Right-1,R.Top);
DBGrid1.Canvas.Pen.Color:=clBlack;
DBGrid1.Canvas.MoveTo(R.Left-1,R.Bottom);
DBGrid1.Canvas.LineTo(R.Left-1,R.Top-1);
DBGrid1.Canvas.LineTo(R.Right,R.Top-1);
DBGrid1.Canvas.LineTo(R.Right,R.Bottom);
DBGrid1.Canvas.LineTo(R.Left-1,R.Bottom);
DBGrid1.Canvas.TextOut(R.Left+10,R.Top+2,DBGrid1.DataSource.DataSet.FieldByName(Column.FieldName).asString);
end;
end;