Grid_自绘
ZC: 测试使用的控件是 Delphi7版本的 TAdvStringGrid(第3方控件)
“DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);” 先绘制,
“CustomCellDraw(Sender: TObject; Canvas: TCanvas; ACol, ARow: Integer; AState: TGridDrawState; ARect: TRect; Printing: Boolean);” 后绘制。
于是 CustomCellDraw()中绘制的内容,位于DrawCell()绘制内容的上层
1、http://bbs.csdn.net/topics/350106894
ZC: 主要是 CustomCellDraw()
2、StringGrid 中单元格的内容,是默认 左对齐的,无法设置属性使之 水平中间对齐,只能在 DrawCell()中自己绘制单元格内容。参考网址:
http://blog.sina.com.cn/s/blog_54da9cc00101f2he.html
http://bbs.csdn.net/topics/380112986
http://bbs.csdn.net/topics/40272991
2.1、ZC: 基本思路为两种(其实是一样的)
2.1.1、使用 WinAPI:“DrawText(Canvas.Handle,PChar(s),Length(s),r,DT_CENTER or DT_SINGLELINE or DT_VCENTER);”
ZC: 这个函数中有参数,可以自动使字符串 水平中间对齐。
2.1.2、使用 Delphi7封装的Canvas.TextRect(Rect, X, Y, str);
ZC: 这个函数,需要自己计算字符串所占用的像素宽度,然后 计算得到字符串开始的坐标(x,y),然后再 绘制字符串
2.1.2.1、Canvas.TextWidth()/TextHeight() 可以得到 字符串的像素宽度/高度,代码跟进去,可以看到 它其实也是调用的 WinAPI “function GetTextExtentPoint32(DC: HDC; Str: PChar; Count: Integer;var Size: TSize): BOOL; stdcall;”
3、Delphi7 测试代码:
ZC: 表格里 一共就处理了 4列(1~4)3行(1~3)数据
unit Unit1; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DateUtils, Grids, BaseGrid, AdvGrid; type
Prelation = ^Rrelation;
Rrelation =record
FbUsing :Boolean;
FbDrawn :Boolean; // 已经画过了
Fnumber :Integer;
FiCol1, FiRow1 :Integer;
FiCol2, FiRow2 :Integer;
end; TForm1 = class(TForm)
Memo1: TMemo;
grid: TAdvStringGrid;
Button4: TButton;
Button5: TButton;
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure gridCustomCellDraw(Sender: TObject; Canvas: TCanvas; ACol,
ARow: Integer; AState: TGridDrawState; ARect: TRect;
Printing: Boolean);
procedure gridDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
private
{ Private declarations }
public
Fcells :array [..,..] of Rrelation;
procedure CustomCellDraw();
procedure CustomCellDraw1(Canvas: TCanvas; ACol, ARow: Integer; AState: TGridDrawState; ARect: TRect);
end; var
Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button4Click(Sender: TObject);
var iCol, iRow :Integer;
begin
Fcells[, ].FbUsing := true;
Fcells[, ].Fnumber := ;
Fcells[, ].FiCol1 := -;
Fcells[, ].FiRow1 := -;
Fcells[, ].FiCol2 := ;
Fcells[, ].FiRow2 := ; Fcells[, ].FbUsing := True;
Fcells[, ].Fnumber := ;
Fcells[, ].FiCol1 := ;
Fcells[, ].FiRow1 := ;
Fcells[, ].FiCol2 := ;
Fcells[, ].FiRow2 := ; Fcells[, ].FbUsing := true;
Fcells[, ].Fnumber := ;
Fcells[, ].FiCol1 := ;
Fcells[, ].FiRow1 := ;
Fcells[, ].FiCol2 := -;
Fcells[, ].FiRow2 := -; for iRow:= to do
for iCol:= to do
grid.Cells[iCol, iRow] := IntToStr(iCol);
end; procedure TForm1.Button5Click(Sender: TObject);
begin
CustomCellDraw;
end; procedure TForm1.gridCustomCellDraw(Sender: TObject; Canvas: TCanvas; ACol,
ARow: Integer; AState: TGridDrawState; ARect: TRect; Printing: Boolean);
var bm :TBitmap;
p :Prelation;
rtSour, rtDest :TRect;
iWidth, iHeight :Integer;
ptMiddle, ptMiddle1, ptMiddle2 :TPoint;
rt1, rt2 :TRect;
begin
CustomCellDraw;
//CustomCellDraw1(Canvas, ACol, ARow, AState, ARect);
end; procedure TForm1.gridDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var str :string;
w, h :Integer;
begin
str := grid.Cells[ACol, ARow];
if (Length(str)>) then
begin
//grid.Canvas.Brush.Color := clSilver;
grid.Canvas.FillRect(Rect); // 清空原来的背景色
DrawText(grid.Canvas.Handle, PChar(str), Length(str), Rect, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
//TextRect State := [gdSelected];
end; //CustomCellDraw;
//CustomCellDraw1(grid.Canvas, ACol, ARow, State, Rect); end; procedure TForm1.FormCreate(Sender: TObject);
var p :Prelation;
i, j :Integer;
begin
for i:= to do
for j:= to do
Fcells[i,j].FbUsing := false;
// p := @(Fcells[1,1]);
// ZeroMemory(p, SizeOf(Rrelation)*12);
end; procedure TForm1.CustomCellDraw();
var bm :TBitmap;
p :Prelation;
rtSour, rtDest :TRect;
iWidth, iHeight :Integer;
ptMiddle, ptMiddle1, ptMiddle2 :TPoint;
rt, rt1, rt2 :TRect;
i, j :integer;
cv :TCanvas;
begin
for i:= to do
for j:= to do
begin
p := @(Fcells[i, j]); if (p.FbUsing)and(not p.FbDrawn) then
begin
p.FbDrawn := true; rt := grid.CellRect(i, j);
iWidth := rt.Right - rt.Left;
iHeight := rt.Bottom - rt.Top; ptMiddle.X := rt.Left + iWidth div ;
ptMiddle.Y := rt.Top + iHeight div ; rtDest.Left := ptMiddle.X - iHeight div ;
rtDest.Right:= rtDest.Left + iHeight;
rtDest.Top := rt.Top;
rtDest.Bottom := rt.Bottom; cv := grid.Canvas;
if (p.FiCol1<>-)and(p.FiRow1<>-) then
begin
rt1 := grid.CellRect(p.FiCol1, p.FiRow1);
ptMiddle1.X := rt1.Left + (rt1.Right - rt1.Left) div ;
ptMiddle1.Y := rt1.Top + (rt1.Bottom - rt1.Top) div ; cv.MoveTo(ptMiddle.X, ptMiddle.Y);
cv.LineTo(ptMiddle1.X, ptMiddle1.Y);
end;
if (p.FiCol2<>-)and(p.FiRow2<>-) then
begin
rt2 := grid.CellRect(p.FiCol2, p.FiRow2);
ptMiddle2.X := rt2.Left + (rt2.Right - rt2.Left) div ;
ptMiddle2.Y := rt2.Top + (rt2.Bottom - rt2.Top) div ; cv.MoveTo(ptMiddle.X, ptMiddle.Y);
cv.LineTo(ptMiddle2.X, ptMiddle2.Y);
end; bm := nil;
try
bm := TBitmap.Create;
bm.LoadFromFile('C:\Users\33\Desktop\D7_Test\bmp\_'+inttostr(p.Fnumber)+'.bmp');
rtSour.Left := ;
rtSour.Top := ;
rtSour.Right := bm.Width;
rtSour.Bottom := bm.Height; cv.CopyRect(rtDest, bm.Canvas, rtSour);//.Draw(ARect.Left, ARect.Top, bm);
finally
if bm<>nil then
bm.Free;
end;
end;
end; for i:= to do
for j:= to do
Fcells[i, j].FbDrawn := false;
end; procedure TForm1.CustomCellDraw1(Canvas: TCanvas; ACol, ARow: Integer; AState: TGridDrawState; ARect: TRect);
var bm :TBitmap;
p :Prelation;
rtSour, rtDest :TRect;
iWidth, iHeight :Integer;
ptMiddle, ptMiddle1, ptMiddle2 :TPoint;
rt1, rt2 :TRect;
begin
if (ACol>=)and(ACol<=)and(ARow>=)and(ARow<=) then
begin
p := @(Fcells[ACol, ARow]); if (p.FbUsing) then
begin
bm := nil;
iWidth := ARect.Right - ARect.Left;
iHeight := ARect.Bottom - ARect.Top; ptMiddle.X := ARect.Left + iWidth div ;
ptMiddle.Y := ARect.Top + iHeight div ; rtDest.Left := ptMiddle.X - iHeight div ;
rtDest.Right:= rtDest.Left + iHeight;
rtDest.Top := ARect.Top;
rtDest.Bottom := ARect.Bottom; if (p.FiCol1<>-)and(p.FiRow1<>-) then
begin
rt1 := grid.CellRect(p.FiCol1, p.FiRow1);
ptMiddle1.X := rt1.Left + (rt1.Right - rt1.Left) div ;
ptMiddle1.Y := rt1.Top + (rt1.Bottom - rt1.Top) div ; Canvas.MoveTo(ptMiddle.X, ptMiddle.Y);
Canvas.LineTo(ptMiddle1.X, ptMiddle1.Y);
end;
if (p.FiCol2<>-)and(p.FiRow2<>-) then
begin
rt2 := grid.CellRect(p.FiCol2, p.FiRow2);
ptMiddle2.X := rt2.Left + (rt2.Right - rt2.Left) div ;
ptMiddle2.Y := rt2.Top + (rt2.Bottom - rt2.Top) div ; Canvas.MoveTo(ptMiddle.X, ptMiddle.Y);
Canvas.LineTo(ptMiddle2.X, ptMiddle2.Y);
end; try
bm := TBitmap.Create;
bm.LoadFromFile('C:\Users\33\Desktop\D7_Test\bmp\_'+inttostr(p.Fnumber)+'.bmp');
rtSour.Left := ;
rtSour.Top := ;
rtSour.Right := bm.Width;
rtSour.Bottom := bm.Height; Canvas.CopyRect(rtDest, bm.Canvas, rtSour);//.Draw(ARect.Left, ARect.Top, bm);
finally
if bm<>nil then
bm.Free;
end;
end;
end;
end; end.
3.1、效果图:
ZC: 自己绘制了 3张bmp图片,自己绘制了 2根线

4、
5、
Grid_自绘的更多相关文章
- 关于DOM的操作以及性能优化问题-重绘重排
写在前面: 大家都知道DOM的操作很昂贵. 然后贵在什么地方呢? 一.访问DOM元素 二.修改DOM引起的重绘重排 一.访问DOM 像书上的比喻:把DOM和JavaScript(这里指ECMScri ...
- arcgis api for js入门开发系列五地图态势标绘(含源代码)
上一篇实现了demo的地图查询功能,本篇新增地图态势标绘模块,截图如下: 本篇核心的在于调用API的Draw工具:https://developers.arcgis.com/javascript/3/ ...
- android图片验证码--自绘控件
自绘控件的内容都是自己绘制出来的 大致流程如下: 1.定义一个类继承view 使用TypedArray初始化属性集合 在view的构造方法中 有一个AttributeSet的参数 很明显是用来保存控件 ...
- 关于repaint(重绘)和reflow( 回流)
repaint就是重绘,reflow就是回流.repaint主要是针对某一个DOM元素进行的重绘,reflow则是回流,针对整个页面的重排 严重性: 在性能优先的前提下,性能消耗 reflow大于re ...
- MFC 滑动条的重绘
MFC自带的滑动条的样子是这样的. 比较难看,所以需要重绘下,重绘后的样子是这样的. 代码如下: CustomSliderCtr.h #pragma once // CCustomSliderCtr ...
- MFC 静态文本的自绘 空心字的实现
想在对话框里,显示几个字是很简单的,只要用静态文本的输出就可以了.然而有时候我们需要显示特效的字,我们希望显示的文字就像Word里的艺术字一样,看起来美观.这时我们可以重写CStatic类.用Draw ...
- WinForm中重绘TabControl选项卡标题
最近开发WinForm频繁使用了TabControl控件,这个控件的选项卡没有BackgroundImage这个属性,那么如何为其各个选项卡添加背景图片呢?(这里说的是每个TabPage的头部,也就是 ...
- 回流(reflow)与重绘(repaint)
最近项目排期不紧,于是看了一下之前看了好久也没看明白的chrome调试工具的timeline.但是很遗憾,虽然大概懂了每一项是做什么的,但是用起来并不能得心应手.所以今天的重点不是timeline,而 ...
- 2013 duilib入门简明教程 -- 自绘标题栏(5)
如果大家有做过标题栏的自绘,肯定会感慨各种不容易,并且现有的一些资料虽然完美的实现了功能,但是代码比较乱,需要自行整理.如果用duilib,就是小case啦. duilib其实并没有区 ...
随机推荐
- 爬虫实战【5】送福利!Python获取妹子图上的内容
[插入图片,妹子图首页] 哈,只敢放到这个地步了. 今天给直男们送点福利,通过今天的代码,可以把你的硬盘装的满满的~ 下面就开始咯! 第一步:如何获取一张图片 假如我们知道某张图片的url,如何获取到 ...
- WCF基础之事务
说到事务,我最先想到的是“回滚”. 百科:事务是恢复和并发控制的基本单位.事务应该具有4个属性:原子性.一致性.隔离性.持久性.这四个属性通常称为ACID特性.好了,具体的就不多复制了. 我小试了一下 ...
- Pycharm中目前用到的快捷键
1.批量注释:Ctrl+/ 2.缩进\不缩进:Tab\Shift+Tab 3.运行:Ctrl+Shift+F10 4.撤销\反撤销:Ctrl+z\Ctrl+shift+z 5.当光标在代码中间,如何回 ...
- QSystemSemaphore 系统级信号量
在之前的一篇文章中,我们讲过了QSemaphore类,其可以用于同步多线程.而今天要讲到的这个类,根据名字就可以猜测到,其可以在整个系统中使用,即它既可以用于多线程,也可以用于多线程.当然,这也意味着 ...
- 洛谷 P4819 [中山市选]杀人游戏
洛谷 题目就是让我们在DAG中找到一些点,覆盖所有点. 因为是DAG,可以想到tarjan缩一下点.假设我们需要找x个点,那么答案就是(n-x)/n. 我们怎么选点呢? 敏锐的我们很快就能想到,直接选 ...
- ApexSQL Recover 恢复一个被drop的表的数据
没有备份的情况下恢复一个被drop的表的数据 ApexSQL Recover 恢复一个被drop的表的数据 转自:https://solutioncenter.apexsql.com/zh/%E6%B ...
- RedisClient For .Net
Redis Client For .Net 介绍 redis支持各种语言版本的client,其中.net平台下比较火的有ServiceStack.Redis和StackExchange.Redis 选 ...
- 基于C#委托的深入分析
1.委托的定义 委托可以看成是一种数据类型,可以用于定义变量能接受的值只能是一个方法. 委托简单的示例: namespace DelegateDemo { class Program { public ...
- LeetCode:寻找数组的中心索引【668】
LeetCode:寻找数组的中心索引[668] 题目描述 给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法. 我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和 ...
- php的异常和处理
常见错误处理类型 语法错误 环境错误 逻辑错误 常见错误级别 Deprecated 最低级别的错误 不推荐,不建议,使用一些过期函数的时候会出现,程序继续执行 Notice 通知级别的错误 使用一些未 ...