TDBGrid的OnDrawDataCell事件中提供自己的绘制例程(自画功能)。
在这里将用到DBGrid的一个重要属性:画布Canvas,很多构件都有这一属性。Canvas代表了当前被显示DBGrid的表面,你如果把另行定义的显示内容和风格指定给DBGrid对象的Canvas,DBGrid对象会把Canvas属性值在屏幕上显示出来。具体应用时,涉及到Canvas的Brush属性和FillRect方法及TextOut方法。Brush属性规定了DBGrid.Canvas显示的图像、颜色、风格以及访问Windows GDI 对象句柄,FillRect方法使用当前Brush属性填充矩形区域,方法TextOut输出Canvas的文本内容。
以下用一个例子来详细地说明如何显示彩色的DBGrid。在例子中首先要有一个DBGrid构件,其次有一个用来产生彩色筛选条件的SpinEdit构件,另外还有ColorGrid构件供自由选择数据单元的前景和背景的颜色。
1.建立名为ColorDBGrid的Project,在其窗体Form1中依次放入所需构件,并设置属性为相应值,具体如下所列:
Table1 DatabaseName: DBDEMOS TableName: EMPLOYEE.DB Active: True;
DataSource1 DataSet: Table1
DBGrid1 DataSource1: DataSource1 DefaultDrawing: False SpinEdit1 Increment:200 Value: 20000
ColorGrid1 GridOrdering: go16*1
2.为DBGrid1构件OnDrawDataCell事件编写响应程序:
//这里编写的程序是<60的网格为红色的情况,其他的可以照此类推
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;Field: TField; State: TGridDrawState); begin
if Table1.Fieldbyname(′Salary′).value<=SpinEdit1.value then DBGrid1.Canvas.Brush.Color:=ColorGrid1.ForeGroundColor else
DBGrid1.Canvas.Brush.Color:=ColorGrid1.BackGroundColor; DBGrid1.Canvas.FillRect(Rect);
DBGrid1.Canvas.TextOut(Rect.left+2,Rect.top+2,Field.AsString); end;
这个过程的作用是当SpinEdit1给定的条件得以满足时,如′salary′变量低于或等于SpinEdit1.Value时,DBGrid1记录以ColorGrid1的前景颜色来显示,否则以ColorGrid1的背景颜色来显示。然后调用DBGrid的Canvas的填充过程FillRect和文本输出过程重新绘制DBGrid的画面。
3.为SpinEdit1构件的OnChange事件编写响应代码:
procedure TForm1.SpinEdit1Change(Sender: TObject); begin
DBGrid1.refresh; //刷新是必须的,一定要刷新哦 end;
当SpinEdit1构件的值有所改变时,重新刷新DBGrid1。
4.为ColorGrid1的OnChange事件编写响应代码:
procedure TForm1.ColorGrid1Change(Sender: TObject); begin
DBGrid1.refresh; //刷新是必须的,一定要刷新哦 end;
当ColorGrid1的值有所改变时,即鼠标的右键或左键单击ColorGrid1重新刷新DBGrid1。
5.为Form1窗体(主窗体)的OnCreate事件编写响应代码:
procedure TForm1.FormCreate(Sender: TObject); begin
ColorGrid1.ForeGroundIndex:=9; ColorGrid1.BackGroundIndex:=15; end;
在主窗创建时,将ColorGrid1的初值设定前景为灰色,背景为白色,也即DBGrid的字体颜色为灰色,背景颜色为白色。
6.现在,可以对ColorDBGrid程序进行编译和运行了。当用鼠标的左键或右键单击ColorGrid1时,DBGrid的字体和背景颜色将随之变化。
在本文中,只是简单展示了以彩色方式显示DBGrid的原理,当然,还可以增加程序的复杂性,使其实用化。同样道理,也可以将这个方法扩展到其他拥有Canvas属性的构件中,让应用程序的用户界面更加友好。
2003-11-17 14:58:08 判断Grid是否有滚动条?这是一个小技巧,如果为了风格的统一的话,还是不要用了。:) 。。。
if (GetWindowlong(Stringgrid1.Handle, GWL_STYLE) and WS_VSCROLL) <> 0 then ShowMessage('Vertical scrollbar is visible!');
if (GetWindowlong(Stringgrid1.Handle, GWL_STYLE) and WS_HSCROLL) <> 0 then ShowMessage('Horizontal scrollbar is visible!'); 。。。
2003-11-17 15:04:27 两个Grid的同步滚动 在实际制作一个项目当中,有时候需要几个grid一起同步滚动以减少用户的操作量。希望下面那段代码对您有一定的参考价值。 {1.}
unit SyncStringGrid;
interface uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs, Grids; type
TSyncKind = (skBoth, skVScroll, skHScroll); TSyncStringGrid = class(TStringGrid)
private
FInSync: Boolean;
FsyncGrid: TSyncStringGrid; FSyncKind: TSyncKind; { Private declarations }
procedure WMVScroll(var Msg: TMessage); message WM_VSCROLL; procedure WMHScroll(var Msg: TMessage); message WM_HSCROLL;
protected
{ Protected declarations }
public
{ Public declarations }
procedure DoSync(Msg, wParam: Integer; lParam: Longint); virtual;
published
{ Published declarations }
property SyncGrid: TSyncStringGrid read FSyncGrid write FSyncGrid;
property SyncKind: TSyncKind read FSyncKind write FSyncKind default skBoth; end;
procedure Register;
implementation
procedure Register; begin
RegisterComponents('Samples', [TSyncStringGrid]); end;
procedure TSyncStringGrid.WMVScroll(var Msg: TMessage); begin
if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skVScroll]) then FSyncGrid.DoSync(WM_VSCROLL, Msg.wParam, Msg.lParam); inherited; end;
procedure TSyncStringGrid.WMHScroll(var Msg: TMessage); begin
if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skHScroll]) then FSyncGrid.DoSync(WM_HSCROLL, Msg.wParam, Msg.lParam); inherited; end;
procedure TSyncStringGrid.DoSync(Msg, wParam: Integer; lParam: Longint); begin
FInSync := True;
Perform(Msg, wParam, lParam); FinSync := False; end; end.
{****************************************} {2.} private
OldGridProc1, OldGridProc2: TWndMethod;
procedure Grid1WindowProc(var Message: TMessage); procedure Grid2WindowProc(var Message: TMessage);
public {...}
procedure TForm1.Grid1WindowProc(var Message: TMessage);
begin
OldGridProc1(Message);
if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or Message.msg = WM_Mousewheel)) then begin
OldGridProc2(Message); end; end;
procedure TForm1.Grid2WindowProc(var Message: TMessage); begin
OldGridProc2(Message);
if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or (Message.msg = WM_Mousewheel)) then begin
OldGridProc1(Message); end; end;
procedure TForm1.FormCreate(Sender: TObject); begin
OldGridProc1 := StringGrid1.WindowProc; OldGridProc2 := StringGrid2.WindowProc; StringGrid1.WindowProc := Grid1WindowProc; StringGrid2.WindowProc := Grid2WindowProc; end;
2003-11-19 9:35:04 在Delphi中随意控制DBGrid 每一行的颜色简易方法 Delphi中使用 DBGrid 控件时,每一列都能按需要随意地改变颜色,但要改变每一行的颜色却很难,那么在不重新制作新控制件的情况下,有没有好的办法让DBGrid按照用户自己要求随意改变每一行颜色的?答案是有,下面介绍一种简单的方法。
要改变DBGrid每一行的颜色,只要在ONDrawColumnCell事件中设定要改变颜色的行的条件,
并指定DBGrid的Canvas.Brush.color属性并且把Canvas.pen.mode属性设成pmmask,再调用DBGrid 的DefaultDrawColumnCell方法即可。注意在改变这两个属性前要先保护好原来的
Canvas.Brush.color 属性的值,调节器用完成 DefaultDrawColumnCell 方法后要把原属性值改
回,现以 Delphi\\demos\\db\\clientmd 目录下的演示程序 clintproj.dpr 为例子,做简单说