【问题标题】:How Can I correctly position the icons centered in a DBGrid?如何正确定位 DBGrid 中居中的图标?
【发布时间】:2014-05-25 15:35:41
【问题描述】:

列宽是: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

【问题讨论】:

    标签: windows delphi draw vcl delphi-6


    【解决方案1】:

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

    由于该错误,报告的图标大小是默认系统图标大小 (GetSystemMetrics(SM_CXICON))。因此,在您的情况下,它是“32”(默认情况下)而不是“16”。在计算绘制图像的位置时将其考虑在内,或者在链接报告之一或其他报告中使用其中一种解决方法,或者设计自己的解决方法。在这种特殊情况下,您可以简单地使用图像列表的尺寸:

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

    【讨论】:

    • +1。非常感谢,Sertac。我没有意识到图标大小返回 32。
    • 其实我没有意识到图标大小是 16
    【解决方案2】:

    使用 TIcon 的 TBitmap

    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;
    

    【讨论】:

    • 谢谢,这会给我带来麻烦吗?图片扩展名为 .ico。作为位图检索可以吗?
    • 如果在TImageList中,没问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多