Search code examples
windowsdelphidrawvcldelphi-6

How Can I correctly position the icons centered in a DBGrid?


The Column Width is: 48 The Icon Width is: 32.

That's how I would like to draw:

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

Here is an 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

Solution

  • Due to a bug in the VCL, the icon's internal size (FSize) values are not updated when the icon is assigned a new image. This bug (1, 2, ...) have since been resolved, and indeed your test case works correctly with, f.i., D2007.

    Due to the bug, the icon size that is reported is the default system icon size (GetSystemMetrics(SM_CXICON)). So it is '32' (by default) instead of '16' in your case. Either take that into account when calculating the place to draw your image, or use one of the workarounds in one of the linked report or perhaps in other reports, or devise your own. In this particular case, you could simply use the dimensions of the image list:

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