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_自绘的更多相关文章

  1. 关于DOM的操作以及性能优化问题-重绘重排

     写在前面: 大家都知道DOM的操作很昂贵. 然后贵在什么地方呢? 一.访问DOM元素 二.修改DOM引起的重绘重排 一.访问DOM 像书上的比喻:把DOM和JavaScript(这里指ECMScri ...

  2. arcgis api for js入门开发系列五地图态势标绘(含源代码)

    上一篇实现了demo的地图查询功能,本篇新增地图态势标绘模块,截图如下: 本篇核心的在于调用API的Draw工具:https://developers.arcgis.com/javascript/3/ ...

  3. android图片验证码--自绘控件

    自绘控件的内容都是自己绘制出来的 大致流程如下: 1.定义一个类继承view 使用TypedArray初始化属性集合 在view的构造方法中 有一个AttributeSet的参数 很明显是用来保存控件 ...

  4. 关于repaint(重绘)和reflow( 回流)

    repaint就是重绘,reflow就是回流.repaint主要是针对某一个DOM元素进行的重绘,reflow则是回流,针对整个页面的重排 严重性: 在性能优先的前提下,性能消耗 reflow大于re ...

  5. MFC 滑动条的重绘

    MFC自带的滑动条的样子是这样的. 比较难看,所以需要重绘下,重绘后的样子是这样的. 代码如下: CustomSliderCtr.h #pragma once // CCustomSliderCtr ...

  6. MFC 静态文本的自绘 空心字的实现

    想在对话框里,显示几个字是很简单的,只要用静态文本的输出就可以了.然而有时候我们需要显示特效的字,我们希望显示的文字就像Word里的艺术字一样,看起来美观.这时我们可以重写CStatic类.用Draw ...

  7. WinForm中重绘TabControl选项卡标题

    最近开发WinForm频繁使用了TabControl控件,这个控件的选项卡没有BackgroundImage这个属性,那么如何为其各个选项卡添加背景图片呢?(这里说的是每个TabPage的头部,也就是 ...

  8. 回流(reflow)与重绘(repaint)

    最近项目排期不紧,于是看了一下之前看了好久也没看明白的chrome调试工具的timeline.但是很遗憾,虽然大概懂了每一项是做什么的,但是用起来并不能得心应手.所以今天的重点不是timeline,而 ...

  9. 2013 duilib入门简明教程 -- 自绘标题栏(5)

        如果大家有做过标题栏的自绘,肯定会感慨各种不容易,并且现有的一些资料虽然完美的实现了功能,但是代码比较乱,需要自行整理.如果用duilib,就是小case啦.     duilib其实并没有区 ...

随机推荐

  1. Consul文档收藏

    英文:https://www.consul.io/intro/getting-started/install.html 中文:http://www.liangxiansen.cn/2017/04/06 ...

  2. C#窗体传值

    整理一下: 1.静态变量传值,非常简单适合简单的非实例的 public calss form1:Form{ public static int A; } public class form2:Form ...

  3. Ubuntu系统下完全卸载和安装Mysql

    删除 mysql sudo apt-get autoremove --purge mysql-server-5.0 sudo apt-get remove mysql-server sudo apt- ...

  4. Python3.6全栈开发实例[014]

    14.好声音选秀大赛评委在打分的时,可以进行输入. 假设,有10个评委.让10个评委进行打分, 要求, 分数必须大于5分, 小于10分. count = 1 while count <= 10: ...

  5. 修改impala表location

    两种方式: 一.通过修改表DDL: alter table t_m_cc set location 'hdfs://heracles/user/video-mvc/hive/warehouse/t_m ...

  6. 0201-开始使用Spring Cloud实战微服务准备工作

    1.Spring Cloud是什么 基于spring boot,之上快速构建分布式系统的工具集 服务注册和发现[eureka.Consul.Zookeeper].服务负载均衡[Ribbon,feign ...

  7. SUBMIT RM07DOCS【MB51】 获取返回清单,抓取标准报表数据

    *&---------------------------------------------------------------------* *& Report YT_SUBMIT ...

  8. python基础27 -----python进程终结篇-----IO模型

    一.IO模型 1.IO模型分类 1.阻塞IO--------blocking IO 2.非阻塞IO------nonblocking IO 3. 多路复用IO------- multiplexing ...

  9. 剑指offer 面试24题

    面试24题: 题目:反转链表 题:输入一个链表,反转链表并输出反转后链表的头节点. 解题思路:注意反转时出现断裂现象,定义3个指针,分别指向当前遍历到的节点pNode.它的前一个节点pPrev及后一个 ...

  10. 前端基础之Bootstrap介绍

    bootstrap简介 http://v3.bootcss.com/ Bootstrap优点:  下载:  Bootstrap引入 <meta name="viewport" ...