• SOUI入门


    环境: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
    View Code

    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
    View Code

    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
    View Code

    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[0], path.length());
        path.resize(dw);
    
        path = path.substr(0, 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"), 1);
                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(), 0))  {
                SASSERT(false);
            }
        }
        else if (res == RES_PE) {
            if (!resProvider->Init((WPARAM)hInstance, 0)) {
                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, 0);
        }
        return sysResProvider;
    }
    View Code

    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
    View Code

    SouiWindow.cpp

    #include "SouiWindow.h"
    
    void SouiWindow::create(SouiWindow* window /*= NULL*/)
    {
        HWND parent = window ? window->m_hWnd : NULL;
        SHostWnd::Create(parent, 0, 0);
        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 0;
    }
    
    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 0;
    }
    View Code

    接下来就是如何使用了,首先编写窗口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);
    View Code

    最后的界面显示为:

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

    我们可以在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。

  • 相关阅读:
    windows下phpunit installing[转]
    一个简单的文件后缀获取——不是通过文件名,而是文件内容
    二进制加法
    收藏一个韩国棒子的未知高度居中方法
    带超时+POST/GET方式的获取远程文件,利用file_get_contents
    较深度地递归转义过滤
    利用单元测试在每个层上对 PHP 代码进行检查[转IBM]
    提取TP的一个格式化为json的针对的原始类型函数
    分享一个正则方式的UTF8/GBK中文切割
    NewBaldwinFlash的登场(稍简单的DNN模块)
  • 原文地址:https://www.cnblogs.com/dongc/p/5225063.html
Copyright © 2020-2023  润新知