记录下学习 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. Nginx 变量漫谈(八)

    与 $arg_XXX 类似,我们在 (二) 中提到过的内建变量 $cookie_XXX 变量也会在名为 XXX 的 cookie 不存在时返回特殊值“没找到”:     location /test  ...

  2. 在WPF中自定义你的绘制(一)

    原文:在WPF中自定义你的绘制(一)   在WPF中自定义你的绘制(一)                                                                 ...

  3. boost库的安装,使用,介绍,库分类

    1)首先去官网下载boost源码安装包:http://www.boost.org/ 选择下载对应的boost源码包.本次下载使用的是 boost_1_60_0.tar.gz (2)解压文件:tar - ...

  4. iis 回收工作进程时出错的解决办法

    第一种解决方案: iis6系统默认的工作进程回收时间是29个小时有很多问题是在回收工作进程后出现很多问题如典型的500错误等经过我做服务器的一段时间的观察大家可以不用回收工作进程而是把应用程序池的最大 ...

  5. BMP彩色转成黑色二值图

    一天半把彩色bmp转成黑白了. 原理是: 第一步:读出位图数据的偏移位置:即第11个字节,用fseek即可. 然后将偏移位置之前的数据全部写入新的bmp图中. 第二步:用fseek移到位图数据这前,判 ...

  6. Ubuntu 14.04 下使用IDEA开发Spark应用 入门

    网上有很多教程,有用sbt ,也有不用sbt的,看的头大,搞了半天,终于运行成功一个例子,如下: 1.官网下载http://www.jetbrains.com/idea/download/ Inter ...

  7. git 之别名配置

    在git操作中有很多命令我们自己可以起别名,以提高操作效率. 1. 配置方式 1)项目级别的配置,仅对当前项目生效(将写入到.git/config文件中)    $ git config --glob ...

  8. uva 748 Exponentiation 浮点数乘方运算 高精度水题

    输入的前六位数表示一个小数,然后输入一个数表示几次方.要求用高精度算出结果. 高精度水题,主要注意处理小数点,先在输入时把小数点提取出来并记录位置,用普通乘法计算出结果后由后向前计算位置添加小数点. ...

  9. 调用Response.Redirect 捕获异常 解决办法(摘抄)

    如果使用 Response.End.Response.Redirect 或 Server.Transfer 方法,将出现 ThreadAbortException 异常.您可以使用 try-catch ...

  10. jquery 设置asp:dropdownlist 选中项

    $("#ddlPro").find('option').each(function () { this.selected = (this.text == dlprom); });