D2010のStringGridでのセンター、右寄せの方法

解決


たか  2009-08-30 05:45:57  No: 35535

D2010(Vista Sp1)のトライアル版を試しています。

初めてグラデーション付きStringGridを見るのですが、
DrawingStyle で gdsClassic 以外を使う場合、
(つまり、グラデーションなどを使う場合)
右寄せやセンター表示はどうすれば良いのでしょうか。

今迄のような
DrawCell...
  ...固定セルの場合
  StringGrid1.Canvas.Brush.Color := StringGrid1.FixedColor;
  StringGrid1.FillRect(Rect);
  DrawText(...DT_CENTER OR DT_VCENTER OR DT_SINGLELINE)

では対処できません。(当然ですがクラシックになる)
何方か、ご教授願います。


やはり・・  2009-08-30 09:13:22  No: 35536

2010触ってないので  正確なところわかりませんが
2007で、固定セルにグラデーションかける時には
GraphUtil.GradientFillCanvas 関数を使っています。
やはり同じように  自前で描く必要があるのではないでしょうか
ただ、元のグラデーションと全く同じにできるか
2010の環境がないので不明ですが  参考までに。


たか  2009-08-30 19:16:28  No: 35537

やはり・・さん、ありがとうございます。
しかし、本質問はグラデーションの作り方ではないんです。
D2010のStringGridは DrawingStyleに
gdsClassic
gdsGradient
gdsThemed
があります。
  gdsGradient, gdsThemed を選択すると、固定セルと選択セルがその適用を受けます。
  StringGridで編集する時に現れるInplaceEditor
というテキストボックスみたいなもの、これは編集が終わったら、
通常、消えてもらわないといけないのに否、消えるんでしょうが、その時に下層にあるCanvasのようなものに描画したその残像が残るんです。その上にテーマ描画をしているような???

  通常、StringGridはDrawCellに掛けて整然と描画させる物だと思うんですが、通常の方法ではクラシック表示しか使えません。
  エンバカデロの最新情報なども気にしているんですが、それに関する情報はまだ無いようです。


やはり・・  2009-08-31 01:34:04  No: 35538

バーチャルpcにvista  2010トライアル入れてみましたが・・・
書かれている「残像が残る」という意味が解りませんでした。
(DrawCellで自分で書いたもの以外で  勝手に上書き表示されるものは?)
DrawCellで書くのであれば、どの表示方法を選択しても一緒ではないのですか?


たか  2009-08-31 08:43:32  No: 35539

やはり・・さん、その通りですですね。勘違いしていました。
’残像が残る’と言うのは自分の今までの簡略なコードでは

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
  if (gdFixed in State) then
  begin
    //クラシックではburshを特定しなくてもよかった。
    StringGrid1.Canvas.FillRect(Rect);
    DrawText(StringGrid1.Canvas.Handle,
             PChar(StringGrid1.Cells[ACol, ARow]),
             Length(StringGrid1.Cells[ACol, ARow]), RECT,
             DT_CENTER or DT_VCENTER or DT_SINGLELINE);
  end else
  ....

こんなコードを多用してきました。これだと残像が残るのです。
問題は
  StringGrid1.Canvas.FillRect(Rect);
が1行では済まなくなった、という事ですよね。

Delphi が用意している関数やプロパティで出来ないんでしょうか?


TS  2009-08-31 18:20:52  No: 35540

>こんなコードを多用してきました。これだと残像が残るのです。
現在のDefaultDrawingは何でしょうか
DefaultDrawingがFalseだと全てのセルを自前で描画しないと
いけません。
以下はテストコードです。uses にGraphUtilを加えています。

procedure TForm1.FormCreate(Sender: TObject);
var i:integer;
begin
  with StringGrid1 do
  begin
    DefaultDrawing:=True;
    for I := 0 to ColCount-1 do
      Cells[i,0]:='Test';
  end;
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  with StringGrid1 do
  begin
    if (gdFixed in State) and (ACol in [2..5]) then
    begin
      GraphUtil.GradientFillCanvas(Canvas,GradientStartColor,GradientEndColor,Rect,gdVertical);
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
        -1, Rect, DT_CENTER OR DT_VCENTER OR DT_SINGLELINE)
    end;
  end;
end;


たか  2009-09-01 05:39:00  No: 35541

TSさん、分かり易い回答、ありがとうございます。
GradientFillCanvasの使い方が良く分かりました。
これでgdsGradientを使った固定セルの操作方法は解決できました。

StringGridの環境を
DefaultDrawing := true
Optoins の goDrawFocusSelect := true
としている場合ですが、入力セルのSelectCellも単色の青ではなく、
グラデーションがかかったようなハイライト色になっていますが、
これをそのまま生かして、入力セルを右寄せ等にするにはどうすればいいんでしょうか。

殆どTSさんのコードを使わせてもらうのですが、

procedure TForm1.FormCreate(Sender: TObject);
var
  i, n: integer;
begin
  with StringGrid1 do
  begin
    DefaultDrawing:=True;
    for i := 1 to ColCount-1 do
      Cells[i,0]:='Col' + IntToStr(i);
    for i := 1 to RowCount -1 do
      Cells[0,i] := 'Row'+ IntToStr(i);
    for i := 1 to ColCount -1 do
      for n := 1 to RowCount - 1 do
        Cells[i,n] := IntToStr(i) + ',' + IntToStr(n);
  end;
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
with StringGrid1 do
  begin
    if gdFixed in State then
    begin
      GraphUtil.GradientFillCanvas(Canvas,GradientStartColor,GradientEndColor,Rect,gdVertical);
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
        -1, Rect, DT_CENTER OR DT_VCENTER OR DT_SINGLELINE)
    end else
    begin
      Canvas.FillRect(Rect);
      Rect.Right := Rect.Right - 3;
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
        -1, Rect, DT_RIGHT OR DT_VCENTER OR DT_SINGLELINE);
    end;
  end;
end;

では、塗りつぶしが利かず、SelectCell のテキストが2重に表示されてしまいます。


TS  2009-09-01 06:27:04  No: 35542

提示のコードで全て自前で描画されている訳ですから。
>Canvas.FillRect(Rect);
の所を
if gdFixed in State then
  選択位置表示
else
  Canvas.FillRect(Rect);
として選択位置を独自描画されたらいいと思います。


TS  2009-09-01 06:28:52  No: 35543

失礼しました。
誤り  if gdFixed in State then

訂正  if gdSelected in State then


たか  2009-09-01 07:00:51  No: 35544

TSさん、助言ありがとうございます。
先のコードを以下のようにするとそれなりにはなるんですが、
(StringGrid の DrawingStyle を gdsGradient として進めています)

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
with StringGrid1 do
  begin
    if gdFixed in State then
    begin
      GraphUtil.GradientFillCanvas(Canvas,GradientStartColor,GradientEndColor,Rect,gdVertical);
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
        -1, Rect, DT_CENTER OR DT_VCENTER OR DT_SINGLELINE)
    end else
    if gdSelected in State then
    begin
      Canvas.Brush.Color := clHighlight;
      Canvas.FillRect(Rect);
      Rect.Right := Rect.Right - 3;
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
        -1, Rect, DT_RIGHT OR DT_VCENTER OR DT_SINGLELINE);
    end else
    begin
      Canvas.FillRect(Rect);
      Rect.Right := Rect.Right - 3;
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
        -1, Rect, DT_RIGHT OR DT_VCENTER OR DT_SINGLELINE);
    end;
  end;
end;

  近づいてはいるんですが、ハイライト部分(選択セル)の描画がデファルトと違います。
  このデファルトの描画を生かして右寄せには出来ないでしょうか?


TS  2009-09-01 07:36:20  No: 35545

やはり・・ さんも言っておられる様に既に独自描画を
しているだけでこのコードではデファルトの描画は
すでに使っていません。
よってデファルトの描画と同じ描画をするのみだと思います。
 if gdSelected in State then
   begin
     GraphUtil.GradientFillCanvas                             (Canvas,clBlue,clNavy,Rect,gdVertical);
     Canvas.Brush.Color := clHighlight;
     Canvas.Font.Color:=clwhite;
     DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]), -1, Rect,
          DT_RIGHT OR DT_VCENTER OR DT_SINGLELINE);
   end


TS  2009-09-01 07:43:25  No: 35546

デファルト  −>デフォルト  ?どっちでしたっけ


たか  2009-09-01 08:05:43  No: 35547

TSさん、何度もすいません。
デフォルトの描画がどうなっているか拡大して見てみたら
やはり、選択セルのハイライトはグラデーションがかかっているんですね。
そこで自分なりにデフォルトを真似てみました。

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
with StringGrid1 do
  begin
    if gdFixed in State then
    begin
      GraphUtil.GradientFillCanvas(Canvas,GradientStartColor,GradientEndColor,Rect,gdVertical);
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
        -1, Rect, DT_CENTER OR DT_VCENTER OR DT_SINGLELINE)
    end else
    if gdSelected in State then
    begin
      GraphUtil.GradientFillCanvas(Canvas,$00FFCA93,clHighlight,Rect,gdVertical);
      Canvas.Pen.Color := $00FF9933;
      Canvas.Rectangle(Rect);//BrushをbsClear とする
      Rect.Right := Rect.Right - 3;
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
        -1, Rect, DT_RIGHT OR DT_VCENTER OR DT_SINGLELINE);
    end else
    begin
      Canvas.FillRect(Rect);
      Rect.Right := Rect.Right - 3;
      DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
        -1, Rect, DT_RIGHT OR DT_VCENTER OR DT_SINGLELINE);
    end;
  end;
end;

ここで使っているカラー($00FFCA93など)はあくまでハイライト色をデフォルトとした場合です。

これで殆どデフォルトの描画で右寄せが完成しました。

gdsThemed の場合、Rect(範囲)が変わるだけで、同じような感じで出来ると思います。

やはり・・さん、TSさん、ありがとうございました。


たか  2009-09-01 10:33:26  No: 35548

ちなみに上の最後のコードでは
Canvas.Rectangle(Rect);
で描いた線が残り、見苦しいので
onMouseDownで

procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  StringGrid1.Refresh;
end;

としておくと大丈夫です。


TS  2009-09-01 16:56:58  No: 35549

お節介ですが
>描いた線が残り、見苦しいので
上記は確認できませんでしたが。
 if gdSelected in State then
 else
   //以下を追加
   Canvas.Pen.Color := clwhite;
   Canvas.Rectangle(Rect);
ではどうなりますか。


たか  2009-09-02 05:04:13  No: 35550

TSさん、ありがとうございます。
TSさんのコードはGood  Idea だと思います。
使わせていただきます。
この度は初心者である私に色々助言頂きましてありがとうございました。
ここまで来れたのはTSさんのアドバイスのお陰です。
これからも我々初心者に分かり易いアドバイス、宜しくお願い致します。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加