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窗口。
如图所示:

发表评论
要发表评论,您必须先登录。