• 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: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、

  • 相关阅读:
    通过SQL Server 2008数据库复制实现数据库同步备份
    SQL Server进制
    Server2008+SQL2008 日志读取代理器未运行 进程无法在“WINXXX”上执行“sp_replcmds”
    swing中使用皮肤包
    JTextArea的自动定位最后一行
    JFrame如何设置背景图片
    swing中单击回车相当于点击登录
    execute、executeUpdate、executeQuery三者的区别(及返回值)
    JTable设置透明
    在eclipse中导入android项目
  • 原文地址:https://www.cnblogs.com/CodeSkill/p/5830285.html
Copyright © 2020-2023  润新知