Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to strike text in stringgrid (delphi)

Tags:

delphi

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

like image 202
PhilLu Avatar asked Oct 21 '22 19:10

PhilLu


1 Answers

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;
like image 184
bummi Avatar answered Oct 23 '22 23:10

bummi