简体   繁体   中英

Using Canvas.TextOut in DBGrid - Delphi XE 3

Please, I need to help with Canvas Use: When the user moves the mouse over the Title Column of DBGrid, the title description disappears in Delphi XE 3. This problem doesn't occurr in delphI 7.

Follow the code below:

unit Unit1;

interface

uses

Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Graphics, Controls, Forms, Dialogs, Data.DB, Datasnap.DBClient,
Grids, DBGrids, Types, StdCtrls;

type
TAccessDBGrid = class(TCustomGrid);

type
TForm1 = class(TForm)

DataSource1: TDataSource;
grid1: TDBGrid;
cdsTabela: TClientDataSet;
cdsTabelacodigo_1: TIntegerField;
cdsTabelacodigo_2: TIntegerField;`enter code here`

procedure grid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);

procedure FormCreate(Sender: TObject);

procedure FormResize(Sender: TObject);

procedure grid1TitleClick(Column: TColumn);

private
    { Private declarations }
public
    { Public declarations }
end;

var
Form1: TForm1;

implementation
    {$R *.dfm}

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

procedure TForm1.FormResize(Sender: TObject);
    begin
        grid1.Refresh;
    end;

procedure TForm1.grid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
S1 : string;

begin

with TAccessDBGrid(grid1) do
begin
    RowHeights[0] := 29;
    Canvas.Brush.Color := clBtnFace;
    case Column.Index of
    0:
    begin
        Column.Title.Caption := '';
        S1 := 'Code';
    end;
    1:
    begin
        Column.Title.Caption := '';
        S1 := 'Description';
    end;
end;

TDBGrid(Sender).Canvas.Font.Color:= clBlack;
Canvas.TextOut(Rect.Left + 3, 19, S1);
end;
end;

procedure TForm1.grid1TitleClick(Column: TColumn);
begin
ShowMessage('Title Click! ');
end;

end

For more information, see the answer I have posted.

The extra information included in the answer you posted makes it far easier to understand what you are trying to do, which is good. Please try to do that in future questions as it more likely that you will get a better answer faster.

Anyway, I suggest you replace your TDBGrid by Mike Shkolnik's TSMDBGrid. See: http://www.scalabium.com/smdbgrid.htm and watch the animation.

His grid includes an OnDrawColumnTitle event, which I think will make it far easier to achieve what you want than trying to do it with TDBGrid. and I gather from your comments that you have followed this suggestion and succeeded in what you were trying to do.

Original answer follows:

I agree with what Ken White has said, but in addition, I think your code is misconceived. To see what I mean, try this:

  1. Save an IDE Debug layout in which the Code Editor does not overlap with your Form1. The point of doing this is so that Form1 isn't forced to repaint which the IDE stos on a breakpoint.

  2. Set DefaultDrawing to False. The point of this is that having it set to True hides quite how broken your Grid1DrawColumnCell is.

  3. Put a breakpoint on the first line of your Grid1DrawColumnCell , ie with TAccessDBGrid(grid1) .

  4. Compile and run. Notice that the Debugger stops on the breakpoint several times while the form is being painted on screen, but after that it doesn't stop on your BP at all. So, your custom painting never occurs once the form is on-screen, until you cause the grid to refresh eg using your form's OnResize handler.

  5. So what causes the column Title Captions to be blank once you move the mouse over the grid. The answer is, you do! To see why ...

  6. In VCL.DBGrids.Pas, find DrawTitleCell in TCustomDBGrid.DrawCell and put a BP on WriteText(Canvas, TextRect, LFrameOffs, LFrameOffs, Caption, Alignment,...

  7. Run the app again to the point where your Grid1DrawColumnCell has executed and the debugger stops on the WriteText BP set in step 6. Evaluate Caption and you will see that it is empty (because your Grid1DrawColumnCell has cleared it, of course). I suppose you could assign your S1 value to the column title's Caption before your DrawColumnCell exits, but the drawing it does would still be a mess, as you will see if you try eg

     case Column.Index of 0: begin // Column.Title.Caption := ''; S1 := 'Code'; Column.Title.Caption := S1; end; 1: begin // Column.Title.Caption := ''; S1 := 'Description'; Column.Title.Caption := S1; end; 

QED

So basically you are wasting your time with your Grid1DrawColumnCell . If you want to know whether it is possible to custom-draw the column headers/titles, and if so, how, I suggest you ask a new q, after doing some research. If you don't find anything, you might consider deriving a TCustomDBGrid descendant and overriding its DrawCell ; that way you could have better control over the whole drawing process and maybe get closer to whatever it is that you are trying to achieve.

Btw the above is based on the application being compiled in Delphi Seatlle, which is more recent than XE3, but I doubt that makes any difference.

The reason I use Canvas.TextOut instead of Title.Caption is I need to write 2 rows in Title:

        Tests
Test One    Test Two

I use "19" instead of Rect.Top because I want to write in Title. If I use Rect.Top, the text is drawn in edition area of column

Canvas.TextOut(Rect.Left + 3, 19, S1);

Follows bellow my real code:

In Grid1DrawColumnCell:

with TAccessDBGrid(grid1) do
begin
  RowHeights[0] := 37;
  Canvas.Brush.Color := clBtnFace;

  case Column.Index of
  0: begin
       Column.Title.Caption := '';
       S1 := 'Code';
     end;
  1: begin
       Column.Title.Caption := '';
       Canvas.Font.Color := clBlack;

       S1 := 'Tests';

       Canvas.Brush.Style := bsSolid;
       Canvas.Brush.Color := clBtnFace;
       Canvas.FillRect(Types.Rect(Rect.Left, 0, Rect.Left + 120, 18));
       Canvas.TextOut(Rect.Left + 3, 1, S1);
       Canvas.Brush.Style := bsSolid;

       S1 := 'Test One';
     end;
  2: begin
       Column.Title.Caption := '';
       S1 := 'Test Two';
     end;
 end;

  Canvas.Font.Color:= clBlack;
  Canvas.TextOut(Rect.Left + 3, 19, S1);
end;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM