Migaro. 技術Tips

                       

ミガロ. 製品の技術情報
IBMiの活用に役立つ情報を掲載!


【Delphi】StringGridで長い文字列を表示するテクニック

StringGridで文字列がセルの幅よりも長くなり、全て表示されないことがあります。

StringGridのOptionsプロパティでgoColSizingをTrueにすると幅を広げることができますが、
全て表示されているのかどうかは見た目では判断できません。

そこで今回は、このような状態になった場合に
StringGridのOnDrawCellイベントを使って表示を工夫する手順を紹介します。

 


省略記号(…)を表示

StringGridのOnDrawCellイベントで、WindowsAPIのDrawTextを使用し
文字を描画する際にオプションにDT_WORD_ELLIPSISを指定すると、
セルに収まらない部分を切り取り省略記号(…)を表示することができます。

以下の例ではカラムが1(左から2列目)のセルでDT_WORD_ELLIPSISを指定して文字を描画します。

//(例)
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  S  : String;
begin
  if  ACol = 1 then
  begin
      S := StringGrid1.Cells[ACol, ARow];
      // セルの塗りつぶし(すでに描画してある文字を消すため)
      StringGrid1.Canvas.FillRect(Rect);
      // 文字の描画
      DrawText(StringGrid1.Canvas.Handle, PChar(S),Length(S), Rect,
           DT_WORD_ELLIPSIS);
  end;
end;

DrawText関数で使用できるオプションについてはMSDNのページなどで説明されていますので、
そちらもご参照下さい。

 


改行コードで複数行表示

『#13#10』の改行リテラルを含んだ文字列を
DrawText関数で出力すると、その部分が改行され複数行になります。

次の例では列が3、4番目のとき改行するように文字列を設定し、
それ以外の列ではStringGridに設定されている文字列をそのまま表示するようになっています。

//(例)
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  s : string;
begin
  // 文字列の設定
  if  ARow = 0  then     // 見出し(行番号=0)のとき
  begin
    case ACol  of        // 列番号指定
      3    :  s := '売上金額' + #13#10 + '(税込)';
      4    :  s := '仕入金額' + #13#10 + '(税込)';
      else    s := StringGrid1.Cells[ACol,0];
    end;
    // セルの塗りつぶし(すでに描画してある文字を消すため)
    StringGrid1.Canvas.FillRect(Rect);
    // 文字の描画
    DrawText(StringGrid1.Canvas.Handle,
                   PChar(s), Length(s), Rect, DT_CENTER);
  end;
end;

OnDrawCellイベント内のパラメータAColARow(いずれも0始まり)で、
対象セルの行番号・列番号を取得します。

またDrawText関数を実行する前にすでに描画してある文字を消すために、
Canvas.FillRectでセルを塗りつぶす必要があります。

上記のコードではDrawText関数の最後のパラメータで DT_CENTER としているため
文字は中央寄せになりますが、左寄せならDT_LEFT、右寄せならDT_RIGHTになります。

 


右端で折り返して複数行表示

先ほどと同じDrawText関数を使用して、
ワードラップを自動で行う場合はオプションDT_WORDBREAKを使用します。

以下の例ではカラムが2(左から3列目)のセルで文字を自動で折り返します。

//(例)
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  S : string;
begin
  if  ACol = 2  then
  begin
    S := StringGrid1.Cells[ACol, ARow];
    // セルの塗りつぶし(すでに描画してある文字を消すため)
    StringGrid1.Canvas.FillRect(Rect);
    // 文字の描画
    DrawText(StringGrid1.Canvas.Handle, PChar(S),Length(S), Rect,
       DT_WORDBREAK);
  end;
end;

TStringGridのOptionsプロパティで行の高さや列の幅をドラッグで変更できるように設定すると、
セルの幅・高さに応じて自動で折り返されることが確認できます。

ただし入力途中には反映されず、入力後に自動折り返しとなります。

 

 

※図:上記1~3をすべて実装した場合の表示例

 

 

(省略記号:ミガロ.情報マガジン「MIGARO News!!」Vol.111 2010年2月号より)
(改行コード:ミガロ.情報マガジン「MIGARO News!!」Vol.107 2009年10月号より)
(右端で折り返し:ミガロ.情報マガジン「MIGARO News!!」Vol.112 2010年3月号より)