【问题标题】:setting background color of child window using window's handle使用窗口句柄设置子窗口的背景颜色
【发布时间】:2015-10-23 07:34:04
【问题描述】:

我已经使用handle_to_this_window[i] = CreateWindow(L"EDIT",...) 在我的主窗口中定义并创建了一堆子窗口 呼叫类型。

我现在需要创建一个函数,允许我设置任何一个窗口的背景颜色。 比如:

R_color_value = 0, G_color_value = 200, B_color_value = 0; ChangeChildBackgroundColor(handle_to_this_window[6], R_color_value, G_color_value, B_color_value);

R_color_value = 200, G_color_value = 0, B_color_value = 0; ChangeChildBackgroundColor(handle_to_this_window[7], R_color_value, G_color_value, B_color_value);

请给我指出如何实现这一目标的正确方向吗?

【问题讨论】:

  • 为您的窗口处理WM_ERASEBKGND 消息并绘制背景
  • 查看WM_CTLCOLOREDIT
  • @RichardCritten:对于编辑控件,让父窗口处理WM_CTLCOLOREDIT 消息。或者切换到 RichEdit 控件并向其发送EM_SETBKGNDCOLOR 消息
  • @RemyLebeau,OP 说子窗口,只是想帮助解决所提出的问题。我知道控制可以不同。
  • @RichardCritten:我知道 OP 说 child windows。他们的窗口代表他们接收WM_CTLCOLOREDIT:“当控件即将被绘制时,非只读或禁用的编辑控件会向其父窗口发送 WM_CTLCOLOREDIT 消息。通过响应此消息,父窗口可以使用指定的设备上下文句柄来设置编辑控件的文本和背景颜色"

标签: c++ winapi colors background


【解决方案1】:

试试这样的:

struct ChildControlInfo
{
    HWND Wnd;
    HBRUSH BkGndBrush;
    COLORREF BkGndColor;
};

ChildControlInfo ChildControls[...];

...

void ChangeChildBackgroundColor(int ChildIndex, COLORREF NewColor)
{
    ChildControlInfo &Child = ChildControls[ChildIndex];
    if ((Child.BkGndColor != NewColor) || (!Child.BkGndBrush))
    {
        if (Child.BkGndBrush) DeleteObject(Child.BkGndBrush);
        Child.BkGndBrush = CreateSolidBrush(NewColor);
        Child.BkGndColor = NewColor;
        if (Child.Wnd) InvalidateRect(Child.Wnd, NULL, TRUE);
    }
}

// in the parent window procedure...
case WM_CTLCOLOREDIT:
{
    HDC hDc = reinterpret_cast<HDC>(wParam);
    HWND hEdit = reinterpret_cast<HWND>(lParam);

    for(int i = 0; i < ARRAYSIZE(ChildControls); ++i)
    {
        ChildControlInfo &Child = ChildControls[i];
        if (Child.Wnd == hEdit)
        {
            SetBkColor(hDc, Child.BkGndColor);
            return reinterpret_cast<LRESULT>(Child.BkGndBrush);
        }
    }
    break;
}

memset(&ChildControls[i], 0, sizeof(ChildControlInfo));
ChildControls[i].Wnd = CreateWindow(L"EDIT",...);.
ChangeChildBackgroundColor(i, RGB(...));

...

ChangeChildBackgroundColor(6, RGB(0, 200, 0));
ChangeChildBackgroundColor(7, RGB(200, 0, 0));

...

// during cleanup...
for(int i = 0; i < ARRAYSIZE(ChildControls); ++i)
{
    ChildControlInfo &Child = ChildControls[i];
    DestroyWindow(Child.Wnd);
    DeleteObject(Child.BkGndBrush);
}

【讨论】:

    【解决方案2】:

    您必须将画笔声明为全局变量:

    HBRUSH gbrush;
    

    您必须在代码中的某处定义画笔。例如在主窗口过程中:

    case WM_CREATE:
    {
        gbrush = CreateSolidBrush(RGB(200, 255, 255));
        //...
    }
    

    然后更改WM_CTLCOLOREDIT中的“背景颜色”和“背景画笔”:

    case WM_CTLCOLOREDIT:
    {
        HDC hdc = (HDC)wParam;
        HWND hedit = (HWND)lParam;
        SetBkColor(hdc, RGB(200, 255, 255));
        return (LRESULT)gbrush;
    }
    

    这将更改所有编辑控件的背景颜色。您可以使用hedit 值以不同方式处理编辑框。

    【讨论】:

    • 请注意,此代码需要在父窗口的窗口过程中实现,并且为了以这种方式实现ChangeChildBackgroundColor(),您必须跟踪WM_CTLCOLOREDIT 可以查看一组编辑/颜色对,以了解根据指定的编辑控件返回哪个画笔。每当调用ChangeChildBackgroundColor() 时,将新颜色存储在数组中并使Edit 控件无效以触发新绘制,以便WM_CTLCOLOREDIT 可以为其返回新颜色。
    • 你不需要SetBkColor(),编辑的背景是用返回的画笔绘制的。文档中对此进行了说明:“如果应用程序处理此消息,则必须返回画笔的句柄。系统使用画笔绘制编辑控件的背景。 i>"
    • @RemyLebeau:它需要SetBkColor,否则当编辑控件获得焦点时,文本背景颜色会跳回默认窗口颜色。然后在编辑控件失去焦点时返回自定义颜色。
    • @Remy Lebeau 如果我知道如何应用它,我想我可以做得很好。我添加了一些全局变量来指定 RGB() 值。所以,现在当我想改变特定孩子的背景时,我:将这些变量设置为我想要的颜色,然后调用 InvalidateRect(handle_to_the_child[i], NULL, TRUE);然后它使用 WM_CTLCOLOREDIT 中的代码来设置背景。但我确实需要弄清楚如何实现这个数组。当我调用 InvalidateRect 时,hEdit 将拥有我的子窗口的句柄,并且我需要从中获取“i”的值。我会使用某种哈希表吗?
    • @a1s2d3f4:我发布了一个带有示例的答案。
    猜你喜欢
    • 1970-01-01
    • 2011-01-07
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 2014-01-22
    • 1970-01-01
    • 2012-02-15
    相关资源
    最近更新 更多