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++对象模型》

  • 相关阅读:
    SQL中Group By的使用
    sqlserver中distinct的用法(不重复的记录)
    ASP.NET控件的ID,ClientID,UniqueId的区别
    四大线程池的简单使用
    Dex文件方法数超过65536怎么破?
    Context的正确使用
    dialog的各类显示方法
    JAVA小记(一)
    Horspool和BM算法解析
    安卓中Canvas实现清屏效果
  • 原文地址:https://www.cnblogs.com/shanql/p/6662050.html
Copyright © 2011-2022 走看看