Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 04/25/25 in Posts

  1. aehimself

    tDBGrid: how to color selected row?

    I'm using this code for alternating colors: Procedure TDBGrid.DrawColumnCell(Const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); Var dataset: TDataSet; {$IFDEF HIDECOLLINESIFEMPTY} colline: Boolean; {$ENDIF} editcolor: TColor; hidefocus: Boolean; Begin dataset := Self.DataSource.DataSet; // This method is only being called on DATA cells, which only happens if there is a dataset connected. Therefore, no // need to perform an assigned check here. {$IFDEF HIDECOLLINESIFEMPTY} colline := True; {$ENDIF} hidefocus := Not (csDesigning In Self.ComponentState) And (gdSelected In State) And Not Self.Focused; If (dgMultiSelect In Self.Options) And (Self.SelectedRows.CurrentRowSelected) Then Begin End Else If dataset.IsEmpty Then Begin {$IFDEF HIDECOLLINESIFEMPTY} colline := False; {$ENDIF} editcolor := TStyleManager.ActiveStyle.GetStyleColor(scEdit); Self.Canvas.Brush.Color := editcolor; Self.Canvas.Font.Color := editcolor; End Else // This code imitates the highlight of the whole row even if RowSelect is disabled. Note that it needs MultiSelect to be enabled! // If Not (gdSelected In State) And grid.SelectedRows.CurrentRowSelected Then // grid.Canvas.Brush.Color := clHighLight // Else If (dataset.RecNo Mod 2 = 0) And ((State = []) Or hidefocus) Then Self.Canvas.Brush.Color := TStyleManager.ActiveStyle.GetStyleColor(scButtonDisabled) Else If (dataset.RecNo Mod 2 = 1) And hidefocus Then Self.Canvas.Brush.Color := TStyleManager.ActiveStyle.GetStyleColor(scEdit); If hidefocus Then Self.Canvas.Brush.Color := TStyleManager.ActiveStyle.GetStyleColor(scCategoryButtonsGradientBase); {$IFDEF HIDECOLLINESIFEMPTY} If HIDECOLLINESIFEMPTY And colline And Not (dgColLines In Self.Options) Then Self.Options := Self.Options + [dgColLines] Else If HIDECOLLINESIFEMPTY And Not colline And (dgColLines In Self.Options) Then Self.Options := Self.Options - [dgColLines]; {$ENDIF} inherited; Self.DefaultDrawColumnCell(Rect, DataCol, Column, State); End; Supports VCL styles and works fine for a couple of years now. I used the "lazy" technique. Save this as uDBGrid.pas, add is to the uses clause of your form and in the declaration change "grdMyDBGrid: TDBGrid;" to "grdMyDBGrid: uDBGrid.TDBGrid". Since the class name is the same no modification in the dfm is necessary. Drawback is, it only works runtime. And it's hacky.
  2. Softacom | Company

    tDBGrid: how to color selected row?

    Yes, it’s not so hard to replace component. You need to follow next steps: 1. Create package with your new component and install it into Delphi (don’t forget to make package DesingnTime and make register procedure). We need it to make designer works. 2. Replace text ': TDBGrid'#13#10 with ': TMyGrid'#13#10 in *.dfm files 3. Replace text ': TDBGrid;'#13#10 with ': TMyGrid;'#13#10 in *.pas files 4. We need to add your pas-file with new type into interface uses section to let compiler find you new class. You can do it in a few ways, but I suggest, replace text ‘Vcl.DBGrids’ with ‘Vcl.DBGrids, MyNewGrid’ in *.pas files 5. If your project not single exe-file and use own bpl-files with this new grid, than you need to add new package into requires section. 6. If your project cannot compile after all this steps – maybe you will need to add path for this new pas-file into “search path” section in options of your project
  3. Softacom | Company

    tDBGrid: how to color selected row?

    There is no easy way to do it. Problem is that this feature is not supported "by design" in TDBGrid. Main issue is in this part of TCustomDBGrid.DrawCell: Value := ''; OldActive := FDataLink.ActiveRecord; try FDataLink.ActiveRecord := ARow; //<-- after this line, current cell is at current row anyway if Assigned(DrawColumn.Field) then Value := DrawColumn.Field.DisplayText; if HighlightCell(ACol, ARow, Value, AState) and DefaultDrawing then DrawCellHighlight(ARect, AState, ACol, ARow); if not Enabled then Font.Color := clGrayText; if FDefaultDrawing then WriteText(Canvas, ARect, 3, 2, Value, DrawColumn.Alignment, (DrawColumn.BidiMode = bdRightToLeft) and UseRightToLeftAlignmentForField(DrawColumn.Field, DrawColumn.Alignment)); if Columns.State = csDefault then DrawDataCell(ARect, DrawColumn.Field, AState); //<-- here we have event DrawColumnCell(ARect, ACol, DrawColumn, AState); //<-- here we have event finally FDataLink.ActiveRecord := OldActive; //<-- after this code, active row at right place again end; So when you try to check active row in event it's always return true. right way to check if current cell is in active row it's: if OldActive = FDataLink.ActiveRecord then but OldActive it's local variable so you don't have access to it. Only way to deal with it - it's make own descendant of TCustomDBGrid and reimplement DrawCell method.
  4. My point is that it's behaviour that you don't ever need to know because the correct way to handle byte data is as, well, bytes and not text. So for sure there's an algorithm, but it's not one that anyone actually needs to know.
  5. Yes, here’s a practical use case: Example: Suppose I have a legacy application with over 100 forms, and I need to log every time a form is shown. Instead of modifying each form manually or forcing them to inherit from a new base class, I use TMethodsInjector to dynamically inject a logging procedure into the OnShow event of each form at runtime — all without changing the existing form code. This approach is especially useful in scenarios where inheritance or code edits aren't feasible — such as working with third-party components, plugin-based modules, or dynamically loaded forms. That said, this class is still in a beta/concept stage and hasn’t been fully battle-tested in real-world production scenarios. If you have a more robust or elegant way to achieve this kind of dynamic behavior injection without modifying the original source, I’d be genuinely glad to hear and learn from it!
×