zoukankan      html  css  js  c++  java
  • MyGui笔记(1)建立第一个工程

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

    步骤:

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

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

    1
     
    F:MyCodeMyGUI_SVNBuildindebug

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

    1
    2
    3
    4
    5
     
    F:MyCodeMyGUI_SVNMyGUIEngineinclude
    F:MyCodeMyGUI_SVNCommon
    F:MyCodeMyGUI_SVNCommonBaseOpenGL
    F:MyCodeMyGUI_SVNPlatformsOpenGLOpenGLPlatforminclude
    F:MyCodeMyGUI_SVNCommonInputWin32

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

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

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

    1
     
    F:MyCodeMyGUI_SVNBuildinDebug$(ProjectName).exe

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

    1
    2
     
    F:MyCodeMyGUI_SVNBuildlibDebug
    F:MyCodeMyGUI_SVNDependencieslibDebug

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

    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 =  0;
        }
         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  0;
    }

    可以看到,首先调用了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,
             0000, 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,  NULL00, PM_REMOVE))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
             if (mExit)
                 break;
             else  if (msg.message == WM_QUIT)
                 break;

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

             if (GetActiveWindow() != hWnd)
                ::Sleep( 50);
        }
    }

    当收到退出的消息,就会退出循环,调用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 =  0;
        }

        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( 1015120130),   //坐标、宽高
            MyGUI::Align::Default,               //对齐方式
             "Main"                               //创建于哪个层上,定义在MyGUI_Layers.xml
            );
        window->setCaption( "Frame");             //标题名称
        window->setMinSize( 8080);              //最小的大小

         //创建位于对话框里的按钮
        MyGUI::Button* button = window->createWidget<MyGUI::Button>(
             "Button",
            MyGUI::IntCoord( 30355030), 
            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:MyCodeMyGUI_SVNMediaMyGUI_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
  • 相关阅读:
    电商零售数仓建模之平台01:平台业务模型
    js自动补零
    Git
    C# HttpClient 请求认证、数据传输笔记
    悲/乐观并发控制的区别
    Win10安装node.js始终出现2503错误解决方法
    行首和行尾快捷键
    IP地址分类和私有地址
    source面板看不到js的调试方法
    js常用类型判断
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3329130.html
Copyright © 2011-2022 走看看