前言:

无论一个DirectUI系统提供的DUI控件多么丰富,总会有些情况下用户需要在DUI窗口上放置有窗口句柄的子窗口。

为了和无窗口句柄的子窗口相区别,这里将有窗口句柄的子窗口称之为真窗口。

每一个使用SOUI创建的界面都是从SHostWnd派生出来的。SHostWnd本身就是一个有窗口句柄的真窗口。

因此和一般的win32编程一样,用户可以简单的自己以SHostWnd.m_hWnd为父窗口创建各种真子窗口。然后和win32一样,响应resize等消息自己管理子窗口的位置及显示。

很显然,这样处理将不能有效的利用SOUI提供的强大的布局及子窗口管理功能。

为了能够更有效的管理真窗口,在SOUI系统中提供了一个控件:SRealWnd。

SRealWnd派生自SWindow,因此它能够实现和SWindow一样的布局功能,并被SOUI系统管理窗口的各种状态:如size,visible等。

要使用SReaWnd来管理子窗口,我们首先需要实现一个接口:IRealWndHandler

IRealWndHandler的定义:

  1. /**
  2. * @struct IRealWndHandler
  3. * @brief
  4. *
  5. * Describe
  6. */
  7. struct IRealWndHandler : public IObjRef
  8. {
  9. /**
  10. * SRealWnd::OnRealWndCreate
  11. * @brief 窗口创建
  12. * @param SRealWnd *pRealWnd -- 窗口指针
  13. *
  14. * Describe 窗口创建
  15. */
  16. virtual HWND OnRealWndCreate(SRealWnd *pRealWnd)=NULL;
  17.  
  18. /**
  19. * SRealWnd::OnRealWndDestroy
  20. * @brief 销毁窗口
  21. * @param SRealWnd *pRealWnd -- 窗口指针
  22. *
  23. * Describe 销毁窗口
  24. */
  25. virtual void OnRealWndDestroy(SRealWnd *pRealWnd)=NULL;
  26.  
  27. /**
  28. * SRealWnd::OnRealWndInit
  29. * @brief 初始化窗口
  30. * @param SRealWnd *pRealWnd -- 窗口指针
  31. * @return BOOL -- FALSE:交由系统处理,TRUE:用户处理
  32. *
  33. * Describe 初始化窗口
  34. */
  35. virtual BOOL OnRealWndInit(SRealWnd *pRealWnd)=NULL;
  36.  
  37. /**
  38. * SRealWnd::OnRealWndSize
  39. * @brief 调整窗口大小
  40. * @param SRealWnd *pRealWnd -- 窗口指针
  41. * @return BOOL -- FALSE:交由SOUI处理; TRUE:用户管理窗口的移动
  42. *
  43. * Describe 调整窗口大小
  44. */
  45. virtual BOOL OnRealWndSize(SRealWnd *pRealWnd)=NULL;
  46. };

可以看到这里一共有4个接口,其中OnRealWndInit是OnRealWndSize为真窗口初始化及位置调整的回调,一般可以不处理,其它2个接口则是管理真窗口的创建及销毁,因此必须有实现。

接口实现示例:

真窗口的具体使用方法可以参考SOUI代码中samples目录下的mfc.demo。

这里把代码实现帖出来:

SouiRealWndHandler.h

  1. #pragma once
  2.  
  3. #include <unknown/obj-ref-impl.hpp>
  4.  
  5. namespace SOUI
  6. {
  7. class CSouiRealWndHandler :public TObjRefImpl2<IRealWndHandler,CSouiRealWndHandler>
  8. {
  9. public:
  10. CSouiRealWndHandler(void);
  11. ~CSouiRealWndHandler(void);
  12.  
  13. /**
  14. * SRealWnd::OnRealWndCreate
  15. * @brief 创建真窗口
  16. * @param SRealWnd * pRealWnd -- 窗口指针
  17. * @return HWND -- 创建出来的真窗口句柄
  18. * Describe
  19. */
  20. virtual HWND OnRealWndCreate(SRealWnd *pRealWnd);
  21.  
  22. /**
  23. * SRealWnd::OnRealWndDestroy
  24. * @brief 销毁窗口
  25. * @param SRealWnd *pRealWnd -- 窗口指针
  26. *
  27. * Describe 销毁窗口
  28. */
  29. virtual void OnRealWndDestroy(SRealWnd *pRealWnd);
  30.  
  31. /**
  32. * SRealWnd::OnRealWndInit
  33. * @brief 初始化窗口
  34. * @param SRealWnd *pRealWnd -- 窗口指针
  35. *
  36. * Describe 初始化窗口
  37. */
  38. virtual BOOL OnRealWndInit(SRealWnd *pRealWnd);
  39.  
  40. /**
  41. * SRealWnd::OnRealWndSize
  42. * @brief 调整窗口大小
  43. * @param SRealWnd *pRealWnd -- 窗口指针
  44. * @return BOOL -- TRUE:用户管理窗口的移动;FALSE:交由SOUI自己管理。
  45. * Describe 调整窗口大小, 从pRealWnd中获得窗口位置。
  46. */
  47. virtual BOOL OnRealWndSize(SRealWnd *pRealWnd);
  48. };
  49.  
  50. }

SouiRealWndHandler.cpp:

  1. #include "StdAfx.h"
  2. #include "SouiRealWndHandler.h"
  3.  
  4. namespace SOUI
  5. {
  6. CSouiRealWndHandler::CSouiRealWndHandler(void)
  7. {
  8. }
  9.  
  10. CSouiRealWndHandler::~CSouiRealWndHandler(void)
  11. {
  12. }
  13.  
  14. HWND CSouiRealWndHandler::OnRealWndCreate( SRealWnd *pRealWnd )
  15. {
  16. const SRealWndParam &param=pRealWnd->GetRealWndParam();
  17. if(param.m_strClassName==_T("button"))
  18. {//只实现了button的创建
  19. //分配一个MFC CButton对象
  20. CButton *pbtn=new CButton;
  21. //创建CButton窗口,注意使用pRealWnd->GetContainer()->GetHostHwnd()作为CButton的父窗口
  22. //把pRealWnd->GetID()作为真窗口的ID
  23. pbtn->Create(param.m_strWindowName,WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,::CRect(,,,),CWnd::FromHandle(pRealWnd->GetContainer()->GetHostHwnd()),pRealWnd->GetID());
  24. //把pbtn的指针放到SRealWnd的Data中保存,以便在窗口destroy时释放pbtn对象。
  25. pRealWnd->SetData(pbtn);
  26. //返回成功创建后的窗口句柄
  27. return pbtn->m_hWnd;
  28. }else
  29. {
  30. return ;
  31. }
  32. }
  33.  
  34. void CSouiRealWndHandler::OnRealWndDestroy( SRealWnd *pRealWnd )
  35. {
  36. const SRealWndParam &param=pRealWnd->GetRealWndParam();
  37. if(param.m_strClassName==_T("button"))
  38. {//销毁真窗口,释放窗口占用的内存
  39. CButton *pbtn=(CButton*) pRealWnd->GetData();
  40. if(pbtn)
  41. {
  42. pbtn->DestroyWindow();
  43. delete pbtn;
  44. }
  45. }
  46. }
  47.  
  48. //不处理,返回FALSE
  49. BOOL CSouiRealWndHandler::OnRealWndSize( SRealWnd *pRealWnd )
  50. {
  51. return FALSE;
  52. }
  53.  
  54. //不处理,返回FALSE
  55. BOOL CSouiRealWndHandler::OnRealWndInit( SRealWnd *pRealWnd )
  56. {
  57. return FALSE;
  58. }
  59. }

整体上代码很简单,配上注释,应该一看就懂。

XML配置:

  1. <SOUI title="DUI-DEMO" width="600" height="400" appwin="0" ncRect="5,5,5,5" resize="1" translucent="0">
  2. <root skin="skin.bkframe" cache="1">
  3. <caption pos="0,0,-0,29">
  4. <text pos="11,9" >%title% ver:%ver%</text>
  5. <imgbtn id="1" name="btn_close" skin="skin.btnclose" pos="-45,0" tip="close" animate="0"/>
  6. </caption>
  7. <window pos="0,29,-0,-0">
  8. <realwnd pos="10,10,-10,-10" name="mfcbtn" wndclass="button" id="100" wndname="MFC Button"/>
  9. </window>
  10. </root>
  11. </SOUI>

在XML中,我们使用了一个realwnd的标签,该标签有一个重要的属性:wndclass,IRealWndHandler通过该属性来判断应该创建一个什么样的真窗口。

运行效果:

上面红框中的按钮即为使用realwnd标签创建的MFC Button。

真窗口的消息响应:

由于真窗口是SOUI主窗口的子窗口,因此真窗口的消息可以在SOUI主窗口的消息映射表中处理(注意:这里不是SOUI控件的事件映射表)。

如:

  1. #pragma once
  2.  
  3. class CRealWndDlg : public SOUI::SHostDialog
  4. {
  5. public:
  6. CRealWndDlg(void);
  7. ~CRealWndDlg(void);
  8.  
  9. //响应MFC.button的按下消息, nID==100为在XML中指定的realwnd的id属性。
  10. void OnBtnClick( UINT uNotifyCode, int nID, HWND wndCtl )
  11. {
  12. if(uNotifyCode == BN_CLICKED && nID == )
  13. {
  14. SOUI::SMessageBox(m_hWnd,_T("the real mfc button is clicked!"),_T("mfc.demo"),MB_OK|MB_ICONEXCLAMATION);
  15. }
  16. }
  17.  
  18. //消息映射表
  19. BEGIN_MSG_MAP_EX(CMainDlg)
  20. MSG_WM_COMMAND(OnBtnClick)
  21. CHAIN_MSG_MAP(SOUI::SHostDialog)
  22. REFLECT_NOTIFICATIONS_EX()
  23. END_MSG_MAP()
  24. };

结束语:

很显然,通过这种方式,也可以非常方便的创建出各种类型的其它窗口。

窗口创建出来后,系统就会自动管理窗口状态。

最后,要记住一条:有真窗口时,SOUI主窗口不能设置translucent="1"这一属性。因为任何子窗口在半透明窗口上都不能正常显示。这一条也适用于包含IE控件的窗口。

第十三篇:在SOUI中使用有窗口句柄的子窗口的更多相关文章

  1. Egret入门学习日记 --- 第十三篇(书中 5.2~5.3节 内容)

    第十三篇(书中 5.2~5.3节 内容) 写日记已经十天多了,我发现越到后面,我书写的方式越来越程序化. 感觉渐渐失去了人类所谓的感情似的. 不过,没想到的是,书中的内容,很少出现了错误,我一路过来到 ...

  2. 第二十八篇:SOUI中自定义控件开发过程

    在SOUI中已经提供了大部分常用的控件,但是内置控件不可能满足用户的所有要求,因此一个真实的应用少不得还要做一些自定义控件. 学习一个新东西,最简单的办法就是依葫芦画瓢.事实上在SOUI系统中内置控件 ...

  3. 第二十一篇:SOUI中的控件注册机制

    Win32编程中,用户需要一个新控件时,需要向系统注册一个新的控件类型.注册以后,调用::CreateWindow时才能根据标识控件类型的字符串创建出一个新的控件窗口对象. 为了能够从XML描述的字符 ...

  4. 第三十一篇:SOUI布局之相对于特定兄弟窗口

    SOUI中通过pos的标志如:[, {, }, ],这4个标志可以相对于前一个及后一个兄弟窗口,但是有时候希望相对于不是前后窗口的兄弟窗口,比如一个通过一个中心窗口同时定义它的上下左右4个窗口,这个时 ...

  5. 第二十三篇:在SOUI中使用LUA脚本开发界面

    像写网页一样做客户端界面可能是很多客户端开发的理想. 做好一个可以实现和用户交互的动态网页应该包含两个部分:使用html做网页的布局,使用脚本如vbscript,javascript做用户交互的逻辑. ...

  6. 第五篇:在SOUI中使用XML布局属性指引(pos, offset, pos2type)

    窗口布局的概念 每一个UI都是由大量的界面元素构成的,在Windows编程,这些界面元素的最小单位通常称之为控件. 布局就是这些控件在主界面上的大小及相对位置. 传统的布局一般使用一个4个绝对坐标来定 ...

  7. 第二十五篇:在SOUI中做事件分发处理

    不同的SOUI控件可以产生不同的事件.SOUI系统中提供了两种事件处理方式:事件订阅 + 事件处理映射表(参见第八篇:SOUI中控件事件的响应) 事件订阅由于直接将事件及事件处理函数连接,不存在事件分 ...

  8. 第二十篇:在SOUI中使用分层窗口

    从Windows 2K开始,MS为UI开发引入了分层窗口这一窗口风格.使用分层窗口,应用程序的主窗口可以是半透明,也可以是逐点半透明(即每一个像素点的透明度可以不同). 可以说,正是因为有了分层窗口, ...

  9. Python开发【第二十三篇】:持续更新中...

    Python开发[第二十三篇]:持续更新中...

随机推荐

  1. 【架构】linkerd:来自Twitter为微服务而生的开源RPC解决方案

    大家要如何以规模化方式运维微服务应用程序?实践当中会出现哪些问题,我们又该如何加以解决?在大规模与非预测性工作负载场景当中,我们需要满足哪些条件才能运行一款大型微服务应用程序,而又能够确保不必受到功能 ...

  2. maven package

    maven package test包下执行test 的配置文件 生成target目录,编译.测试代码,生成测试报告,生成jar/war文件 maven 配置文件详解 http://blog.csdn ...

  3. Split Array Largest Sum

    Given an array which consists of non-negative integers and an integer m, you can split the array int ...

  4. IPC---共享内存

    共享内存就是允许两个或多个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据时,不需要在客户进程和服务器进程之间幅值,因此是最快的一种IPC.不同进程之间共享的内存通常安 ...

  5. Icon Font的转换

    Icon Font是用于网页的纯色图标,这里引用一张网络图片: 由于体积小,易维护等特点,IconFont应用非常广泛. 这里推荐一个转换器,通过Upload一个后缀ttf的字体文件,可以反解出文件下 ...

  6. $.each 和$(selector).each()的区别

    $.each() 对数组或对对象内容进行循环处理 jQuery.each( collection, callback(indexInArray, valueOfElement) ) collectio ...

  7. 20145213《Java程序设计》第八周学习笔记

    20145213<Java程序设计>第八周学习笔记 教材学习内容总结 "桃花春欲尽,谷雨夜来收"谷雨节气的到来意味着寒潮天气的基本结束,气温回升加快.刚出冬的我对于这种 ...

  8. 高校排名 加强版(codevs 2799)

    题目描述 Description 大学排名现在已经非常流行.在网上搜索可查到关于中国大学排行的各个方面的消息. 我们知道,在一大学里通常都由许多不同的"系"(专业)组成,比如计算机 ...

  9. 解决osg路径与文件名中的中文字符问题

    转至:http://blog.csdn.net/zhuqinglu/article/details/2064013 在打开或者保存一个osg模型的时候,经常遇到中文路径或者中文文件名的问题,此时会提示 ...

  10. Git 操作的一些场景

    1. 某些不需要的文件/文件夹,如:/build 之类,在添加对应的gitignore之前Push了,导致每次编译都会产生新的文件 解决方法:直接删掉不需要的文件/文件夹,然后push gitigno ...