Нужно ли выбирать HBRUSH при замене фона в редакторе?
Моя цель - заменить фон для элемента управления редактирования общего элемента управления. Мой текущий код делает это:
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);
}
РЕДАКТИРОВАТЬ 2: Я сделал небольшой пример проекта MFC, чтобы проиллюстрировать проблему. По сути, когда я быстро убираю приложение с экрана и затем возвращаюсь, оно создает этот визуальный "сбой", но только если элемент управления не имеет стиля ES_MULTILINE:
1 ответ
Когда кисть фона создается из растрового изображения с помощью 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
изменить фон только для редактирования элемента управления.