移动/调整窗口大小时闪烁

Pau*_*vie 7 windows winapi image flicker

我开发了一个显示jpeg图像的应用程序.它可以显示4个图像,每个图像在屏幕的每个象限中.它使用了4个窗口.窗口没有边框(框架)和标题栏.加载新图像时,将为新图像调整窗口大小,然后显示图像.

特别是当窗口变大时,通常会出现闪烁.在我看到切口时,似乎在显示新内容之前调整大小时会移动旧内容.

我咨询了很多资源并使用了所有技巧:

  • 窗口只有样式CS_DBLCLKS(没有CS_HREDRAWCS_VREDRAW);

  • 背景画笔为NULL;

  • WM_ERASEBKGND 返回1;

  • WM_NCPAINT 返回0;

  • WM_NCCALCSIZE 告诉我对齐未移动的一侧(你能告诉它丢弃客户区吗?);

  • WM_WINDOWPOSCHANGING 返回0;

  • SetWindowPos有标志SWP_NOCOPYBITS | SWP_DEFERERASE | SWP_NOREDRAW | SWP_NOSENDCHANGING.

但是,在调整窗口大小时,会出现闪烁(或内容移动).我想要的是:

  • SetWindowPos到新的大小和位置;

  • InvalidateRect(hWnd,NULL,FALSE);

  • UpdateWindow(HWND);

没有任何绘画,背景擦除或内容移动,直到WM_PAINT.

WM_PAINT 作用:

hDC= BeginPaint (hWnd, &ps);
hMemDC= CreateCompatibleDC (hDC);
hOldBitmap = SelectObject (hMemDC, hNewBitmap);
BitBlt (hDC,...,hMemDC,0,0,SRCCOPY);
SelectObject (hMemDC, hOldBitmap);
DeleteDC (hMemDC);
EndPaint (hWnd, &ps);
Run Code Online (Sandbox Code Playgroud)

任何人都可以告诉我是否/我在哪里犯了一个错误导致窗口的旧内容被移动?

硬件等:HP Elitebook Core7 64位上的Windows 7,NVIDIA Quadro K1000m驱动程序9.18.13.3265(更新至341.44).


更新(17年7月)

我已经在另一台Windows计算机上看到了该程序的行为(Windows 8/10).它似乎不是NVIDIA的显示驱动程序.

调整平铺到屏幕中心(右下角= w/2,h/2)到左上角或左上角(0,0)的窗口大小时,行为最明显.

我可能在WM_NCCALCSIZE消息的计算上遇到问题,告诉Windows不要做任何事情.有人可以为我的目的举例计算吗?另请参阅当用户调整对话框大小时,如何强制窗口不重绘对话框中的任何内容?

Luk*_*sen 1

你有一个令人印象深刻的抗闪烁技巧列表:-)

我不知道这是否重要(因为这取决于您的工具窗口的创建方式,特别是它们是否是公共父窗口的子窗口):尝试WS_CLIPCHILDREN在工具窗口的父窗口中设置窗口样式(如果有)一)。

如果未设置,父窗口将擦除其(整个)背景,然后将绘制消息转发到子窗口,这将导致闪烁。如果WS_CLIPCHILDREN设置了,则父窗口对子窗口占用的客户区域不执行任何操作。因此,子窗口区域不会绘制两次,并且不会出现闪烁。