避免多控件窗体闪烁
2010-04-22 16:55
211 查看
前面说到模仿Control类自身的BeginUpdateInternal和EndUpdateInternal方法,封装各个控件都适用的基础类,先看代码吧
1
class
AvoidControlFlicker
2
{
3
private
int
_paintFrozen;
4
5
public
void
FreezePainting(Control toFreezeControl,
bool
isToFreeze)
6
{
7
if
(
null
==
toFreezeControl)
8
throw
new
ArgumentNullException(
"
toFreezeControl
"
);
9
10
if
(isToFreeze
&&
toFreezeControl.IsHandleCreated
&&
toFreezeControl.Visible)
11
{
12
if
(
0
==
_paintFrozen
++
)
13
{
14
NativeMethods.SendMessage(toFreezeControl.Handle, NativeConsts.WM_SETREDRAW,
0
,
0
);
15
}
16
}
17
if
(
!
isToFreeze)
18
{
19
if
(
0
==
_paintFrozen)
return
;
20
if
(
0
==
--
_paintFrozen)
21
{
22
NativeMethods.SendMessage(toFreezeControl.Handle, NativeConsts.WM_SETREDRAW,
1
,
0
);
23
toFreezeControl.Invalidate(
true
);
24
}
25
}
26
}
27
}
代码很简单,
当需要"冻结" 控件对象时,由windows向该控件发送WM_SETREDRAW事件,
不需要"冻结"时,将该事件再发一次,改变参数即可,注意的是
1.添加一个计数器,防止多次发同一个消息
2.将控件"解冻"后,需要强制让控件重绘,即23行代码:
toFreezeControl.Invalidate(true);
因为Invalidate方法是Control类自身提供的,所以可以直接拿来用了,其中true参数表示该控件的所有子控件也一并重绘了,false表示只重绘自身
那么,如果针对外部窗体怎么写呢?
(不属于该进程的窗体,或者无法直接访问的窗体对象),拿windows任务栏来说,需要先获取它的句柄:
IntPtr taskBarHandle
=
NativeMethods.FindWindowA(
"
Shell_TrayWnd
"
,
""
);
拿到句柄后就可以给它发windows消息了:
NativeMethods.SendMessage(taskBarHandle, NativeConsts.WM_SETREDRAW,
0
,
0
);
//
禁止重绘
需要"解冻"时:
NativeMethods.SendMessage(taskBarHandle, NativeConsts.WM_SETREDRAW,
1
,
0
);
NativeMethods.RedrawWindow(taskBarHandle, IntPtr.Zero, IntPtr.Zero, NativeConsts.WM_NCPAINT);
//
强制重绘
至于demo代码就很简单了,
在窗体的resize事
PS:原文
1
class
AvoidControlFlicker
2
{
3
private
int
_paintFrozen;
4
5
public
void
FreezePainting(Control toFreezeControl,
bool
isToFreeze)
6
{
7
if
(
null
==
toFreezeControl)
8
throw
new
ArgumentNullException(
"
toFreezeControl
"
);
9
10
if
(isToFreeze
&&
toFreezeControl.IsHandleCreated
&&
toFreezeControl.Visible)
11
{
12
if
(
0
==
_paintFrozen
++
)
13
{
14
NativeMethods.SendMessage(toFreezeControl.Handle, NativeConsts.WM_SETREDRAW,
0
,
0
);
15
}
16
}
17
if
(
!
isToFreeze)
18
{
19
if
(
0
==
_paintFrozen)
return
;
20
if
(
0
==
--
_paintFrozen)
21
{
22
NativeMethods.SendMessage(toFreezeControl.Handle, NativeConsts.WM_SETREDRAW,
1
,
0
);
23
toFreezeControl.Invalidate(
true
);
24
}
25
}
26
}
27
}
代码很简单,
当需要"冻结" 控件对象时,由windows向该控件发送WM_SETREDRAW事件,
不需要"冻结"时,将该事件再发一次,改变参数即可,注意的是
1.添加一个计数器,防止多次发同一个消息
2.将控件"解冻"后,需要强制让控件重绘,即23行代码:
toFreezeControl.Invalidate(true);
因为Invalidate方法是Control类自身提供的,所以可以直接拿来用了,其中true参数表示该控件的所有子控件也一并重绘了,false表示只重绘自身
那么,如果针对外部窗体怎么写呢?
(不属于该进程的窗体,或者无法直接访问的窗体对象),拿windows任务栏来说,需要先获取它的句柄:
IntPtr taskBarHandle
=
NativeMethods.FindWindowA(
"
Shell_TrayWnd
"
,
""
);
拿到句柄后就可以给它发windows消息了:
NativeMethods.SendMessage(taskBarHandle, NativeConsts.WM_SETREDRAW,
0
,
0
);
//
禁止重绘
需要"解冻"时:
NativeMethods.SendMessage(taskBarHandle, NativeConsts.WM_SETREDRAW,
1
,
0
);
NativeMethods.RedrawWindow(taskBarHandle, IntPtr.Zero, IntPtr.Zero, NativeConsts.WM_NCPAINT);
//
强制重绘
至于demo代码就很简单了,
在窗体的resize事
PS:原文
相关文章推荐
- 使用双重缓冲,避免窗体中控件位置移动的时候闪烁
- [补充]避免多控件窗体闪烁demo
- 如何避免多控件窗体重新布局时闪烁
- 如何避免多控件窗体重新布局时闪烁
- 如何避免多控件窗体重新布局时闪烁
- 避免多控件窗体闪烁demo
- 如何避免treeview控件闪烁刷新
- winform 设定双缓存避免控件闪烁
- 消除窗体/内容/控件闪烁(Win32 SDK、C++ 语言描述)
- 【LibUIDK界面库系列文章】Web Browser控件避免闪烁
- 【原创】使用timer、imagelist与notifyicon控件实现图标闪烁-----并避免了GDI泄漏(重点)
- .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)
- C#中弹出式窗体如何避免闪烁?
- winform窗体加背景图片后,控件闪烁
- 如何防止拖动窗体大小时控件闪烁的问题
- [改善] dcef3 for Firemonkey 浏览器控件,拉动窗体大小会闪烁的问题
- winform窗体加背景图片后,控件多了会闪烁,该如何处理
- C#窗体加载和控件加载不同步导致控件闪烁
- 跨线程调用控件时关闭窗体时如何避免出现异常:Cannot access a disposed object.
- 窗体控件闪烁