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 [1..4,1..3] 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[1, 1].FbUsing := true; Fcells[1, 1].Fnumber := 1; Fcells[1, 1].FiCol1 := -1; Fcells[1, 1].FiRow1 := -1; Fcells[1, 1].FiCol2 := 4; Fcells[1, 1].FiRow2 := 2; Fcells[4, 2].FbUsing := True; Fcells[4, 2].Fnumber := 4; Fcells[4, 2].FiCol1 := 1; Fcells[4, 2].FiRow1 := 1; Fcells[4, 2].FiCol2 := 2; Fcells[4, 2].FiRow2 := 3; Fcells[2, 3].FbUsing := true; Fcells[2, 3].Fnumber := 2; Fcells[2, 3].FiCol1 := 4; Fcells[2, 3].FiRow1 := 2; Fcells[2, 3].FiCol2 := -1; Fcells[2, 3].FiRow2 := -1; for iRow:=1 to 3 do for iCol:=1 to 4 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)>0) 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:=1 to 4 do for j:=1 to 3 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:=1 to 4 do for j:=1 to 3 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 2; ptMiddle.Y := rt.Top + iHeight div 2; rtDest.Left := ptMiddle.X - iHeight div 2; rtDest.Right:= rtDest.Left + iHeight; rtDest.Top := rt.Top; rtDest.Bottom := rt.Bottom; cv := grid.Canvas; if (p.FiCol1<>-1)and(p.FiRow1<>-1) then begin rt1 := grid.CellRect(p.FiCol1, p.FiRow1); ptMiddle1.X := rt1.Left + (rt1.Right - rt1.Left) div 2; ptMiddle1.Y := rt1.Top + (rt1.Bottom - rt1.Top) div 2; cv.MoveTo(ptMiddle.X, ptMiddle.Y); cv.LineTo(ptMiddle1.X, ptMiddle1.Y); end; if (p.FiCol2<>-1)and(p.FiRow2<>-1) then begin rt2 := grid.CellRect(p.FiCol2, p.FiRow2); ptMiddle2.X := rt2.Left + (rt2.Right - rt2.Left) div 2; ptMiddle2.Y := rt2.Top + (rt2.Bottom - rt2.Top) div 2; cv.MoveTo(ptMiddle.X, ptMiddle.Y); cv.LineTo(ptMiddle2.X, ptMiddle2.Y); end; bm := nil; try bm := TBitmap.Create; bm.LoadFromFile('C:Users33DesktopD7_Testmp\_'+inttostr(p.Fnumber)+'.bmp'); rtSour.Left := 0; rtSour.Top := 0; 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:=1 to 4 do for j:=1 to 3 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>=1)and(ACol<=4)and(ARow>=1)and(ARow<=3) 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 2; ptMiddle.Y := ARect.Top + iHeight div 2; rtDest.Left := ptMiddle.X - iHeight div 2; rtDest.Right:= rtDest.Left + iHeight; rtDest.Top := ARect.Top; rtDest.Bottom := ARect.Bottom; if (p.FiCol1<>-1)and(p.FiRow1<>-1) then begin rt1 := grid.CellRect(p.FiCol1, p.FiRow1); ptMiddle1.X := rt1.Left + (rt1.Right - rt1.Left) div 2; ptMiddle1.Y := rt1.Top + (rt1.Bottom - rt1.Top) div 2; Canvas.MoveTo(ptMiddle.X, ptMiddle.Y); Canvas.LineTo(ptMiddle1.X, ptMiddle1.Y); end; if (p.FiCol2<>-1)and(p.FiRow2<>-1) then begin rt2 := grid.CellRect(p.FiCol2, p.FiRow2); ptMiddle2.X := rt2.Left + (rt2.Right - rt2.Left) div 2; ptMiddle2.Y := rt2.Top + (rt2.Bottom - rt2.Top) div 2; Canvas.MoveTo(ptMiddle.X, ptMiddle.Y); Canvas.LineTo(ptMiddle2.X, ptMiddle2.Y); end; try bm := TBitmap.Create; bm.LoadFromFile('C:Users33DesktopD7_Testmp\_'+inttostr(p.Fnumber)+'.bmp'); rtSour.Left := 0; rtSour.Top := 0; 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、