밑에 답변주신 이중철님 정말 감사합니다. 왼쪽위에 잔상 check박스가 남던 문제는 해결 되었습니다..
다시 스트링 그리드에 대한 질문인데요.
팁란에 있는 스트링 그리드에 체크 박스 넣기 방법과
홍성락님께서 올리신 방법을 조합해서 사용하려고 합니다.
그런데 문제가 발생합니다. 스크롤이 없을 땐 문제가 없는데 row값이 커지면서 스크롤을 하게 되면
찍힌 체크의 잔상이 남아 체크가 엉망이 되버립니다.
최소화 시켰다가 다시 확대하면 제대로 찍혀 있는걸로 봐서
체크된게 옮겨지는게 아니라 스크롤 되고 다시 그리면서 잔상이 남는거 같습니다.
팁란에 타락천사님이 올리신 코드를 보니 제가 사용한 방법이 그 방법인거 같은데
밑에 체크박스 잔상을 어떻게 해야하는가에 대한 질문이 몇개 있는데
그에 대한 해결 방안이 안올라와 있네요. 머슴님이 수정하신 방법으로도 해결이 안되구요.
질문만 있고 답변이 없으니 답답합니다. 아시는 분(이미 이 방법을 사용하고 계시는 것같은 홍성락님이나 타락천사님도... 부탁드립니다... T_T)은 꼭 답변해 주세요.
밑에는 제 소스입니다.
-------------------------------------------------------------------
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, Grids, jpeg, ExtCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
StringGrid1: TStringGrid;
procedure FormShow(Sender: TObject);
procedure CheckBoxMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
procedure StringGridInCheckBoxCreate(sg :TStringGrid; Col, Row :Integer; pChecked :Boolean);
procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormShow(Sender: TObject);
var
i, j : integer;
begin
With StringGrid1 Do Begin
RowCount := 20;
ColCount := 4;
ColWidths[1] := 60;
ColWidths[3] := 230;
for i := 0 to ColCount-2 do begin
for j := 0 to RowCount-1 do begin
if i = 1 then
StringGridInCheckBoxCreate(StringGrid1,i,j,True)
ELSE
StringGridInCheckBoxCreate(StringGrid1,i,j,false);
end;
end;
end;
end;
procedure TForm1.StringGridInCheckBoxCreate(sg :TStringGrid; Col, Row :Integer; pChecked :Boolean);
var
LeftWidth, iCnt :Integer;
begin
if not (sg.Objects[Col, Row] is TCheckBox) then
sg.Objects[Col, Row] := TCheckBox.Create(sg);
with TCheckBox(sg.Objects[Col, Row]) do
begin
OnMouseUp := CheckBoxMouseUp;
Parent := sg;
Checked := pChecked;
BoundsRect := sg.CellRect(Col, Row);
Width := 14;
Height := sg.RowHeights[Row];
Hint := inttostr(Row);
showHint := False;
visible := false;
end;
end;
procedure TForm1.CheckBoxMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: integer);
var
i, Row: integer;
begin
with TCheckBox(Sender) do
Row := StrToInt(Hint);
for i := 0 to StringGrid1.ColCount-1 do begin
if (StringGrid1.objects[i,Row] is TCheckBox) then
TCheckBox(StringGrid1.objects[i,Row]).Checked := false;
end;
TCheckBox(Sender).Checked := true;
end;
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
CellStr : String;
begin
if (TStringGrid(Sender).Objects[ACol, ARow] is TCheckBox) then begin
with TCheckBox(TStringGrid(Sender).Objects[ACol, ARow]) do begin
top := Rect.Top;
Left := (Rect.Left+Rect.Right) Div 2 - 7;
visible := true;
end;
with TStringGrid(Sender) do begin
// Canvas.Font := Font;
// Canvas.TextRect(Rect, Rect.left+14,(Rect.Top+Rect.Bottom-Font.Size-2) div 2, TStringGrid(Sender).Cells[ACol,ARow] );
end;
end
else
if ACol = 4 then // 가운데 정렬
begin
with TStringGrid(Sender).Canvas do
begin
CellStr := TStringGrid(Sender).Cells[ACol, ARow];
Left := ((Rect.Right - Rect.Left - TStringGrid(Sender).Canvas.TextWidth(CellStr)) div 2) + Rect.Left;
FillRect(Rect);
TextOut(Left, Rect.Top + 2, CellStr);
end;
end;
END;
end.
체크박스 만드는 StringGridInCheckBoxCreate 에 이 루틴을
추가해 보세요..
top := sg.CellRect(Col, Row).Top;
Left := sg.CellRect(Col, Row).Left + sg.ColWidths[Col] Div 2 - 7;
TopLeftChanged 이 부문 추가해서 넣으시고
procedure TForm1.StringGrid1TopLeftChanged(Sender: TObject);
var i , j : integer;
begin
StringGrid1.Visible := false;
for i := 0 to StringGrid1.RowCount - 1 do
for j := 0 to 2 do begin
StringGrid1DrawCell(StringGrid1, j, i, StringGrid1.CellRect(j,i), [gdSelected ] );
end;
StringGrid1.Visible := True;
end;
에고 아까 올린것은 테스트를 안해봐서요.. 쩝 지송..
이놈의 스트링그리드 짜증나는 컨트롤이네요..