How to strike text in stringgrid (delphi)

delphi

Solution

Since the property Rows is of type TStrings you might store the needed information about being marked as deleted in the Object of the first item (e.g. quick and dirty as integer). The painting is done in OnDrawCell using the stored information.

const
  CRLF = #13#10;


procedure TForm3.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
var
  i: Integer;
begin
  With TStringGrid(Sender) do
  begin
    With Canvas Do
    begin
      if Integer(Rows[ARow].Objects[0]) = 1 then
        Font.Style := Font.Style + [fsStrikeOut]
      else
        Font.Style := Font.Style - [fsStrikeOut];
      if ARow = 0 then
        Brush.Color := clBtnFace // title
      else
        Brush.Color := clWhite;
      FillRect(Rect);
      Rect.Top := Rect.Top + 4;
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]), -1, Rect, DT_CENTER);
    end;
  end;
end;

procedure TForm3.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
const
  C_Message: Array [0 .. 1] of String = ('Disable', 'Enable');
var
  C, R: Integer;
begin
  StringGrid1.MouseToCell(X, Y, C, R);
  if (Button = mbRight) and (C > -1) and (R > 0 { -1 } ) then
  begin // Allow  Disable or Enable depending on the stored state
    if (MessageDlg(C_Message[Integer(StringGrid1.Rows[R].Objects[0])] + ' row ' + IntToStr(R), mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes) then
    begin
      If Integer(StringGrid1.Rows[R].Objects[0]) = 0 then
        StringGrid1.Rows[R].Objects[0] := TObject(1)
      else
        StringGrid1.Rows[R].Objects[0] := TObject(0);
      StringGrid1.Invalidate; // force repainting
    end;
  end;
end;

procedure TForm3.FormCreate(Sender: TObject);
var
  R, C: Integer;
begin // Demo content
  With StringGrid1 do
  begin
    FixedCols := 0;
    DefaultDrawing := false;
    Rowcount := 6;
    Colcount := 4;
    DefaultColWidth := 100;
    Rows[0].Text := 'COL 1' + CRLF + 'COL 2' + CRLF + 'COL 3' + CRLF + 'COL 4';
    for R := 1 to Rowcount - 1 do
      for C := 0 to Colcount - 1 do
        Cells[C, R] := Format('Content %d - %d', [C + 1, R]);
  end;
end;

Problem

I would like to strike text of all cells from a line in a stringgrid by right click on that line. My code is about ok, but the clicked cell from the line is not striked (the other well)!?! Also, I have to click first on a line and then right click to proceed, I would like just to right click but don't know how :-/ My code: ``` procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var i, j: integer; begin if Button = mbRight then begin j:=StringGrid1.Selection.Top; If MessageDlg('Disable row '+IntToStr(j), mtConfirmation, [mbYes, mbNo], 0, mbYes) =mrYes then begin With Stringgrid1 As TStringGrid Do With Canvas Do begin for i := 0 to 2 do begin Rect := CellRect (i, StringGrid1.Selection.Top); Font.Style := Font.Style + [fsStrikeOut]; FillRect(Rect); DrawText(Canvas.Handle, PChar(Cells[i,j]), -1, Rect ,DT_CENTER ); end; end; end; end; end; ``` Wonderfull!!! But if I want to store the striked status I also add a column containing a 'x'; it works fine BUT when I create form I load the stringrid value and some 'x' in column 3, I try to use that code in form.create to strike these row but doesn't work :-( ``` for J := 1 to stringGrid1.RowCount-1 do begin if stringGrid1.Cells[3,J]='x' then for I:=1 to 2 do begin StringGrid1.Canvas.Font.Style := Font.Style + [fsStrikeOut]; StringGrid1.Canvas.Brush.Color := clBtnFace; // title StringGrid1.Canvas.FillRect(Rect); Rect.Top := Rect.Top + 4; drawText(Canvas.Handle, PChar(StringGrid1.Cells[I, J]), -1, Rect, DT_CENTER); StringGrid1.Invalidate; end else begin StringGrid1.Canvas.Font.Style := Font.Style - [fsStrikeOut]; StringGrid1.Canvas.Brush.Color := clBtnFace; // title StringGrid1.Canvas.FillRect(Rect); Rect.Top := Rect.Top + 4; drawText(Canvas.Handle, PChar(StringGrid1.Cells[I, J]), -1, Rect, DT_CENTER); StringGrid1.Invalidate; end; end; ``` Any idea???

Original source