【问题标题】:Changing win32's radio button text color更改 win32 的单选按钮文本颜色
【发布时间】:2015-10-29 11:58:04
【问题描述】:

当颜色改变时,我会听 WM_CTLCOLORSTATIC 并采取相应的行动:

LRESULT ProcessWindowMessage(_In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
    {
        switch (uMsg)
        {
        case WM_CTLCOLORSTATIC:
            LRESULT lBrush = ::DefWindowProc(hWnd, uMsg, wParam, lParam); // get default brush used so far
            ::SetBkMode((HDC)wParam, TRANSPARENT);
            ::SetTextColor((HDC)wParam, RGB(m_color.red, m_color.green, m_color.blue));
            return lBrush;
        }
    }

这适用于常规静态文本:标签等,但对常规单选按钮没有影响。

在调试过程中,我尝试过听:

  1. WM_DRAWITEM - 不接收任何事件
  2. WM_CTLCOLORBTN - 仅接收常规按钮的事件(OK / CANCEL)
  3. WM_CTLCOLOREDIT - 不接收任何事件。

我将子类化到另一个不是由我生成/创建,而是由我的进程构建的窗口。

【问题讨论】:

  • 当主题处于活动状态时,您无法控制这些颜色。
  • 按钮控件支持NM_CUSTOMDRAW,或许可以这样改变文字颜色(我没试过)。
  • 你为什么不处理 WM_PAINT 和 WM_ERASEBKGND 并自己画出来
  • @Tony 是的。这是唯一的方法。
  • 说真的,覆盖主题并不“难”。使用DrawThemeBackground 绘制单选按钮形状,使用DrawText 绘制文本。不是火箭科学。

标签: c++ winapi gdi


【解决方案1】:

如果您有兴趣绘制完整的单选按钮,您需要为单选按钮设置一个自定义窗口过程。在该过程中,您会收到 WM_PAINT 和 WM_ERASEBKGND 消息。 在擦除背景中,您可以只填充控件的背景颜色。

在 WM_PAINT 中,您绘制控件,获取控件的窗口文本并使用 SetTextColor 将颜色设置为您需要的任何颜色的 DrawText

绘制一个radio的图像(圆圈和一个点)。您可以获取控件的所有状态变量并根据它进行绘制,例如是否选中它。每当您需要重绘时,即设置了新文本,只需调用 invalidateRect 即可强制重绘..

【讨论】:

  • Visual Styles 呢?
  • 1999 年打来电话,他们希望得到答复
【解决方案2】:

@igal k 说 SetWindowTheme 不起作用。由于示例代码的注释不够。我将其发布为答案。

首先是结果。

代码:

OnInitDialog:
    ::SetWindowTheme(GetDlgItem(IDC_RADIO1)->GetSafeHwnd(), L"wstr", L"wstr");

HBRUSH CMFCApplication1Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    // Call the base class implementation first! Otherwise, it may 
    // undo what we're trying to accomplish here.
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

    // Are we painting the IDC_MYSTATIC control? We can use 
    // CWnd::GetDlgCtrlID() to perform the most efficient test. 
    if (pWnd->GetDlgCtrlID() == IDC_RADIO1)
    {
        // Set the text color to red
        pDC->SetTextColor(RGB(255, 0, 0));

        // Set the background mode for text to transparent  
        // so background will show thru.
        pDC->SetBkMode(TRANSPARENT);

        // Return handle to our CBrush object
        hbr = m_brush;
    }

    return hbr;
}

【讨论】:

  • @Jicaho,成功了!另外,我还发现,我没有调用原来的 WndProc 函数,而是不小心调用了 ::DefWindowProc()...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-21
  • 1970-01-01
  • 2021-11-20
相关资源
最近更新 更多