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???