窗口之父CXWnd的封装<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

[http://blog.csdn.net/mythma]

在一般的程序中的对话框、按钮、编辑框等都属于窗口。在MFC中,类CWnd作为窗口类的基类,抽象出了它们的共同特征,并由此派生出若干的子类。在普通的windows程序中,我们可以方便的使用MFC为我们封装好的这些类(CDialog, CButton ,CEdit等),而在游戏程序中,由于需要与dx/opengl结合以及效率等原因,因此不直接使用它们,这就需要我们自己来封装。如此之多的控件如何封装能?我们不妨也为所有的窗口、控件抽象一个基类,就叫她CXWnd。那就让我们从 CXWnd开始,一步一步来实现我们真正的UI吧。

我们先撇开DX具体绘制窗口的过程,看看窗口、控件有什么共同的特征,以及如何在CXWnd中来实现。

1、  窗口的大小与位置

窗口是一个矩形的区域,因此用两个变量就可以表示其大小(宽:m_Wdith, 高:m_Height)。

窗口的位置也可以用两个变量表示( X坐标:       m_XPos , Y坐标:m_YPos)。但这两个变量表示窗口的绝对坐标(相对于屏幕左上角)还是相对坐标(相对于父窗口的坐上角)呢?

从用户的角度(即创建窗口)看,使用相对坐标方便一点;

从程序的角度(即绘制窗口)看,使用绝对坐标方便一点。

我们封装CXWnd的目的在于使用,因此要从用户的角度出发,即m_XPos和m_YPos表示的是窗口的相对坐标。当绘制窗口的时候,我们需要获得窗口的绝对坐标,因此需要提供一个成员函数来转化——GetAbsolutePos(float& x, float& y)。

(图就不用画了吧,:))

2、  窗口之间的联系

为了更具代表性,想一下(就不画了哦)一个带属性页的对话框的窗口层次,与它相关的窗口有一个父窗口(不包括祖父哦),若干的子窗口(各种控件),以及若干个同级窗口,因此就需要有一个指向其父窗口的指针(CXWnd* m_wndParent),一个指向其子窗口链表的指针(CXWnd* m_wndChild,m_wndChild指向窗口链表的第一个窗口,该窗口z序在子窗口中最小,既显示在最前面),再加上同级窗口间的指针(CXWnd* m_wndNextSibling指向下一个同级窗口;CXWnd* m_wndPreviousSibling指向前一个同级窗口)。这么多窗口之间用这四种指针联系起来,画出来就是一棵窗口关系树。为什么同级窗口需要两个指针呢?在消息循环中就可以找到答案了。

对这些指针,需要哪些操作呢?

除了基本的Get***Wnd() 和Set***Wnd()外,还需要:

添加一个子窗口AddChildWnd(wndChild : CXWnd*)

删除一个子窗口DeleteChildWnd(wndChild : CXWnd*)

删除所有的子窗口DeleteAllChildWnd(),用来释放内存。

获取子窗口个数 GetChildCount()

以上几个都是对单向链表的基本操作。

3、  消息循环

从经典的消息函数WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)那,得到消息后,主窗口需要传递下去,于是CXWnd有了一个相似的函数——PostMessage(UINT msg, WPARAM wParam, LPARAM lParam, void* Data);,其中对消息进行分类处理。

1) 鼠标消息

鼠标消息处理,当然是如下三个(不过在CXWnd中不需要实现它们,只是声明为纯虚函数,因为各个控件的鼠标处理函数都不尽相同)

virtual void OnMouseDown(int Button, int X, int Y) = NULL;

virtual void OnMouseMove(int X, int Y) = NULL;

virtual void OnMouseUp(int Button, int X, int Y) = NULL;

如何得知是哪个窗口得到了鼠标消息呢?那就需要挨个搜索各个窗口,看鼠标当前的坐标(注意是绝对坐标)在哪个窗口上。因此加入函数CursorIntersect(FLOAT X, FLOAT Y)来完成此功能。

鼠标消息是如何在窗口树中传递的呢?范围肯定是从大到小扫描,即先看是否在某窗口上,若在则看是否在该窗口的子窗口上……,终于找到最上的最底层的窗口,于是子窗口先处理鼠标消息,即最上的子窗口具有处理鼠标消息的优先权。因此消息的传递是从上而下,就称之为正序消息传递吧——PostMsgToChildren(……)负责把消息正序传给每一个子窗口。

2) 键盘消息

同鼠标消息一样,键盘消息的处理有如下两个纯虚成员函数:

virtual void OnKeyDown(WPARAM Key, LPARAM Extended) = NULL;

virtual void OnKeyUp(WPARAM Key, LPARAM Extended) = NULL;

键盘消息的处理的特殊之处在于处理它的窗口(控件)需要获得焦点(原因很简单),因此每个窗体需要一个存放其获取焦点的子窗体的指针成员变量(CXWnd* m_wndFocus)和一个判断其是否获得焦点的bool成员变量(bool m_bFocus),从而就有了SetFocusWnd(……)和GetFocus()成员函数。

键盘消息的传递与鼠标消息的传递一样。

3) 窗口绘制消息

窗口的绘制是与具体的窗口对象相关的,因此在CXWnd中不予实现,但窗口绘制的消息是要传递的,那该消息是如何传递的呢?

每个窗口都有自己的z序,最后面的要先绘制,最前面的要后绘制(要不就被当住了),对应与窗口树就是,父窗口要先绘制,然后最下子窗口后绘制,最后是最上的子窗口。因此最下的窗口具有处理窗口绘制消息的优先权。而最上的子窗口排在子窗口链表的最前面,因此该消息需要逆序从后往前传递。因此需要一个专门的传递该消息的成员函数——PostMsgToChildrenReverse(……)。

窗口的z序不是固定的,因此需要一个函数来改变它们的z序 ——MoveToFront(……)。

至此,CXWnd的主体功能已经完成了,看看它有那些成员吧:

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

转载于:https://www.cnblogs.com/wuwuwu/archive/2004/10/14/6335379.html

游戏UI设计(2.1)--窗口之父CXWnd的封装相关推荐

  1. 游戏ui设计,游戏ui设计需要学什么

    游戏ui设计,游戏ui设计需要学什么?随着人类对休闲的追求,对游戏的体验方式也在不断的进步,游戏ui也将出现一次质的飞跃.在游戏中,ui设计也无处不在.那么,什么是ui设计,游戏ui设计需要学什么?今 ...

  2. 优漫动游:游戏ui设计包括什么?

      游戏UI设计是游戏开发过程中非常重要的一部分,涉及到游戏中各种交互元素的设计.下面将介绍游戏UI设计包括哪些内容. ​   主菜单界面设计   主菜单是游戏的入口,主菜单界面设计需要具有视觉冲击力 ...

  3. 「教程」游戏开发基础——游戏UI设计基本原则

    UI是什么? "一般来说,UI设计的目标是产生用户界面,使用户界面能够使人类以简单愉快高效的的方式操作机器.这通常意味着操作者需要提供最少的输入来实现期望的输出,并且该机器使错误的输出最小化 ...

  4. 游戏UI设计的准备工作,流程分析

    1.了解游戏的世界观念 判断一款游戏ui的成功不能只看视觉的表示,它是否切合游戏世界观才是重要的判断条件 游戏的世界观告诉我们这是一个什么世界,世界的主要矛盾,,,可以说整个游戏所有的 元素都是为游戏 ...

  5. 游戏UI设计从小白到高手-百度UE讲堂-专题视频课程

    游戏UI设计从小白到高手-239人已学习 课程介绍         一套完整的游戏UI设计手绘课程,从美术基础出发,覆盖了众多不同物品的表现技法,既是优秀的手绘教程,又是工作过程中很好的参照. 课程收 ...

  6. wpf 使子ui元素可视区域不超过父元素_对游戏UI设计的一点思考

    UI决定了一个游戏的初体验,甚至决定了玩家的初始留存,甚至可以说决定了一个游戏的品质,虽然看起来是表象的,却是直指游戏核心的.简单讲,玩家认可一款游戏永远都是造型场景好,剧情好,画质棒:但是玩家骂一款 ...

  7. 游戏UI设计干货:怎么让游戏界面更具科技感?

    说到科技风,大家都会想到或者感觉到的是未来感,高科技的产物风格.那么大家可以一起想一下,在我们的身边有哪些是让你觉得有未来感.科技感的设计. 星球大战系列.科幻大片.液晶仪表盘.多媒体.VR AR.. ...

  8. 游戏UI设计的一些原则与思考

    UI决定了一个游戏的初体验,甚至决定了玩家的初始留存,甚至可以说决定了一个游戏的品质,虽然看起来是表象的,却是直指游戏核心的.简单讲,玩家认可一款游戏永远都是造型场景好,剧情好,画质棒:但是玩家骂一款 ...

  9. 游戏UI设计(1.2)--Textures Sprite之封装

    1.2  Textures & Sprite 之封装CXTexture & CXSprite<?xml:namespace prefix = o ns = "urn:s ...

最新文章

  1. js左侧三级菜单导航代码
  2. mongodb拆库分表脚本
  3. 对象类什么是面向对象(1)
  4. AlertDialog显示错误 Unable to add window token null is not for an application
  5. SD-WAN5年增长率超过40%,为什么越来越受到企业欢迎?
  6. Weblogic常见配置
  7. c语言无效参数视为严重错误,C语言编译错误:错误:‘-’参数类型无效(有‘int’)...
  8. MULE ESB参考网站所在位置
  9. 51nod 1027 大数乘法
  10. 最全NFC芯片技术厂商介绍及应用介绍
  11. java 获取dataset_Java OHLCDataset.getX方法代码示例
  12. Java对Map排序
  13. 网站压力测试的几种方法
  14. 【解决】updateAppMessageShareData:fail, the permission value is offline verifying
  15. Java实现 LeetCode 686 重复叠加字符串匹配
  16. linux怎么下载dnw工具,Deepin Linux 安装dnw工具
  17. TOGAF(企业架构)
  18. SRRC认证问题合集
  19. Circular-Circular 和 Circular-Linear Regression
  20. 多变量干扰事件发生下的地铁客流预测

热门文章

  1. 利用Python脚本编写一个学生平均成绩
  2. 如何查看linux的版本?
  3. Layui或Layuimini整合Echarts 5
  4. 待支付取件费用是什么意思_SEDEX验厂是什么意思,sedex验厂审核费用是多少?...
  5. 怎样把照片中的头像扶正_微信头像用对了,2020运气差不了
  6. java运算级别_java运算符优先级别
  7. TokenInsight:反映区块链行业整体表现的TI指数较昨日同期下跌2.77%
  8. S.Finance已上线收益稳定币UU
  9. HIVE高级函数--get_json_object()和json_tuple()
  10. 数据可视化、模板框架、动态控件、可视化大屏、数据原型、监控平台、图表元件库、数据看板、驾驶舱、统计图表、消防、大屏展示、安防、智慧城市、旅游、运输、医疗卫生、贸易、电力、政务、水质、工业园区环境监测