CWnd和HWND的区别(hWnd只是CWnd对象的一个成员变量,代表与这个对象绑定的窗口)

        所有控件类都是CWnd类的派生类,CWnd的所有成员函数在控件类中都可以使用。在MFC中,CWnd类是一个很重要的类,它封装了Windows的窗口句柄HWND。在Windows编程中,每一个窗口都是有窗口句柄标识的。但是,类CWnd的对象和窗口句柄之间的概念并不是等同的。CWnd对象的创建和销毁,是由类CWnd的构造函数和析构函数完成的,而Windows窗口是Windows内部的一种数据结构,它由类CWnd的Create成员函数创建,由析构函数销毁。除此之外,成员函数DestroyWindow可以销毁Windows窗口,而不会销毁CWnd对象。

一般情况下,他创建一个窗口需要两步:首先,调用类CWnd的构造函数,构造一个CWnd对象,然后调用CWnd的成员函数Create,创建窗口。当用户要关闭该窗口时,可以销毁与窗口有关的CWnd对象,或者调用CWnd对象的成员函数DestoryWindow,删除窗口并销毁其数据结构。

HWND是Windows系统中对所有窗口的一种标识,即窗口句柄。这是一个SDK概念。

CWnd是MFC类库中所有窗口类的基类。在MFC中将所有窗口的通用操作都封装到了这个类中,如:ShowWindow等等,同时它也封保存了窗口句柄即在m_hWnd成员。

1.由一个HWND变量hWnd实例化一个CWnd*对象:

CWnd *pWnd;  HWND hWnd;

得到hWnd的方式:1.从参数获得   2.从CreateWindow(…..)返回

pWnd->Attach(hWnd);  //pWnd对象和窗口资源关联

用staticCWnd*   CWnd::FromHandle(HWND   hWnd) ;

如果一个CWnd对象没有和这个hWnd绑定,一个临时的CWnd对象将被构造,并且和hWnd绑定。如果绑定了就不是一个临时CWnd对象。返回的这个指针可能是临时的,所以最好不要保存用于后来使用。

用staticCWnd*   CWnd::FromHandlePermanent(HWND   hWnd);

如果CWnd对象没有和hWnd绑定,返回NULL,而不会构造一个临时对象。

2.由CWnd获取HWnd

CWnd的一个成员m_hWnd就是其所对应窗口的句柄:hWnd = pWnd->m_hWnd;

用hWnd = pWnd->GetSafeHwnd() 比pWnd->m_hWnd 安全,因为:

因为前者在 pWnd == NULL 的时候返回 NULL 不易察觉,而后者出现 access violation。

1.      获得父窗体的控件或子窗体的“窗口句柄—hWnd”

HWND hWnd = ::GetDlgItem(this->m_hWnd,IDC_XXXX_SIZE);  //参数1:父窗口的句柄

CWnd *CWnd::GetDlgItem( int nID );  // 返回控件/子窗体对象

void GetDlgItem( int nID, HWND*phWnd );  //获得控件/子窗体的句柄

总结:综上可知在MFC概念下,hWnd只是CWnd对象的一个成员变量,代表与这个对象绑定的窗口;在SDK下hWnd原本就是用来代表一个窗口。hWnd在SDK和MFC概念都是一致的。而CWnd类是MFC将除了hWnd外的其它许多属性和操作进行封装的结果。

补充:

MFC中的每一个窗口类型(从CWnd直接/间接派生)对象fromWnd,在实例化之前,其

fromWnd.m_hWnd必定为NULL。

CButton button;  //此时button.m_hWnd ==NULL

button.Create(“按钮”,BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,

CRect(0,0,100,50),this,123); //此时button.m_hWnd != NULL

根据这个特点可以在动态控件的创建过程检测控件对象是否实例化,以避免重复/没有实例化。

http://blog.****.net/qq2399431200/article/details/10997461

上一篇:2018/03/31 每日一个Linux命令 之 date


下一篇:Android05-UI02布局,自定义控件,ListView