7や2007からXE2へアプリを移植しています。
その中で、StringGridの表示がおかしくなってしまいます。
具体的には、各セルの表示をセルの中心にしている場合、
Fixセルと(1,1)のセルが左端(標準の表示)とセルの中心の表示の
二重表示になります。他のセルは問題なく中心の表示になっています。
確認のため、新しいフォームにButtonとStringGridを一つ置き、
下記のコードで実験しても同様です。
procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
begin
//適当なデータの表示
for i := 0 to 4 do
begin
StringGrid1.Cells[i,0] := IntToStr(i);
StringGrid1.Cells[i,1] := IntToStr(i*i);
StringGrid1.Cells[i,2] := IntToStr(i*i*2);
StringGrid1.Cells[i,3] := IntToStr(i*i*3);
end;
end;
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
X,Y,SH,SW :Integer;
begin
StringGrid1.Canvas.FillRect(Rect);
SW := StringGrid1.Canvas.TextWidth( StringGrid1.Cells[ACol,ARow]) div 2;
SH := StringGrid1.Canvas.TextHeight(StringGrid1.Cells[ACol,ARow]) div 2;
X := Rect.Left + (Rect.Right - Rect.Left) div 2 - SW ;
Y := Rect.Top + (Rect.Bottom - Rect.Top) div 2 - SH ;
StringGrid1.Canvas.TextOut(X,Y,StringGrid1.Cells[ACol,ARow]);
end;
StringGridをクラシック表示にすると問題なく表示できますが・・・・・
対処方法は何かないでしょうか?
よろしくお願いします。
>https://www.petitmonte.com/bbs/answers?question_id=7366
こっちの答えににもなるだけど
TStringGrid = class(vcl.Grids.TStringGrid);
procedure TForm2.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
X,Y,SH,SW :Integer;
ARect: TRect;
FOnDrawCell: TDrawCellEvent;
S: String;
C: TColor;
begin
FOnDrawCell := StringGrid1.OnDrawCell;
StringGrid1.OnDrawCell := nil;
if StyleServices.Enabled then Rect.Left := Rect.Left - 4;
//背景再描画
if gdFixed in State then C := StringGrid1.FixedColor else C := StringGrid1.Color;
StringGrid1.DrawCellBackground(Rect,C,State,ACol,ARow);
//テキスト再描画
S := StringGrid1.Cells[ACol,ARow];
SW := StringGrid1.Canvas.TextWidth(S);
SH := StringGrid1.Canvas.TextHeight(S);
X := Rect.Left + ((Rect.Right - Rect.Left) - SW) div 2;
Y := Rect.Top + ((Rect.Bottom - Rect.Top) - SH) div 2;
if StyleServices.Enabled then
begin
ARect := System.Classes.Rect(X-6,Rect.Top,Rect.Right,Rect.Bottom);
end
else
begin
ARect := System.Classes.Rect(X-2,Y-2,Rect.Right,Rect.Bottom);
end;
StringGrid1.DrawCell(ACol,ARow,ARect,State);
StringGrid1.OnDrawCell := FOnDrawCell;
end;
KHE00221さま、ありがとうございます。
上記コードで二重表示の問題はクリアーできました。
ただ、2つほど疑問が残りましたのでお教えいただけますでしょうか?
1.何も処理をしないコード(7や2007でのコード)の場合
Fixedセル以外にセル(1,1)も2重表示になりますがなぜなのでしょうか?
2.KHE00221さまのコードを使用させていただいた場合、
StringGridのフォーカスが当たっているセルの表示について
他のコンポーネントにフォーカスがある場合==>表示内容が消える
StringGridにフォーカスが当たっている場合==>内容が表示される
過去に「フォーカスの当たっているセルの背景の色をなになにする」と
同様の考え方だろうかな?と思い、探しましたが見つけることができませんでした。
このため、疑問として残ってしまいました。
申し訳ありませんが、疑問の解消のお手伝いをよろしくお願いいたします。
こんにちは.
TStringGridのOnDrawCellイベントは,内部でDrawCellメソッドを実行しています.
ソースコードを追いかけるのは大変ですが...
OnDrawCellイベントが呼び出された時点で,DrawCellメソッドが実行されています.
このDrawCellメソッドは既に文字の描画を行っています.
したがって,既にレスにあるように,一度背景を塗り潰さないと,DrawCellが描画した
内容が見えてしまうことになります.
OnDrawCellで描画すると,重ね書きということになります.
「難解」と言われている私のサイトの記事ですが,参考になれば,
[05_セルのカスタム描画 - 文字列のアライメント]
http://mrxray.on.coocan.jp/Delphi/plSamples/050_TStringGrid_OnDrawCell.htm#05
>1.何も処理をしないコード(7や2007でのコード)の場合
>Fixedセル以外にセル(1,1)も2重表示になりますがなぜなのでしょうか?
意味が分からない
>2.KHE00221さまのコードを使用させていただいた場合、
>StringGridのフォーカスが当たっているセルの表示について
> 他のコンポーネントにフォーカスがある場合==>表示内容が消える
> StringGridにフォーカスが当たっている場合==>内容が表示される
表示内容消えないのでなんとも・・・・
フォーカスの色の事なら
//背景再描画
if gdFixed in State then
begin
C := StringGrid1.FixedColor;
end
else
begin
if gdSelected in State then C := clRed else C := StringGrid1.Color;
end;
StringGrid1.DrawCellBackground(Rect,C,State,ACol,ARow);
で指定できる
>>1.何も処理をしないコード(7や2007でのコード)の場合
>>Fixedセル以外にセル(1,1)も2重表示になりますがなぜなのでしょうか?
>意味が分からない
確認されず意味不明???
質問時のコードで3台のPCで7、2007、XE、XE2で確認しています。
[0,0] [0,1] [0,2] [0,3]====>Fixd
[1,0] [1,1]=====>>ここ「Fixedでないセル」が2重表示です
[2,0]
[3,0]
↑
Fixed
Fixedセルが2重表示は分かるにしても、どうしてセル[1,1]までそうなのか
他のセルはOKです。
>表示内容消えないのでなんとも・・・・
同様に3台で確認していますが、質問時のコードで、
Button1でStringGridに内容を表示させると
StringGridではセル[1,1]にフォーカスがあたっていると思いますが、
フォーム上ではButton1にフォーカスがあります、
この状態で、StringGridのセル[1,1]の表示が消えた形になります。
ここで、StringGridをクリック(選択)すると[1,1]のセルの表示がされます。
StringGrid.SetFocusで回避はできますが、
同一フォーム上で他の処理をしていく場合(ほかのButton等が在った場合など)、
この表示の問題が出てきます。
腕ずくで回避しないといけないのでしょうか????
Fixedを描画するときは fsClear
Cells を描画するときは fsSolid
>Fixedセルが2重表示は分かるにしても、どうしてセル[1,1]までそうなのか
Cells(1,1) は Fixed の直後なので fsClear なので 2重に表示されてしまう
>この状態で、StringGridのセル[1,1]の表示が消えた形になります。
消えるじゃなくて2重表示?
Cellをクリックすると
1) ClickしたCell描画 (fsSolid)
2) Clickする前にあった Cell を描画 (fsSolid)
3) なぜか Cell(0,0) を描画 (fsClear)
ここでフォーカスを失うと fsClear のまま fsSelected だったセルが
描画されるので 2重に表示される
>Cells(1,1) は Fixed の直後なので fsClear なので 2重に表示されてしまう
これうそ
gsSelected は fsClear
gsFouces は fsSolid
最初 Cells(1,1) が Selected で、 Button Click で フォーカス
をうしなって Cells(1,1) だけ fsClear
なので ほかのセルを選んで Button1 Click するとそこが2重表示
クリックすると Selected と Fouces になるので Solid
エリア指定すると Fouces のとこは fsSolid だけど
ほかのとこは fsClear で2重表示
あくまで動作からの推測
問題の切り分けです
1.「2重表示」==>まだなぜなのかは理解できていませんが、
お教えいただいたコードで回避できました。
2.セル[1,1]が表示されない
お教えいただいたコードでやってみて同様でした。
Button1でStringGridに適当なデータを表示します。
[0,0] [0,1] [0,2] [0,3]====>Fixd
[1,0] [1,1]=====>>このセルの内容が表示されません
[2,0]
[3,0]
フォーム上にButton2とButton3を置き
procedure TForm1.Button2Click(Sender: TObject);
begin
StringGrid1.SetFocus;//===> セル[1,1]のデータが表示される(2重表示ではない)
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Button1.SetFocus;//===> セル[1,1]のデータ表示が消える
end;
このような動きをします。
実際のアプリを作成した場合使い勝手が悪くなります、
回避方法はないでしょうか?
追加です
実験していくと
StringGridがフォーカスを失うとき、
選択されているセルの内容の表示が消えます。
上の Buttonでフォーカスを他のコンポーネントに移すとき
StringGridで選択されているセルが任意の場合でも、
そのセルのデータ表示が消えてしまいます。
セル[2,2]に選択されているときに、
ほかのコンポーネントにフォーカスが移動すると、
セル[2,2]の内容が非表示になってしまいます。
追加実験しました
XP+XE XP+XE2では StringGridからフォーカスが他のコンポーネントに移ると、
StringGridのフォーカスがあたっているセルで、表示が消えます。==>上の実験
7(64Bit)+XE2 の場合KHE00221さまのコードで正常に表示されます。
StringGridがフォーカスを失っても正常な表示です。
OSによって動きが違ってきていますので考えてしまいます。
XP + XE2 できえないので
わかりません!
ツイート | ![]() |