简体   繁体   English

调整主窗口大小时,静态控件会稍微闪烁

[英]Static controls slightly flicker when main window is resized

INTRODUCTION AND RELEVANT INFORMATION: 简介和相关信息:

I have a complex painting to implement in my main window's WM_PAINT handler. 我在主窗口的WM_PAINT处理程序中要实现一个复杂的绘画。

I have submitted a picture bellow to illustrate it: 我提交了下面的图片进行说明:

在此处输入图片说明

Main window has static controls, instead of buttons, which have style SS_NOTIFY . 主窗口具有样式为SS_NOTIFY静态控件,而不是按钮。

When user clicks on them, certain actions occur in program. 当用户单击它们时,程序中会发生某些动作。

The following picture shows where static controls in the main window are: 下图显示了主窗口中静态控件的位置:

在此处输入图片说明

Map on the orange panel is an EMF file ,top left and right logos are PNG files, and other pictures are bitmaps. 橙色面板上的Map是EMF文件,左上和右上徽标是PNG文件,其他图片是位图。

In order to implement this task, I have decided to draw the entire picture in WM_PAINT , and to put invisible static controls over the images on the picture that correspond them. 为了实现此任务,我决定在WM_PAINT绘制整个图片,并在与之对应的图片上放置不可见的静态控件。

Therefore, I only return NULL_BRUSH in WM_CTLCOLORSTATIC handler like this: 因此,我只在WM_CTLCOLORSTATIC处理程序中返回NULL_BRUSH ,如下所示:

case WM_CTLCOLORSTATIC:
    return (LRESULT)( (HBRUSH)GetStockObject(NULL_BRUSH) );

I work on Windows XP , using MS Visual Studio C++ 2008 Express Edition and pure Win32 API . 我在Windows XP上工作,使用MS Visual Studio C++ 2008 Express Editionpure Win32 API

One note : since Express edition of VS doesn't have resource editor, resource file and resource header were created using ResEdit from here: http://www.resedit.net/ . 注意事项 :由于VS Express版没有资源编辑器,因此可使用ResEdit从以下位置创建资源文件和资源头: http : //www.resedit.net/

PROBLEM: 问题:

When I resize my window, static controls slightly flicker. 调整窗口大小时,静态控件会稍微闪烁。

MY EFFORTS TO SOLVE THE PROBLEM: 我为解决问题所做的努力:

I have handled WM_ERASEBKGND (returned (LRESULT)1 ), and I have excluded styles CS_VREDRAW and CS_HREDRAW from my window class-therefore flickering should not be caused because of this. 我已经处理了WM_ERASEBKGND (返回(LRESULT)1 ),并且从我的窗口类中排除了样式CS_VREDRAWCS_HREDRAW因此不应因此而引起闪烁。

My window doesn't have WS_CLIPCHILDREN style. 我的窗口没有WS_CLIPCHILDREN样式。

EDIT: In response to the comment bellow, I explain why my window doesn't have this style set: 编辑:为了回应下面的评论,我解释了为什么我的窗口没有设置这种样式:

The problem is that part of the desktop picture is seen where static controls are. 问题在于,桌面图片的一部分可以在静态控件的位置看到。

I have implemented double buffering for both handlers, in order to avoid flickering. 为了避免闪烁,我为两个处理程序都实现了双重缓冲。

I have used the tool GDIView , downloaded from here: http://www.nirsoft.net/utils/gdi_handles.html to track down GDI leaks . 我使用了从此处下载的工具GDIViewhttp : GDIView来跟踪GDI leaks

Each time I resize my window, GDIView shows +4 in column for regions, which means that I leak regions. 每次我调整窗口大小时, GDIView的区域列都会显示+4,这意味着我泄漏了区域。

I can't figure out how is this possible, since I do not use API's that manipulate with regions. 我不知道这怎么可能,因为我没有使用对区域进行操作的API。

To illustrate exactly what I am facing with, I have made a demo application , with thorough comments: http://www.filedropper.com/geotermistgrafika 为了确切说明我所面临的问题,我制作了一个演示应用程序,并提供了详尽的注释: http : //www.filedropper.com/geotermistgrafika

I believe that this is more efficient way, then posting code since it will consume too much space. 我相信这是一种更有效的方法,然后发布代码,因为它会占用太多空间。

QUESTION: 题:

How can I modify code in demo project to get rid of flickering? 如何在演示项目中修改代码以消除闪烁?

Is my approach wrong, and if it is, what is the right one? 我的方法错误吗?如果是,正确的方法是什么?

Thank you. 谢谢。 Regards. 问候。

When the main window is resized the WM_SIZE handler moves the static child windows. 调整主窗口大小后, WM_SIZE处理程序将移动静态子窗口。

When a child window is moved, Windows automatically copies the client area of the child control from the old location to the new location. 移动子窗口时,Windows会自动将子控件的客户区从旧位置复制到新位置。

The main window will then repaint itself in the WM_PAINT handler. 然后,主窗口将在WM_PAINT处理程序中重新绘制自身。

In other words, when the window is resized all the static controls move to their new position and then the rest of the window is repainted. 换句话说,当调整窗口大小时,所有静态控件将移至其新位置,然后重新绘制窗口的其余部分。 This lack of synchronization appears as flicker. 缺乏同步表现为闪烁。

You can avoid this by passing the SWP_NOCOPYBITS flag to SetWindowPos . 您可以通过将SWP_NOCOPYBITS标志传递给SetWindowPos来避免这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM