0

我正在尝试TStringGrid通过向网格中的单元格添加视觉对象来自定义 a。一列需要在每一行中包含标准窗口按钮,另一列需要包含带有预定义选项的下拉菜单。

从我读到的最好的方法是在OnDrawCell事件处理程序中手动绘制按钮。我发现的所有示例都DrawFrameControl()没有像您在 Windows 7 或更高版本中所期望的那样绘制主题按钮。

是否有一个等效的功能DrawFrameControl()可以让我绘制一个主题按钮,如果可以,有人可以举例说明我如何使用它吗?

我还尝试创建一个向量TButtons并将每个按钮的父级设置为 StringGrid,并将每个按钮放置在相关单元格中。这也有效,但现在允许在有更多单元格可以显示可见区域时滚动网格。

我正在使用 RAD Studio 10.2 C++ builder 并使用 BCC32C 编译器(clang-enhanced)。它是一个 VCL WIN32 应用程序。

4

2 回答 2

2

是否有一个等效的功能DrawFrameControl()可以让我绘制一个主题按钮

Win32DrawFrameControl()函数用于绘制非主题的 UI 控件。要绘制主题 UI 控件,您需要使用 Win32 主题函数 - DrawThemeBackground()DrawThemeEdge()、等。这些函数由 VCL 的单元DrawThemeText()为您包装。Vcl.Themes特别是使用TThemeServices类,它有各种方法,当它们都为真时,Draw...()你可以使用它们。TThemeServices.AvailableTThemeServices.Enabled

我还尝试创建一个向量TButtons并将每个按钮的父级设置为 StringGrid,并将每个按钮放置在相关单元格中。这也有效,但现在允许在有更多单元格可以显示可见区域时滚动网格。

正确的。您必须继承 StringGrid 以拦截滚动,以便您可以手动重新定位按钮。

于 2019-09-04T20:10:12.357 回答
0

为了完整起见,这里是我为了在 TStringGrid 单元格中绘制 Windows 主题按钮而工作的代码:

void __fastcall TForm_Controller::StringGrid1DrawCell(TObject *Sender, int ACol,
          int ARow, TRect &Rect, TGridDrawState State)
{
    TStringGrid *grid;
    bool ButtonDown = false, ButtonHot = false, ButtonInFocus = false;
    TThemedElementDetails LDetails;
    TTextFormatFlags LTextFormat;
    TColor LColor, TempColor;
    TCustomStyleServices *LStyle;
    int XPos, YPos;
    TPoint points[3];

    grid = (TStringGrid *)Sender;

    //a cell with a button ('+' or '-')
    if((ACol == 0) && (ARow > 0) && grid->Cells[ACol][ARow].Length())
    {
        Rect.Left -= 4;  //override padding so button fills entire cell


        if ((FocusCell.X == ACol) && (FocusCell.Y == ARow))
            ButtonHot = true;
        if ((CellDown.X == ACol) && (CellDown.Y == ARow))
            ButtonDown = true;

        LStyle = StyleServices();
        if (LStyle->Enabled && LStyle->Available)
        {
            if (ButtonDown)
                LDetails = LStyle->GetElementDetails(tbPushButtonPressed);
            else if (ButtonHot)
                LDetails = LStyle->GetElementDetails(tbPushButtonHot);
            else if (ButtonInFocus)
                LDetails = LStyle->GetElementDetails(tbPushButtonDefaulted);
            else
                LDetails = LStyle->GetElementDetails(tbPushButtonNormal);
            LStyle->DrawElement(grid->Canvas->Handle, LDetails, Rect);

            if (LStyle->GetElementColor(LDetails, ecTextColor, LColor))
                grid->Canvas->Font->Color = LColor;
            grid->Canvas->Font->Size = 13;
            LTextFormat = (tfCenter);

            LStyle->DrawTextA(grid->Canvas->Handle, LDetails, grid->Cells[ACol][ARow], Rect, TTextFormat() << tfCenter << tfVerticalCenter);           
        }
        else    //themed drawing not available so revert to old style
            DrawButtonFace(grid->Canvas, Rect, 1, bsAutoDetect, true, ButtonDown, ButtonInFocus);
    }
}

然后我使用OnMouseDownOnMouseMove和事件来确定按钮需要处于什么状态,使用 3OnMouseLeave个对象、、。OnMouseUpTPointFocusCellPrevCellCellDown

于 2020-01-09T20:40:43.923 回答