特定の列のすべてのセルにDelphiのTCheckBox
内部を配置したいと思います。TStringGrid
DelphiXEを使用しています。
3 に答える
有効になっている場合は、できれば視覚的なテーマを使用して、独自のチェックボックスを描画する必要があります。これは、その方法の簡単なスケッチです。
const
Checked: array[1..4] of boolean = (false, true, false, true);
procedure TForm4.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
const
PADDING = 4;
var
h: HTHEME;
s: TSize;
r: TRect;
begin
if (ACol = 2) and (ARow >= 1) then
begin
FillRect(StringGrid1.Canvas.Handle, Rect, GetStockObject(WHITE_BRUSH));
s.cx := GetSystemMetrics(SM_CXMENUCHECK);
s.cy := GetSystemMetrics(SM_CYMENUCHECK);
if UseThemes then
begin
h := OpenThemeData(StringGrid1.Handle, 'BUTTON');
if h <> 0 then
try
GetThemePartSize(h,
StringGrid1.Canvas.Handle,
BP_CHECKBOX,
CBS_CHECKEDNORMAL,
nil,
TS_DRAW,
s);
r.Top := Rect.Top + (Rect.Bottom - Rect.Top - s.cy) div 2;
r.Bottom := r.Top + s.cy;
r.Left := Rect.Left + PADDING;
r.Right := r.Left + s.cx;
DrawThemeBackground(h,
StringGrid1.Canvas.Handle,
BP_CHECKBOX,
IfThen(Checked[ARow], CBS_CHECKEDNORMAL, CBS_UNCHECKEDNORMAL),
r,
nil);
finally
CloseThemeData(h);
end;
end
else
begin
r.Top := Rect.Top + (Rect.Bottom - Rect.Top - s.cy) div 2;
r.Bottom := r.Top + s.cy;
r.Left := Rect.Left + PADDING;
r.Right := r.Left + s.cx;
DrawFrameControl(StringGrid1.Canvas.Handle,
r,
DFC_BUTTON,
IfThen(Checked[ARow], DFCS_CHECKED, DFCS_BUTTONCHECK));
end;
r := Classes.Rect(r.Right + PADDING, Rect.Top, Rect.Right, Rect.Bottom);
DrawText(StringGrid1.Canvas.Handle,
StringGrid1.Cells[ACol, ARow],
length(StringGrid1.Cells[ACol, ARow]),
r,
DT_SINGLELINE or DT_VCENTER or DT_LEFT or DT_END_ELLIPSIS);
end;
end;
もちろん、実際のシナリオでは、配列は定数ではないため、セルペイントイベント間でメトリックとテーマハンドルChecked
を保存することをお勧めします。しかし、原則はここにあります。s
h
ここで欠けているのは、チェックボックスの状態を変更する機能です。OnClick
ハンドラーで状態を切り替えることをお勧めします。本当に真面目な場合は、マウスの動きに反応し、テーマが利用可能な場合はチェックボックスにマウスホバー効果を表示することもできます。
青みがかった編集:チェックボックスの状態を切り替えるには、この回答でメソッドの使用Invalidate
方法を説明します。
TCheckBox
内に実際のコントロールを配置しようとしないでくださいTStringGrid
。代わりに、Win32 API関数でグリッドのOnDrawCell
イベントを使用してDrawFrameControl()
、必要に応じて各セル内にチェックボックスコントロールの画像を描画します。OnClick/OnMouse...
グリッドのプロパティでイベントを使用してObjects[][]
、必要に応じて各セルのチェックされた状態を追跡できます。TStringGrid
実際のコントロールをホストするように設計されていないため、これは管理がはるかに簡単です。
チェックボックスをサポートする、 RomanMochalovによるExGridViewと呼ばれる仮想グリッドを使用します。
Unicodeなどに移植されたGridViewの私自身の変更されたフォークは、TGridViewの代わりにTExGridViewという名前で、チェックボックスのデモがあり、ここでは/ wpostma/exgridviewとしてbitbucketにあります。
ExGridViewコンポーネントのプロパティインスペクターにCheckboxプロパティがあり、これをtrueに設定する必要があります。次に、Columnのチェックボックスタイプがcheckboxまたはラジオボタンに設定されるようにColumnプロパティを設定する必要があります。次に、GetCheckStateイベントコールバックを実装する必要があります。bitbucketプロジェクトに含まれているデモを参照してください。
このコードの元のソースはここにありましたが、最近のバージョンではビルドできません。私のビットバケットバージョンは、Delphi 2007、2009、および2016年現在のすべてのバージョン(Delphi 10 Seattle)でテストされ、動作しています。