关于"VC技术内幕"-控件上绘图代码的解释

void CMyDlg::OnPaint()
{
    CWnd   *pWnd   =   GetDlgItem(IDC_STATIC1);    
    RECT   rect;  
    pWnd->GetClientRect(&rect);  
    CDC   *pControlDC   =   pWnd->GetDC();  
    pWnd->Invalidate();  
    pWnd->UpdateWindow();  
    pControlDC->SelectStockObject(BLACK_BRUSH);  
    pControlDC->Rectangle(rect.left,   rect.top,   rect.right,rect.bottom);  
    pWnd->ReleaseDC(pControlDC);  
}

 这里连用了 pWnd->Invalidate();   pWnd->UpdateWindow();  
 原文解释:“这里面的一个技巧就在于我们既要在控件窗口内绘图,又要防止Windows对它进行重复绘制。”

 就是这两句代码(pWnd->Invalidate();   pWnd->UpdateWindow();  )让许多人摸不着头脑。
 归纳起来有两种问题:
1、认为这是死循环
  这是初学者提的问题,这里需指出:pWnd是IDC_STATIC控件的指针,并不是对当前窗体
2、对Invalidate、UpdateWindow均会引起WM_PAINT事件的不解
  “系统会在多个不同的时机发送WM_PAINT消息:当第一次创建一个窗口时,当改变窗口的大小时,当把窗口从另一个窗口背后移出时,当最大化或最小化窗口时,等等,这些动作都是由系统管理的,应用只是被动地接收该消息,在消息处理函数中进行绘制操作;大多数的时候应用也需要能够主动引发窗口中的绘制操作,比如当窗口显示的数据改变的时候,这一般是通过InvalidateRect和 InvalidateRgn函数来完成的。InvalidateRect和InvalidateRgn把指定的区域加到窗口的Update Region中,当应用的消息队列没有其他消息时,如果窗口的Update Region不为空时,系统就会自动产生WM_PAINT消息。”最后一句话指出了问题所在,Invalidate使客户区无效,但并没有及时触发WM_PAINT,WM_PAINT是由系统控制的,只有当在消息队列没有其他消息时才触发WM_PAINT
  系统为什么不在调用Invalidate时发送WM_PAINT消息呢?又为什么非要等应用消息队列为空时才发送WM_PAINT消息呢?
  "这是因为系统把在窗口中的绘制操作当作一种低优先级的操作,于是尽可能地推后做,这样有利于提高绘制的效率:在两个WM_PAINT消息之间多个Invalidate调用使之失效的区域就会被累加起来,然后在一个WM_PAINT消息中一次得到更新,不仅能避免多次重复地更新同一区域,也优化了应用的更新操作。像这种通过InvalidateRect和InvalidateRgn来使窗口区域无效,依赖于系统在合适的时机发送WM_PAINT消息的机 制实际上是一种异步工作方式,也就是说,在无效化窗口区域和发送WM_PAINT消息之间是有延迟的;有时候这种延迟并不是我们希望的,这时我们当然可以在无效化窗口区域后利用SendMessage 发送一条WM_PAINT消息来强制立即重画,但不如使用Windows GDI为我们提供的更方便和强大的函数:UpdateWindow和RedrawWindow。UpdateWindow会检查窗口的Update Region,当其不为空时才发送WM_PAINT消息;RedrawWindow则给我们更多的控制:是否重画非客户区和背景,是否总是发送WM_PAINT消息而不管Update Region是否为空等"

     

       这也就解释了代码中去掉pWnd->UpdateWindow() 后不能出现所绘图的现象,其实图像已经绘制,只不过被Invalidate滞后触发的WM_PAINT刷了

  MSDN的解释
  pWnd->Invalidate();  
     Specifies   whether   the   background   within   the   update   region   is   to   be   erased      
  pWnd->UpdateWindow();  
     Updates   the   client   area   by   sending   aWM_PAINT   message   if   the   update   region   is   not             empty.   The   UpdateWindow   member   function   sends   a   WM_PAINT   message   directly,   bypassing   the   application   queue.   If   the   update   region   is   empty,   WM_PAINT   is   not   sent.  

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sinhua_ren/archive/2007/06/21/1660473.aspx

分析一下这个json {"name":"12312","project_id":"87156","project_name":"上上下下左左右右baba与聚法科技(长春)有限公司与公司、证券、保险、票据等有关的民事纠纷","client":"[{"type":"自然人","customer_id":"80236","customer_name":"上上下下左左右右baba"}]","sign_date":"2023-06-06","expire_date":"2023-06-21","subject_amount":"123","contract_amount":"123","charge_method":"一次性,分阶段,风险,计时","equity_amount":"13811","amount_info":"[{"type":"一次性","pay_date":"2023-07-03","charge_amount":"12"},{"type":"分阶段","pay_date":"2023-06-13","charge_amount":"123","is_satisfy":"是","pay_condition":"12312"},{"type":"风险","pay_date":"","charge_amount":"","is_satisfy":"是","pay_condition":"123","basic_amount":"123","risk_amount":"12","object_amount":"123123","object":"赔偿金","risk_prop":"13213","member":"","rate":"","hours":""},{"type":"计时","member_id":"392159","member":"曹野","rate":"11","hours":"1231"}]","seal_person":"123","seal_type":"律所公章,法人名章,财务章","seal_num":"123","file_path":"[{"title":"导入错误数据 (15).xls","path":"382585/1686381522542/导入错误数据 (15).xls","size":"91136"},{"title":"3.txt","path":"382585/1686561731102/3.txt","size":44078}]","remark":"123123"} 并使用php转换成字符串
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值