这几个月的开发工作主要是关于游戏内GUI的,业务开发之余也时常会看看客户端工程里的GUI系统这一块的代码,这里系统的总结下。

一、GUI树形结构

 

  在GUI中所有的控件都遵循树形结构:



  在客户端初始化时,会创建出一个无形的,跟客户端窗口等大的root窗口:g_FBClient_Global.m_pRootWnd。在游戏中添加的窗口,一般都挂载在root窗口下。要在游戏中新增一个窗口,当在GUI编辑器中创建好了窗口资源后,代码中创建该窗口资源的的方式一般是在对应的类的构造函数中使用:CreateFromRes(strWndResourceName, g_FBClient_Global.m_pRootWnd)。第一个参数是在编辑器中对应窗口资源的名称;第二个为要挂载的父窗口,如前面所述,这里一般都是挂载在根窗口下。该方法成功执行后,该窗口及窗口下的所有子控件便都创建出来了并且都是默认显示的。(关于GUI编辑器的介绍及使用,这个是内部资料了,见/src/Tools/ArkGUIEditor/bin/用ArkGUI创建一个窗口的步骤.doc)

  GUI的绘制时,是在游戏主循环中调用m_pRootWnd->Render(),从根窗口自顶向下地依此树形结构递归地显示绘制。游戏退出时对资源的回收,也是如此进行的(所以在窗口中创建的控件,如果在创建时挂载在了该窗口下的话,都无需自己手动释放)。

二、关于CArkWnd类

  class CArkWnd;是所有窗口和控件的基类。其中绝大部分为虚方法,包括窗口生命周期函数如OnCreated()、OnDestroy()、OnUpdateDataBeforeDraw()等;响应消息的一些函数如OnMouseWheel()、OnChildmsg()以及设置窗口属性功能的函数如EnableWnd()、SetFontSize()、SetWndText()等。

  一个窗口的生命周期大致可以表示如下:



一些常用的控件:

  1. 按钮类

      像按钮CArkButton、复选框CArkCheckoutButton等的显示,是在GUI编辑器中设置了一个按钮的各个状态的贴图包括点击、鼠标经过、禁用等状态。 按钮自己接收到鼠标事件进行不同状态的响应,在重写的虚函数DrawWndBackground()中实现:

    void CArkButton::DrawWndBackground()
    {
    DrawBackImage(m_pWndData->m_Enable,m_pWndData->m_Disable,
    m_MouseOverImage,m_ClickDownImage,IsHeld());// 传入各个状态的图片链表
    }
  2. 富文本框

      游戏内大部分显示文本的地方都是使用的富文本控件,最典型的像任务描述面板和聊天面板。在富文本框中的文字可以设置字体风格颜色及换行。

      通过CArkRichText和CArkRichTextFormat进行换行和颜色解析等功能的具体实现。(RichWnd格式化文字说明(内部网址):http://192.168.1.252:8080/pages/viewpage.action?pageId=9110273)

  3. 其他常用的控件还有诸如文本编辑框CArkEdit、泡泡提示框CTorchbearerWnd、确认框/确认取消框CRichMsgBox等等。

三、消息响应

  一个消息响应流程大致如下:

  由根窗口接收到消息:

  g_FBClient_Global.m_pRootWnd->ReceiveMsg(message, wParam, lParam);

  再由CArkWnd类中的窗口管理器CArkGUIManage,调用:pGUI->WndProc(message,wParam,lParam);

  在这个函数中分别处理鼠标消息和键盘消息:

  CArkMouseMsgProc::ProcessMsg(uint32 message, WPARAM wParam, LPARAM lParam)

  CArkKeyMsgProc::ProcessMsg(uint32 message, WPARAM wParam, LPARAM lParam)

  在上面的处理函数中,会找到最顶层的CArkWnd窗口,也就是我们在界面上实际操作的控件。然后调用这个CArkWnd的方法:

  CArkWnd::WndProc(uint32 message, WPARAM wParam, LPARAM lParam)

  在WndProc函数中,根据消息类型执行对应的处理函数;假设我们是点击了某个按钮,那么根据消息为点击事件,就执行虚方法OnLButtonDown()。那么实际就是由按钮类CarkButton的OnLButtonDown函数执行,在里面做一些特殊操作例如播放该按钮被点击时的特效。

  在平时GUI的开发中最主要接触的是这个OnChildMsg函数。在自己编写的窗口中,由这个函数的pChild和uMsgID参数得到子控件名称和消息类型,就能确定在界面上进行了什么操作,然后做后续的业务逻辑;比如在商城点击了“购买”按钮,那么当GenWndName(pChild)== ”BuyBtn”&& uMsgID==BUTTON_CLICK时就响应BuyItem()函数发消息给服务器。

  大致流程还可以看下面这张图:

客户端GUI结构学习总结的更多相关文章

  1. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  2. 机器学习&数据挖掘笔记_24(PGM练习八:结构学习)

    前言: 本次实验包含了2部分:贝叶斯模型参数的学习以及贝叶斯模型结构的学习,在前面的博文PGM练习七:CRF中参数的学习 中我们已经知道怎样学习马尔科夫模型(CRF)的参数,那个实验采用的是优化方法, ...

  3. Linux 目录结构学习与简析 Part2

    linux目录结构学习与简析 by:授客 QQ:1033553122 ---------------接Part 1-------------- #1.查看CPU信息 #cat /proc/cpuinf ...

  4. Linux 目录结构学习与简析 Part1

    linux目录结构学习与简析 by:授客 QQ:1033553122 说明: /             linux系统目录树的起点 =============== /bin      User Bi ...

  5. C++ GUI Qt4学习笔记01

    C++ GUI Qt4学习笔记01   qtc++signalmakefile文档平台 这一章介绍了如何把基本的C++只是与Qt所提供的功能组合起来创建一些简单的图形用户界面应用程序. 引入两个重要概 ...

  6. C++ GUI Qt4学习笔记03

    C++ GUI Qt4学习笔记03   qtc++spreadsheet文档工具resources 本章介绍创建Spreadsheet应用程序的主窗口 1.子类化QMainWindow 通过子类化QM ...

  7. C++ GUI Qt4学习笔记08

    C++ GUI Qt4学习笔记08   qtc++signal图形引擎文档 本章介绍Qt的二维图形引擎,Qt的二维图形引擎是基于QPainter类的.<span style="colo ...

  8. C++ GUI Qt4学习笔记09

    C++ GUI Qt4学习笔记09   qtc++ 本章介绍Qt中的拖放 拖放是一个应用程序内或者多个应用程序之间传递信息的一种直观的现代操作方式.除了剪贴板提供支持外,通常它还提供数据移动和复制的功 ...

  9. C++ GUI Qt4学习笔记05

    C++ GUI Qt4学习笔记05   qtc++正则表达式 QIntValidator           --  只让用户输入整数 QDoubleValidator     --  只让用户输入浮 ...

随机推荐

  1. Python---基础---常用的内置模块(Github、P有charm、math数学模块和random随机数模块,做一些简单的练习)

    2019-05-24 ----------------------------------

  2. man mkfs

    ---恢复内容开始--- MKFS(8)                                                                MKFS(8) NAME/名称  ...

  3. java源码生成可运行jar

    参考资料:https://blog.csdn.net/whatday/article/details/54767187 源码目录层级如下:

  4. java扫描仪上传文件

    问题: 项目中有一个功能,原来是用ckfinder做的,可以选择本地图片上传至服务器,然后将服务器的图片显示在浏览器中,并可以将图片地址保存到数据库:现在客户觉得麻烦,提出连接扫描仪扫描后直接上传至服 ...

  5. WPF 设置窗体大小为显示器工作区域大小

      最近做的项目遇到一个问题,窗体在1680*1050分辨率下显示,系统字体设置为小字体时,显示没问题,但是调到中等字体时,窗体显示位置出了问题.主窗体为无边框窗体,拖动及放大缩小事件都是自己写的. ...

  6. MySQL5.7.21报错:[Err] 1055

    [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated c ...

  7. PHP常用工具函数之手机号相关

    1.手机号正确与否判定 //测试手机号 $phone = '17777777777'; $pattern = '/^1[356789]\d{9}$/'; $is = preg_match($patte ...

  8. Java多线程,实现卖电影票的业务

    本篇重点:多线程共享资源时发生的互斥问题 一般的我们售卖电影票或者火车票时会有多个窗口同时买票, 我们来看测试代码:主方法new一个Ticket(一个堆),之后三个线程来启动(三个窗口买票) clas ...

  9. 1208C Magic Grid

    题目大意 给你一个n 让你用0~n^2-1的数填满一个n*n的正方形 满足每个数值出现一次且每行每列的异或值相等 输出任意一种方案 分析 我们发现对于4*4的正方形 0  1  2  3 4  5  ...

  10. 牛客提高D2t1 ACGT

    分析 用map维护一下每种字符串当前有几个即可 代码 #include<iostream> #include<cstdio> #include<cstring> # ...