在我的win32应用程序中,我创建了一个弹出窗口,我用它来显示其他窗口的内容。
例如,我正在运行一个Photoshop应用程序。我抓住它的主窗口的句柄,使其样式成为子窗口,并将其父窗口设置为我自己的窗口。这将Photoshop放在我的应用程序中。
之后,我隐藏了photoshop窗口(将不透明度设置为0),而是将其设备上下文内容抓取到我创建的位图中,然后在窗口上绘制这个位图。为此,我设置了一个每16毫秒(60赫兹)滴答的计时器。这是计时器:
void CALLBACK drawProc( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime )
{
updateFrames();
RECT r;
GetClientRect( hwnd, &r );
//Erase background
HBRUSH eraseBrush = CreateSolidBrush( RGB( 255, 255, 255 ) );
FillRect( bbHDC, &r, eraseBrush );
DeleteObject( eraseBrush );
//Draw frames
drawFrames( bbHDC );
RedrawWindow( hwnd, 0, 0, RDW_INVALIDATE | RDW_NOCHILDREN );
}
问题是,这会降低photoshop(以及其他一些应用程序的速度)。通过评论行我发现redrawWindow导致了这一点。我认为重绘主窗口可能会导致photoshop重绘其内容,所以我添加了RDW_NOCHILDREN但仍然缓慢。
如果有人可以帮我解决这个问题,我会很高兴。
感谢。
答案 0 :(得分:3)
我甚至不会评论为什么这是一件奇怪的事情:)
为什么这么慢:
每次调用它时, RedrawWindow
可能会强制完全重画。毕竟,你使整个窗口无效。这将是一个昂贵的操作 - 通常在Windows应用程序中,您只在您知道需要时绘制(通过使矩形或区域无效,这是一个非常便宜的操作,并在某些时候处理WM_PAINT
消息,并且在处理该绘画时仅使用无效区域,这是可能的最小工作。)
值得阅读painting and drawing in Windows,尤其是when to draw in a window。
现在,尝试回答您的问题:
大多数情况下,嵌入式Photoshop窗口不会发生变化。换句话说,你的程序正在做的大量的浩瀚的大部分绘画工作是完全没必要的。当Photoshop窗口发生变化并且需要重新绘制自己时,你应该做的只是绘制到你的窗口 - 理想情况下,即使这样,也只重绘需要重新绘制的部分。 (一个示例是对鼠标悬停做出反应的按钮:您只需重新绘制按钮,或按钮所在的矩形,而不是整个窗口。)
您正在做的是polling的一般情况。这是非常低效的,因为你做了很多工作,即使不需要做任何事情。您希望在需要工作时收到通知,这样效率会更高。
以下是一个建议,我没有尝试过,但它应该工作。 Windows已经有一个内置框架,因此应用程序知道何时需要绘制:消息队列中将出现WM_PAINT
消息。您可以使用PeekMessage查看窗口的消息队列并查看其中的消息,而不删除任何消息。这将告诉你窗口何时需要绘制:然后重新绘制。或者,hook the message function或subclass the window,当收到WM_PAINT消息时,将其传递给原始消息函数,然后重新绘制。您可以使用GetUpdateRect
查看要绘制的区域,然后在WM_PAINT
处理完成后,将该区域仅复制到您自己的窗口。等
这是一般答案:尝试其中一些事情,看看会发生什么。请记住,如果您对特定部件有疑问,可以发布另一个问题!