Recent

Author Topic: [SOLVED] DBGrid color behavior difference when migrating from Delphi to Lazarus  (Read 735 times)

lhl

  • New member
  • *
  • Posts: 9
I'm migrating a routine from Delphi to Lazarus, but it's not working the same way.
In Delphi, this routine darkens the focused record and paints the selected field with the clNavy color within the DBGrid.
However, in Lazarus this behavior is not working correctly. When leaving the registry, it does not return to its original condition.

Has anyone faced this problem or know how to adjust this functionality in Lazarus?

Code: Pascal  [Select][+][-]
  1. type
  2. ...
  3.     TccDBGridAux    = class(TDBGrid);
  4. ...
  5. constructor TccPainel.Create(AOwner: TComponent);
  6. begin
  7.    inherited Create(AOwner);
  8.    FGrid.OnDrawColumnCell := @GridCorCelula;
  9.    ...
  10. end;
  11. ...
  12. procedure TccPainel.GridCorCelula(Sender: TObject; const Rect: TRect;
  13.   DataCol: Integer; Column: TColumn; State: TGridDrawState);
  14. var xCor: TColor;
  15.  
  16.    function Intensidade(cor: TColor; valor: integer): TColor;
  17.    begin
  18.       Result := RGBToColor(Max(GetRValue(ColorToRGB(cor)) + valor, 0),
  19.       Max(GetGValue(ColorToRGB(cor)) + valor, 0),
  20.       Max(GetBValue(ColorToRGB(cor)) + valor, 0));
  21.    end;
  22.  
  23. begin
  24.  
  25.    If (gdselected in State) and (FGrid.Focused) then begin
  26.  
  27.       FGrid.Canvas.Brush.Color := clNavy;
  28.       FGrid.Canvas.Font.Color  := clWhite;
  29.  
  30.    End Else Begin
  31.  
  32.       xCor := clAliceBlue;
  33.  
  34.       if Assigned(FCorGrid) Then Begin
  35.          xCor := FCorGrid(FDS.DataSet);
  36.       end;
  37.  
  38.       if Assigned(FGridCorCampo) then begin
  39.          xCor := FGridCorCampo( Column.Field, xCor );
  40.       end;
  41.  
  42.       if (TccDBGridAux(FGrid).DataLink.ActiveRecord + 1) = TccDBGridAux(FGrid).Row then begin
  43.          if (gdselected in State) then begin
  44.  
  45.             if (dgAlwaysShowEditor in FGrid.Options) then begin
  46.                FGrid.Canvas.Brush.Color := clNavy;
  47.                FGrid.Canvas.Font.Color  := clWhite;
  48.             end else begin
  49.                FGrid.Canvas.Brush.Color := Intensidade(xCor, -30);
  50.             end;
  51.          end else begin
  52.             FGrid.Canvas.Brush.Color := Intensidade(xCor, -30);
  53.          end;
  54.       end else begin
  55.          FGrid.Canvas.Brush.Color := xCor;
  56.       end;
  57.  
  58.    end;
  59.  
  60.    FGrid.Canvas.FillRect(Rect);
  61.    FGrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
  62.  
  63. end;
  64.  

« Last Edit: March 18, 2025, 12:54:01 pm by lhl »

lhl

  • New member
  • *
  • Posts: 9
While studying the component, I discovered the dgRowHighlight property, which does exactly what I need.

However, when I set different colors for records using the OnPrepareCanvas or OnDrawColumnCell events, the dgRowHighlight does not work.

wp

  • Hero Member
  • *****
  • Posts: 12762
Yes, that's clear, because OnPrepareCanvas is called immediately before a cell is painted. Canvas properties already have been set to their standard properties, and this event is a last opportunity to change something.

Do you know https://wiki.lazarus.freepascal.org/Grids_Reference_Page? It contains many details and many examples.

In the attached demo I am showing you a small database application in which the OnPrepareCanvas event is used to define the color of rows depending on some field value: The IntField column contains random integers between -50 and 50. The rows in which the value is <-20 are painted in red, >20 in green, and the rows in between are yellow.


lhl

  • New member
  • *
  • Posts: 9
Thank you for the feedback, wp
I did some more tests here and I have some important points:

1. Behavior using DBGrid1.Options := DBGrid1.Options + [dgRowHighlight]
The row is painted only for records that do not assign a color using the OnPrepareCanvas event.

2. Behavior using DBGrid1.Options := DBGrid1.Options - [dgRowHighlight] and manually setting parameters in the event: OnPrepareCanvas or OnDrawColumCell
Navigation using the up and down arrow keys in the column where I am works for both entering and leaving the record. In the other columns, the row is marked using my CorIntensidade function, but when I leave the focused record, it is not unmarked.

Interestingly, when using the mouse to perform the same test, it works perfectly.

wp

  • Hero Member
  • *****
  • Posts: 12762
Contrary to TStringGrid, no Col/Row parameters are passed to the drawing methods of TDBGrid. This results from the fact the grid displays only a range of records before and after the active record; therefore there is no unique relation between row index and record (ActiveRecord).

When the State parameter contains the gdSelected element, you know that the selected cell is currently painted. But what about the other cells in that row? This is why the dgRowHighlight option was introduced: when it is included in the grid's Options the element gdRowHighLight (note the exchanged g and d) is added to the State parameter while any cell in the row with the selected cell is painted.Otherwise there is not way to determine which row currently is painted.

Code: Pascal  [Select][+][-]
  1.   ...
  2.   if gdSelected in AState then
  3.   begin
  4.     DBGrid1.Canvas.Brush.Color := clNavy;
  5.     DBGrid1.Canvas.Font.Color := clWhite;
  6.   end else
  7.   begin
  8.     if intValue > 20 then
  9.     begin
  10.       DBGrid1.Canvas.Brush.Color := $00C1FFC1;
  11.       DBGrid1.Canvas.Font.Color := clBlack;
  12.     end else
  13.     if intValue < -20 then
  14.     begin
  15.       DBGrid1.Canvas.Brush.Color := $00C4C4FF;
  16.       DBGrid1.Canvas.Font.Color := clBlack;
  17.     end else
  18.     begin
  19.       DBGrid1.Canvas.Brush.Color := $00B9FFFF;
  20.       DBGrid1.Canvas.Font.Color := clBlack;
  21.     end;
  22.     if gdRowHighlight in AState then
  23.       DBGrid1.Canvas.Brush.Color := CorIntensidade( DBGrid1.Canvas.Brush.Color );
  24.   end;

lhl

  • New member
  • *
  • Posts: 9
Perfect! It solved my problem. This was exactly what I was needing.
Thank you very much!

 

TinyPortal © 2005-2018