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其实并没有区 ...
随机推荐
- 使用RestTemplate post方式提交表单数据
HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODE ...
- angularjs 复选框 单选框
关于复选框,在做项目的时候,有一下几点心得 单选框 1.判断哪个单选框选中的情况 html代码 判断该复选框是否选中 $scope.agree.isChecked 判断这个值,如果等于1,代表 ...
- 修改已生成项目app名称
在搜索里添加product Name,然后修改成你需要的app名称 修改完后可能会报错误如下 原因是test的测试路径发生了变化,其实如果不修改Test host的路径保留原来的重命名之前的app也是 ...
- Decimal fixed point and floating point arithmetic
decimal — Decimal fixed point and floating point arithmetic — Python 3.8.0a0 documentation https://d ...
- linux下tmp目录里很多php开头的文件
cd /tmp; ll -ash; 51M -rw------- 1 nginx nginx 51M Sep 17 09:33 php3p7FPA 51M -rw------- 1 nginx ngi ...
- amortized analysis
w https://en.wikipedia.org/wiki/Amortized_analysis In computer science, amortized analysis is a meth ...
- php自定义函数: 改进升级版curl
<?php function dcurl($url, $method = 'GET', $postFields = null, $header = null) { $ch = curl_init ...
- Vue的插值与表达式
正常情况我们在页面取值都是通过 {{ data }}来取值,但是有时候我们就是想输出HTML,而不是将数据解析后的纯文本,这个时候可以使用v-html来绑定数据 <span v-html=&qu ...
- 基于Django的Disqus如何支持每月80亿PV(转)
原文:基于Django的Disqus如何支持每月80亿PV 本文由 伯乐在线 - 贱圣OMG 翻译.未经许可,禁止转载!英文出处:Matt Robenolt.欢迎加入翻译小组. 现在我们Disqus能 ...
- Android的代码都得自己一个个敲一遍吗?
近期在Android学习中,碰到一个头疼的问题.众所周知Android是一个开发源码的平台,网上有非常多网友分享的关于各种样例的demo,比方扫描二维码,瀑布流等,对于前人已有的成果,我们 ...