Если окно охватывает несколько мониторов, я не могу нарисовать его - PullRequest
4 голосов
/ 08 января 2010

Если у меня есть окно, которое охватывает оба монитора в системе с несколькими мониторами, я не могу стереть (закрасить черным цветом) все окно. Вместо этого только главное окно рисуется черным. Вторичным остается оригинальный белый цвет. Кто-нибудь видел такое поведение?

WxWidgets:

wxClientDC dc(this); 
Erase(dc); 

void SpriteWindowFrame::Erase(wxDC& dc) 
{ 
    dc.SetBackground(*wxBLACK_BRUSH); 
    dc.SetBrush(*wxBLACK_BRUSH); 
    dc.Clear(); 
   //wxLogDebug("Erase called. Rect is %i, %i w:%i, h:%i", GetPosition().x, GetPosition().y, GetSize().GetWidth(), GetSize().GetHeight()); 
 } 

Внутри функции dc.Clear () есть этот код

WxWidgets:

void wxDC::Clear() 
{ 
WXMICROWIN_CHECK_HDC 

RECT rect; 
if ( m_canvas ) 
{ 
    GetClientRect((HWND) m_canvas->GetHWND(), &rect); 
} 
else 
{ 
    // No, I think we should simply ignore this if printing on e.g. 
    // a printer DC. 
    // wxCHECK_RET( m_selectedBitmap.Ok(), wxT("this DC can't be cleared") ); 
    if (!m_selectedBitmap.Ok()) 
        return; 

    rect.left = -m_deviceOriginX; rect.top = -m_deviceOriginY; 
    rect.right = m_selectedBitmap.GetWidth()-m_deviceOriginX; 
    rect.bottom = m_selectedBitmap.GetHeight()-m_deviceOriginY; 
} 

#ifndef __WXWINCE__ 
(void) ::SetMapMode(GetHdc(), MM_TEXT); 
#endif 

DWORD colour = ::GetBkColor(GetHdc()); 
HBRUSH brush = ::CreateSolidBrush(colour); 
::FillRect(GetHdc(), &rect, brush); 
::DeleteObject(brush); 

#ifndef __WXWINCE__ 
int width = DeviceToLogicalXRel(VIEWPORT_EXTENT)*m_signX, 
    height = DeviceToLogicalYRel(VIEWPORT_EXTENT)*m_signY; 

::SetMapMode(GetHdc(), MM_ANISOTROPIC); 

::SetViewportExtEx(GetHdc(), VIEWPORT_EXTENT, VIEWPORT_EXTENT, NULL); 
::SetWindowExtEx(GetHdc(), width, height, NULL); 
::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX, (int)m_deviceOriginY, NULL); 
::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX, (int)m_logicalOriginY, NULL); 
#endif 

}

Используя отладчик, я проверил, что вернул GetClientRect, и, конечно же, он возвращает прямоугольник с расположением 0 и шириной / высотой объединенных двух мониторов, так что это правильно. Может быть, функция fillrect не способна рисовать на двух дисплеях?

Ответы [ 2 ]

2 голосов
/ 08 января 2010

Можете ли вы отследить конструктор wxClientDC?

wxClientDC dc(this);

Многое зависит от того, какой тип DC wx дал вам. Windows API для извлечения DC окна имеет вид hdc = GetDC (hwnd), и в системах с несколькими мониторами он извлекает дескриптор DC «зеркального драйвера», который предназначен для отражения вызовов ко всем DC контроллера домена, который охватывает монитор .

Единственная возможная причина такого поведения, которую я могу придумать, заключается в том, что wx каким-то образом получает DC дисплея, а не DC окна.

0 голосов
/ 10 января 2010

Я уверен, что Крис прав, что дело о "перекрывающемся окне" где-то для вас. Но где?

Рендеринг с окнами GDI и «контекстами отображения», о которых вы упомянули, очень примитивен и подвержен всевозможным проблемам. GDI - один из самых бедных интерфейсов, когда-либо виденных, плохой даже для Microsoft. Поскольку большинство «оконных» программ нормально работают на нескольких мониторах, подумайте об анимации в «окне» - и как это «окно» попадает на «дисплей», лучше всего оставить загадкой.

Возможно, DC не поддерживает несколько мониторов. Ищите все, что позволяет обрабатывать несколько DC одинаково. Разрисовывание графики на сетке из бумажных листов будет похоже на плиточный «принтер DC». Видеостена была бы плиточным «дисплеем DC», и вы были бы довольны взломом с двумя мониторами, то есть «multimon dc» перекликается с «владельцем» дисплея и «другим», если окно охватывает оба.

Если вы хотите сделать «настоящую» анимацию на окнах, вам нужно будет перейти на DirectX. Кроме того, многому можно научиться, но гораздо больше возможностей: графы сцен, текстуры, видео, альфа-каналы, ...

...