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其实并没有区 ...
随机推荐
- 安装IntelliJ IDEA 破解安装
IDEA 功能介绍 1-深度智力 IntelliJ IDEA为您的源代码编制索引后,通过在每个环境中提供相关建议,提供快速,智能的体验:即时和智能的代码完成,即时代码分析和可靠的重构工具. 2-开箱即 ...
- javascript中字符串截取的两种方法
var testStr = "hello kay!"; 1.substr testStr.substr(1) ->ello kay! testStr.substr(1,4 ...
- 阻塞队列 ArrayBlockingQueue 我给自己挖了一个坑
说一句MMB, 一下午时间, package cn.tbnb1.seckil.quene; import java.util.concurrent.ArrayBlockingQueue; import ...
- D3D9和OpenGL加载纹理图片的API是哪个?
D3D9 创建一个空纹理,当返回 S_OK 且 ppTexture 纹理对象指针不为 NULL 时,则表示该函数调用成功. HRESULT D3DXCreateTexture( _In_ LPDIR ...
- MySQL 第四天
回顾 列属性: 主键, 自增长, 唯一键 关系: 一对一,一对多和多对多 范式: 三层范式 1NF: 字段设计必须符合原子性 2NF: 不存在部分依赖(没有复合主键) 3NF: 不存在传递依赖 ...
- Hadoop “Name node is in safe mode” 错误解决方法
Hadoop 解除 "Name node is in safe mode" 运行hadoop程序时,有时候会报以下错误:org.apache.hadoop.dfs.SafeMode ...
- 印象笔记Mac端快捷键
- boost之内存池
讲到内存池我们会想到对对象进行动态分配的过程new包含三个过程 1.使用operator new分配内存 2.使用placement new 初始化 3.返回内存地址. 分配内存可以分解成分配内存和获 ...
- 曾经跳过的坑----js截取字符串substr与substring 和 trim
不废话直接代码.自己理解...... > "abcdefg".substring(1,6)> "bcdef"> "abcdefg&q ...
- LCA(最近公共祖先)专题(不定期更新)
Tarjan(离线)算法 思路: 1.任选一个点为根节点,从根节点开始. 2.遍历该点u所有子节点v,并标记这些子节点v已被访问过. 3.若是v还有子节点,返回2,否则下一步. 4.合并v到u上. 5 ...