Windows 如果窗口跨越多个监视器,我可以';我不喜欢它

Windows 如果窗口跨越多个监视器,我可以';我不喜欢它,windows,graphics,winapi,wxwidgets,gdi,Windows,Graphics,Winapi,Wxwidgets,Gdi,如果在多监视器系统中有一个窗口跨越两个监视器,那么我似乎无法擦除(将其涂成黑色)整个窗口。相反,只有主窗口被绘制为黑色。次选项保留原始白色。有人见过这种行为吗 wxwidgets: wxClientDC dc(this); Erase(dc); void SpriteWindowFrame::Erase(wxDC& dc) { dc.SetBackground(*wxBLACK_BRUSH); dc.SetBrush(*wxBLACK_BRUSH);

如果在多监视器系统中有一个窗口跨越两个监视器,那么我似乎无法擦除(将其涂成黑色)整个窗口。相反,只有主窗口被绘制为黑色。次选项保留原始白色。有人见过这种行为吗

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()); 
 } 
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 
在dc.Clear()函数中,有以下代码

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()); 
 } 
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的rectange,以及组合的两个监视器的宽度/高度,因此它是正确的。可能fillrect函数无法绘制两个显示?

您可以跟踪wxClientDC的构造函数吗

wxClientDC dc(this);
这在很大程度上取决于wx提供给您的DC类型。检索窗口DC的windows API为hdc=GetDC(hwnd),在多监视器系统上,它检索“镜像驱动程序”DC的句柄,这意味着反映对监视器所跨越的所有底层显示设备DC的调用


对于这种行为,我能想到的唯一可能的原因是wx以某种方式检索显示DC而不是窗口DC。

我相信Chris是正确的,“重叠窗口”的情况是在某个地方为您处理的。但是在哪里呢

使用windows GDI和您提到的“显示上下文”进行渲染非常原始,容易出现各种问题。GDI是有史以来最差的界面之一,甚至对微软来说也是如此。由于大多数“窗口”程序在多个显示器上都可以正常工作,所以想想在一个“窗口”中设置动画吧,这个“窗口”是如何进入“显示器”的最好还是个谜

也许DC根本不具备多监视器功能。寻找任何允许统一处理多个DC的方法。将图形渲染到一张纸的网格上就像一个平铺的“打印机DC”。视频墙将是一个平铺的“显示DC”,你会很高兴有一个2显示器的黑客,即“multimon DC”回声“拥有”显示器和“另一个”如果窗口跨越这两个窗口

如果您想在windows上制作“真实”动画,则需要移动到DirectX。它也有很多东西需要学习,但功能更强:场景图、纹理、视频、alpha通道等等