Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 查找文本高度并设置BS_GROUPBOX控件的标题背景色_C++_Winapi_Directx - Fatal编程技术网

C++ 查找文本高度并设置BS_GROUPBOX控件的标题背景色

C++ 查找文本高度并设置BS_GROUPBOX控件的标题背景色,c++,winapi,directx,C++,Winapi,Directx,我正在设计一个组框控件,其目的是自动排列附加到它的控件 组框包含一个可选的标题文本,我的问题是,当我将Y坐标设置为0(零)时,标题文本将重叠(不可见),如下所示: 我算出,标题文本的高度大约为20,因此如果我手动将Y坐标设置为20,我会得到正确的结果: 所以,我的第一个问题是,有没有一种传统的方法来获取分组框标题的高度 我确实看了一下GetSystemMetrics(),但似乎没有一个度量标准 第二个问题,您可以看到示例标题文本的背景如何不是相同的浅蓝色,而是灰色 我必须处理WM_PAINT

我正在设计一个组框控件,其目的是自动排列附加到它的控件

组框包含一个可选的标题文本,我的问题是,当我将
Y
坐标设置为
0
(零)时,标题文本将重叠(不可见),如下所示:

我算出,标题文本的高度大约为20,因此如果我手动将
Y
坐标设置为20,我会得到正确的结果:

所以,我的第一个问题是,有没有一种传统的方法来获取分组框标题的高度

我确实看了一下
GetSystemMetrics()
,但似乎没有一个度量标准

第二个问题,您可以看到示例标题文本的背景如何不是相同的浅蓝色,而是灰色

我必须处理
WM_PAINT
才能更改此颜色吗?我希望避免这种情况,因为只需处理
WM_ERASEBKGND
就可以轻松设置组框背景色,但标题背景始终保持灰色(不在
WM_ERASEBKGND
中处理)

下面是我用来擦除背景的代码。它是代码注释中链接中代码的修改版本。现在它使用了一些自定义类型、宏和DirectX,但这不适用于标题背景。我肯定我遗漏了一些东西来绘制标题颜色

case WM_ERASEBKGND:
{
    /*
    SYMPTOMS
    ========
    When a BS_GROUPBOX style window is created, its background does not erase
    correctly.

    CAUSE
    =====
    The parent window of the BS_GROUPBOX style window has the WS_CLIPCHILDREN style,
    which prevents the parent window from erasing the group box's background.

    RESOLUTION
    ==========
    Subclass the group box window to process the WM_ERASEBKGND message by erasing
    its background. Listed below is a code fragment to demonstrate this procedure.

    STATUS
    ======
    This behavior is by design.

    MORE INFORMATION
    ================
    https://jeffpar.github.io/kbarchive/kb/079/Q79982/
    */

    HRESULT hr = CreateGraphicsResources();
    SmartObject<DrawableWindow> parent = nullptr;

    if (FAILED(hr) || !mParent->IsDrawable())
        return FALSE;

    // Obtain parent window's background color.
    parent = mParent;
    const D2D1::ColorF color = parent->GetBackgroundColor();
    mpBrush->SetColor(color);

    // Other drawing variables
    RECT rect{ };
    HDC hDC = GetDC(mhWnd);
    auto pRender = std::get<1>(mpRenderTarget);
    const D2D1_SIZE_F size = pRender->GetSize();
    const D2D1_RECT_F rectangle = D2D1::RectF(0, 0, size.width, size.height);

    // Erase the group box's background.
    GetClientRect(mhWnd, &rect);
    pRender->BindDC(hDC, &rect);

    pRender->BeginDraw();
    pRender->FillRectangle(&rectangle, mpBrush);
    hr = pRender->EndDraw();

    if (FAILED(hr))
    {
        ShowError(ERR_BOILER, hr);
    }

    ReleaseDC(mhWnd, hDC);

    // Instruct Windows to paint the group box text and frame.
    InvalidateRect(mhWnd, &rect, FALSE);

    // Insert code here to instruct the contents of the group box
    // to repaint as well.

    return TRUE; // Background has been erased.
}
case WM_ERASEBKGND:
{
/*
症状
========
创建BS_GROUPBOX样式的窗口时,其背景不会擦除
正确地
原因
=====
BS_GROUPBOX样式窗口的父窗口具有WS_CLIPCHILDREN样式,
这可以防止父窗口擦除组框的背景。
决议
==========
对group box窗口进行子类化,以通过擦除来处理WM_ERASEBKGND消息
它的背景。下面列出了一段代码来演示这个过程。
地位
======
这种行为是故意的。
更多信息
================
https://jeffpar.github.io/kbarchive/kb/079/Q79982/
*/
HRESULT hr=CreateGraphicsResources();
SmartObject父对象=nullptr;
if(失败(hr)| |!mParent->IsDrawable())
返回FALSE;
//获取父窗口的背景色。
父母=父母;
const D2D1::ColorF color=parent->GetBackgroundColor();
mpBrush->SetColor(颜色);
//其他图形变量
RECT{};
HDC HDC=GetDC(mhWnd);
auto-pRender=std::get(mpRenderTarget);
常量D2D1\u SIZE\u F SIZE=pRender->GetSize();
常量D2D1_RECT_F rectangle=D2D1::RectF(0,0,size.width,size.height);
//删除组框的背景。
GetClientRect(mhWnd和rect);
pRender->BindDC(hDC和rect);
pRender->BeginDraw();
pRender->FillRectangle(&rectangle,mpBrush);
hr=pRender->EndDraw();
如果(失败(小时))
{
淋浴器(锅炉,hr);
}
释放DC(mhWnd,hDC);
//指示Windows绘制组框文本和框架。
无效(mhWnd和rect、FALSE);
//在此处插入代码以指示分组框的内容
//还要重新油漆。
return TRUE;//背景已被擦除。
}
所以,我的第一个问题是,有没有一种传统的方法来获取 组框标题的高度

您可以使用
GetTextExtentPoint32
进行高度测量。请参阅“”

第二个问题,您可以看到示例标题的背景如何 文本不是相同的浅蓝色,而是灰色

要更改标题背景色,可以通过handle message设置静态控件的文本背景色

case WM_CTLCOLORSTATIC:
{
    if (GetDlgItem(hDlg, IDC_STATIC4) == (HWND)lParam)
    {
        HDC hdcStatic = (HDC)wParam;
        SetBkColor(hdcStatic, RGB(0, 255, 0));

        if (hbrBkgnd == NULL)
        {
            hbrBkgnd = CreateSolidBrush(RGB(0, 255, 0));
        }
        return (INT_PTR)hbrBkgnd;
    }
}
结果如下:


我想你指的是高度,不是宽度。每个控件都可以有自己的字体,标题的高度将基于控件当前使用的字体。您可以通过多种方式获得字体的高度,其中一种方法是调用
GetTextExtentPoint32
@JonathanPotter谢谢,这个函数正是我想要的!你好,丽塔!我要感谢你1000次,你让我开心!我只需要编写从
D2D1::Color
COLOREF
的转换函数,其余的都很容易复制。