如何正确定位DBGrid中心的图标?

时间:2014-04-11 12:59:03

标签: windows delphi draw vcl delphi-6

列宽为:48 图标宽度为:32。

这就是我想画的方式:

12345678901234567890123456789012345678901234567   => 48, Column witdh
--------1234567890123456789012345678901--------   => 32, Icon width     
12345678-------------------------------12345678   => blank spaces 8 (before and after)

这是一个SSCCE:

.PAS

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, Provider, ImgList, Grids, DBGrids, DBClient, StdCtrls,
  ExtCtrls;

type
  TForm1 = class(TForm)
    ClientDataSet1: TClientDataSet;
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
    ImageList1: TImageList;
    Button1: TButton;
    ClientDataSet1FieldA: TIntegerField;
    ClientDataSet1FieldB: TStringField;
    ClientDataSet1Status: TIntegerField;
    procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
      DataCol: Integer; Column: TColumn; State: TGridDrawState);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  FIcon: TIcon;
  X,Y: Integer;
begin
  if Assigned(Column.Field) and (Column.FieldName = 'Status') then
  begin
    if Column.Field.DataSet.RecordCount = 0 then
      Exit;

    if Column.Field.Tag <> 0 then
      FIcon := TIcon(Pointer(Column.Field.Tag))
    else
    begin
      FIcon := TIcon.Create;
      try
        ImageList1.GetIcon(0, FIcon);
        Column.Field.Tag := Integer(Pointer(FIcon));
      except
        FIcon.Free;
        raise;
      end;
    end;

    if Assigned(FIcon) then
    begin
      if Column.Width < FIcon.Width then
      begin
        Column.Width := FIcon.Width;
        X:= Rect.Left;
        Y:= Rect.Top;
      end
      else
      begin
        //X:= Rect.Left + (Column.Width - FIcon.Width) div 2;
        //or 
        X:= Rect.Left + Round((Column.Width - FIcon.Width) / 2);
        Y:= Rect.Top;
      end;

      DBGrid1.Canvas.Draw(X, Y, FIcon);
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ClientDataSet1.DisableControls;
  try
    ClientDataSet1.Append;
    ClientDataSet1FieldA.AsInteger := 1;
    ClientDataSet1FieldB.AsString := 'One';
    ClientDataSet1.Post;

    ClientDataSet1.Append;
    ClientDataSet1FieldA.AsInteger := 2;
    ClientDataSet1FieldB.AsString := 'Two';
    ClientDataSet1.Post;

    ClientDataSet1.Append;
    ClientDataSet1FieldA.AsInteger := 3;
    ClientDataSet1FieldB.AsString := 'Three';
    ClientDataSet1.Post;
  finally
    ClientDataSet1.EnableControls;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ClientDataSet1.CreateDataSet;
end;

end.

.DFM

object Form1: TForm1
  Left = 491
  Top = 151
  Width = 681
  Height = 471
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object DBGrid1: TDBGrid
    Left = 8
    Top = 8
    Width = 561
    Height = 417
    DataSource = DataSource1
    Options = [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit]
    TabOrder = 0
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = 'MS Sans Serif'
    TitleFont.Style = []
    OnDrawColumnCell = DBGrid1DrawColumnCell
    Columns = <
      item
        Expanded = False
        FieldName = 'FieldA'
        Visible = True
      end
      item
        Expanded = False
        FieldName = 'FieldB'
        Visible = True
      end
      item
        Alignment = taCenter
        Expanded = False
        FieldName = 'Status'
        Font.Charset = DEFAULT_CHARSET
        Font.Color = clWindow
        Font.Height = -11
        Font.Name = 'MS Sans Serif'
        Font.Style = []
        ReadOnly = True
        Width = 47
        Visible = True
      end>
  end
  object Button1: TButton
    Left = 576
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Show'
    TabOrder = 1
    OnClick = Button1Click
  end
  object ClientDataSet1: TClientDataSet
    Aggregates = <>
    FieldDefs = <>
    IndexDefs = <>
    Params = <>
    StoreDefs = True
    Left = 504
    Top = 24
    object ClientDataSet1FieldA: TIntegerField
      FieldName = 'FieldA'
    end
    object ClientDataSet1FieldB: TStringField
      FieldName = 'FieldB'
    end
    object ClientDataSet1Status: TIntegerField
      FieldName = 'Status'
    end
  end
  object DataSource1: TDataSource
    DataSet = ClientDataSet1
    Left = 504
    Top = 72
  end
  object ImageList1: TImageList
    BlendColor = clWhite
    BkColor = clWhite
    DrawingStyle = dsTransparent
    Left = 504
    Top = 120
    Bitmap = {
      494C010101000400040010001000FFFFFF00FF10FFFFFFFFFFFFFFFF424D3600
      0000000000003600000028000000400000001000000001002000000000000010
      000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FCFC
      FC00F1F5F300D7EAE400D1E8E000D0E8E000D0E7E000D0E8E000D8EBE500F4F6
      F500FCFCFC00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FEFE
      FE00A7DFCC005ED0A60046CB990043CA970040C995003CC893003FC79300A7DF
      CB00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00F7FB
      FA0094DDC30052D4A20035CC910032CB90002ECA8D002AC98B0026C789006AD2
      AC00FCFDFD00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00F6FB
      F90097DFC5004DD39F0034CC910032CB8F002ECA8D002AC88B0026C7890065D1
      A900FBFDFD00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00F6FB
      F90097DEC5004ED39F0034CC910032CB8F002ECA8D002AC88B0026C7890065D1
      A900FBFDFD00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00FEFEFE00FEFEFE00F5FA
      F90097DEC5004ED39F0034CC910032CB8F002ECA8D002AC88B0026C7890065D0
      A900FAFCFB00FEFEFE00FEFEFE00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000C1E9DC0094DDC30081D9B9007BD6
      B50060D2A80043D09A0035CC910032CB8F002ECA8D002AC88B0026C789003AC7
      92006BD1AB006CD1AC006CD1AC00B0E3D1000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000A0DFC90080DEBA004DD49F0041D0
      99003DCF960039CE940036CC920032CB8F002ECA8D002AC88B0026C7890023C6
      870020C585001DC483001BC1810081D6B7000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000E8F6F10095DEC40070DBB20044D1
      9A003DCF96003ACE940036CC920032CB8F002ECA8D002AC88B0026C7890023C6
      870020C585001DC3830062CFA700E8F6F1000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00E2F4EE008CDCBF0065D9
      AC003ECF970039CE940036CC920032CB8F002ECA8D002AC88B0026C7890023C6
      870020C4850052CB9E00E1F3ED00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00FFFFFF00D8F0E80083DA
      BA0059D6A50039CD940036CC920032CB8F002ECA8D002AC88B0026C7890023C6
      870045C99700D3EFE600FFFFFF00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00CDEC
      E20078D8B5004DD39F0034CC910032CB8F002ECA8D002AC88B0026C789003AC7
      9200C3EADC00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFF
      FF00C1E9DB006FD6AF0042D0990031CB8F002ECA8D002AC88B0034C78F00B0E4
      D200FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFF
      FF00FEFEFE00B3E5D40063D4A9003ACD94002DCA8D0030C78D009CDEC700FCFD
      FD00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFF
      FF00FFFFFF00FAFDFC00A5E1CC0055D1A10035C8900088D9BC00F8FCFB00FFFF
      FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFF
      FF00FFFFFF00FFFFFF00F5FBF900B5E5D500ADE3D000F1F9F700FFFFFF00FFFF
      FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000424D3E000000000000003E000000
      2800000040000000100000000100010000000000800000000000000000000000
      000000000000000000000000FFFFFF00E007000000000000E00F000000000000
      E007000000000000E007000000000000E0070000000000008001000000000000
      0000000000000000000000000000000000000000000000008001000000000000
      C003000000000000E007000000000000F00F000000000000F00F000000000000
      F81F000000000000FC3F00000000000000000000000000000000000000000000
      000000000000}
  end
end

2 个答案:

答案 0 :(得分:2)

由于VCL中存在错误,因此在为图标分配新图像时,不会更新图标的内部大小(FSize)值。此错误(12,...)已经解决,确实您的测试用例可以正常使用,f.i.,D2007。

由于该错误,报告的图标大小是默认的系统图标大小(GetSystemMetrics(SM_CXICON))。所以它是&#39; 32&#39; (默认情况下)而不是&#39; 16&#39;在你的情况下。要么在计算绘制图像的位置时考虑到这一点,要么在链接报告之一中使用其中一种解决方法,或者在其他报告中使用其中一种解决方法,或者设计自己的。在这种特殊情况下,您只需使用图像列表的尺寸:

X:= Rect.Left + Round((Column.Width - ImageList1.Width) / 2);

答案 1 :(得分:1)

使用TBitmap代替TIcon

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  FIcon: TBitmap;
  X,Y: Integer;
begin
  if Assigned(Column.Field) and (Column.FieldName = 'Status') then
  begin
    if Column.Field.DataSet.RecordCount = 0 then
      Exit;

    if Column.Field.Tag <> 0 then
      FIcon := TBitmap(Pointer(Column.Field.Tag))
    else
    begin
      FIcon := TBitmap.Create;
      try
        ImageList1.GetBitmap(0, FIcon);
        Column.Field.Tag := Integer(Pointer(FIcon));
      except
        FIcon.Free;
        raise;
      end;
    end;

    if Assigned(FIcon) then
    begin
      if Column.Width < FIcon.Width then
      begin
        Column.Width := FIcon.Width;
        X:= Rect.Left;
        Y:= Rect.Top;
      end
      else
      begin
        //X:= Rect.Left + (Column.Width - FIcon.Width) div 2;
        //or
        X:= Rect.Left + Round((Column.Width - FIcon.Width) / 2);
        Y:= Rect.Top;
      end;

      DBGrid1.Canvas.Draw(X, Y, FIcon);
    end;
  end;
end;