Фоновое изображение окна Win32 MFC мозаично, когда оно не должно

Я делаю образец экрана-заставки в MFC, который ничего не делает, кроме отображения самого верхнего окна без полей с изображением в качестве фона. У меня действительно странная проблема, которая возникает на компьютере моих друзей, но не на моем, хотя мы используем одну и ту же ОС. Я исправил проблему, но хотел бы узнать, почему это могло происходить на его машине, а не на моей, и почему альтернативная версия, которую я создал, работает на обеих машинах.

Неверный метод 1 (работает у меня, а не у него)

BOOL Splash::PreCreateWindow(CREATESTRUCT& cs)
{
    if (!CFrameWnd::PreCreateWindow(cs))
        return FALSE;

    CBitmap bitmap; bitmap.LoadBitmap(MAKEINTRESOURCE(IDB_BITMAP1));
    CBrush bitmapBrush; bitmapBrush.CreatePatternBrush(&bitmap);
    bitmap.DeleteObject();

    cs.style = WS_POPUP;
    cs.dwExStyle = WS_EX_TOPMOST;

    cs.lpszClass = AfxRegisterWndClass(0, 0, (HBRUSH)bitmapBrush.Detach());
    bitmapBrush.DeleteObject();

    return TRUE;
}

Вышеприведенное отлично работает в двух моих версиях Windows (Windows 7 и 10) и показывает мозаичное растровое изображение со смещением по центру на экземпляре Windows 7 моего друга.

Рабочий метод 2 (до сих пор работает на всем протестированном)

void Splash::OnPaint()
{
    CRect window;
    this->GetClientRect(&window);

    PAINTSTRUCT paint = { 0 };
    CDC *dc = this->BeginPaint(&paint);

    CDC memDC;
    memDC.CreateCompatibleDC(dc);
    CBitmap *oldBitmap = memDC.SelectObject(&this->m_SplashBitmap);

    dc->BitBlt(window.left, window.top, window.right, window.bottom, &memDC, 0, 0, SRCCOPY);

    memDC.SelectObject(oldBitmap);
    memDC.DeleteDC();

    this->EndPaint(&paint);
}

Приведенный выше код работает в моей Windows 7, Windows 10 и экземпляре Windows 7 моего друга. Есть идеи, почему это так или что может произойти? Может быть, моя первая итерация сделана совершенно неправильно?


person vane    schedule 18.02.2017    source источник
comment
Согласно документам, классы окон могут использовать только физическую кисть для фоновой кисти, а CreatePatternBrush возвращает логическую кисть. Вероятно, это случайность, что он вообще работает, зависит от видеокарты, которую я себе представляю.   -  person Jonathan Potter    schedule 19.02.2017
comment
@JonathanPotter Не могли бы вы дать ссылку на эту документацию, о которой вы говорите? Я просмотрел документацию для WNDCLASSEX и AfxRegisterWndClass, оба ничего не говорят об этом и бесчисленное множество примеры в Интернете для установки фонового изображения окна используют тот же метод, что и я. В документации по CreatePatternBrush тоже ничего не нашел.   -  person vane    schedule 19.02.2017
comment
msdn.microsoft.com/en -us/library/windows/desktop/ Этот элемент может быть дескриптором физической кисти, используемой для рисования фона, или значением цвета   -  person Jonathan Potter    schedule 19.02.2017
comment
@JonathanPotter Я не совсем уверен, что это действительно имеет значение. Структуры WNDCLASS и WNDCLASSEX используются в одних и тех же процедурах создания окон. WNDCLASS был заменен WNDCLASSEX, а в документации WNDCLASSEX вообще не говорится, что это должна быть физическая кисть. Из документации WNDCLASSEX в том же абзаце, на который вы ссылаетесь из WNDCLASS: этот член может быть дескриптором кисти, которая будет использоваться для рисования фона, или может быть значением цвета, обратите внимание, что в новой документации был удален квалификатор physical.   -  person vane    schedule 19.02.2017
comment
Не могли бы вы добавить скриншоты, показывающие результат первого метода на обеих машинах?   -  person Adrian McCarthy    schedule 27.03.2017


Ответы (1)


Компьютер вашего друга работает с другим DPI, чем ваш, и ваше приложение не помечено как поддерживающее DPI.

Я предполагаю, что вы попытались сделать растровое изображение и окно одного размера, ожидая, что ровно одна копия растрового изображения заполнит окно.

На одной машине без масштабирования DPI все просто работает.

На другом компьютере с масштабированием DPI размер окна фактически будет увеличен. Фоновый рисунок, вероятно, сделан с помощью PatBlt, который не масштабируется; узор (кисть) просто повторяется столько раз, сколько необходимо для заполнения области.

Когда вы используете BitBlt, Windows будет применять к блиту то же масштабирование DPI, что и к окну, поэтому оно работает независимо от того, включено ли масштабирование.

person Adrian McCarthy    schedule 24.03.2017
comment
Я не думаю, что это проблема, поскольку мы оба тестировали его с несколькими настройками DPI. В каждом случае мой работал правильно, а его был выложен плиткой. Ответ имеет смысл и должен быть тем, что происходит, но я не вижу этого при тестировании на обеих машинах с несколькими настройками DPI. - person vane; 26.03.2017