zoukankan      html  css  js  c++  java
  • 在OnPaint中必须调用一次BeginPaint和EndPaint,且也只能调用一次。(上) .

    基于对话框的程序(mfc默认生成),重载OnEraseBkgnd函数,其它不动,若在OnPaint函数中不调用其基类的OnPaint函数,即注释掉CDialog::OnPaint();,代码如下:
    1. void CDDDDlg::OnPaint()  
    2. {  
    3.     if (IsIconic())  
    4.     {  
    5.         CPaintDC dc(this); // device context for painting   
    6.   
    7.         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);  
    8.   
    9.         // Center icon in client rectangle   
    10.         int cxIcon = GetSystemMetrics(SM_CXICON);  
    11.         int cyIcon = GetSystemMetrics(SM_CYICON);  
    12.         CRect rect;  
    13.         GetClientRect(&rect);  
    14.         int x = (rect.Width() - cxIcon + 1) / 2;  
    15.         int y = (rect.Height() - cyIcon + 1) / 2;  
    16.   
    17.         // Draw the icon   
    18.         dc.DrawIcon(x, y, m_hIcon);  
    19.     }  
    20.     else  
    21.     {  
    22.         //CDialog::OnPaint();   
    23.     }  
    24. }  


     则执行后界面没有问题,如下图:

    但是,如果将此界面隐藏后再显示,则上面的控件都不能显示了,如下图:

    跟踪程序会发现,第一次生成界面时候,进入过OnCtlColor函数(TRACE("OnCtlColor\n");语句输出),

    当隐藏界面再显示后,就再也没进过OnCtlColor函数。当然看不见原先界面的控件了,因为根本没有重绘出来。原因见下篇

    A:在OnPaint中注释此句CDialog::OnPaint();为什么会不停地调用OnPaint函数呢(不断执行TRACE("OnPaint\n");语句)?

    Q:如果自己的OnPaint代码什么也没做的话(至少没有声明过CPaintDC类型的变量),还必须调用一下CDialog::OnPaint,否则BeginPaint和EndPaint就没有办法被调用了。
    总之,在响应WM_PAINT消息的时候,必须调用一遍BeginPaint和EndPaint。调用的方法有三种:
    1、声明一个CPaintDC类型的变量(即使你什么也不画),CPaintDC的构造函数就是调用BeginPaint,析构函数就是调用EndPaint。
    2、调用基类的OnPaint(实际上就是调用API的DefWindowProc,它会自动调用BeginPaint和EndPaint)。
    3、自己直接调用BeginPaint和EndPaint。
    上述三种方法,必须选择其一,而且也只能选择其一(因为在一个WM_PAINT消息内不能调用两次BeginPaint和EndPaint)。

    正如我猜想的,因为你调用了CDialog::OnPaint();
    你把这句注释掉就可以了。
    所以说凡事总有因果,CDialog::OnPaint()调用默认的窗口过程来绘制,也会调用BeginPaint/EndPaint()。而这两个函数的作用,是获取DC、剪裁区域和从消息队列中移走WM_PAINT消息(因此,如果不用上述三种方法的一种调用一遍BeginPaint和EndPaint的话,WM_PAINT消息就不会从消息队列里面移走,系统就会不停的发送WM_PAINT,这就是问题中所提到的不停的调用OnPaint函数的原因了)。这两个函数,必须在WM_PAINT消息中调用,而且只能调用一次!

    相关帖子:

    http://topic.csdn.net/u/20100801/11/40897468-807e-445a-a817-ede00dfd406e.html

    http://topic.csdn.net/u/20080620/15/1D8E30FD-584A-4551-B93A-DA97D5F6423C.html#r_50392023

  • 相关阅读:
    深入浅出TCP之listen
    indexing and hashing
    c++四种强制类型转化
    c++实现web服务框架
    MVC、MVP、MVVM概念解析
    常用设计模式
    [React]虚拟DOM
    防抖和节流
    函数柯里化
    apply, bind, call方法剖析
  • 原文地址:https://www.cnblogs.com/lidabo/p/2576174.html
Copyright © 2011-2022 走看看