记录下学习 MyGui的一些笔记,从建立第一个工程开始。

步骤:

1.右键MYGUI解决方案,添加→新建项目,选择“Win32 项目”,名称为:TestHello。下一步,勾选“空项目”。

2.设置工程Debug版本属性。“调试”→“工作目录”填入如下:

1

 
F:\MyCode\MyGUI_SVN\Build\bin\debug

“C/C++”→“常规”→“附加包含目录”填入以下:

1

2

3

4

5

 
F:\MyCode\MyGUI_SVN\MyGUIEngine\include

F:\MyCode\MyGUI_SVN\Common

F:\MyCode\MyGUI_SVN\Common\Base\OpenGL

F:\MyCode\MyGUI_SVN\Platforms\OpenGL\OpenGLPlatform\include

F:\MyCode\MyGUI_SVN\Common\Input\Win32

“预处理器”→“预处理器定义”填入如下:

1

 
WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;MYGUI_OPENGL_PLATFORM;MYGUI_SAMPLES_INPUT_WIN32;

“链接器”→“常规”→“输出文件”填入如下

1

 
F:\MyCode\MyGUI_SVN\Build\bin\Debug\$(ProjectName).exe

“附加库目录”填入如下:

1

2

 
F:\MyCode\MyGUI_SVN\Build\lib\Debug

F:\MyCode\MyGUI_SVN\Dependencies\lib\Debug

“输入”→“附加依赖项”填入如下:

1

 
kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib gdiplus.lib glu32.lib opengl32.lib Common_d.lib MyGUI.OpenGLPlatform_d.lib MyGUIEngine_d.lib freetype2311_D.lib

3.添加C++类TestKeeper,派生自base::BaseDemoManager,在TestKeeper.h 文件添加如下头文件:

1

 
#include 
"Base/BaseDemoManager.h"

在TestKeeper.cpp文件添加如下头文件:

1

 
#include 
"Base/Main.h"

在最底下添加如下代码:

1

 
MYGUI_APP(TestKeeper)

这是一个宏,实质是Win32应用程序的入口函数,源码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

 
#if MYGUI_PLATFORM == MYGUI_PLATFORM_WIN32

#   ifdef MYGUI_CHECK_MEMORY_LEAKS

#       define MYGUI_APP(cls) INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT argc) { _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); 
return startApp<cls>(); }

#   
else

#       define MYGUI_APP(cls) INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT argc) { 
return startApp<cls>(); }

#   endif


#else

#   define MYGUI_APP(cls) 
int main(
int argc, 
char **argv) { 
return startApp<cls>(); }


#endif

template <
class AppClass>


int startApp()

{

    
try

    {

        AppClass* app = 
new AppClass();

        app->prepare();

        
if (app->create())

        {

            app->run();

            app->destroy();

        }

        
delete app;

        app = 
;

    }

    
catch (MyGUI::Exception& _e)

    {


#if MYGUI_PLATFORM == MYGUI_PLATFORM_WIN32

        MessageBoxA( 
NULL, _e.getFullDescription().c_str(), 
"An exception has occured", MB_OK | MB_ICONERROR | MB_TASKMODAL);


#else

        std::cerr << 
"An exception has occured" << 
" : " << _e.getFullDescription().c_str();


#endif

        
throw;

    }

    
return 
;

}

可以看到,首先调用了prepare方法进行了准备工作,这是个虚函数,没有具体实现,派生类可以实现自己需要的工作。接着调用create方法进行创建窗口,内部代码部分注释如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

 
bool BaseManager::create(
int _width, 
int _height)

{

    
//中间省略
    hWnd = CreateWindow(wc.lpszClassName, TEXT(
"OpenGL Render Window"), WS_POPUP,

        



, GetDesktopWindow(), 
NULL, wc.hInstance, 
this);

    
//中间省略
    

    
//创建渲染  根据所选的渲染系统,创建渲染显示
    
if (!createRender(width, height, windowed))

    {

        
return 
false;

    }

    
//创建Gui  包含加载资源setupResources
    createGui();

    
//创建输入管理器  调用的是基类的InputManager::createInput
    createInput((size_t)hWnd);

    
//创建指针管理器  调用的是基类的PointerManager::createPointerManager
    createPointerManager((size_t)hWnd);

    
//创建场景  没有实现,具体由派生类来实现
    createScene();

    
//内部函数  窗口变化大小时,会触发来重新设置渲染窗口大小
    _windowResized();

return 
true;

}

之后就是调用run方法来进行消息的处理了,代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

 
void BaseManager::run()

{

    MSG msg;

    
while (
true)

    {

        
while (PeekMessage(&msg, 
NULL, 

, PM_REMOVE))

        {

            TranslateMessage(&msg);

            DispatchMessage(&msg);

        }

        
if (mExit)

            
break;

        
else 
if (msg.message == WM_QUIT)

            
break;

captureInput(); 
//捕获输入  由派生类来实现
        drawOneFrame(); 
//绘制一帧  调用相应的渲染方法

if (GetActiveWindow() != hWnd)

            ::Sleep(
);

    }

}

当收到退出的消息,就会退出循环,调用destroy方法,相应地将create创建出来的东西倒序销毁掉,代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

 
void BaseManager::destroy()

{

    destroyScene();

destroyPointerManager();

destroyInput();

destroyGui();

destroyRender();

if (hWnd)

    {

        DestroyWindow(hWnd);

        hWnd = 
;

    }

UnregisterClass(WND_CLASS_NAME, hInstance);

}

此时,编译运行程序的话,将会看到一个黑色的窗口。

4.简单地显示一个对话框和按钮。重载createScene方法,代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

 
void TestKeeper::createScene()

{

    base::BaseDemoManager::createScene();

//创建一个主对话框
    MyGUI::Window* window = MyGUI::Gui::getInstance().createWidget<MyGUI::Window>(

        
"WindowCS",                         
//皮肤
        MyGUI::IntCoord(



),  
//坐标、宽高
        MyGUI::Align::Default,              
//对齐方式
        
"Main"                              
//创建于哪个层上,定义在MyGUI_Layers.xml
        );

    window->setCaption(
"Frame");            
//标题名称
    window->setMinSize(

);             
//最小的大小

//创建位于对话框里的按钮
    MyGUI::Button* button = window->createWidget<MyGUI::Button>(

        
"Button",

        MyGUI::IntCoord(



), 

        MyGUI::Align::Default

        );

    button->setCaption(
"Button");

}

createScene方法是用来初始化时创建场景的,在这里可以进行添加控件。编译运行,可看到如下结果:

5.分析资源的载入和控件的创建。资源的载入从createGui方法开始,代码如下:

1

2

3

4

5

6

7

8

9

10

 
void BaseManager::createGui()

{

    mPlatform = 
new MyGUI::OpenGLPlatform();

    mPlatform->initialise(
this);

setupResources();

mGUI = 
new MyGUI::Gui();

    mGUI->initialise(mResourceFileName);

}

createGui方法内部调用了setupResources方法,setupResources方法用来设定资源的路径,默认读取应用程序同目录下的resources.xml配置,配置内容如下:

1

2

3

4

5

6

 
<?xml version=
"1.0"
 encoding=
"UTF-8"
?>

<Paths>

  
<Path root=
"true"
>F:
/MyCode
/MyGUI_SVN
/Media
</Path>

  
<Path>F:
/MyCode
/MyGUI_SVN
/Media
/MyGUI_Media
</Path>


</Paths>

标签Path代表一个路径,带有root="true"属性的,表示这是个根资源路径,底下包含着多个子资源目录,默认不指定递归,每当需要对某个子资源目录添加为程序的资源加载路径时,使用类似如下代码:

1

 
addResourceLocation(getRootMedia() + 
"/Common/Base");

设定资源路径之后,创建Gui,并以资源文件名进行初始化,资源文件名默认为MyGUI_Core.xml,这时会从设定的资源路径去寻找这个文件,在F:\MyCode\MyGUI_SVN\Media\MyGUI_Media路径下找到它,内容如下:

1

2

3

4

5

6

7

8

9

10

11

 
<?xml version=
"1.0"
 encoding=
"UTF-8"
?>


<MyGUI type=
"List"
>

    
<List file=
"MyGUI_GeneratedFonts.xml"
/>

    
<List file=
"MyGUI_Fonts.xml"
/>

    
<List file=
"MyGUI_CommonSkins.xml"
/>

    
<List file=
"MyGUI_BlueWhiteTheme.xml"
/>

    
<List file=
"MyGUI_PointerImages.xml"
/>

    
<List file=
"MyGUI_Pointers.xml"
/>

    
<List file=
"MyGUI_Layers.xml"
/>

    
<List file=
"MyGUI_Settings.xml"
/>


</MyGUI>

列表里的XML文件都保存各自不同的信息,具体这些配置是做什么用的,等之后有涉及到再说明。ResourceManager资源管理器加载这些XML配置。下面分析下控件创建的过程,根控件以MyGUI::Gui::getInstance().createWidget来创建,这是个模板方法,代码如下:

1

2

3

4

5

 
template <
typename T>

T* createWidget(
const std::string& _skin, 
const IntCoord& _coord, Align _align, 
const std::string& _layer, 
const std::string& _name = 
"")

{

    
return 
static_cast<T*>(createWidgetT(T::getClassTypeName(), _skin, _coord, _align, _layer, _name));

}

实质是调用createWidgetT方法,但不同的是这个方法返回的是相应的控件指针。每个参数的意思如下:

  • _type 控件类型(可在WidgetManager::initialise()查看所有的控件类型)
  • _skin 控件皮肤(先查找MyGUI_BlueWhiteTemplates.xml,没有的话再查找MyGUI_BlueWhiteSkins.xml文件)
  • _coord 控件坐标 (左、上、宽、高)
  • _align 控件对齐方式 (定义在Align,包括居左、居右、水平拉伸等等)
  • _layer 控件将被创建到哪一层(所有的层定义在MyGUI_Layers.xml文件)
  • _name 控件名称(可以通过这个名称来寻找控件)

每个控件类都含有MYGUI_RTTI_DERIVED(DerivedType)声明,这是一个宏,用来实现类型RTTI,其含有getClassTypeName方法用来获得类名,即控件类型DerivedType。下一篇继续……


更多资料:

  1. MyGUI_Orge官网教程翻译 http://blog.csdn.net/adfansong/article/category/1566083
  2. MyGUI 学习笔记 http://blog.csdn.net/jean7155/article/category/1333155
  3. MyGUI 架构介绍 http://blog.csdn.net/geometry_/article/category/1084100
  4. MyGUI wiki翻译 http://blog.csdn.net/efulao/article/category/1611683
  5. MyGUI 3.2资源文件的分析 http://blog.sina.com.cn/s/blog_be4206db01018w7v.html

MyGui笔记(1)建立第一个工程的更多相关文章

  1. 《MFC游戏开发》笔记二 建立工程、调整窗口

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9300383 作者:七十一雾央 新浪微博:http:/ ...

  2. vivado设计一:建立第一个入门工程(基于zybo)

    vivado设计一:建立第一个入门工程(基于zybo) 0赞 发表于 2014/6/17 23:03:25 阅读(8777) 评论(4) 软件:vivado 2013.4 电脑:xp系统 硬件:zyb ...

  3. 用Firefly创建第一个工程

    原地址:http://blog.csdn.net/uxqclm/article/details/10382097 安装完成之后,在python script包中就存在 firefly-admin的工具 ...

  4. struts2讲义----建立一个struts2工程

    建立一个Struts2 工程 Ø 1在MyEclipse中新建web工程 Ø 2在struts-2.2.1.1-all\struts-2.2.1.1解压struts2-blank.war( 最基础的示 ...

  5. Annotation 的第一个工程

    一.什么是 Annotation? java.lang.annotation,接口 Annotation.对于Annotation,是Java5的新特性,JDK5引入了Metadata(元数据)很容易 ...

  6. hibernate 的第一个工程

    一.什么是Hibernate? Hibernate 是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hiber ...

  7. Django:学习笔记(2)——创建第一个应用

    Django:学习笔记(2)——创建第一个应用 创建应用 在 Django 中,每一个应用都是一个 Python 包,并且遵循着相同的约定.Django 自带一个工具,可以帮你生成应用的基础目录结构, ...

  8. 使用keil建立标准STM32工程模版(图文详细版!)

    1.   模板工程的创建(超级详细版,使用的是keil 4.5版本) 1.1创建工程目录 良好的工程结构能让文件的管理更科学,让开发更容易更方便,希望大家养成良好的习惯,使用具有合理结构的工程目录,当 ...

  9. CCS5 建立SYS/BIOS工程时报错“cannot find file "./configPkg/linker.cmd" bios”的解决方法

    CCS5 建立SYS/BIOS工程时报错“cannot find file "./configPkg/linker.cmd" bios”的解决方法 报错 #10008-D cann ...

随机推荐

  1. SemaphoreFullException when checking user role via ASP.NET membership

    将指定的计数添加到该信号量中会导致其超过最大计数 This issue was fixed by restarting ASP.NET Development Server on windows ta ...

  2. Amazon 解决下载文件乱码

    大家在做多个站点的时候,可能会遇到下载下来的报告文件出现乱码. 法国站点和意大利站点均会出现这样的情况,那怎么解决呢? 这是由于编码的问题而导致,在我们读取数据插入到本地数据库的时候,不妨先将格式转成 ...

  3. 一次使用Eclipse Memory Analyzer分析Tomcat内存溢出(转)

    前言 在平时开发.测试过程中.甚至是生产环境中,有时会遇到OutOfMemoryError,Java堆溢出了,这表明程序有严重的问题.我们需要找造成OutOfMemoryError原因.一般有两种情况 ...

  4. Monthly Expense(二分) 分类: 二分查找 2015-06-06 00:31 10人阅读 评论(0) 收藏

    Description Farmer John is an astounding accounting wizard and has realized he might run out of mone ...

  5. Web scraping with Python (part II) « Jean, aka Sig(gg)

    Web scraping with Python (part II) « Jean, aka Sig(gg) Web scraping with Python (part II)

  6. Codeforces 551C GukiZ hates Boxes 二分答案

    题目链接 题意:  一共同拥有n个空地(是一个数轴,从x=1 到 x=n),每一个空地上有a[i]块石头  有m个学生  目标是删除全部石头  一開始全部学生都站在 x=0的地方  每秒钟每一个学生都 ...

  7. [Android]APK程序卸载二次确认的实现

    严正声明        本人本着技术开放,思想分享的目的,撰写本文.文章仅供参考之用,请勿使之于非法或有害于社会和谐之用. Sodino 2011-01-24 Android上能不能实现卸载时提示呢, ...

  8. mobilebone.js 移动web APP单页切换骨架

    轻便体积小 原生无依赖 插件可扩展 设计无限制 动效可定制 动静两相宜 能进亦能退 桌面也兼修 一句话功能简介跟传统网页浏览的差别仅仅在于无刷新! 例如,我们浏览首页,首页上有个如下HTML链接: & ...

  9. VMware虚拟机中调整Linux分区大小手记(转发)

      前段时间用VMware5.5安装了CentOS5.3,安装的时候分配了5Gb的虚拟硬盘空间给Linux系统,系统安装选择很多组件和软件,后面使用时又安装也一些软件,结果导致虚拟硬盘空间不足.查看分 ...

  10. (转)MarginTop 为何影响父元素的 MarginTop

    这个问题困惑了很久,虽然没有大碍早就摸出来怎么搞定它,但始终不明白原因出在哪里,如果只是IE有问题我也不会太在意,可问题是所有上等浏览器都表现如此,这样叫我怎能安心?今天总算下狠心查出来怎么回事,居然 ...