更改 win32 的单选按钮文本颜色
Changing win32's radio button text color
颜色变化后,我听 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;
}
}
这适用于常规静态文本:标签等,但对常规单选按钮无效。
在调试过程中,我试过听:
- WM_DRAWITEM - 没有收到任何事件
- WM_CTLCOLORBTN - 仅接收常规按钮(确定/取消)的事件
- WM_CTLCOLOREDIT - 没有收到任何事件。
我正在子类化到另一个 window 不是由我生成/创建,而是由我的过程构建的。
如果您有兴趣绘制完整的单选按钮,您需要做的是为单选按钮 button.In 设置一个自定义的 window 过程,该过程会得到 WM_PAINT 并且WM_ERASEBKGND 条消息。
在擦除背景中,您可以只为控件填充背景颜色。
在 WM_PAINT 中绘制控件,获取控件的 window 文本,然后使用 SetTextColor
将颜色设置为您需要的颜色的 DrawText
画一个radio的图像(圆圈和里面的点)。你可以得到控件的所有状态变量并根据它绘制,比如它是否选中了它。每当您需要重绘时,即设置新文本,只需调用 invalidateRect 强制重绘..
@igal k 说 SetWindowTheme 不起作用。由于示例代码的注释不够。我post它作为答案。
首先是结果。
代码:
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;
}
颜色变化后,我听 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;
}
}
这适用于常规静态文本:标签等,但对常规单选按钮无效。
在调试过程中,我试过听:
- WM_DRAWITEM - 没有收到任何事件
- WM_CTLCOLORBTN - 仅接收常规按钮(确定/取消)的事件
- WM_CTLCOLOREDIT - 没有收到任何事件。
我正在子类化到另一个 window 不是由我生成/创建,而是由我的过程构建的。
如果您有兴趣绘制完整的单选按钮,您需要做的是为单选按钮 button.In 设置一个自定义的 window 过程,该过程会得到 WM_PAINT 并且WM_ERASEBKGND 条消息。 在擦除背景中,您可以只为控件填充背景颜色。
在 WM_PAINT 中绘制控件,获取控件的 window 文本,然后使用 SetTextColor
将颜色设置为您需要的颜色的 DrawText画一个radio的图像(圆圈和里面的点)。你可以得到控件的所有状态变量并根据它绘制,比如它是否选中了它。每当您需要重绘时,即设置新文本,只需调用 invalidateRect 强制重绘..
@igal k 说 SetWindowTheme 不起作用。由于示例代码的注释不够。我post它作为答案。
首先是结果。
代码:
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;
}