现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

getOwner与getParent的区别

2012-07-27 22:17 工业·编程 ⁄ 共 1740字 ⁄ 字号 暂无评论

    CWnd::GetOwner 这个函数获得窗口的拥有者的指针。如果窗口没有拥有者,则缺省地返回父窗口对象的指针。注意在拥有者和被拥有者之间的关系与父子关系在几个重要方面的差别。例如,具有父窗口的窗口被限制在父窗口的客户区内,但是被拥有的窗口可以被画在桌面上的任何位置。 CWnd::GetParent 如果这个成员函数执行成功,则返回父窗口指针;否则返回值为NULL,表明发生了错误或没有父窗口。调用这个函数以获得子窗口的父窗口(如果有)的指针。GetParent函数返回直接父窗口的指针。 要知道一个窗口有一个父窗口(他是父窗口的child),就是用GetParent得到,一个child窗口只能在父窗口的客户区移动。 而对于对话框来说,他的父窗口永远是最顶层的窗口,但是可以用GetOwner得到他的逻辑意义上的“父窗口”(因为对话框可以在屏幕中到处移动

,而child不是的。)


CWnd,CDC, Cxxx等都是MFC的类,这些类提供了很多成员函数来执行系统调用等操作,但是核心的类成员数据都是 句柄,(包括窗口句柄,DC句柄,线程句柄等)。
m_hWnd
m_hDC
m_hThread

如果这些类对象的这些句柄为空,就表示无效对象。比如你 CWnd * pWnd = new CWnd,执行是合法的,但是没有Create就没有窗口句柄,基本上就是一个无效对象,只是系统内存申请了内存分配空间而已,很多操作都无法执行(debug模式下会出现断言错误窗口)。
但是,假如你申请了一个CWnd,CDC的对象实体,可以使用Attach来指定一个有效的句柄付给这个对象。那么此对象就是Valid的了。你可能跟踪看看Attach的实现,其实就是给m_hxxx赋值,而Detach就是值复位。
这2个操作没有申请内存释放内存操作,就是一个赋值而已,是不是成对使用看你代码的实际情况吧。只要理解了这2函数的意义就行了

其实CWnd,CDC等类就是多了一个包装,方便用户(程序开发者)使用,如果用SDK开发,完全可以实现一样的功能。

句柄是操作系统内核对象,而窗口指针、DC指针是用户对象(由你的程序管理)。

首先,要明白Windows对象和MFC对象的区别。MFC对象实际上并没有把整个Windows对象都包装在其中,它只是有一个窗口句柄而已,这个窗口句柄如果指向一个实际存在的窗口对象(窗口对象,也就是WNDCLASS,是一个Windows对象),那么这个MFC对象就是有效的,否则这个MFC对象是空的。如果你还不明白,请回忆一下,当我们使用MFC创建一个窗口时,是分两步进行的,第一步,new一个CWnd对象,这一步是创建MFC对象,但是其中的HWND还是非法的,因为对应的Windows对象还没有被创建出来;第二步,调用CWnd的成员函数Create创建真正的Windows对象,同时,把先前创建的MFC的CWnd对象的HWND成员指向该窗口,这样才算创建完毕一个窗口。而如果你是用SDK方式,那么只要创建一个WNDCLASS结构,然后调用Create或者CreateEx就创建了一个窗口。 好,现在回答你的问题,你可以假设,现在你已经有了一个有效窗口句柄,那么你想把这个窗口和一个CWnd对象关联起来怎么办?很简单,用Attach,其实就是让一个CWnd对象的HWND成员指向这个窗口句柄。这就是Attach主要完成的任务。 第二个,关于Detach。如前所述,WNDCLASS其实和CWnd根本没有什么关系。它们之间只是通过CWnd的成员HWND联系起来的。如果把Attach看做“联姻”的话,那么Detach就是“离婚”了,通俗地说,就是切断一个CWnd对象和一个有效窗口的脐带。为什么要切断呢?因为CWnd是C++的对象,C++的对象有一个生存期的概念,脱离了该对象的作用域,这个对象就要被销毁,但是Windows对象没有这个特点,当销毁CWnd对象的时候,我们不一定希望WNDCLASS一起被销毁,那么在此之前,我们就先要把这个“脐带”剪断,以免“城门失火,殃及池鱼”。

eg:

CWnd* pWnd = new CWnd; pWnd->Create(_T("STATIC"), "Hi", WS_CHILD | WS_VISIBLE,

给我留言

留言无头像?