在编辑控件中替换背景时是否需要 select HBRUSH?

Do I need to select HBRUSH when replacing background in the edit control?

我的目标是为通用控件 edit control 替换背景。我当前的代码是这样做的:

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;
}

问题是,退货前需要selecthbr吗? (请参阅上面的注释行。)我似乎在不同的在线示例中看到它是通过两种方式完成的。

编辑: 还忘了说,我这样重写了 WM_ERASEBKGND

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

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

    ::ReleaseDC(hWnd, hDc);
}

EDIT2: 我做了一个小 sample MFC project 来说明这个问题。基本上,当我将应用程序快速移出屏幕然后返回时,它会创建此视觉效果 "glitch" 但前提是控件没有 ES_MULTILINE 样式:

当使用 CreatePatternBrush 从位图创建背景画笔时,在对话框调整大小或移动过程中可能会出现一些 "repeating artifacts"。

要删除这些工件,强制子控件重新绘制以响应 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的基础上添加其他条件,只改变编辑控件的背景。