关于窗口实现
代码
资源文件
- 工程目录下建立
uires
目录,里面存放一些工程用到的资源文件,包括图片以及一些XML文件。 - 同时
uires
目录下应该还有个uires.xml文件,里面定义程序中用到的其他资源的类型和名称。
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 |
<?xml version="1.0" encoding="utf-8"?> <resource> <UIDEF> <file name="xml_init" path="xml\init.xml" /> </UIDEF> <ICON> <file name="LOGO" path="image\img_logo.ico" /> </ICON> <CURSOR> <file name="ANI_ARROW" path="image\a.ani" /> <file name="CUR_TE" path="image\ae.cur" /> </CURSOR> <LAYOUT> <file name="maindlg" path="xml\dlg_main.xml" /> <file name="testdlg" path="xml\test_dlg.xml" /> </LAYOUT> <IMGX> <file name="png_icon" path="image\page_icons.png" /> </IMGX> <GIF> <file name="gif_horse" path="image\horse.gif" /> </GIF> <rtf> <file name="test_rtf" path="rtf\test.rtf" /> </rtf> <script> <file name="rtf_test" path="lua\tee.lua" /> </script> <translator> <file name="lang_cn" paht="translation_file\lang_cn.xml" /> </translator> </resource> |
入口函数
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpstrCmdLine*/, int /*nCmdShow*/) { //必须要调用OleInitialize来初始化运行环境 HRESULT hRes = OleInitialize(NULL); SASSERT(SUCCEEDED(hRes)); int nRet = 0; //定义一组组件加载辅助对象 //SComLoader实现从DLL的指定函数创建符号SOUI要求的类COM组件。 SComLoader imgDecLoader; SComLoader renderLoader; SComLoader transLoader; SComLoader scriptLoader; SComLoader zipResLoader; //将程序的运行路径修改到demo所在的目录 TCHAR szCurrentDir[MAX_PATH]={0}; GetModuleFileName( NULL, szCurrentDir, sizeof(szCurrentDir) ); LPTSTR lpInsertPos = _tcsrchr( szCurrentDir, _T('\\') ); _tcscpy(lpInsertPos,_T("\\..\\demo")); SetCurrentDirectory(szCurrentDir); { //定义一组类SOUI系统中使用的类COM组件 //CAutoRefPtr是一个SOUI系统中使用的智能指针类 CAutoRefPtr<IImgDecoderFactory> pImgDecoderFactory; //图片解码器,由imagedecoder-wid.dll模块提供 CAutoRefPtr<IRenderFactory> pRenderFactory; //UI渲染模块,由render-gdi.dll或者render-skia.dll提供 CAutoRefPtr<ITranslatorMgr> trans; //多语言翻译模块,由translator.dll提供 CAutoRefPtr<IScriptModule> pScriptLua; //lua脚本模块,由scriptmodule-lua.dll提供 BOOL bLoaded=FALSE; int nType=MessageBox(GetActiveWindow(),_T("选择渲染类型:\n[yes]: Skia\n[no]:GDI\n[cancel]:Quit"),_T("select a render"),MB_ICONQUESTION|MB_YESNOCANCEL); if(nType == IDCANCEL) return -1; //从各组件中显示创建上述组件对象 bLoaded=renderLoader.CreateInstance(nType==IDYES?COM_RENDER_SKIA:COM_RENDER_GDI,(IObjRef**)&pRenderFactory); SASSERT_FMT(bLoaded,_T("load module [%s] failed!"),nType==IDYES?COM_RENDER_SKIA:COM_RENDER_GDI); bLoaded=imgDecLoader.CreateInstance(COM_IMGDECODER,(IObjRef**)&pImgDecoderFactory); SASSERT_FMT(bLoaded,_T("load module [%s] failed!"),COM_IMGDECODER); bLoaded=transLoader.CreateInstance(COM_TRANSLATOR,(IObjRef**)&trans); SASSERT_FMT(bLoaded,_T("load module [%s] failed!"),COM_TRANSLATOR); //为渲染模块设置它需要引用的图片解码模块 pRenderFactory->SetImgDecoderFactory(pImgDecoderFactory); //定义一个唯一的SApplication对象,SApplication管理整个应用程序的资源 SApplication *theApp=new SApplication(pRenderFactory,hInstance); //定义一人个资源提供对象,SOUI系统中实现了3种资源加载方式,分别是从文件加载,从EXE的资源加载及从ZIP压缩包加载 CAutoRefPtr<IResProvider> pResProvider; #if (RES_TYPE == 0)//从文件加载 CreateResProvider(RES_FILE,(IObjRef**)&pResProvider); if(!pResProvider->Init((LPARAM)_T("uires"),0)) { SASSERT(0); return 1; } #elif (RES_TYPE==1)//从EXE资源加载 CreateResProvider(RES_PE,(IObjRef**)&pResProvider); pResProvider->Init((WPARAM)hInstance,0); #elif (RES_TYPE==2)//从ZIP包加载 bLoaded=zipResLoader.CreateInstance(COM_ZIPRESPROVIDER,(IObjRef**)&pResProvider); SASSERT(bLoaded); ZIPRES_PARAM param; param.ZipFile(pRenderFactory, _T("uires.zip")); bLoaded = pResProvider->Init((WPARAM)¶m,0); SASSERT(bLoaded); #endif //将创建的IResProvider交给SApplication对象 theApp->AddResProvider(pResProvider); if(trans) {//加载语言翻译包 theApp->SetTranslator(trans); pugi::xml_document xmlLang; if(theApp->LoadXmlDocment(xmlLang,_T("lang_cn"),_T("translator"))) { CAutoRefPtr<ITranslator> langCN; trans->CreateTranslator(&langCN); langCN->Load(&xmlLang.child(L"language"),1);//1=LD_XML trans->InstallTranslator(langCN); } } #ifdef DLL_SOUI //加载LUA脚本模块,注意,脚本模块只有在SOUI内核是以DLL方式编译时才能使用。 bLoaded=scriptLoader.CreateInstance(COM_SCRIPT_LUA,(IObjRef**)&pScriptLua); SASSERT_FMT(bLoaded,_T("load module [%s] failed!"),COM_SCRIPT_LUA); if(pScriptLua) { theApp->SetScriptModule(pScriptLua); size_t sz=pResProvider->GetRawBufferSize(_T("script"),_T("lua_test")); if(sz) { CMyBuffer<char> lua; lua.Allocate(sz); pResProvider->GetRawBuffer(_T("script"),_T("lua_test"),lua,sz); pScriptLua->executeScriptBuffer(lua,sz); } } #endif//DLL_SOUI //向SApplication系统中注册由外部扩展的控件及SkinObj类 SWkeLoader wkeLoader; if(wkeLoader.Init(_T("wke.dll"))) { theApp->RegisterWndFactory(TplSWindowFactory<SWkeWebkit>());//注册WKE浏览器 } theApp->RegisterWndFactory(TplSWindowFactory<SGifPlayer>());//注册GIFPlayer theApp->RegisterSkinFactory(TplSkinFactory<SSkinGif>());//注册SkinGif SSkinGif::Gdiplus_Startup(); //加载系统资源 HMODULE hSysResource=LoadLibrary(SYS_NAMED_RESOURCE); if(hSysResource) { CAutoRefPtr<IResProvider> sysSesProvider; CreateResProvider(RES_PE,(IObjRef**)&sysSesProvider); sysSesProvider->Init((WPARAM)hSysResource,0); theApp->LoadSystemNamedResource(sysSesProvider); } //加载全局资源描述XML theApp->Init(_T("xml_init")); { //创建并显示使用SOUI布局应用程序窗口,为了保存窗口对象的析构先于其它对象,把它们缩进一层。 CMainDlg dlgMain; dlgMain.Create(GetActiveWindow(),0,0,800,600); dlgMain.GetNative()->SendMessage(WM_INITDIALOG); dlgMain.CenterWindow(); dlgMain.ShowWindow(SW_SHOWNORMAL); nRet=theApp->Run(dlgMain.m_hWnd); } //应用程序退出 delete theApp; SSkinGif::Gdiplus_Shutdown(); } OleUninitialize(); return nRet; } |
主窗口
- 非模态窗口从
SHostWnd
派生,模态窗口从SHostDialog
派生。
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
class CMainDlg : public SHostWnd { public: /** * CMainDlg * @brief 构造函数 * Describe 使用uires.idx中定义的maindlg对应的xml布局创建UI */ CMainDlg() : SHostWnd(_T("maindlg")),m_bLayoutInited(FALSE) { } protected: ////////////////////////////////////////////////////////////////////////// // Window消息响应函数 LRESULT OnInitDialog(HWND hWnd, LPARAM lParam); void OnDestory(); void OnClose() { AnimateHostWindow(200,AW_CENTER|AW_HIDE); PostMessage(WM_QUIT); } void OnMaximize() { GetNative()->SendMessage(WM_SYSCOMMAND,SC_MAXIMIZE); } void OnRestore() { GetNative()->SendMessage(WM_SYSCOMMAND,SC_RESTORE); } void OnMinimize() { GetNative()->SendMessage(WM_SYSCOMMAND,SC_MINIMIZE); } void OnSize(UINT nType, CSize size) { SetMsgHandled(FALSE); //这一行很重要,保证消息继续传递给SHostWnd处理,当然也可以用SHostWnd::OnSize(nType,size);代替,但是这里使用的方法更简单,通用 if(!m_bLayoutInited) return; if(nType==SIZE_MAXIMIZED) { FindChildByID(3)->SetVisible(TRUE); FindChildByID(2)->SetVisible(FALSE); }else if(nType==SIZE_RESTORED) { FindChildByID(3)->SetVisible(FALSE); FindChildByID(2)->SetVisible(TRUE); } } int OnCreate(LPCREATESTRUCT lpCreateStruct); void OnShowWindow(BOOL bShow, UINT nStatus); //DUI菜单响应函数 void OnCommand(UINT uNotifyCode, int nID, HWND wndCtl); protected: ////////////////////////////////////////////////////////////////////////// // SOUI事件处理函数 //演示屏蔽指定edit控件的右键菜单 BOOL OnEditMenu(CPoint pt) { return TRUE; } //按钮控件的响应 void OnBtnSelectGIF(); void OnBtnMenu(); void OnBtnInsertGif2RE(); void OnBtnHideTest(); void OnBtnMsgBox(); void OnBtnWebkitGo(); void OnBtnWebkitBackward(); void OnBtnWebkitForeward(); void OnBtnWebkitRefresh(); //演示如何使用subscribeEvent来不使用事件映射表实现事件响应 bool OnListHeaderClick(EventArgs *pEvt); //UI控件的事件及响应函数映射表 EVENT_MAP_BEGIN() EVENT_ID_COMMAND(1, OnClose) EVENT_ID_COMMAND(2, OnMaximize) EVENT_ID_COMMAND(3, OnRestore) EVENT_ID_COMMAND(5, OnMinimize) EVENT_NAME_CONTEXTMENU(L"edit_1140",OnEditMenu) EVENT_NAME_COMMAND(L"btn_msgbox",OnBtnMsgBox) EVENT_NAME_COMMAND(L"btnSelectGif",OnBtnSelectGIF) EVENT_NAME_COMMAND(L"btn_menu",OnBtnMenu) EVENT_NAME_COMMAND(L"btn_webkit_go",OnBtnWebkitGo) EVENT_NAME_COMMAND(L"btn_webkit_back",OnBtnWebkitBackward) EVENT_NAME_COMMAND(L"btn_webkit_fore",OnBtnWebkitForeward) EVENT_NAME_COMMAND(L"btn_webkit_refresh",OnBtnWebkitRefresh) EVENT_NAME_COMMAND(L"btn_hidetst",OnBtnHideTest) EVENT_NAME_COMMAND(L"btn_insert_gif",OnBtnInsertGif2RE) EVENT_MAP_END() //HOST消息及响应函数映射表 BEGIN_MSG_MAP_EX(CMainDlg) MSG_WM_CREATE(OnCreate) MSG_WM_INITDIALOG(OnInitDialog) MSG_WM_DESTROY(OnDestory) MSG_WM_CLOSE(OnClose) MSG_WM_SIZE(OnSize) MSG_WM_COMMAND(OnCommand) MSG_WM_SHOWWINDOW(OnShowWindow) CHAIN_MSG_MAP(SHostWnd) REFLECT_NOTIFICATIONS_EX() END_MSG_MAP() protected: ////////////////////////////////////////////////////////////////////////// // 辅助函数 void InitListCtrl(); private: BOOL m_bLayoutInited;/**<UI完成布局标志 */ }; |
资源
UIDEF资源
- xml_init用来定义全局使用的UI。
- 对应的xml文件是入口函数中被
SApplication
对象使用。
1 2 3 4 5 6 |
//... //定义一个唯一的SApplication对象,SApplication管理整个应用程序的资源 SApplication *theApp=new SApplication(pRenderFactory,hInstance); //... //加载全局资源描述XML theApp->Init(_T("xml_init")); |
- 其中,init.xml文件内容如下:
- xml_init必须是以UIDEF为唯一根节点。
- UIDEF下可以有5个子节点:
- font
- string
- skins
- style
- objattr
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
<?xml version="1.0" encoding="utf-8"?> <UIDEF> <font face="微软雅黑" size="18"/> <string> <ver value="1.0"/> </string> <skin> <imglist name="skin_page_icons" src="imgx:png_page_icons" states="9"/> <imglist name="skin_small_icons" src="imgx:png_small_icons" states="12"/> <imglist name="skin_tree_icon" src="imgx:png_treeicon" states="3"/> <imglist name="skin_menuicon" src="imgx:png_small_icons" states="12"/> <border name="skin_menuborder" src="imgx:png_menu_border" left="2" top="2" border="2,2,2,2" key="FF00FF" alpha="100"/> <imglist name="skin_webbtn_back" src="imgx:webbtn_back" states="4"/> <imglist name="skin_webbtn_forward" src="imgx:webbtn_forward" states="4"/> <imglist name="skin_webbtn_refresh" src="imgx:webbtn_refresh" states="4"/> <imglist name="skin_tab_left" src="imgx:png_tab_left" states="3"/> <imglist name="skin_tab_left_splitter" src="imgx:png_tab_left_splitter"/> <imglist name="skin_tab_main" src="imgx:png_tab_main" states="3"/> <imglist name="skin_btn_menu" src="imgx:btn_menu" states="3"/> <gif name="gif_horse" src="gif:gif_horse"/> <gif name="gif_penguin" src="gif:gif_penguin"/> </skin> <style> <class name="cls_dlg_frame" skin="_skin.sys.wnd.bkgnd" font="" colorText="#000000" margin-x="0"/> <class name="cls_btn_link" cursor="hand" colorHover="#0A84D2" /> <!--定义文字按钮的样式--> <class name="cls_btn_weblink" cursor="hand" colorText="#1e78d5" colorHover="#1e78d5" font="italic:1" fontHover="underline:1,italic:1" /> <class name="cls_txt_red" font="face:宋体,bold:1" colorText="#FF0000" /> <!--定义白色粗体宋体--> <class name="cls_txt_black" font="face:宋体,bold:1" colorText="#000000" /> <!--定义黑色粗体宋体--> <class name="cls_txt_white" font="face:宋体,bold:1" colorText="#FFFFFF" /> <!--定义白色粗体宋体--> <class name="normalbtn" font="" colorText="#385e8b" colorTextDisable="#91a7c0" textMode="25" cursor="hand" margin-x="0"/> <class name="toptext" textMode="20" /> <class name="vcentertext" textMode="24"/> <class name="rightvcentertext" textMode="26"/> <class name="centertext" textMode="25"/> <class name="righttext" textMode="22"/> <class name="linkimage" cursor="hand"/> <class name="cls_edit" ncSkin="_skin.sys.border" margin-x="2" margin-y="2" /> </style> <objattr> <button class="normalbtn"/> <imgbtn class="linkimage"/> <tabctrl colorText="000000" align="top" tabWidth="70" tabHeight="38" tabSpacing="0" tabPos="10" dotted="1"/> <edit transParent="1" margin-x="2" margin-y="2"/> <treectrl colorItemBkgnd="#FFFFFF" colorItemSelBkgnd="#000088" colorItemText="#000000" colorItemSelText="#FFFFFF" indent="17" itemMargin="4"/> </objattr> </UIDEF> |
font
- 字体(只有face,size属性)
string
- 一个字符串表,定义一个"name-字符串"映射,在布局的XML文件中可以通过引用字符串的name来获得字符串
skins
- SOUI系统默认实现了如下几种绘图类型:
- SSkinImgList(imglist)
- SSkinImgFrame(imgframe)
- SSkinButton(button)
- SSkinGradation(gradation)
- SSkinScrollbar(scrollbar)
- SSkinMenuBorder(border)
imglist
1 2 3 4 5 6 |
SOUI_ATTRS_BEGIN() ATTR_CUSTOM(L"src", OnAttrImage) //skinObj引用的图片文件定义在uires.idx中的name属性。 ATTR_INT(L"tile", m_bTile, TRUE) //绘制是否平铺,0--位伸(默认),其它--平铺 ATTR_INT(L"vertical", m_bVertical, TRUE)//子图是否垂直排列,0--水平排列(默认), 其它--垂直排列 ATTR_INT(L"states",m_nStates,TRUE) //子图数量,默认为1 SOUI_ATTRS_END() |
1 2 3 |
<skins> <imglist name=“skin_btn_next" src="imgx:btn_next" states="4" tile="0" vertical="0"/> </skins> |
imgframe
1 2 3 4 5 6 7 8 |
SOUI_ATTRS_BEGIN() ATTR_INT(L"left", m_rcMargin.left, TRUE) //九宫格左边距 ATTR_INT(L"top", m_rcMargin.top, TRUE) //九宫格上边距 ATTR_INT(L"right", m_rcMargin.right, TRUE) //九宫格右边距 ATTR_INT(L"bottom", m_rcMargin.bottom, TRUE) //九宫格下边距 ATTR_INT(L"margin-x", m_rcMargin.left=m_rcMargin.right, TRUE)//九宫格左右边距 ATTR_INT(L"margin-y", m_rcMargin.top=m_rcMargin.bottom, TRUE)//九宫格上下边距 SOUI_ATTRS_END() |
button
1 2 3 4 5 6 7 8 9 10 11 |
SOUI_ATTRS_BEGIN() ATTR_COLOR(L"colorBorder", m_crBorder, TRUE) //边框颜色 ATTR_COLOR(L"colorUp", m_crUp[ST_NORMAL], TRUE) //正常状态渐变起始颜色 ATTR_COLOR(L"colorDown", m_crDown[ST_NORMAL], TRUE) //正常状态渐变终止颜色 ATTR_COLOR(L"colorUpHover", m_crUp[ST_HOVER], TRUE) //浮动状态渐变起始颜色 ATTR_COLOR(L"colorDownHover", m_crDown[ST_HOVER], TRUE) //浮动状态渐变终止颜色 ATTR_COLOR(L"colorUpPush", m_crUp[ST_PUSHDOWN], TRUE) //下压状态渐变起始颜色 ATTR_COLOR(L"colorDownPush", m_crDown[ST_PUSHDOWN], TRUE) //下压状态渐变终止颜色 ATTR_COLOR(L"colorUpDisable", m_crUp[ST_DISABLE], TRUE) //禁用状态渐变起始颜色 ATTR_COLOR(L"colorDownDisable", m_crDown[ST_DISABLE], TRUE) //禁用状态渐变终止颜色 SOUI_ATTRS_END() |
gradation
1 2 3 4 5 |
SOUI_ATTRS_BEGIN() ATTR_COLOR(L"colorFrom", m_crFrom, TRUE) //渐变起始颜色 ATTR_COLOR(L"colorTo", m_crTo, TRUE) //渐变终止颜色 ATTR_INT(L"vertical", m_bVert, TRUE) //渐变方向,0--水平(默认), 1--垂直 SOUI_ATTRS_END() |
scrollbar
1 2 3 4 5 |
SOUI_ATTRS_BEGIN() ATTR_INT(L"margin",m_nMargin,FALSE) //边缘不拉伸大小 ATTR_INT(L"hasGripper",m_bHasGripper,FALSE) //滑块上是否有帮手(gripper) ATTR_INT(L"hasInactive",m_bHasInactive,FALSE) //是否有禁用态 SOUI_ATTRS_END() |
border
style
- 定义UI布局中SOUI窗口对象的属性集合,它们是SWindow对象的属性,所有SWindow对象都可以通过class属性来引用style节点中定义的属性集合
objattr
- 可以为每一类UI控件通过objattr来提供一种默认属性集合,以减少在XML布局中的重复定义
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ Windows创建进程实例:权限及子进程监控相关10/19
- ♥ WinDbg语法规则07/11
- ♥ 关于异常的捕获和dump文件的生成07/05
- ♥ Zlib记述:一09/17
- ♥ C++_关于对象的具体初始化顺序11/30
- ♥ Soui应用 动画一06/24