MFC工程上创建SOUI环境
准备工作
1、 从SVN获取SOUI项目代码,并编译成功。
2、 然后创建一个环境变量假定是%SOUIPATH%,这个环境变量指向的目录是SOUI源代码的目录。(如果安装了SOUI向导的话,这个环境变量会自动创建,SOUI向导的目录是:SOUI源代码目录下的wizard文件夹。双击wizard文件夹下的wizard.setup.exe文件并选择相应的VS版本就可以安装。)
操作步骤
1、 创建一个MFC 工程,然后把MFC自动生成的主对话框的资源以及类删除掉(因为我们要用SOUI作界面,所以MFC生成的对话框没必要保留)。
2、 在MFC工程的properties下的include下添加目录:(SOUIPATH)\SOUI\include;[Math Processing Error](SOUIPATH)\SOUI\bin;(SOUIPATH)\utilities\include;[Math Processing Error](SOUIPATH)\config;$(SOUIPATH)\components;
如图:
3、 在MFC工程的properties下的Additional Dependencies下添加两个库文件souid.lib,utilitiesd.lib。
如图:
4、 把Code Generation中的Runtime Libray(运行时库)从MDd修改为MTd,相应的需要把Use of MFC 改为Use MFC in a Static Library。(原因是SOUI默认的编译配置就是用MTd:mutithread+debug,多线程调试版,连接LIBMITD.lib库)。
如图:
5、 把Language中的Treat WChar_t As Built in Type 改为Yes(/Zc:wchar_t)。(因为SOUI默认编译配置如此,不改的话,会报错)
如图:
6、 准备资源文件并将所有资源文件放在Uires文件夹内,并存放在工程目录下。
Uires.idx:定义资源索引;
init.xml:定义全局UI的属性。
dlg_main.xml:主窗口的XML。
(xml的具体格式参考demo)
7、 资源文件准备好后,把这些xml文件都插入到工程中,如图。直接插入到工程中,工程无法读取这些资源文件,所以需要将Uires.idx中索引的文件转换为pe资源可以识别的资源类型+类型名的形式,这里SOUI作者提供了tools\uiresbuild.exe工具,我们需要用命令行实现资源的转换,具体命令行是:”$(SOUIPATH)\tools\uiresbuilder.exe” -i “%(FullPath)” -p uires -r .\res\soui_res.rc2
在uires文件的属性中添加Custom Build tool,然后将上述命令行输入,如图所示。如此一来,我们每次对资源文件进行操作,编译时都会自动调用命令实现资源转换。
8、 上述步骤完成并编译就会在res文件下生产soui_res.rc2文件,然后把改文件添加到工程的资源那文件中,然后我们还需要在.rc资源包含中加上我们生产的.rc2文件,具体操作步骤是在.rc的资源包括菜单中加上一段链接代码如图所示。
9、 完成上述操作后,基本的SOUI环境就已经部署完成。此时编译程序的话会报出警告属于正常情况(这是SOUI内部代码和MFC相冲突的问题),报出的错误如图
我们只需要在CommandLine中定义一下即可解决问题。具体操作如图:
至此,SOUI的运行环境就完成了,并且可以编译成功。
工程中实现一个SOUI主窗口界面,具体步骤:
1、(在完成MFC工程中运行SOUI的环境的基础上进行如下操作)。如果在代码中用SOUI函数,必须要在stdafx.h文件中包含几个头文件如图所示:
2、 完成上述操作之后我们需要写SOUI的入口函数了,这里我们在MFC的app类的InitInstance()函数中配置SOUI的入口函数。
3、 首先在app类的头文件处,添加:
1.
1 |
using namespace SOUI;(必须在此处添加,不能在stdafx.h中添加,则会报错,CRect重复定义) |
2.
1 2 3 4 5 6 |
``` #ifdef _DEBUG #define SYS_NAMED_RESOURCE _T("soui-sys-resourced.dll") #else #define SYS_NAMED_RESOURCE _T("soui-sys-resource.dll") #endif |
这段代码是加载系统资源时用到的dll库。
3.
1 2 3 4 |
#define RES_TYPE 1 //从PE资源中加载UI资源 //#define RES_TYPE 0 // 从文件中加载资源 // #define RES_TYPE 2 //从zip包中加载资源 RES_TYPE是在SOUI入口函数代码中决定从哪里加载资源的。本例是从PE资源中加载资源的所以把RES_TYPE 定义为1. |
4、 在app类中的初始化函数中写入SOUI的一些基本配置代码如下,代码具体做了什么操作,请参考demo。
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 |
//////////////////////////////SOUI入口函数//////////////////////////// HRESULT hRes = OleInitialize(NULL); SASSERT(SUCCEEDED(hRes)); SComMgr *pComMgr = new SComMgr; //将程序的运行路径修改到项目所在目录所在的目录 TCHAR szCurrentDir[MAX_PATH] = { 0 }; GetModuleFileName(NULL, szCurrentDir, sizeof(szCurrentDir)); LPTSTR lpInsertPos = _tcsrchr(szCurrentDir, _T(‘\’)); _tcscpy(lpInsertPos + 1, _T(“..”)); SetCurrentDirectory(szCurrentDir); { BOOL bLoaded = FALSE; CAutoRefPtr pImgDecoderFactory; CAutoRefPtr pRenderFactory; bLoaded = pComMgr->CreateRender_GDI((IObjRef**)&pRenderFactory); SASSERT_FMT(bLoaded, _T(“load interface [render] failed!”)); bLoaded = pComMgr->CreateImgDecoder((IObjRef**)&pImgDecoderFactory); SASSERT_FMT(bLoaded, _T(“load interface [%s] failed!”), _T(“imgdecoder”)); pRenderFactory->SetImgDecoderFactory(pImgDecoderFactory); SApplication *pSOUIApp = new SApplication(pRenderFactory, m_hInstance); //从DLL加载系统资源 HMODULE hModSysResource = LoadLibrary(SYS_NAMED_RESOURCE); if (hModSysResource) { CAutoRefPtr sysResProvider; CreateResProvider(RES_PE, (IObjRef**)&sysResProvider); sysResProvider->Init((WPARAM)hModSysResource, 0); pSOUIApp->LoadSystemNamedResource(sysResProvider); FreeLibrary(hModSysResource); } else { SASSERT(0); } CAutoRefPtr pResProvider; #if (RES_TYPE == 0) CreateResProvider(RES_FILE, (IObjRef**)&pResProvider); if (!pResProvider->Init((LPARAM)_T("uires"), 0)) { SASSERT(0); return 1; } #else CreateResProvider(RES_PE, (IObjRef**)&pResProvider); pResProvider->Init((WPARAM)m_hInstance, 0); #endif CSouiRealWndHandler * pRealWndHandler = new CSouiRealWndHandler(); pSOUIApp->SetRealWndHandler(pRealWndHandler); pRealWndHandler->Release(); pSOUIApp->AddResProvider(pResProvider); pSOUIApp->Init(_T("XML_INIT")); int nRet = 0; //括号中是显示主窗口的代码 { /* CMainDlg dlgMain; dlgMain.Create(GetActiveWindow()); dlgMain.SendMessage(WM_INITDIALOG); dlgMain.CenterWindow(dlgMain.m_hWnd); dlgMain.ShowWindow(SW_SHOWNORMAL); nRet = pSOUIApp->Run(dlgMain.m_hWnd); */ } delete pSOUIApp; } delete pComMgr; OleUninitialize(); ///////////////////////////////////////////////////////// |
5、 实现主窗口的类并与dlg_main.xml绑定。
实现主窗口派生子SHostWnd,并在主窗口的构造函数中以如下格式绑定xml文件,即
CMainDlg ::CMainDlg() : SHostWnd(_T(“LAYOUT:XML_MAINWND”))
其中的XML_MAINWND是在uires.idx资源索引文件中定义的dlg_main.xml文件的name。
如图
主窗口的类具体不做论述,可参照demo。
6、 在第4步的显示主窗口的括号中加入相应代码,并编写dlg_main.xml文件布局,编译即可产生一个SOUI窗口。
如图所示:
发表评论
要发表评论,您必须先登录。