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 [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:\Users\33\Desktop\D7_Test\bmp\_'+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:\Users\33\Desktop\D7_Test\bmp\_'+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、

 

posted @ 2016-09-01 16:09  CodeSkill  阅读(499)  评论(0)    收藏  举报