如何更改SysDateTimePick32或CDateTimeCtrl的背景颜色?

时间:2015-11-26 03:21:09

标签: c++ windows winapi mfc win32gui

我似乎无法更改SysDateTimePick32控件的背景颜色(在这种情况下为白色):

enter image description here

在我的Win32 / MFC应用程序中。

我首先尝试在父窗口中覆盖OnCtlColor通知消息,甚至没有被调用。

然后我尝试了一种子类化方法described here,它被称为正常,但控件没有在视觉上改变。 (我在Windows 8.1机器上进行了测试。)

那么有人知道怎么做吗?

PS。我需要它在Windows XP及更高版本上运行。

1 个答案:

答案 0 :(得分:0)

我不确定以下解决方案有多少黑客攻击,但它似乎可以快速修复,直到有人建议更好的解决方案。同样,它基于this code,还需要Windows Vista或更高版本的操作系统:

//Called from a subclassed WndProc
case WM_PAINT:
{
    PAINTSTRUCT ps;
    ::BeginPaint(hWnd, &ps);

    //Render control
    RenderWithBkgndColor(hWnd, ps.hdc, RGB(255, 0, 0));

    ::EndPaint(hWnd, &ps);

    return 0;
}


void RenderWithBkgndColor(HWND hWnd, HDC hDC, COLORREF clrBkgnd)
{
    //Render control with the background color
    //'clrBkgnd' = color for the background (if control is enabled)

    //SOURCE:
    //  http://comp.os.ms-windows.programmer.win32.narkive.com/0H8cHhw1/setting-color-for-sysdatetimepick32-control

    RECT rect;
    ::GetWindowRect(hWnd, &rect);
    ::MapWindowPoints(NULL, hWnd, (LPPOINT)&rect, 2);
    long nWidth = rect.right - rect.left, nHeight = rect.bottom - rect.top;

    HDC hDCMem = ::CreateCompatibleDC(hDC);
    HBITMAP hBitmap = ::CreateBitmap(nWidth, nHeight, ::GetDeviceCaps(hDC, PLANES), ::GetDeviceCaps(hDC, BITSPIXEL), (const void *) NULL);
    if (hBitmap)
    {
        HBITMAP hBitmapOld = (HBITMAP)::SelectObject(hDCMem, hBitmap);

        //Render control itself
        ::SendMessage(hWnd, WM_PRINT, (WPARAM)hDCMem, PRF_CLIENT | PRF_CHILDREN | PRF_NONCLIENT);

        //Only if we have the color
        if(clrBkgnd != NULL)
        {
            //Only if control is enabled
            if((::GetWindowLongPtr(hWnd, GWL_STYLE) & (WS_VISIBLE | WS_DISABLED)) == (WS_VISIBLE | 0))
            {
                #define ALLOWED_DIFF 20

                DWORD dwBkgClr = ::GetSysColor(COLOR_WINDOW);   //0xFFFFFF;

                DWORD br0 = dwBkgClr & 0xFF;
                DWORD br1 = (dwBkgClr & 0xFF00) >> 8;
                DWORD br2 = (dwBkgClr & 0xFF0000) >> (8 * 2);

                for(int y = 0; y < nHeight; y++)
                {
                    for(int x = 0; x < nWidth; x++)
                    {
                        COLORREF clrPxl = ::GetPixel(hDCMem, x, y);

                        DWORD r0 = clrPxl & 0xFF;
                        DWORD r1 = (clrPxl & 0xFF00) >> 8;
                        DWORD r2 = (clrPxl & 0xFF0000) >> (8 * 2);

                        int nDiff_r0 = r0 - br0;
                        int nDiff_r1 = r1 - br1;
                        int nDiff_r2 = r2 - br2;

                        if(abs(nDiff_r0) < ALLOWED_DIFF &&
                            abs(nDiff_r1) < ALLOWED_DIFF &&
                            abs(nDiff_r2) < ALLOWED_DIFF)
                        {
                            ::SetPixel(hDCMem, x, y, clrBkgnd);
                        }
                    }
                }

            }

        }

        ::BitBlt(hDC, rect.left, rect.top, nWidth, nHeight, hDCMem, 0, 0, SRCCOPY);

        ::SelectObject(hDCMem, hBitmapOld);
        ::DeleteObject(hBitmap);
    }

    ::DeleteDC(hDCMem);
}