2017-02-18 45 views
0

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

Сломанный метод 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; 
} 

Вышеприведенные отлично работает на моей 2 версиях 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. Любая идея, почему это так или что может произойти? Может быть, моя первая итерация полностью ошибочна?

+0

В соответствии с окнами классов документов можно использовать только физическую кисть для фоновой кисти, а 'CreatePatternBrush' возвращает логическую кисть. Наверное, случайность, что она работает вообще, зависит от видеокарты, которую я себе представляю. –

+0

@JonathanPotter Не могли бы вы ссылаться на эту документацию, о которой вы говорите? Я просмотрел документацию для [WNDCLASSEX] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms633577 (v = vs.85) .aspx) и [AfxRegisterWndClass] (https: // msdn.microsoft.com/en-us/library/cw5335z0.aspx), об этом ничего не говорят, и бесчисленные примеры в Интернете для установки фонового изображения окна используют тот же метод, что и я. Я не смог найти ничего в документации для «CreatePatternBrush». – vane

+0

https://msdn.microsoft.com/en-us/library/windows/desktop/ms633576(v=vs.85).aspx "* Этот член может быть дескриптором ** физической кисти **, который будет использоваться для рисования фона, или это может быть значение цвета * " –

ответ

0

Машина вашего друга работает с другим DPI, который ваш и ваше приложение не отмечены как DPI.

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

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

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

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

+0

Я не думаю, что это проблема, поскольку мы оба тестировали ее на нескольких настройках DPI. В каждом случае моя работала должным образом, и он был облицован плиткой. Ответ имеет смысл и должен быть тем, что происходит, но я не вижу этого при тестировании на обеих машинах в нескольких настройках DPI. – vane