Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: bonmario - Marzo 20, 2013, 02:39:15 pm

Titolo: TStringGrid: testo di una cella su 2 righe
Inserito da: bonmario - Marzo 20, 2013, 02:39:15 pm
Ciao a tutti,
sto provando, ma non trovo niente.
In una StringGrid, se possibile, vorrei fare in modo che in ogni cella ci siano 2 righe di testo.
Ho provato con questo, ma non funziona
Codice: [Seleziona]
  StringGrid1.Cells[1, 1]:='riga1' + LineEnding + 'riga2';

Sapere se è possibile farlo?

Grazie in anticipo, Mario
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: Stilgar - Marzo 20, 2013, 03:02:25 pm
Hai provato a "riscrivere" il render della cella?
In questo modo se quella "std" non permette di andare a capo, la tua versione dovrebbe soddisfare questa nuova esigenza ;)

Stilgar
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: bonmario - Marzo 20, 2013, 04:54:46 pm
Non sono a certi livelli ... per me è come se leggessi l'arabo !!!!

Nel frattempo ho trovato la risposta valida anche per chi, come me, ne capice poco: http://stackoverflow.com/questions/4414870/how-to-put-cr-lf-into-a-tstringgrid-cell

Peccato che nel frattempo è cambiata l'esigenza e non mi serve più scrivere la cella su 2 righe ... in ogni caso, l'ho provata e funziona.

Ciao, Mario
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: Stilgar - Marzo 20, 2013, 05:57:21 pm
Codice: [Seleziona]
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  with TStringGrid(Sender) do
    if Pos(#13#10, Cells[ACol, ARow]) > 0 then
    begin
      Canvas.FillRect(Rect);
      Inc(Rect.Left, 2);
      Inc(Rect.Top, 2);
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]), -1, Rect,
        DT_NOPREFIX or DT_WORDBREAK);
    end;
end;

E' quello che ti suggerivo io ;) Fare il disegno (render) del contenuto della cella.
:D
Stilgar
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: bonmario - Marzo 20, 2013, 06:15:09 pm
Ah, ok ... adesso ho capito !!!

Grazie ancora, Mario
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: bonmario - Marzo 20, 2013, 07:25:03 pm
Del link di prima, io ho usato il codice della risposta n° 5:
Codice: [Seleziona]
procedure DrawSGCell(Sender : TObject; C, R : integer; Rect : TRect;
          Style : TFontStyles; Wrap : boolean; Just : TAlignment;
          CanEdit : boolean);
  { draws formatted contents in string grid cell at col C, row R;
    Style is a set of fsBold, fsItalic, fsUnderline and fsStrikeOut;
    Wrap invokes word wrap for the cell's text; Just is taLeftJustify,
    taRightJustify or taCenter; if CanEdit false, cell will be given
    the background color of fixed cells; call this routine from
    grid's DrawCell event }
var
  S        : string;
  DrawRect : TRect;
begin
  with (Sender as tStringGrid), Canvas do begin
    { erase earlier contents from default drawing }
    if (R >= FixedRows) and (C >= FixedCols) and CanEdit then
      Brush.Color:= Color
    else
      Brush.Color:= FixedColor;
    FillRect(Rect);
    { get cell contents }
    S:= Cells[C, R];
    if length(S) > 0 then begin
      case Just of
        taLeftJustify  : S:= ' ' + S;
        taRightJustify : S:= S + ' ';
        end;
      { set font style }
      Font.Style:= Style;
      { copy of cell rectangle for text sizing }
      DrawRect:= Rect;
      if Wrap then begin
        { get size of text rectangle in DrawRect, with word wrap }
        DrawText(Handle, PChar(S), length(S), DrawRect,
          dt_calcrect or dt_wordbreak or dt_center);
        if (DrawRect.Bottom - DrawRect.Top) > RowHeights[R] then begin
          { cell word-wraps; increase row height }
          RowHeights[R]:= DrawRect.Bottom - DrawRect.Top;
          SetGridHeight(Sender as tStringGrid);
          end
        else begin
          { cell doesn't word-wrap }
          DrawRect.Right:= Rect.Right;
          FillRect(DrawRect);
          case Just of
            taLeftJustify  : DrawText(Handle, PChar(S), length(S), DrawRect,
                               dt_wordbreak or dt_left);
            taCenter       : DrawText(Handle, PChar(S), length(S), DrawRect,
                               dt_wordbreak or dt_center);
            taRightJustify : DrawText(Handle, PChar(S), length(S), DrawRect,
                               dt_wordbreak or dt_right);
            end;
          end
        end
      else
        { no word wrap }
        case Just of
          taLeftJustify  : DrawText(Handle, PChar(S), length(S), DrawRect,
                             dt_singleline or dt_vcenter or dt_left);
          taCenter       : DrawText(Handle, PChar(S), length(S), DrawRect,
                             dt_singleline or dt_vcenter or dt_center);
          taRightJustify : DrawText(Handle, PChar(S), length(S), DrawRect,
                             dt_singleline or dt_vcenter or dt_right);
          end;
      { restore no font styles }
      Font.Style:= [];
      end;
    end;
end;

Su Windows, ho dovuto disabilitare questa istruzione, perché mi dava l'errore "Error: Identifier not found "SetGridHeight"":
Codice: [Seleziona]
SetGridHeight(Sender as tStringGrid);

Pur disabilitando quella riga funzionava bene.


Adesso, qui a casa, su Linux, invece non funziona, perché non ridisegna la cella.

Qualcuno di voi ha anche Delphi e mi sa dire se SetGridHeight è una funzione Delphi ed eventualmente cosa fa?

Grazie in anticipo, Mario
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: bonmario - Marzo 21, 2013, 02:35:21 pm
Trovato !!!
Casomai dovesse servire a qualcuno in futuro, ho adattato il codice postato qui sopra, in modo che faccia solo la gestione della scrittura su più righe.
Ecco il codice:
Codice: [Seleziona]
{Permette di scrivere una cella su più righe tramite l'utilizzo del LineEnding.
Aggiungere il richiamo della presente "procedure" all'interno della "DrawCell"}
procedure ScriviCellaSuPiuRighe(Sender:TObject; aCol, aRow:Integer; Rect:TRect);
var WrkStr:String;
    DrawRect:TRect;

  procedure SetGridHeight(const WrkGrid: TStringGrid);
  var Counter, NewHeight: Integer;
  begin
    NewHeight:=0;

    with WrkGrid do begin
      for Counter:=0 to RowCount - 1 do begin
        NewHeight:=NewHeight +
                   RowHeights[Counter] +
                   GridLineWidth;
      end;

      ClientHeight:=NewHeight -
                    GridLineWidth;
    end;
  end;

begin
  with (Sender as tStringGrid), Canvas do begin
    { erase earlier contents from default drawing }
    if (aRow >= FixedRows) and (aCol >= FixedCols) then begin
      Brush.Color:= Color
    end else begin
      Brush.Color:= FixedColor;
    end;
    FillRect(Rect);
    { get cell contents }
    WrkStr:=Cells[aCol, aRow];
    if Length(WrkStr) > 0 then begin
      { copy of cell rectangle for text sizing }
      DrawRect:=Rect;

      if (Pos(LineEnding, WrkStr) > 0) then begin
        //Se la riga da emettere contiene "LineEnding", riformatto la cella
        { get size of text rectangle in DrawRect, with word wrap }
        DrawText(Handle, PChar(WrkStr), Length(WrkStr), DrawRect, DT_CALCRECT or DT_WORDBREAK or DT_CENTER);
        if ((DrawRect.Bottom - DrawRect.Top) > RowHeights[aRow]) then begin
          { cell word-wraps; increase row height }
          RowHeights[aRow]:=DrawRect.Bottom - DrawRect.Top;
          SetGridHeight(Sender as tStringGrid);
        end else begin
          { cell doesn't word-wrap }
          DrawRect.Right:=Rect.Right;
          FillRect(DrawRect);
          DrawText(Handle, PChar(WrkStr), Length(WrkStr), DrawRect, DT_WORDBREAK);
        end;
      end else begin
        //La riga da emettere non contiene "LineEnding": scrivo direttamente
        DrawText(Handle, PChar(WrkStr), Length(WrkStr), DrawRect, DT_SINGLELINE or DT_VCENTER);
      end;
    end;
  end;
end;

Provato e funzionante sia su Windows che su Linux.

Ciao, Mario
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: Stilgar - Marzo 21, 2013, 05:10:10 pm
Fai una demo?
Così la mettiamo nel repository del forum (source forge).
Stilgar
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: bonmario - Marzo 21, 2013, 08:22:50 pm
Oggi e domani probabilmente no. Sabato dovrei riuscire a farla. Poi posto qui lo zip del progetto?

Ciao, Mario
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: Stilgar - Marzo 22, 2013, 09:27:29 am
Va bene.
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: bonmario - Marzo 23, 2013, 10:25:38 am
Eccolo !!!

Ciao, Mario
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: Stilgar - Marzo 23, 2013, 12:18:12 pm
https://svn.code.sf.net/p/lazarusiug/liug/trunk/demos/TStringGrid-Cella-RigheMultiple
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: Stilgar - Marzo 23, 2013, 12:18:46 pm
Inserito ;)
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: bonmario - Marzo 23, 2013, 12:34:19 pm
Grazie !!!
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: mimmolazzaro - Marzo 25, 2013, 10:32:28 am
https://svn.code.sf.net/p/lazarusiug/liug/trunk/demos/TStringGrid-Cella-RigheMultiple

Scusate, quali sono le credenziali per accedere a tale link? Bisogna iscriversi da qualche parte?

Grazie
Mimmo
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: nomorelogic - Marzo 25, 2013, 11:01:48 am
prova con http:
http://svn.code.sf.net/p/lazarusiug/liug/trunk/demos/TStringGrid-Cella-RigheMultiple
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: mimmolazzaro - Marzo 25, 2013, 12:55:34 pm
prova con http:
http://svn.code.sf.net/p/lazarusiug/liug/trunk/demos/TStringGrid-Cella-RigheMultiple

ahhh quindi basta togliere una s  :)  in https://
Grazie
Mimmo
Titolo: Re:TStringGrid: testo di una cella su 2 righe
Inserito da: bonmario - Marzo 25, 2013, 01:24:29 pm
Credo SourceForge