设置子窗口的文字颜色

时间:2019-04-23 10:44:51

标签: c++ winapi

我正在尝试更改静态控件的文本/背景颜色。我可以通过以下方式做到这一点:

   // This is the 'main' window
   BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
   {
       hInst = hInstance;
       HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW &~WS_MAXIMIZEBOX | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
    CW_USEDEFAULT, 0, 1035, 764, nullptr, nullptr, hInstance, nullptr);
       ...
   }

   LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
   {
     case WM_CTLCOLORSTATIC:
        {
            MessageBox( NULL, "CTLCOLORSTATIC called", "", MB_OK );
            HDC hdcStatic = (HDC)wParam;
            SetTextColor(hdcStatic, RGB(200, 200, 20));
            SetBkColor(hdcStatic, RGB(10, 10, 10));

            return (INT_PTR)CreateSolidBrush(RGB(30, 30, 30));
        }
        default:
                return DefWindowProc( hWnd, message, wParam, lParam );
   }

但是,如果我将窗口放置在另一个窗口中,则子控件的文本/背景颜色将保持默认设置:

    // This is the 'parent' window, which resides in the 'main' window
    HWND parent = CreateWindowEx
    (
        0,
        _TEXT("STATIC"),
        "",
        WS_TABSTOP | WS_VISIBLE  | BS_SOLID | WS_CLIPCHILDREN,
        10, 10, 500, 500,
        hwnd,
        NULL,
        (HINSTANCE)GetWindowLong(hwnd, GWLP_HINSTANCE),
        NULL
    );

    // This is the 'child' window which resides in the 'parent' window
    HWND child = CreateWindowEx
    (
        0,
        _TEXT("STATIC"),
        "SubItem",
        WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_SOLID,
        10, 10, 100, 100,
        parent,
        NULL,
        (HINSTANCE)GetWindowLong(parent, GWLP_HINSTANCE),
        NULL
    );

最后,我有3个窗口:

    HWND hwnd;   // the 'main' application window (color changes fine)
    HWND parent; // the 'parent/container' window which is inside the 'main' window (color changes fine)
    HWND child;  // the 'child' window which is inside the 'parent' window (color DOES NOT change)      

即使我将MessageBox放在WM_CTLCOLORSTATIC内,每次看到孩子时,我都会看到它触发,但是颜色不会为孩子而仅为父对象更改。

据我了解,我需要在主窗口过程中处理该消息,但是我并不清楚如何做到这一点。如果我将(HWND)lParam与孩子的HWND进行比较,则它们是相同的(在默认开关的情况下),因此我可以在“默认”部分中获取引用,但不确定如何处理它从那里。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    case WM_CTLCOLORSTATIC:
    {
        if ((HWND)lParam == child )
            MessageBox( NULL, "Reference Match for CTLCOLORSTATIC", "", MB_OK ); // <-- THIS NEVER TRIGGERS
    }
        ....
    default:
        if ((HWND)lParam == child )
            MessageBox( NULL, "Reference Match for DEFAULT", "", MB_OK ); // <-- THIS DOES TRIGGER

            return DefWindowProc( hWnd, message, wParam, lParam );
        }
        return 0;
}

我将一个窗口放置在另一个窗口中的原因是,以便可以在父级中使用WS_CLIPCHILDREN属性(以防子级将移动/滚动)。

2 个答案:

答案 0 :(得分:0)

WM_CTLCOLORSTATIC由静态控件发送到其父窗口,而不是顶级窗口。

hwndMain: WM_CTLCOLORSTATIC for hwnd1
|    
\--hwnd1: WM_CTLCOLORSTATIC for hwnd2 (You might have to subclass hwnd1)
   |
   \--hwnd2

您还会泄漏画笔,在创建窗口时将CreateSolidBrush处的画笔存储在某个位置,并在窗口被破坏时将其删除。

答案 1 :(得分:0)

通过阅读MSDN文档,我知道一个函数SetWindowsLongPtr,其参数GWLP_WNDPROC可以为窗口过程设置一个新地址。

此功能可以更改子窗口的文本颜色和背景颜色,也就是说,它可以触发WM_CTLCOLORSTATIC

但是经过测试,我发现它对次要窗口无效,也就是说,它不能更改父窗口的文本颜色。

我还查阅了很多信息,很少涉及三层窗户的文件。

因此,我认为要解决此问题并使所有三个窗口都更改文本的颜色,您可能必须自己重写WndProc,但这非常复杂并且涉及很多事情。

  

编辑:如果只需要更改文本颜色和背景颜色   您可以自定义控件,以便可以   处理所有操作。

希望能为您提供帮助。