zoukankan      html  css  js  c++  java
  • 从CWnd::GetSafeHwnd实现得到的知识

    在看MFC源码的过程中,有个地方一直不解,看如下代码

    BOOL CFrameWnd::Create(LPCTSTR lpszClassName,
        LPCTSTR lpszWindowName,
        DWORD dwStyle,
        const RECT& rect,
        CWnd* pParentWnd,
        LPCTSTR lpszMenuName,
        DWORD dwExStyle,
        CCreateContext* pContext)
    {
        HMENU hMenu = NULL;
        if (lpszMenuName != NULL)
        {
            // load in a menu that will get destroyed when window gets destroyed
            HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName, ATL_RT_MENU);
            if ((hMenu = ::LoadMenu(hInst, lpszMenuName)) == NULL)
            {
                TRACE(traceAppMsg, 0, "Warning: failed to load menu for CFrameWnd.
    ");
                PostNcDestroy();            // perhaps delete the C++ object
                return FALSE;
            }
        }
    
        m_strTitle = lpszWindowName;    // save title for later
    
        if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
            rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
            pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext))
        {
            TRACE(traceAppMsg, 0, "Warning: failed to create CFrameWnd.
    ");
            if (hMenu != NULL)
                DestroyMenu(hMenu);
            return FALSE;
        }
    
        return TRUE;
    }

    注意Create函数参数pParentWnd如果传NULL进来,pParentWnd->GetSafeHwnd并不会报错。开始一看,吓我一大跳,怎么不出现内存访问违规呢,奇怪了。经过试验,还是自己的知识太欠缺了啊。

    原因还得在代码中找,看下GetSafeHwnd的实现, 内部判断了this==NULL(第一次知道还可以这样用)

    _AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const
        { return this == NULL ? NULL : m_hWnd; }

    以下是试验代码:

    #include <iostream>
    
    using namespace std;
    
    
    class TestClass
    {
    public:
        TestClass():m_nInt( 222 ) 
        {
            cout << "TestClass()" << endl; 
        }
    
        virtual ~TestClass() 
        { 
            cout << "~TestClass()" << endl;
        }
    
        //this==NULL时,未使用本类变量
        int GetInt() 
        {
            if ( this == NULL )
            {
                return 888;
            }
            return m_nInt;
        }
    
        //函数引用此类变量
        int GetInt2()
        {
            return m_nInt;
        }
    
    private:
        int m_nInt;
    };
    
    
    int main()
    {
        TestClass* pTest = NULL;
    
        //this==NULL时,未使用本类变量,故可正常调用 
        int nRet = pTest->GetInt();
    
        //this==NULL时,使用本类变量,
        //而对象并不存在,内存访问违规!!!
        int nRet2 = pTest->GetInt2();
        return 0;
    }

    TODO: 有空要学习下《深度探索C++对象模型》

  • 相关阅读:
    java_爬虫_从腾讯视频播放界面爬取视频真实地址
    杂_小技巧_将网页上的内容通过亚马逊邮箱传到kindle中
    java_基础_接口和抽象类
    知乎上的50道SQL练习题
    第 4 章 WebDriver API
    第 2 章 测试环境搭建
    第 1 章 自动化测试基础
    【软件测试】9.QC管理学习(类禅道)学习
    01 Python简介、环境安装、变量、数据类型
    【MySQL面试指南】
  • 原文地址:https://www.cnblogs.com/shanql/p/6662050.html
Copyright © 2011-2022 走看看