下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、父窗口与拥有者窗口一、概念和区别在windows系统中,每个窗口对象都对应有一个数据结构,形成一个list链表。系统的 窗口管理器通过这个list来获取窗口信息和管理每个窗口。这个数据结构中有四个数据用来 构建 list,即 child、sibling、parent、owner 四个域。所以我们可以看到,窗口之间的关系有两种:owner-owned关系和parent-child关系。 前者称之为拥有/被拥有关系,后者称之为父/子关系。在这篇文字中,我把owner窗口称之 所有者窗口。换句话说,一个窗口在有一个父窗口(parent)的同时,还可能被不同的窗口拥 有(owner),也可以有自己的子
2、窗口(child)。在MFC的CWnd类中,所有者窗口保存在 m_hWndOwner成员变量中,父窗口则保存在m_hParent中,但是这两个值并不一定和窗口 对象数据结构中的值相对应。窗口之间的关系,决定了窗口的外在表现。比如显示、销毁等。如果一个窗口数据的owner域非NULL,则它和该窗口建立了 owner-owned关系,拥 有关系决定了:(1)被拥有的窗口永远显示在拥有它的那个窗口的前面;(2)当所有者窗口最小化的时候,它所拥有的窗口都会被隐藏;(3)当所有者窗口被销毁的时候,它所拥有的窗口都会被销毁。需要注意的是,隐藏所有者窗口并不会影响它所拥有的窗口的可见状态。比如:如果窗 口
3、A拥有窗口 B,窗口 B拥有窗口 C,则当窗口 A最小化的时候,窗口 B被隐藏,但是窗口 C还是可见。如果一个窗口的parent域非NULL,则它和该窗口之间就建立了 parent-child关系。父 子决定了:(1)窗口在屏幕上面的显示位置。父窗口提供了用来定位子窗口的坐标系统,一个子 窗口只能显示在它的父窗口的客户区中,之外的部分将被裁减。这个裁减法则决定了如果父 窗口不可见,则子窗口肯定不可见。如果父窗口移动到了屏幕之外,子窗口也一样。(2)当父窗口被隐藏时,它的所有子窗口也被隐藏。(3)父窗口被销毁的时候,它所拥有的子窗口都会被销毁。注意!最小化父窗口不会影响子窗口的可见状态,子窗口会
4、随着父窗口被最小化,但 是它的WS_VISIBLE属性不会变。Windows系统为什么要使用两种关系呢?这是为了更加灵活的管理窗口。举个例子: 组合框(combobox)的下拉列表框(list box)可以超出组合框的父窗口的客户区,这样有利 于显示,因此系统创建该list box的时候,是作为控制台窗口(desktop window)的子窗口, 它的父窗口 hWndParent是NULL,这样,list box的显示区域是限制在整个屏幕内,但是该 list box的所有者却是组合框的第一个非子窗口祖先(比如对话框)当它的所有者窗口销毁 后,该list box自动销毁。另外,窗口之间消息的传递
5、也和窗口关系有关,通常,一个窗口会把自己的通知消息发 送给它的父窗口,但不全是这样,比如,CToolBar发送通知消息给它的所有者窗口而不是 父窗口。这样以来,就可以允许工具条作为一个窗口(比如一个OLE容器程序窗口)的子 窗口的同时,能够给另一个窗口(比如in-place框架窗口)发送消息。至于某类窗口到底是 把消息发送给谁,是父窗口还是所有者窗口,microsoft并没有明示。还有,在现场(in-place) 编辑的情况下,当一个server窗口激活或者失效的时候,框架窗口所拥有的子窗口自动隐 藏或者显示,这也是通过直接调用SetOwner函数实现的。二、窗口类型的说明和限制(1)控制台窗
6、口( desktop window)o这是系统最早创建的窗口。可以认为它是所有 WS_OVERLAPPED类型窗口的所有者和父窗口。Kyle Marsh在他的文章“Win32 Window Hierarchy and Styles ”中指出,当系统初始化的时候,它首先创建控制台窗口,大小覆盖整 个屏幕。所有其它窗口都在这个控制台窗口上面显示。窗口管理器所用的窗口 list中第一个 就是这个控制台。它的下一层窗口叫做顶级窗口(top-level),顶级窗口是指所有非child、 没有父窗口,或者父窗口是desktop的窗口,它们没有WS_CHILD属性。(2)WS_OVERLAPPED类型的窗口
7、可以显示在屏幕的任何地方。它们的所有者窗口是控 制台。Overlapped类型的窗口属于顶级窗口,一般作为应用程序的主窗口。不论是否给出了 WS_CAPTION、WS_BORDER属性,这类窗口创建后都有标题栏和边框。Overlapped窗 口可以拥有其它顶级窗口或者被其它顶级窗口所拥有。所有overlapped窗口都有 WS_CLIPSIBLINGS属性。系统可以自动设置overlapped窗口的大小和初始位置。当系统shuts down的时候,它将销毁所有overlapped类型的窗口。(3)WS_POPUP类型的窗口可以显示在屏幕任何地方,它们一般没有父窗口,但是如果明 确调用SetPa
8、rent,这类窗口也可以有父窗口。WS_POPUP类型的窗口的所有者是在CreateWindow函数中通过设置hWndParent参数 给定的,如果hWndParent不是子窗口,则该窗口就成为这个新的弹出式窗口的owner,否 则,系统从hWndParent的父窗口向上找,直到找到第一个非子窗口,把它作为该弹出窗口 的owner。当owner窗口销毁的时候,系统自动销毁这个弹出窗口。Pop-up类型的窗口也属于顶级窗口,它和overlapped窗口的主要区别是弹出式窗口 不需要有标题栏,也不必有边框。弹出式可以拥有其它顶级窗口或者被拥有。所有弹出式窗 口也都有 WS_CLIPSIBLINGS
9、 属性。(4)所有者窗口(owner)只能是overlapped或者pop-up类型的窗口,子窗口不能是所有 者窗口,也就是说子窗口不能拥有其它窗口。overlapped或者pop-up类型的窗口在拥有其它窗口的同时,也可以被拥有。在使用CreateWindowEx创建 WS_OVERLAPPED或者 WS_POPUP类型的窗口时,可 以在hwndParent参数中给出它的所有者窗口的句柄。如果hwndParent给出的是一个child 类型的窗口句柄,则系统自动将新创建窗口的所有权交给该子窗口的顶级父窗口。在这种情 况下,参数hwndParent被保存在新建窗口的parent域中,而它的所有
10、者窗口句柄则保存在 owner域中。缺省情况下,对话框和消息框属于owned窗口,除非在创建它们的时候明确给出了 WS_CHILD属性,(比如对话框中嵌入对话框的情形)否则由系统负责给它们指定owner窗口。需要注意的是,一旦创建了 owned类型的窗口, 就无法再改变其所有关系,因为WIN32没有没有提供改变窗口所有者的方法。而且在Win32中,由于有多线程的存在,所以要注意保证父子窗口或者owner/owned窗 口要同属于一个线程。对于WS_CHILD类型的窗口,它的父窗口就是它的所有者窗口。一个子窗口的父窗 口也是在CreateWindow函数中用hWndParent参数指定的。子窗口
11、只能在父窗口的客户区中 显示,并随父窗口一起销毁。子窗口必须有一个父窗口,这是它和overlapped以及pop-up窗口之间的主要区别。 父窗口可以是顶级窗口,也可以是其它子窗口。三、几个相关函数的说明(1)获取/设置所有者窗口win32 API提供了函数GetWindow函数(GW_OWNER标志)来获取一个窗口的所有 者窗口句柄。GetWindow(hWnd, GW_OWNER )永远返回窗口的所有者(owner)。对于子窗口,函数返 回NULL,因为它们的父窗口就相当于所有者(注意,是“相当于”)。因为Windows系统 没有维护子窗口的所有者信息。MFC中则是通过如下函数得到所有者窗
12、口指针:_AFXWIN_INLINE CWnd* CWnd:GetOwner() const( return m_hWndOwner != NULL ? CWnd:FromHandle(m_hWndOwner): GetParent(); 从上述代码我们可以看出,它返回的值和GetWindow返回的有所区别,如果当前窗口 没有owner,那么将返回它的父窗口指针。但是Windows没有提供改变窗口所有者的方法。MFC中则提供了改变所有者的方法:_AFXWIN_INLINE void CWnd:SetOwner(CWnd* pOwnerWnd)( m_hWndOwner = pOwnerWnd
13、!= NULL ? pOwnerWnd-m_hWnd : NULL; 另外,mfc 还提供了 CWnd:GetSafeOwner( CWnd* pParent, HWND* pWndTop );函数, 可以用来得到参数pParent的第一个非child属性的父窗口指针。如果这个参数是NULL,则 返回当前线程的主窗口(通过AfxGetMainWnd得到)。框架经常使用这个函数查找对话框或者属性页的所有者窗口。获取/设置父窗口WIN32 API给出了函数GetParent和SetParent。而mfc也是完全封装了这两个函数:_AFXWIN_INLINE CWnd* CWnd:SetParent
14、(CWnd* pWndNewParent)( ASSERT(:IsWindow(m_hWnd); return CWnd:FromHandle(:SetParent(m_hWnd, pWndNewParent-GetSafeHwnd(); _AFXWIN_INLINE CWnd* CWnd:GetParent() const( ASSERT(:IsWindow(m_hWnd); return CWnd:FromHandle(:GetParent(m_hWnd); 对于SetParent, msdn里面说明了父子窗口必须是同一个进程的。但是由于窗口句柄是 系统全局唯一的,不属于同一个进程的情况下,也可以成功调用,但是后果未知。GetParent的返回值比较复杂,对于overlapped类型的窗口,它返回0,对于WS_CHILD 类型,它返回其父窗口,对于WS_POPUP类型,它返回其所有者窗口,如果想得到创建它 时所传递进去的那个hwndParent参数,应该用GetWindowWord(GWW_HWNDPARENT函 数。GetWindowWord(hWnd, GWW_HWNDPARENT)返回一个窗口的父窗口,如果没有, 则返回其所有者。上面谈
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年渔业雌核发育产业创新趋势分析报告
- 2026年新入职护士基础护理理论考核测试卷及答案
- 2026年平板电脑回收超声波清洗技术创新报告
- 2026年脊髓损伤关节挛缩预防康复护理考试试卷及答案
- 2026年植入性支架行业管理系统创新报告
- 2026年互联网保险行业风险控制与创新发展报告
- 某汽配厂质量条例
- 2026年沸石行业技术革新分析报告
- 2026年劳动人事争议仲裁业务考试题库及答案
- 2025年消防设施检测员考核试题库及答案
- 《礼赞伟大祖国 争做时代少年-小学四年级国庆主题班会》
- 《医疗器械临床使用管理办法》培训考试测试题含答案
- 综合管理竞聘测试题及答案
- 湖北武汉市2026-2027学年高三年级上学期9月调研考试英语试卷
- 2026年部编版新教材道德与法治五年级上册全套教学设计(共4个单元有教学计划)
- 混凝土结构设计原理中国建筑工业出版社
- 人教版初中英语八年级上册第一单元完整教案
- 高考英语谓语与非谓语组合练100题(含答案)
- 国药数科2026届春季校园招聘建设笔试备考试题及答案解析
- 内分泌科护理服务质量管理标准
- 煤矿职业病危害培训课件
评论
0/150
提交评论