DBGrid Mouseover cell colour lazarus / 21-General ---------------------------------------------------------------------- pcurtis · 2021-02-19 09:46 Hi All, I know this question has been asked a million times but I cant find a definitive answer. How do I change a cells font style to italic (for example) on the cell the mouse is over (not the entire row only the cell), and hide the row selection? Thanks in advance. ---------------------------------------------------------------------- luca · 2021-02-19 10:27 Hi, I found this solution: 1. Write OnMouseMove event method to save Row and Column (of the cell you're over with the mouse) in two private global variables (you can write some logic here to exclude some columns/cells);  then call a Repaint of the grid 2. Write OnPrepareCanvas event method to check if the aCol/aRow  parameters are equal to the variables you saved on step 1. If yes simply Set the StringGrid.Canvas.Font.Style := [fsItalic]; if Not reset the StringGrid.Canvas.Font.Style to [] For the row selection I see an Option to be set: dgRowSelect. Regards Luca ---------------------------------------------------------------------- pcurtis · 2021-02-19 11:23 How do I get aRow from this ? procedure TForm1.DBGrid1PrepareCanvas(sender: TObject; DataCol: Integer; Column: TColumn;   AState: TGridDrawState); ---------------------------------------------------------------------- luca · 2021-02-19 15:05 I see. There is no such information on this event for DBGrid. I've checked and in my project I used a TStringGrid instead of a TDBGrid to show some records from a database view. Regards Luca ---------------------------------------------------------------------- wp · 2021-02-20 14:48 DBGrid focuses its properties and events on the underlying dataset. However, it is still a TCustomGrid after all. And when you create a derived class then you have access to the inherited protected methods of the TCustomGrid without the database cover. Among them there is DrawCellText which has the purpose to paint the cell text. At this time all colors, fonts, etc already have been prepared, and you only need to changed the attributes that you want to be different and then call "inherited" to let the method continue with its task. The subclassing is done by defining an child class of TDBGrid, and in this class you override the DrawCellText method: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TMyDBGrid = class(TDBGrid)  protected    procedure DrawCellText(aCol, aRow: Integer; aRect: TRect; aState: TGridDrawState; aText: String); override;  end; // Draws everything like TDBGrid, except for the cell under the mouse which become bold and larger here.procedure TMyDBGrid.DrawCellText(aCol,aRow: Integer; aRect: TRect; aState: TGridDrawState; aText: String);var  mouseCell: TPoint;begin  mouseCell := GCache.Mousecell;   if (aCol > 0) and (aRow >= FixedRows) and  // ignore the header cols/rows     (aCol = mouseCell.X) and (aRow = mouseCell.Y) then // change font in mouse cell  begin    Canvas.Font.Style := [fsItalic, fsBold]    Canvas.Font.Size := 11;  end;   inherited;end; Normally you would put this class into a package an create a new component of it (of course, you still can), but it is necessary. When the form has been created with a TDBGrid you create an instance of TMyDBGrid, copy all the properties of the DBGrid to the new instance, destroy the DBGrid and rename the new instance like the destroyed DBGrid. This way you effectively replace the DBGrid by a MyDBGrid with the same properties but different behaviour in cell painting. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i // Replace the DBGrid1 on the form by a TMyDBGrid having the same propertiesprocedure TForm1.FixDBGrid;var  grid: TDBGrid;begin  grid := TMyDBGrid.Create(self);  // grid.Assign(DBGrid1);  // Unfortunately, TDBGrid does not provide its own Assign. Therefore, we must  // copy the relevant properties ourselves.  grid.Parent := DBGrid1.Parent;  grid.DataSource := DBGrid1.DataSource;  grid.SetBounds(DBGrid1.Left, DBGrid1.Top, DBGrid1.Width, DBGrid1.Height);  grid.OnMouseMove := DBGrid1.OnMouseMove;  grid.Options := DBGrid1.Options;  DBGrid1.Free;  DBGrid1 := grid;end;   procedure TForm1.FormCreate(Sender: TObject);begin  FixDBGrid;end; Of course you must trigger a repaint of then grid in the OnMouseMove event of the grid (call the grid's Invalidate method). I could imagine that on slow machines this could create some flicker, though. See the entire mini-project in the attachment ---------------------------------------------------------------------- wp · 2021-02-20 15:37 Yes, of course, I forgot about it... I am attaching the project again, now with jamie's trick. I also move the OnMouseMove event handler into the MouseMove method of the new grid. Note that the declaration of the subclassed TDBGrid must be put before its first usage, i.e. before TForm1. You can also put the declaration and implementation of the new grid into a separate unit. This unit must be listed in the uses clause AFTER the dbgrids unit, so that the new unit will be used instead of the original one. This way all grids of a project can be modified if their units list the new unit in their uses clause (--> project version -3) ---------------------------------------------------------------------- pcurtis · 2021-02-20 19:27 Thanks guys. Perfect. Just one small thing. This affects all dbgrids in the project. 'How can I make it apply to a specific grid? I made this small change. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TDBGrid.DrawCellText(aCol,aRow: Integer; aRect: TRect;  aState: TGridDrawState; aText: String);var  mouseCell: TPoint;begin  mouseCell := GCache.Mousecell;   if (aCol > 0) and (aRow >= FixedRows) and  // ignore the header cols/rows     (aCol = mouseCell.X) and (aRow = mouseCell.Y) and     (Self.Name = 'DBGrid1') // ADDED THIS  then  begin    Canvas.Font.Style := [fsBold];    Canvas.Font.Size := 11;  end;   inherited;end;  Or is there a better way? ---------------------------------------------------------------------- Hansvb · 2021-08-22 09:57 Is it also possible to change the color of all the cells in the row the mouse is over? (And back to default when mouse is left. I found this (Old code) but i think that datalink.activerecord doesn't work anymore. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TDBGrid_visueel.DBGrid_GVSXDrawColumnCell(DBGrid: TDBGrid;  const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);begin  with DBGrid do    begin      if NOT ((gdFocused in State) or (gdSelected in State))          AND (MouseOverRow = 1 + THackDBGrid(DBGrid).DataLink.ActiveRecord) then       begin         with DBGrid.Canvas do         begin           Brush.Color := clSilver;           Font.Color := clBlue; //clNavy;         end;       end;       DBGrid.DefaultDrawColumnCell(Rect, DataCol, Column, State) ;    end;end; ---------------------------------------------------------------------- Hansvb · 2021-08-22 10:10 Found it the cast THackDBGrid(DBGrid) is not needed anymore