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

  • 相关阅读:
    Leetcode 50.Pow(x,n) By Python
    Leetcode 347.前K个高频元素 By Python
    Leetcode 414.Fizz Buzz By Python
    Leetcode 237.删除链表中的节点 By Python
    Leetcode 20.有效的括号 By Python
    Leetcode 70.爬楼梯 By Python
    Leetcode 190.颠倒二进制位 By Python
    团体程序设计天梯赛 L1-034. 点赞
    Wannafly挑战赛9 C-列一列
    TZOJ Start
  • 原文地址:https://www.cnblogs.com/lidabo/p/2576174.html
Copyright © 2011-2022 走看看