一般的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
时设定的个数,可能会造成系统崩溃。在WindowsNT系列下不会有这样的问题。
分享到:
相关推荐
本文将深入探讨GDI贴图闪烁的原因,并提供相应的解决方法。 首先,我们来看闪烁产生的主要原因: 1. **刷新周期不匹配**:GDI函数在向屏幕输出图像时,不是立即显示,而是写入显存,然后由显卡在刷新周期内将内容...
在Windows编程中,GDI(Graphics Device Interface)是系统提供的一种图形绘制机制,而GDI+则是其增强版,增加了更多的图形处理功能,包括对透明贴图的支持。本篇文章将详细探讨如何使用GDI++来绘制透明贴图,并实现...
DirectDraw支持双缓冲技术,能有效解决画面闪烁问题;它还提供了纹理贴图、Alpha混合和色彩键等特性,为高级图形效果提供了可能。此外,DirectDraw还支持硬件级别的YUV色彩空间转换,对于视频播放和处理非常有用。 ...
在VS2008环境下,你可以创建一个Windows Forms应用程序,并在Form的Paint事件中实现这三种绘图方法。通过绘制60*60个圆点并计算每秒绘制的次数(帧速),可以直观地比较它们的性能差异。为了确保公平性,需要在相同...
在C#中,我们通常使用GDI+(Graphics Device Interface Plus)或Windows Presentation Foundation (WPF)来实现双缓冲。对于本题中提到的“利用双缓冲技术贴图”,我们可以假设是在WinForms应用中,使用GDI+进行操作...
在Windows编程中,通常使用GDI (Graphics Device Interface) 或者GDI+进行图形绘制,包括界面贴图。GDI允许开发者处理窗口、设备上下文、字体、颜色以及位图等,而GDI+则提供了更多的图形绘制功能,如抗锯齿和透明度...
在Windows编程中,GDI(Graphics Device Interface)是一个用于处理设备输出的图形库,它提供了丰富的图形绘制功能,包括对透明贴图的支持。在“透明贴图源代码lx2.zip”中,我们可以期待找到一个使用GDI实现透明...
在C++中,可能使用GDI+或Direct2D这样的库来处理带有alpha通道的位图,并在屏幕上以正确的方式显示它们。 **键盘读取**: 在程序中,我们需要监听用户的键盘输入以做出响应。这通常涉及到注册键盘事件处理函数,如...
在Windows API中,可以使用GDI(Graphics Device Interface)或者更现代的Direct2D、Direct3D来实现这一功能。GDI提供了如BitBlt这样的函数,可以将位图从一个设备上下文复制到另一个设备上下文,从而实现贴图。而...
DirectDraw和GDI是两种在Windows平台上进行图形绘制的技术。DirectDraw是Microsoft DirectX的一部分,而GDI(Graphics Device Interface)是Windows操作系统内核提供的图形接口。这两种技术各有特点,适用于不同的...
开发者可能采用了各种优化技巧,比如减少不必要的重绘,使用双缓冲技术来减少闪烁,或者利用GDI的硬件加速特性。 8. **可扩展性与兼容性**:一个好的界面库应该易于扩展,适应不同的项目需求,并且能在不同的...
- **Windows Forms或WPF**: 如果是桌面应用,可以使用Windows Forms或WPF的控件如PictureBox或Canvas,结合Graphics或Visual对象进行绘图。 - **Direct2D或Direct3D**: 对于更复杂的3D效果,可以利用Direct2D或...
在计算机编程领域,尤其是涉及到图形用户界面(GUI)开发时,"双缓冲"技术是一种常见的优化手段,用于解决图像更新时出现的闪烁问题。本文将深入探讨如何利用C++实现图片的双缓冲显示,以及其在游戏编程中的应用。 ...
例如,在重写的`OnDraw`方法中,可以通过GDI函数如`BitBlt`来绘制背景位图。为了避免点击时背景位图的闪烁,可以使用双缓冲技术,即在内存中预先绘制好背景位图,然后再将其绘制到屏幕上。 #### 四、示例应用 为了...
- **合理利用无效区域**:Windows系统只重绘无效区域,因此在`OnPaint()`方法中,可以通过`e.ClipRectangle`获取需要重绘的区域,并仅在此区域内绘制,以减少不必要的绘图操作。 - **直接贴图**:对于需要频繁更新...
在Windows编程中,我们可以使用GDI(Graphics Device Interface)库来处理图形资源,包括位图。使用`LoadImage`函数可以从文件中加载位图资源,该函数返回一个位图句柄,我们可以用它来操作位图。需要注意的是,位图...
在GDI中,双缓冲是为了减少屏幕闪烁和图像撕裂而设计的一种优化方法。传统的单缓冲绘图方式可能导致屏幕更新不一致,特别是在频繁更新图形时,用户可能会看到不完整的图像。双缓冲则是先在内存中的一个缓冲区完成...
这与传统的 GDI(图形设备接口)相比,能更有效地减少图像闪烁并提高帧率。 直接修改显存数据的核心在于创建和管理 DirectDraw 表面(DirectDraw Surface)。这些表面是存储图形数据的内存区域,可以映射到显存或者...