としてここに書こうかと思いましたがCellだけの描画ですのでダメだと考え、
procedure Paint; override;
procedure TCustomHsCalendarGrid.Paint;
var
R: TRect;
H, W, Offset: Integer;
begin
inherited Paint;
FillChar(R, SizeOf(R), 0);
H := 30;
W := 100;
Offset := 50;
R.Top := 100;
R.Left := 10;
R.Right := R.Left + W;
R.Bottom := R.Top + H;
Canvas.Brush.Color := clAqua;
Canvas.FillRect(R);
R.Top := Offset+ R.Bottom;
R.Right := R.Left + W;
R.Bottom := R.Top + H;
Canvas.Brush.Color := clDkGray;
Canvas.FillRect(R);
R.Top := Offset+ R.Bottom;
R.Right := R.Left + W;
R.Bottom := R.Top + H;
Canvas.Brush.Color := clRed;
Canvas.FillRect(R);
end;
とゆうように書きましたが、描画はされるがスクロールされると消えしまうだ
けでなくスクロールによって消えていた箇所の描画が表示されません。
どうすればよいでしょうか?
こんなのはどうかな?
--------------------------------
http://khe00221.image.coocan.jp/
--------------------------------
procedure TForm2.StringGrid1DrawCell(Sender: TObject; ACol, ARow:
Integer;
ARect: TRect; State: TGridDrawState);
var
X1,X2,W,StartCol,StartRow : Integer;
XRect : TRect;
begin
X1 := 30; // 数値
X2 := 50; // 1 Col 当たりの数値
StartCol := 2; // 開始 Col
StartRow := 2; // 開始 Row
if ARow =StartRow then
begin
if ACol >= StartCol then
begin
if (ACol - StartCol) * X2 < X1 then
begin
if (X1 div X2) < (ACol-StartCol+1) then
begin
W := (ARect.Right - ARect.Left) * (X1 mod X2) div X2;
XRect := Rect(ARect.Left,ARect.Top,ARect.Left +
W,ARect.Bottom);
StringGrid1.Canvas.Brush.Color := clRed;
StringGrid1.Canvas.FillRect(XRect);
end
else
begin
if ACol = StartCol then
begin
XRect :=
Rect(ARect.Left,ARect.Top,ARect.Right+1,ARect.Bottom);
end
else
begin
XRect :=
Rect(ARect.Left-1,ARect.Top,ARect.Right+1,ARect.Bottom);
end;
StringGrid1.Canvas.Brush.Color := clRed;
StringGrid1.Canvas.FillRect(XRect);
end;
end;
end;
end;
Exit;
end;
ソースコードのご提示ありがとうございました。
ただ、DrawCellイベントでは、セル単位での描画を対称にしています。ぼくが
したいのはRow単位やCol単位での描画したいのです。
http://khe00221.image.coocan.jp/index.php?FrontPage%2FTips2%2F%A5%B3%A5%
F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8%20-%20TStringGrid%2F%A5%B0%A5%E9%A5%D5%
A4%F2%C9%C1%B2%E8%A4%B9%A4%EB
-----Original Message-----
From: 近藤 [mailto:t_k...@hazimesoft.com]
Sent: Wednesday, February 06, 2008 5:58 PM
To: Del...@ml.users.gr.jp
まことに申し訳ありません。いろいろとコメント感謝しております。
おっしゃってられる意味は理解しております。
ただ、やはりDrawCellイベントだと文字がCell単位になるのではという考えか
らDrawCellイベントでは。。。と考えています。最初に「文字も」と書いとけば
よかったと反省しています。
procedure TForm2.StringGrid1DrawCell(Sender: TObject; ACol, ARow:
Integer;
ARect: TRect; State: TGridDrawState);
begin
if (ACol=3) and (ARow=3) then
begin
StringGrid1.Canvas.Brush.Color := clRed;
StringGrid1.Canvas.FillRect(Rect(ARect.Left,ARect.Top,ARect.Right*2,ARec
t.Bottom));
StringGrid1.Canvas.TextOut(ARect.Left+2,ARect.Top+1,'AAAAAAAAAAAAAAAAAAA
');
end;
end;
等とすればCELLを越えて描画できますよ?
全て自前で描画する必要はありますが
-----Original Message-----
From: 近藤 [mailto:t_k...@hazimesoft.com]
Sent: Wednesday, February 06, 2008 7:08 PM
To: Del...@ml.users.gr.jp
|DefaultDrawing を False にして
|全て自前で描画する必要はありますが
他の描画処理を自前で書くには困難ですので、Paint;でできないか?というご
相談を申し上げているところです。
要件があいまいなような気がしますが、
T~Gridを内部で保持したTScrollBox継承クラスを作成し、
さらに棒グラフっぽいTPanelなりTProgressBarなりを
動的に生成すれば良いのではないでしょうか?
GridではスクロールしないでScrollBoxでってことで
--
SilverWhale <Silve...@nifty.com>
Delphi5/7 Enterprise
WinXP Pro SP2
やりたいことがつかめないのですが、
■Paint は無効領域を描画するだけです。無効領域を適切に
管理しないとスクロールで表示が乱れるのは当然です。
TCustomGrid の中には InvalidateCell とか InvalidateRow とか
無効領域管理のメソッドが用意されていますのでこれらを活用しましょう。
#スクロールとは無関係に一定の場所に描きたいのでしょうか???
■DrawCellのOverride も検討すべきです。
こちらのほうが必セルの座標の取得が簡単だからです。
DefaultDarwing を OFF にして、同様の処理を DrawCellに持たせるのは
容易です。また、セルに跨って文字を描くのを複数回の DrawCell の描画に
分担させるのもそれほど難しくありません。
Quoting 近藤 <t_k...@hazimesoft.com>:
----------
(株)ブレーン 中村拓男
|やりたいことがつかめないのですが、
理想的にはスケジューラーとして横帯の棒グラフ形状の表示及び文字列などの
表示ができればOKだと考えています。もちろんマウスで移動という処理ができれ
ば理想ですが、一足飛びや2足飛びではできませんから、現段階では表示のみで
OKです。
|■Paint は無効領域を描画するだけです。無効領域を適切に
|管理しないとスクロールで表示が乱れるのは当然です。
で、とりあえず、以下の処理を書いてみました。表示や文字はDrawCell2で書
くことでぎりぎり合格点の可能性があるという感じです。
procedure TCustomxxxxGrid.Paint;
var
DrawInfo: TGridDrawInfo;
//このままの処理では1行に1つだけ
procedure DrawCells2(ARow: Longint; StartY, StopX, StopY: Integer);
var
CurCol, CurRow: Longint;
Where: TRect;
begin
CurRow := ARow;
Where.Top := StartY + 20;
while (Where.Top < StopY) and (CurRow < RowCount) do
begin
CurCol := 0;//ACol;
Where.Left := ColWidths[CurCol] + 1;
Where.Bottom := Where.Top + RowHeights[CurRow] - 40;
Where.Right := Where.Left - 1 + (DefaultColWidth + DrawInfo.
Vert.EffectiveLineWidth) * 4;//ColWidths[CurCol]* 3;// * (ColCount -
4));
if (Where.Right > Where.Left) and RectVisible(Canvas.Handle,
Where) then
begin
if DefaultDrawing or (csDesigning in ComponentState) then
DrawCell2(CurCol, CurRow, Where); //ここに描画コード
end;
with DrawInfo do
begin
Where.Left := Where.Right + Horz.EffectiveLineWidth;
Where.Top := Where.Bottom + Vert.EffectiveLineWidth + 40;
end;
Inc(CurRow);
end;
end;
begin
inherited Paint;
CalcDrawInfo(DrawInfo);
with DrawInfo do
DrawCells2(TopRow, Vert.FixedBoundary, Horz.FixedBoundary, Vert.
GridBoundary);
end;
しかし、上記コードだと将来的な処理(マウスイベント、フォーカスイベント
など)へのコーティングが無理そうな気がしています。
ここは、TGraphicControlあたりを継承したものをGridに載せたらよいのか
な?とも考えています。
|
|TCustomGrid の中には InvalidateCell とか InvalidateRow とか
|無効領域管理のメソッドが用意されていますのでこれらを活用しましょう。
|#スクロールとは無関係に一定の場所に描きたいのでしょうか???
スクロールイベントなどはGridで取れますか?取れれば再描画処理でOKです。
実はスクロールイベントの取り方を知りません。
再描画処理が使えるとバリエーションが増えます。
余り細かく見ていないのですが、WMVScroll/WMHScroll メッセージ処理メソッドで
スクロールメッセージを捕らえています。
procedure WMVScroll(var Msg: TWMVScroll); message WM_VSCROLL;
procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL;
procedure XXXGrid.WMVScroll(var Msg: TWMVScroll);
begin
inherited;
invalidate;
end;
procedure XXXGrid.WMHScroll(var Msg: TWMHScroll);
begin
inherited;
invalidate;
end;
などとするのがよいかもしれません。
#これらのメソッドでは ScrollWindow でウィンドウ内の表示イメージを転送して
#再描画を最小限に抑えているようです。
#Invalidate で再描画領域がウィンドウ全体に広がると思いますが、未試験です。
Quoting 近藤 <t_k...@hazimesoft.com>:
> スクロールイベントなどはGridで取れますか?取れれば再描画処理でOKです。
> 実はスクロールイベントの取り方を知りません。
> 再描画処理が使えるとバリエーションが増えます。
>
----------
(株)ブレーン 中村拓男
| procedure WMVScroll(var Msg: TWMVScroll); message WM_VSCROLL;
| procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL;
これはぼくもこの質問を上げる前にチェックしてみましたが、スクロールバー
の操作のみのメッセージは取得できますが、その他のスクロールのメッセージは
取得できなかったです。
ですから、Gridの場合のこうした処理にはPaintイベントしかダメかな?など
と考えているところです。