更改特定标签win32的颜色

时间:2015-10-05 07:33:08

标签: winapi visual-c++

我有一组标签[8] [8],每个标签都带有它自己的Id,从我调用的例程中更改标签颜色给出hWnd,但是没有任何反应,但如果我没有指定case WM_CTLCOLORSTATIC:所有标签上的ID都会改变颜色

DWORD WINAPI changecolor(LPVOID lpParameter){
clrLabelBkGnd = RGB(255, 255, 0x00);
            InvalidateRect(hWndLabel[0][0], NULL, TRUE);
return 0;
}

回拨功能

case WM_CTLCOLORSTATIC: 
        ctrlID = GetDlgCtrlID((HWND)lParam);
    if (ctrlID == 1000) {
            hdc = reinterpret_cast<HDC>(wParam);
            SetBkColor(hdc, clrLabelBkGnd);
            return reinterpret_cast<LRESULT>(hBrushLabel);
        }
        else break;

主程序

/* fill the labels IDs*/
    for (int i = 0; i < 8; i++){
        for (int j = 0; j < 8; j++){
            labelId[i][j] = (i * 8 + j)+1000;
        }
    }

在此示例中,当我指定存在hWndLabel[0][0]的ID 1000时,没有任何颜色,但如果我没有指定ID,或者如果我将id > 1000放在case WM_CTLCOLORSTATIC:中,则所有标签都会被着色只调用hWndLabel[0][0]

2 个答案:

答案 0 :(得分:2)

这部分错了:

case WM_CTLCOLORSTATIC: 
        if (LOWORD(wParam) == 1000) {
            hdc = reinterpret_cast<HDC>(wParam);

由于wParam是设备上下文的句柄,为什么你使用它的低位字作为控件的ID?

看看WM_CTLCOLORSTATIC

wParam 
   Handle to the device context for the static control window.
lParam 
   Handle to the static control.

您需要使用的是lParam

DWORD ctrlID = GetDlgCtrlID((HWND)lParam));
if (ctrlID == 1000)
{
}

更新:根据您提供的评论,您需要有一种机制来保留已失效的标签的ID。

DWORD WINAPI changecolor(LPVOID lpParameter)
{
    clrLabelBkGnd = RGB(255, 255, 0x00);
    someVariableToHoldLabelIdWithRightScope = labelId[0][0]; // Or GetDlgCtrlID(hWndLabel[0][0]);
    InvalidateRect(hWndLabel[0][0], NULL, TRUE);
    return 0;
}

然后,当你处理颜色时:

case WM_CTLCOLORSTATIC: 
    ctrlID = GetDlgCtrlID((HWND)lParam);
    if (ctrlID == someVariableToHoldLabelIdWithRightScope)
    {
        hdc = reinterpret_cast<HDC>(wParam);
        SetBkColor(hdc, clrLabelBkGnd);
        return reinterpret_cast<LRESULT>(hBrushLabel);
    }
    else break;

如果一次使多个标签无效,那么这样的一个变量是不够的。您需要具有ID的列表/数组/队列。

答案 1 :(得分:2)

马吕斯回答了你的问题 - 你误用WM_CTLCOLORSTATIC的参数,这就是为什么你的画不能正常工作。

我建议您解决问题。有一个颜色列表,每个标签有一组Text / BkGnd颜色。使changecolor()根据需要更新指定标签的颜色条目,然后使该标签无效以触发重绘。然后WM_CTLCOLORSTATIC可以使用当前正在绘制的标签的当前颜色。无需跟踪调用changecolor()和触发WM_CTLCOLORSTATIC之间更改的控件ID(这样做很容易出错 - 想想如果你想在之前更改另一个标签的着色会发生什么处理了之前更改的WM_CTLCOLORSTATIC

我建议std::map将每个标签HWND与持有该标签颜色的struct相关联,例如:

#include <map>

struct sLabelColors
{
    COLORREF clrText;
    COLORREF clrBkGnd;
    HBRUSH hBrushBkGnd;
};

std::map<HWND, sLabelColors> labelColors;

hWndLabel[0][0] = CreateWindowEx(...);
if (hWndLabel[0][0] != NULL)
{
    sLabelColors &colors = labelColors[hWndLabel[0][0]];
    colors.clrText = GetSysColor(COLOR_WINDOWTEXT);
    colors.clrBkGnd = GetSysColor(COLOR_WINDOW);
    colors.hBrushBkGnd = NULL;
}

case WM_CTLCOLORSTATIC: 
{
    HDC hdc = reinterpret_cast<HDC>(wParam);
    sLabelColors &colors = labelColors[(HWND)lParam];
    SetTextColor(hdc, colors.clrText);
    SetBkColor(hdc, colors.clrBkGnd);
    if (!colors.hBrushBkGnd) colors.hBrushBkGnd = CreateSolidBrush(colors.clrBkGnd);
    return reinterpret_cast<LRESULT>(colors.hBrushBkGnd);
}

case WM_PARENTNOTIFY:
{
    if (LOWORD(wParam) == WM_DESTROY)
    {
        HWND hWnd = (HWND)lParam;
        std::map<HWND, sLabelColors>::iterator iter = labelColors.find((HWND)lParam);
        if (iter != labelColors.end())
        {
            if (iter->hBrushBkGnd) DeleteObject(iter->hBrushBkGnd);
            labelColors.erase(iter);
        }
    }
    break;
}

DWORD WINAPI changecolor(LPVOID lpParameter)
{
    sLabelColors &colors = labelColors[hWndLabel[0][0]];

    if (colors.hBrushBkGnd) {
        DeleteObject(colors.hBrushBkGnd);
        colors.hBrushBkGnd = NULL;
    }

    colors.clrBkGnd = RGB(255, 255, 0x00);
    InvalidateRect(hWndLabel[0][0], NULL, TRUE);

    return 0;
}