Моя цель — заменить фон для общего контроля редактировать контроль. Мой текущий код делает это:
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: Я сделал маленький пример проекта МФЦ чтобы проиллюстрировать проблему. По сути, когда я быстро убираю приложение с экрана и затем возвращаюсь, оно создает этот визуальный «сбой», но только если элемент управления не имеет стиля ES_MULTILINE:
Когда кисть фона создается из растрового изображения с помощью 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;
}
Вы можете добавить другие условия на основе wnd
или же nCtlColor
изменить фон только для редактирования элемента управления.
Других решений пока нет …