【问题标题】:Static Control Background Color with C++使用 C++ 的静态控制背景颜色
【发布时间】:2011-05-28 14:05:04
【问题描述】:

我正在使用 Windows API 创建基本 GUI,但遇到了问题。它从一个主窗口开始,该窗口以我设置的自定义背景颜色(RGB(230,230,230)) 打开。然后它会在左上角显示带有静态控件的文本。

settingstext = CreateWindow("STATIC",
                             "SETTINGS",
                             SS_LEFT | WS_CHILD,
                             12,
                             20,
                             100,
                             20,
                             hwnd,
                             NULL,
                             proginstance,
                             NULL);
ShowWindow(settingstext, 1);

这行得通,但是当显示文本时,我需要一种方法来更改它的背景以匹配主窗口,否则它看起来就像它没有融入。

我的问题是,我该怎么做?我目前使用下面的方法并且它有效,但我想知道,有没有办法以某种方式永久设置背景颜色,就在静态控件的CreateWindow 函数之后而不改变系统颜色,并且只是让它适用于那个控件而不是发送WM_CTLCOLORSTATIC 消息的任何东西。我已经尝试在消息循环之外使用GetDC 函数和SetBkColor 函数,但没有任何效果。

    case WM_CTLCOLORSTATIC:
    {
    HDC hdcStatic = (HDC) wParam;
    SetTextColor(hdcStatic, RGB(0,0,0));
    SetBkColor(hdcStatic, RGB(230,230,230));
    return (INT_PTR)CreateSolidBrush(RGB(230,230,230));
    }

我想这样做是因为...

  • 我不想用每次重新绘制窗口时都需要调用的函数来填充我的消息循环。
  • 仅将更改应用于此静态控件。

如果能提供任何帮助,我将非常感谢,至少可以为我指明正确的方向,谢谢。

【问题讨论】:

  • 您可以通过检查(HWND)lParam == settingstext 来将WM_CTLCOLORSTATIC 代码的效果限制在您的静态控件中。您的示例存在一个问题,即您创建的所有画笔永远不会被删除。

标签: c++ winapi controls static background-color


【解决方案1】:

对于静态文本控件,没有固定的方法来设置文本颜色或其背景。即使您想将更改应用于单个静态控件;当控件即将被绘制时,您仍然需要在父 dlgproc 中处理 WM_CTLCOLORSTATIC 通知消息。

这是由于DefWindowProc 每次处理WM_CTLCOLORSTATIC 时都会覆盖您对设备上下文的更改,如MSDN 所述:

默认情况下,DefWindowProc 函数为静态控件选择默认系统颜色。

static HBRUSH hBrush = CreateSolidBrush(RGB(230,230,230));

case WM_CTLCOLORSTATIC:
{
    if (settingstext == (HWND)lParam)

              //OR if the handle is unavailable to you, get ctrl ID

    DWORD CtrlID = GetDlgCtrlID((HWND)lParam); //Window Control ID
    if (CtrlID == IDC_STATIC1) //If desired control
    {
       HDC hdcStatic = (HDC) wParam;
       SetTextColor(hdcStatic, RGB(0,0,0));
       SetBkColor(hdcStatic, RGB(230,230,230));
       return (INT_PTR)hBrush;
    }
}

如果您想让控件的背景在父对话框上透明,您可以使用SetBkMode(hdcStatic, TRANSPARENT)

【讨论】:

  • 如果你已经调用了SetBkColor,你能解释一下为什么需要为后台创建hBrush吗?如果是透明背景,你还需要透明画笔吗?
【解决方案2】:

我认为有一个永久的方法可以做到这一点。

创建标签后,使用 GetDC() 函数获取设备上下文。 然后使用:

SetTextColor(hdcStatic, RGB(0,0,0));
SetBkColor(hdcStatic, RGB(230,230,230)); // Code Copied from the above answer by cpx.

它应该这样做。

【讨论】:

  • 这不起作用,因为DefWindowProc 将在每次处理控件的WM_CTLCOLORSTATIC 消息时将这些更改重置为设备上下文。 MSDN: "默认情况下,DefWindowProc 函数为静态控件选择默认系统颜色。"
【解决方案3】:

您是否考虑过将静态窗口子类化并进行所有者绘制?

【讨论】:

  • 我不知道那是什么,所以我会快速研究一下子类化。
  • 基本上,这意味着您将消息发送到静态控件而不是转到您的代码(不要忘记将那些您不处理的消息传递给原始处理程序)。如果您处理背景擦除和绘制消息,那么您可以让窗口显示您想要的任何内容。
  • 所以这只会发生在单个控件上,还有一种方法可以减少我为该控件制作的自定义过程中的函数数量。基本上,我对整个“过程中的功能不多”的理解是,它似乎会减慢应用程序在每次必须重新绘制时都必须执行这些功能,或者这不是什么大不了的事?
  • 它不会变慢,因为您的绘画例程将替换当前的例程(无论如何它都会被绘画)。此外,您不必为子类化的每个控件编写绘制例程。您可以使用相同的 WndProc 子类化多个窗口。我一直这样做。尽管如此,对于您需要的东西来说,这可能有点过头了。我不完全确定。
猜你喜欢
  • 2017-11-18
  • 1970-01-01
  • 2012-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
相关资源
最近更新 更多