记录下学习MyGui的一些笔记,从建立第一个工程开始。
环境:MyGui3.2.0(OpenGL平台)
步骤:
1.右键MYGUI,添加→新建项目,选择“Win32 项目”,名称为:TestHello。下一步,勾选“空项目”。
2.设置工程Debug版本属性。“调试”→“工作目录”填入如下:
“C/C++”→“常规”→“附加包含目录”填入以下:
2
3
4
5
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
“预处理器”→“预处理器定义”填入如下:
“链接器”→“常规”→“输出文件”填入如下
“附加库目录”填入如下:
2
F:\MyCode\MyGUI_SVN\Dependencies\lib\Debug
“输入”→“附加依赖项”填入如下:
3.添加C++类TestKeeper,派生自base::BaseDemoManager,在TestKeeper.h 文件添加如下头文件:
在TestKeeper.cpp文件添加如下头文件:
在最底下添加如下代码:
这是一个宏,实质是Win32应用程序的入口函数,源码如下:
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
# 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方法进行创建窗口,内部代码部分注释如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
//中间省略
hWnd = CreateWindow(wc.lpszClassName, TEXT("OpenGL Render Window"), WS_POPUP,
0, 0, 0, 0, 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方法来进行消息的处理了,代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
MSG msg;
while (true)
{
while (PeekMessage(&msg, NULL, 0, 0, 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创建出来的东西倒序销毁掉,代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
destroyScene();
destroyPointerManager();
destroyInput();
destroyGui();
destroyRender();
if (hWnd)
{
DestroyWindow(hWnd);
hWnd = 0;
}
UnregisterClass(WND_CLASS_NAME, hInstance);
}
此时,编译运行程序的话,将会看到一个黑色的窗口。
4.简单地显示一个对话框和按钮。重载createScene方法,代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
base::BaseDemoManager::createScene();
//创建一个主对话框
MyGUI::Window* window = MyGUI::Gui::getInstance().createWidget<MyGUI::Window>(
"WindowCS", //皮肤
MyGUI::IntCoord(10, 15, 120, 130), //坐标、宽高
MyGUI::Align::Default, //对齐方式
"Main" //创建于哪个层上,定义在MyGUI_Layers.xml
);
window->setCaption("Frame"); //标题名称
window->setMinSize(80, 80); //最小的大小
//创建位于对话框里的按钮
MyGUI::Button* button = window->createWidget<MyGUI::Button>(
"Button",
MyGUI::IntCoord(30, 35, 50, 30),
MyGUI::Align::Default
);
button->setCaption("Button");
}
createScene方法是用来初始化时创建场景的,在这里可以进行添加控件。编译运行,可看到如下结果:
5.分析资源的载入和控件的创建。资源的载入从createGui方法开始,代码如下:
2
3
4
5
6
7
8
9
10
{
mPlatform = new MyGUI::OpenGLPlatform();
mPlatform->initialise(this);
setupResources();
mGUI = new MyGUI::Gui();
mGUI->initialise(mResourceFileName);
}
createGui方法内部调用了setupResources方法,setupResources方法用来设定资源的路径,默认读取应用程序同目录下的resources.xml配置,配置内容如下:
2
3
4
5
6
<Paths>
<Path root="true">F:/MyCode/MyGUI_SVN/Media</Path>
<Path>F:/MyCode/MyGUI_SVN/Media/MyGUI_Media</Path>
</Paths>
标签Path代表一个路径,带有root="true"属性的,表示这是个根资源路径,底下包含着多个子资源目录,默认不指定递归,每当需要对某个子资源目录添加为程序的资源加载路径时,使用类似如下代码:
设定资源路径之后,创建Gui,并以资源文件名进行初始化,资源文件名默认为MyGUI_Core.xml,这时会从设定的资源路径去寻找这个文件,在F:\MyCode\MyGUI_SVN\Media\MyGUI_Media路径下找到它,内容如下:
2
3
4
5
6
7
8
9
10
11
<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来创建,这是个模板方法,代码如下:
2
3
4
5
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。下一篇继续……
更多资料:
昨天安装的飞信,今天早上来中心后,体验了一下,总体来说进步很大,当然与QQ和微信相比还是有一定的差距,但是飞信在进步,虽然有抄袭的嫌疑,但是对用户而言,他们不会在意谁到底抄袭了谁,他们只是希望在安装的时候少一些膈应。
第一次写关于产品的文章,参考了早读课的文章,大概理了下思路,就执笔开始写,写的不好大家见谅。
我所认为的界面——
1)就是不需要用户点击,APP自动执行并展示给用户可视化的画面。
2)用户没用明显目的的操作行为,APP展示给用户的界面。
3)APP传递给用户的感性信息。
图标ICON飞信在这一方面做了很大的改变,飞信也采用类似QQ和360安全卫士的那样的“温馨感言”的情感导入,情感导入应该精准的定位自己的核心用户群,然后分析核心用户的生活状态然后进行情感导入,我作为一个深度用户,感觉做的有所偏差。
唯一不好的界面就是不应该再这样一个温情的界面加入那个常规启动的欢迎界面,可以将飞信的logo加到情感导入的最后一个页面中,和谐的加入,并且不能作为该页面的主导。
导航,最好的导航就是一眼看上去不用思索就知道这里面什么样的功能,最好的导航就是当寻找某一个功能的时候我下意识的就可以认为这样功能应该在这个导航指向的界面中。(其实这部分应该归到交互设计中)
消息和好友这两个标题设置的很常规,不错。身边 这个导航的名字就有点不伦不类,身边 点击后发现,这个身边其中的内容不够统一或者分档不够明确,身边 一词没不能很好地去概括这一些功能。
更多 这个导航的图标有点平淡,应该更换,另外这个界面采用的设计可以说是飞信最差劲的一个页面,这个页面已经很好的把“一致性”这个准则喂狗了。
顶部的色彩和下部的九宫格的色彩是如此的不搭调,我知道这么做是为了强调优先级,但是——这个 更多 导航的内容以宫格的形式展示和前面的三个导航用list展示反差很大,差。
还好吧,顶部导航做的不错,但是其功能存在Bug。
在 好友 的右上角已经添加一个聊天的选项,可以选择群聊或者其他群发。
身边 这个导航名字 基本上把这个Activity中的信息给毁了。身边动态 点击去之后 默认的竟然是好友动态,然后在次级导航中最上部存在着选择的菜单,这样增加了操作的难度,更会让用户对该部分内容产生迷茫和误解,本来身边的动态和好友的动态是按照两个维度区分的,前者是地域后者是人际关系,不应该分到一起,建议在 身边 这个导航区域 的身边动态 改为 好友动态和身边动态 这个是动态可以列为一小组 。
身边的群 ,很中规中矩,没有价值的取向——没有引导性,没有兴趣点。名字要改,或者说功能级别的重构。
推荐好友做的不错。赞一个。
我不知道为什么要把同窗放到 更多 中 ,
更多 中功能都不错,但是分类没有逻辑,让整个功能成为了鸡肋——功能不错,但是体验不佳。
最想吐槽的就是群发的功能,我做测试的时候,给我们班学委发短信,然后她对我说这个版本的飞信群发功能很差劲,果断卸掉了。
群发是不好用,要一个一个去选择。也许提供了群组群发,但是我试图去操作,飞信没有反应,没有提供我想要的联系人,我不知道是谁的错误。
好友 中 列表 是按照备注名字的首字母的A~Z序列排列的,取消了以前的按组别排列,应该给用户选择,并把组别应用为默认的显示方案。
点击好友后,显示的是好友的名片。应该可以直接输入信息,就像之前的版本就可以。现有的呈现信息,可以用在点击用户头像后呈现,若真是这样做我只会说声完美。
其他的交互现在还没有体现,以后再说。
今天闲来无事,就看了一下乔布斯的电影,感触很深刻,
脑袋里时刻在回荡一句话
只有偏执狂才能生存
只有给自己的产品注入个性和灵魂才能颠覆
乔布斯已经被推向了神坛
无法超越
我们除了被他的创造的产品改变之外
却很少触及他所给自己的产品注入的灵魂
我们学习乔布斯
却无法学到其精髓
仰望
也许是这一个时代
对乔布斯最后的礼物吧
在看电影的时候
我被乔布斯能够感受到的东西吸引
那种痴迷
沉醉
和放松于美丽的事物中间的感受
你我也许都曾体会过
却都没有根植于我们的灵魂
没有深刻的影响我们的生活
我们只是被动的体会着
却没有去追求
去让那种感觉流传下去
最后的独白部分
振聋发聩
生的意义何在
乔布斯的回答是
在你的生活中创造出属于自己的东西
与众不同