避免多控件窗体闪烁

前面说到模仿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: 原文

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值