环境:win7_64旗舰版,VS2013

发现了一个比较好用的DirectUI库——SOUI,但是写一个窗口程序不是很方便,程序初始化的地方稍显繁琐,这里稍微封装一下。

大概包含6个文件:

SouiConfig.h:负责SOUI的配置,包括导入动态库,定义SOUI系统资源名称等。

#ifndef _SOUI_CONFIG_
#define _SOUI_CONFIG_ #ifdef _DEBUG
#define SYS_NAMED_RESOURCE _T("soui-sys-resourced.dll")
#pragma comment(lib, "souid.lib")
#pragma comment(lib, "utilitiesd.lib")
#else
#define SYS_NAMED_RESOURCE _T("soui-sys-resource.dll")
#pragma comment(lib, "soui.lib")
#pragma comment(lib, "utilities.lib")
#endif // _DEBUG #define DLL_SOUI #endif

SouiInclude.h:负责包含SOUI的头文件。

#ifndef _SOUI_INCLUDE_H_
#define _SOUI_INCLUDE_H_ #include "SouiConfig.h"
#include "souistd.h"
#include "core/SHostDialog.h"
#include "control/SMessageBox.h"
#include "control/souictrls.h"
#include "com-cfg.h" using namespace SOUI; #endif

SouiApp类:负责SOUI应用程序初始化,包括设置资源路径,初始化渲染引擎,初始化OLE和消息循环。

SouiApp.h

#ifndef _SOUI_APP_H_
#define _SOUI_APP_H_ #include <string>
#include "SouiInclude.h" class SouiApp {
public:
SouiApp() : m_initOle(false), m_app(NULL) {
}
~SouiApp(); public:
// 初始化OLE
void initOle();
// 初始化应用程序
void initApp(HINSTANCE hInstance);
// 消息循环
void run(SHostWnd& mainWnd) { m_app->Run(mainWnd.m_hWnd); } public: // 属性设置
// 获取当前应用程序路径
std::wstring getAppPath() const;
// 设置资源路径
void setResPath(const std::wstring& path); private:
// 初始化渲染工厂
CAutoRefPtr<SOUI::IRenderFactory> initRenderFactory();
// 初始化语言翻译管理器
CAutoRefPtr<SOUI::ITranslatorMgr> initTranslator(const std::wstring& path);
// 初始化自定义资源
CAutoRefPtr<IResProvider> initResProvider(HINSTANCE hInstance, const std::wstring& path);
// 初始化系统资源
CAutoRefPtr<IResProvider> initSysResource(); private:
bool m_initOle; // 初始化OLE
std::wstring m_resPath; // 资源路径 SComMgr m_comMgr; // SOUI组件配置
SApplication* m_app; // SOUI应用程序类
}; #endif

SouiApp.cpp

#include <windows.h>
#include "SouiApp.h" SouiApp::~SouiApp()
{
delete m_app;
m_app = NULL; if (m_initOle) {
::OleUninitialize();
}
} void SouiApp::initOle()
{
SASSERT(!m_initOle);
HRESULT hRes = ::OleInitialize(NULL);
SASSERT(SUCCEEDED(hRes));
m_initOle = true;
} void SouiApp::initApp(HINSTANCE hInstance)
{
try
{
SASSERT(!m_app);
// 初始化渲染工厂
CAutoRefPtr<SOUI::IRenderFactory> renderFactory = initRenderFactory();
if (!renderFactory) {
throw std::runtime_error("init render factory faild!");
}
m_app = new SApplication(renderFactory, hInstance); // 初始化语言翻译管理器
CAutoRefPtr<SOUI::ITranslatorMgr> trans = initTranslator(m_resPath + L"\\translator\\lang_cn.xml");
if (!trans) {
throw std::runtime_error("init translator faild!");
}
m_app->SetTranslator(trans); // 初始化自定义资源
CAutoRefPtr<IResProvider> resProvider = initResProvider(hInstance, m_resPath);
if (!resProvider) {
throw std::runtime_error("init resource faild!");
}
m_app->AddResProvider(resProvider); // 初始化系统资源
CAutoRefPtr<IResProvider> sysResProvider = initSysResource();
if (!sysResProvider) {
throw std::runtime_error("init system resource faild!");
}
m_app->LoadSystemNamedResource(sysResProvider); m_app->Init(L"XML_INIT");
}
catch (std::runtime_error&)
{
}
} std::wstring SouiApp::getAppPath() const
{
std::wstring path(MAX_PATH, L'');
DWORD dw = ::GetModuleFileName(NULL, &path[], path.length());
path.resize(dw); path = path.substr(, path.rfind(L"\\"));
return path;
} void SouiApp::setResPath(const std::wstring& path)
{
m_resPath = path;
::SetCurrentDirectory(m_resPath.c_str());
} CAutoRefPtr<SOUI::IRenderFactory> SouiApp::initRenderFactory()
{
CAutoRefPtr<SOUI::IRenderFactory> renderFactory;
CAutoRefPtr<SOUI::IImgDecoderFactory> imgDecoderFactory;
if (m_comMgr.CreateRender_GDI((IObjRef**)&renderFactory)
&& m_comMgr.CreateImgDecoder((IObjRef**)&imgDecoderFactory)) {
renderFactory->SetImgDecoderFactory(imgDecoderFactory);
}
return renderFactory;
} CAutoRefPtr<SOUI::ITranslatorMgr> SouiApp::initTranslator(const std::wstring& path)
{
CAutoRefPtr<SOUI::ITranslatorMgr> trans;
if (m_comMgr.CreateTranslator((IObjRef**)&trans)) {
pugi::xml_document xmlLang;
if (xmlLang.load_file(path.c_str())) {
CAutoRefPtr<ITranslator> langCN;
trans->CreateTranslator(&langCN);
langCN->Load(&xmlLang.child(L"language"), );
trans->InstallTranslator(langCN);
}
}
return trans;
} CAutoRefPtr<IResProvider> SouiApp::initResProvider(HINSTANCE hInstance, const std::wstring& path)
{
const BUILTIN_RESTYPE res = RES_FILE;
CAutoRefPtr<IResProvider> resProvider;
CreateResProvider(res, (IObjRef**)&resProvider);
if (res == RES_FILE) {
if (!resProvider->Init((LPARAM)path.c_str(), )) {
SASSERT(false);
}
}
else if (res == RES_PE) {
if (!resProvider->Init((WPARAM)hInstance, )) {
SASSERT(false);
}
}
return resProvider;
} CAutoRefPtr<IResProvider> SouiApp::initSysResource()
{
CAutoRefPtr<IResProvider> sysResProvider;
HMODULE hSysResource = LoadLibrary(SYS_NAMED_RESOURCE);
if (hSysResource) {
CreateResProvider(RES_PE, (IObjRef**)&sysResProvider);
sysResProvider->Init((WPARAM)hSysResource, );
}
return sysResProvider;
}

SouiWindow类:负责SOUI窗口。

SouiWindow.h

#ifndef _SOUI_WINDOW_H_
#define _SOUI_WINDOW_H_ #include "SouiInclude.h" class SouiWindow : public SHostWnd {
public:
SouiWindow(LPCTSTR pszResName) : SHostWnd(pszResName), m_bLayoutInited(false) {}
virtual ~SouiWindow() {} // 创建
void create(SouiWindow* window = NULL);
// 居中显示
void centerShow();
// 显示
void show(); protected:
void OnClose() { DestroyWindow(); }
void OnMaximize() { SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE); }
void OnRestore() { SendMessage(WM_SYSCOMMAND, SC_RESTORE); }
void OnMinimize() { SendMessage(WM_SYSCOMMAND, SC_MINIMIZE); } int OnCreate(LPCREATESTRUCT lpCreateStruct);
void OnSize(UINT nType, CSize size);
BOOL OnInitDialog(HWND hWnd, LPARAM lParam); protected:
EVENT_MAP_BEGIN()
EVENT_NAME_COMMAND(L"btn_close", OnClose)
EVENT_NAME_COMMAND(L"btn_min", OnMinimize)
EVENT_NAME_COMMAND(L"btn_max", OnMaximize)
EVENT_NAME_COMMAND(L"btn_restore", OnRestore)
EVENT_MAP_END() BEGIN_MSG_MAP_EX(SouiWindow)
MSG_WM_CREATE(OnCreate)
MSG_WM_INITDIALOG(OnInitDialog)
MSG_WM_CLOSE(OnClose)
MSG_WM_SIZE(OnSize)
CHAIN_MSG_MAP(SHostWnd)
REFLECT_NOTIFICATIONS_EX()
END_MSG_MAP() private:
bool m_bLayoutInited;
}; #endif

SouiWindow.cpp

#include "SouiWindow.h"

void SouiWindow::create(SouiWindow* window /*= NULL*/)
{
HWND parent = window ? window->m_hWnd : NULL;
SHostWnd::Create(parent, , );
SHostWnd::SendMessage(WM_INITDIALOG);
} void SouiWindow::centerShow()
{
SHostWnd::CenterWindow(m_hWnd);
show();
} void SouiWindow::show()
{
SHostWnd::ShowWindow(SW_SHOW);
} int SouiWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
SetMsgHandled(FALSE);
return ;
} void SouiWindow::OnSize(UINT nType, CSize size)
{
SetMsgHandled(FALSE);
if (!m_bLayoutInited) return;
if (nType == SIZE_MAXIMIZED)
{
FindChildByName(L"btn_restore")->SetVisible(TRUE);
FindChildByName(L"btn_max")->SetVisible(FALSE);
}
else if (nType == SIZE_RESTORED)
{
FindChildByName(L"btn_restore")->SetVisible(FALSE);
FindChildByName(L"btn_max")->SetVisible(TRUE);
}
} BOOL SouiWindow::OnInitDialog(HWND hWnd, LPARAM lParam)
{
m_bLayoutInited = true;
return ;
}

接下来就是如何使用了,首先编写窗口XML布局文件,这里是MainWnd.xml,具体的内容这里不再详述。

SouiApp app;
// 资源路径一般为当前程序运行目录下面的res文件下
app.setResPath(app.getAppPath() + L"\\res");
app.initApp(hInstance); // 必须在uires.idx文件中,必须编写窗口资源名称和窗口XML布局文件路径,例如'<file name="XML_MAINWND" path="MainWnd.xml" />'
SouiWindow mainWnd(L"LAYOUT:XML_MAINWND");
mainWnd.create();
mainWnd.centerShow(); // 消息循环
app.run(mainWnd);

最后的界面显示为:

这里有一个小技巧,如何让窗体四周没有圆角矩形呢?

我们可以在root节点中使用属性skin="skin.border",它是一个半透明的png图片,定义为<imgframe name="skin.border"  src="PNG:ID_SHADOW" left="5" top="3" right="5" bottom="7"/>,只显示窗口边框的阴影部分;

然后在window节点中使用一张背景图片,就可以到的上图的效果,具体可参考SOUI中的"360"deom。

SOUI入门的更多相关文章

  1. UI神器-SOUI

    前言 在Windows平台上开发客户端产品是一个非常痛苦的过程,特别是还要用C++的时候.尽管很多语言很多方法都可以开发Windows桌面程序,目前国内流行的客户端产品都是C++开发的,比如QQ,YY ...

  2. 重大发现: windows下C++ UI库 UI神器-SOUI(转载)

    转载:http://www.cnblogs.com/setoutsoft/p/4996870.html 在Windows平台上开发客户端产品是一个非常痛苦的过程,特别是还要用C++的时候.尽管很多语言 ...

  3. 转: windows下C++ UI库 UI神器-SOUI

    转:http://www.cnblogs.com/setoutsoft/p/4996870.html 前言 在Windows平台上开发客户端产品是一个非常痛苦的过程,特别是还要用C++的时候.尽管很多 ...

  4. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  5. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  6. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  7. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  8. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  9. Angular2入门系列教程4-服务

    上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...

随机推荐

  1. ActiveMQ in Action(6) - Features

    关键字: activemq 2.6 Features    ActiveMQ包含了很多功能强大的特性,下面简要介绍其中的几个.2.6.1 Exclusive Consumer    Queue中的消息 ...

  2. vim menu乱码

    syntax enable syntax on colorscheme desert set nocompatible set filetype=c set number set wrap " ...

  3. java链接mysql添加中文和模糊查询

    如下内容为转载 http://sunshinechen2008.blog.163.com/blog/static/107585374201162442643967/     mysql如果不对乱码处理 ...

  4. Hibernate5-课程笔记6

    Hibernate检索优化: 检索即查询.为了减轻DB的访问压力,提高检索效率,Hibernate对检索进行了优化. 所谓检索优化,指的是对查询语句的执行时机进行了细致.严格的把控:并不是代码中一出现 ...

  5. Hibernate5--课程笔记5

    关联关系映射: 关联关系,是使用最多的一种关系,非常重要.在内存中反映为实体关系,映射到DB中为主外键关系.实体间的关联,即对外键的维护.关联关系的发生,即对外键数据的改变. 外键:外面的主键,即,使 ...

  6. js数组、对象、正则

    1.根据给定的条件在原有的数组上,得到所需要的新数组var a = [-1, -1, 1, 2, -2, -2, -3, -3, 3, -3];function f(s, e) {    var re ...

  7. 关于对象存入NSUserDefaults

    #import <Foundation/Foundation.h> @interface Student : NSObject <NSCoding> @property (no ...

  8. C#字符串转INT

    Convent.ToInt32(string ) 可以转化字符串   其他 * .tostring();   (int ) char //强制类型转换 不能转化字符串

  9. Xcode-App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.

    在xcode中上报数据时候,logserver一直没有数据,后来发现控制台有一个提示: 找了半天是因为Xcode7禁止明码的HTTP请求,而自己使用的是Xcode7.2.1 解决办法:修改info.p ...

  10. (转)提高代码质量---one

    1. 摘要 这是烂代码系列的第二篇,在文章中我会跟大家讨论一下如何尽可能高效和客观的评价代码的优劣. 在发布了关于烂代码的那些事(上)之后,发现这篇文章竟然意外的很受欢迎,很多人也描(tu)述(cao ...