2010. november 15., hétfő
Highlight an entire row in a TStringGrid (2)
Problem/Question/Abstract:
I have a TStringGrid component and I want change the color of the text in one row.
Answer:
Any kind of custom drawing in a TStringgrid requires a OnDrawCell handler (or overriding the DrawCell method in a derived grid class). Often this is not enough,however. If you base your special drawing on the active cell or its row or column you also need to make sure cells you previously drew in your custom manner are redrawn normal when the active cell moves, that the grid shows the special drawing only when it has focus and so on. This can get a bit complex, as shown by the sample below.
Note that is is simpler when you only customize the active cell, since this cell will be redrawn automatically when it is activated or deactivated.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, Grids;
const
UM_INVALIDATEROW = WM_USER + 321;
type
TForm1 = class(TForm)
StatusBar: TStatusBar;
Button1: TButton;
OpenDialog1: TOpenDialog;
Label1: TLabel;
StringGrid1: TStringGrid;
Edit1: TEdit;
procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
State: TGridDrawState);
procedure StringGrid1Enter(Sender: TObject);
procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var
CanSelect: Boolean);
procedure StringGrid1Exit(Sender: TObject);
private
{ Private declarations }
FGridActive: Boolean;
procedure UMInvalidateRow(var msg: TMessage); message UM_INVALIDATEROW;
public
{ Public declarations }
end;
var
Form1: TForm1;
dummy: Integer;
implementation
{$R *.DFM}
type
TGridCracker = class(TStringgrid); { gives access to protected methods }
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
grid: TStringgrid;
begin
{Task: color the current row}
grid := Sender as TStringgrid;
if FGridActive and (aRow = grid.Row) and (aCol >= grid.FixedCols) then
begin
grid.Canvas.brush.Color := clBlue;
grid.canvas.font.color := clWhite;
grid.canvas.FillRect(Rect);
InflateRect(rect, -2, -2);
grid.Canvas.TextRect(Rect, rect.left, rect.top, grid.cells[aCol, aRow]);
end
else if (gdSelected in State) and not grid.Focused then
begin
grid.Canvas.brush.Color := grid.color;
grid.canvas.font.color := grid.font.color;
grid.canvas.FillRect(Rect);
InflateRect(rect, -2, -2);
grid.Canvas.TextRect(Rect, rect.left, rect.top, grid.cells[aCol, aRow]);
end;
end;
procedure TForm1.StringGrid1Enter(Sender: TObject);
begin
if Sender is TStringgrid then
with TGridCracker(sender) do
PostMessage(self.handle, UM_INVALIDATEROW, Row, Integer(sender));
FGridActive := true;
{ Cannot rely on grid.focused here, it is not yet true when the message send
above is processed for some reason. }
end;
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
var
grid: TStringgrid;
begin
grid := Sender as TStringgrid;
if grid.Row <> aRow then
PostMessage(handle, UM_INVALIDATEROW, grid.Row, Integer(grid));
PostMessage(handle, UM_INVALIDATEROW, aRow, Integer(grid));
end;
procedure TForm1.UMInvalidateRow(var msg: TMessage);
begin
TGridCracker(msg.lparam).InvalidateRow(msg.wparam);
end;
procedure TForm1.StringGrid1Exit(Sender: TObject);
begin
if Sender is TStringgrid then
with TGridCracker(sender) do
PostMessage(self.handle, UM_INVALIDATEROW, Row, Integer(sender));
FGridActive := false;
end;
end.
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése