在Delphi中将TCheckBox放在TStringGrid中 [英] Put a TCheckBox inside a TStringGrid in Delphi

查看:1270
本文介绍了在Delphi中将TCheckBox放在TStringGrid中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Delphi中的某个列的每个单元格的 TStringGrid 中放置一个 TCheckBox 。我正在使用Delphi XE。

I want to put a TCheckBox inside a TStringGrid in Delphi in every cell of certain column. I'm using Delphi XE.

推荐答案

如果启用,您应该绘制自己的复选框,最好使用视觉主题。这是一个简单的草图,如何做到这一点:

You should draw your own checkboxes, preferably using visual themes, if enabled. This is a simple sketch of how to do that:

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 主题句柄事件但原则是这里。

Of course, in a real scenario, the Checked array is not a constant, and you might wish to save the s metrics and h theme handle between cell painting events. But the principle is here.

http:/ /privat.rejbrand.se/stringcheck1.png
http:// privat。 rejbrand.se/stringcheck2.png

这里缺少的是一个功能来更改复选框的状态。您可能想要在 OnClick 处理程序中切换状态。如果您真的很认真,您还希望回复鼠标的动作,如果主题可用,请在复选框上显示鼠标悬停效果。

What is missing here is a function to alter the state of the checkboxes. You will probably want to toggle the state in an OnClick handler. If you are really serious, you'll also wish to respond to the motion of the mouse, and display the mouse hover effect on the checkboxes if themes are available.

编辑通过蓝色:要切换复选框状态此答案解释了如何使用无效方法。

EDIT by bluish: To toggle checkbox state, this answer explains how you can use Invalidate method.

这篇关于在Delphi中将TCheckBox放在TStringGrid中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆