前面说到模仿Control类自身的BeginUpdateInternal和EndUpdateInternal方法,封装各个控件都适用的基础类,先看代码吧
1.添加一个计数器,防止多次发同一个消息
2.将控件"解冻"后,需要强制让控件重绘,即23行代码: toFreezeControl.Invalidate(true); 因为Invalidate方法是Control类自身提供的,所以可以直接拿来用了,其中true参数表示该控件的所有子控件也一并重绘了,false表示只重绘自身
那么,如果针对外部窗体怎么写呢? (不属于该进程的窗体,或者无法直接访问的窗体对象),拿windows任务栏来说,需要先获取它的句柄:
需要"解冻"时:
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事件, 不需要"冻结"时,将该事件再发一次,改变参数即可,注意的是
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
7
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
12
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
14
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
16
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
17
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
19
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
20
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
22
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
24
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
25
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
26
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
27
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
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); // 强制重绘
NativeMethods.RedrawWindow(taskBarHandle, IntPtr.Zero, IntPtr.Zero, NativeConsts.WM_NCPAINT); // 强制重绘
至于demo代码就很简单了, 在窗体的resize事