【Visual C++】Windows GDI贴图闪烁解决方法

简介:


一般的windows 复杂的界面需要使用多层窗口而且要用贴图来美化,所以不可避免在窗口移动或者改变大小的时候出现闪烁。

先来谈谈闪烁产生的原因

原因一:
如果熟悉显卡原理的话,调用GDI函数向屏幕输出的时候并不是立刻就显示在屏幕
上只是写到了显存里,而显卡每隔一段时间把显存的内容输出到屏幕上,这就是刷新周期。

一般显卡的刷新周期是 1/80秒左右,具体数字可以自己设置的。

这样问题就来了,一般画图都是先画背景色,然后再把内容画上去,如果这两次操作不在同一个
刷新周期内完成,那么给人的视觉感受就是,先看到只有背景色的图像,然后看到画上内容的图像,
这样就会感觉闪烁了。

解决方法:尽量快的输出图像,使输出在一个刷新周期内完成,如果输出内容很多比较慢,那么采用
内存缓冲的方法,先把要输出的内容在内存准备好,然后一次输出到显存。要知道一次API调用一般可以
在一个刷新周期内完成。

对于GDI,用创建内存DC的方法就可以了

原因二:

复杂的界面有多层窗口组成,当windows在窗口改变大小的时候是先重画父窗口,然后重画子窗口,子父
窗口重画的过程一般无法在一个刷新周期内完成,所以会呈现闪烁。

我们知道父窗口上被子窗口挡住的部分其实没必要重画的

解决方法:给窗口加个风格 WS_CLIPCHILDREN ,这样父窗口上被子窗口挡住的部分就不会重画了。

如果同级窗口之间有重叠,那么需要再加上 WS_CLIPSIBLINGS 风格

原因三:

有时候需要在窗口上使用一些控件,比如IE,当你的窗口改变大小的时候IE会闪烁,即使你有了WS_CLIPCHILDREN
也没用。原因在于窗口的类风格有CS_HREDRAW 或者 CS_VREDRAW,这两个风格表示窗口在宽度或者高度变化的时候
重画,但是这样就会引起IE闪烁

解决方法:注册窗口类的时候不要使用这两个风格,如果窗口需要在改变大小的时候重画,那么可以在WM_SIZE的时候
调用RedrawWindow。

原因四:

界面上窗口很多,而且改变大小时很多窗口都要移动和改变大小,如果使用MoveWindow或者SetWindowPos两个API来
改变窗口的大小和位置,由于他们是等待窗口重画完成后才返回,所以过程很慢,这样视觉效果就可能会闪烁。

解决方法:

使用以下API来处理窗口移动,BeginDeferWindowPos, DeferWindowPos,EndDeferWindowPos
先调用 BeginDeferWindowPos 设定需要移动的窗口的个数
使用DeferWindowPos,来移动窗口,这个API并不真的造成窗口移动
EndDeferWindowPos 一次性完成所有窗口的大小和位置的改变。

有个地方要特别注意,要仔细计算清楚要移动多少个窗口,BeginDeferWindowPos设定
的个数一定要和实际的个数一致,否则在Win9x下,如果实际移动的窗口数多于调用BeginDeferWindowPos
时设定的个数,可能会造成系统崩溃。在Windows NT系列下不会有这样的问题。



    本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/dyllove98/archive/2012/04/07/2461863.html,如需转载请自行联系原作者


相关文章
|
4月前
|
编译器 开发工具 C++
【Python】已解决error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build
【Python】已解决error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build
2213 0
|
1月前
|
弹性计算 安全 网络安全
阿里云国际版无法远程连接Windows服务器的解决方法
阿里云国际版无法远程连接Windows服务器的解决方法
|
5月前
|
存储 分布式数据库 API
技术好文:VisualC++查看文件被哪个进程占用
技术好文:VisualC++查看文件被哪个进程占用
|
2月前
|
C++ 内存技术
[转]Visual C++内嵌swf文件并播放
[转]Visual C++内嵌swf文件并播放
|
3月前
|
安全 编译器 C++
Microsoft Visual C++ Redistributable的作用主要体现以及可以删除吗?
这些是Microsoft Visual C++不同版本的Redistributable安装包,用于32位系统,确保相关应用正常运行。它们提供C++运行时环境,简化部署流程,支持第三方库及框架,并确保应用兼容性。定期更新可修复问题并引入新功能。在空间有限或需解决程序冲突时可考虑删除,但需谨慎操作以防影响应用稳定性和兼容性。删除前请确认无应用依赖,并通过控制面板安全卸载。
168 1
Microsoft Visual C++ Redistributable的作用主要体现以及可以删除吗?
|
2月前
|
Windows
Windows7电脑启动时提示文件winload.exe无法验证其数字签名,错误代码0xc0000428的解决方法
Windows7电脑启动时提示文件winload.exe无法验证其数字签名,错误代码0xc0000428的解决方法
|
4月前
|
C++ Windows
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
在Windows上使用Visual Studio 2022进行FFmpeg和SDL2集成开发,首先安装FFmpeg至E:\msys64\usr\local\ffmpeg,然后新建C++控制台项目。在项目属性中,添加FFmpeg和SDL2的头文件及库文件目录。接着配置链接器的附加依赖项,包括多个FFmpeg及SDL2的lib文件。在代码中引入FFmpeg的`av_log`函数输出"Hello World",编译并运行,若看到"Hello World",即表示集成成功。详细步骤可参考《FFmpeg开发实战:从零基础到短视频上线》。
171 0
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
|
3月前
|
安全 C++ Windows
Windows下C++使用gRPC(Qt和VS,含文件包和使用方法)
Windows下C++使用gRPC(Qt和VS,含文件包和使用方法)
|
3月前
|
缓存 C++ Windows
Inno setup 脚本判断 Microsoft Visual C++ Redistributable 不同版本区别
Inno setup 脚本判断 Microsoft Visual C++ Redistributable 不同版本区别
|
3月前
|
编译器 C++ 开发者
Visual Studio属性表:在新项目中加入已配置好的C++库
通过以上步骤可以确保Visual Studio中新项目成功地加入了之前已配置好的C++库。这个过程帮助开发者有效地管理多个项目中共享的库文件,提升开发效率。
103 0