1

我的目标是替换公共控件的编辑控件的背景。我当前的代码是这样做的:

HBITMAP hBmp = ::LoadBitmap(hInstance, MAKEINTRESOURCE(BKGND_ID));
HBRUSH hBkgndBrush = ::CreatePatternBrush(hBmp);
::DeleteObject(hBmp);


HBRUSH CDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

    // TODO:  Change any attributes of the DC here

    if(pWnd->GetDlgCtrlID() == MY_CTRL_ID && hBkgndBrush)
    {
        hbr = hBkgndBrush;

        //Do I need to select it?
        //pDC->SelectObject(hbr);   //This line?

        pDC->SetBkMode(TRANSPARENT);
    }

    // TODO:  Return a different brush if the default is not desired
    return hbr;
}

问题是,我需要hbr在返回之前选择吗?(请参阅上面注释掉的行。)我似乎看到它在网上的不同示例中以两种方式完成。

编辑:也忘了提,我这样覆盖WM_ERASEBKGND

HDC hDc = ::GetDC(hWnd);
if(hDc)
{
    RECT rc = {0};
    ::GetClientRect(hWnd, &rc);

    ::FillRect(hDc, &rc, hBkgndBrush);

    ::ReleaseDC(hWnd, hDc);
}

EDIT2:我做了一个小样本 MFC 项目来说明这个问题。基本上,当我将应用程序快速移出屏幕然后返回时,它会产生这种视觉“故障”,但前提是控件没有 ES_MULTILINE 样式:

在此处输入图像描述

4

1 回答 1

2

当使用 位图创建背景画笔CreatePatternBrush时,在调整对话框大小或移动时可能会出现一些“重复的伪影”。

要删除这些工件,请强制子控件重新绘制以响应ON_WM_WINDOWPOSCHANGED消息:

void CMyDialog::OnWindowPosChanged(WINDOWPOS *wndpos)
{
    CDialog::OnWindowPosChanged(wndpos);

    CWnd *wnd = GetWindow(GW_CHILD);
    while (wnd)
    {
        wnd->Invalidate(TRUE);
        wnd = wnd->GetWindow(GW_HWNDNEXT);
    }
}

或者

void CMyDialog::OnWindowPosChanged(WINDOWPOS *wndpos)
{
    CDialog::OnWindowPosChanged(wndpos);
    edit1.Invalidate(FALSE);
    edit2.Invalidate(FALSE);
    ...
}

OnCtlColor覆盖将如下:

HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* wnd, UINT nCtlColor)
{
    if (nCtlColor == CTLCOLOR_DLG)
        return CDialogEx::OnCtlColor(pDC, wnd, nCtlColor); 
    pDC->SetBkMode(TRANSPARENT);
    return hBkgndBrush;
}

您可以根据wndnCtlColor仅更改编辑控件的背景添加其他条件。

于 2016-06-13T09:37:29.760 回答