日期:2014-05-18  浏览次数:21198 次

[高难度]如何解决设置TransparencyKey属性后窗体闪烁问题?
环境:VS2005 C# WinForm

窗口设置TransparencyKey属性后(不管设成什么颜色),窗口加载时,未被透明的部分会先出现黑块,然后刷新成正常颜色,从而造成了闪烁。

双缓冲、屏蔽WM_ERASEBKGND这些方法都不管用(重载WndProc或采用下面代码)
C# code

            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲



我觉得这黑块是系统为了画出透明部分而产生的。因此和是否擦除背景无关。(一篇资料上说VC下可以重载OnEraseBkgnd来防止设置透明色后带来的闪烁http://www.vckbase.com/document/viewdoc/?id=1148)


哪位朋友能够解决这个问题?

------解决方案--------------------
沙发,没有遇到过不怎懂,路过帮忙顶下~
------解决方案--------------------
试了一下,没有出现楼主说的问题(Win7+VS2005)

UI控件很多?

Form的构造函数代码贴上来看看
------解决方案--------------------
帮顶一下。。。
------解决方案--------------------
探讨
如果不透明区放的是系统控件,那么肯定会出现闪烁。用下面方法可以确定黑块是否存在:

------解决方案--------------------
帮up,闪烁问题太烦人了
------解决方案--------------------
确实有这个问题.
但是当TransparencyKey=Black就不会出黑块了,
只是文本如果是黑色,全部变成透明,继续找原因,很有意思.
------解决方案--------------------
我想我可以解决你的问题。我起初遇到这个问题是尝试了N中方案,都无济于事,最后发现了一个“不成文”但很凑效的办法:
需要一个Timer,
先设置要加载窗体的Opacity=0,然后执行加载,最后启动Timer。
Timer的Interval随便,效果是一样的。我一般都是设为1ms。Timer_Tick事件里设置窗体的Opacity=1,停止Timer1即可。

效果:相比现在的黑框,修改后的程序加载时会稍微顿一下,但没有任何闪烁或黑框!


例如,我有一个项目几乎所有控件和图像资源都是在运行时生成的,需要从远程加载图片。而Form是个不规则的窗体,必须设置TransparencyKey。加载时黑的很恐怖。。我的解决办法就是:

首先:
this.Visible = False
this.Opacity = 0

然后设置窗体大小布局等,连接远程主机,读取数据库,加载图片资源,生成控件等。

最后;this.timer1.Enabled = True
(Load结束)

Sub timer1_Tick()
{
this.Opacity = 1
timer1.Enabled = False
}

这个方法我已经在多个项目中使用并且非常奏效。
------解决方案--------------------
另外,如果最小化后还原时还有黑框闪烁,处理WndProc就行了。最小化时Opacity = 0,还原时启动timer。
例如:

VB.NET code

Protected Overrides Sub WndProc(ByRef m As Message)
        Select Case m.Msg
            Case &H5
                ' 为避免加载窗体或还原窗体时绘制出现黑框,处理Windows消息
                'change size: WM_SIZE
                If True Then
                    Dim newState As FormWindowState = FormWindowState.Normal
                    Select Case m.WParam.ToInt32()
                        Case 0
                            'SIZE_RESTORED
                            Me.Timer1.Enabled = True
                        Case 1
                            'SIZE_MINIMIZED
                            Me.Opacity = 0
                        Case 2
                            'SIZE_MAXIMIZED
                        Case Else
                            Exit Select
                    End Select

                End If
                Exit Select
            Case Else
                Exit Select
        End Select
        MyBase.WndProc(m)
    End Sub