当前位置:   article > 正文

duilib把ZIP皮肤编译进EXE_duilib skin编译进去

duilib skin编译进去
duilib的皮肤界面用的是XML和图片资源,发布duilib时需要带上XML和图片文件夹,
但是这样容易被别人修改,幸好duilib提供了一个函数
void CPaintManagerUI::SetResourceZip(LPCTSTR pStrPath, bool bCachedResourceZip);
利用这个静态函数,可以把XML和图片资源压缩成一个zip包来供duilib使用。
但是这样仍然不是最好的解决方案,因为我们的程序有时候只是一个EXE程序,或则只是提供一个
使用duilib的DLL供别的程序调用,那么就有必要把所用到的皮肤文件放到EXE中去了,
duilib提供了一个函数来做这个事情
void CPaintManagerUI::SetResourceZip(LPVOID pVoid, unsigned int len);
这个函数同样是静态函数,pVoid代表zip的数据,len是数据的长度,来实践一下吧。
先建立一个头文件 CMainWindow.h
 
#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H
 
#include <Windows.h>
#include <objbase.h>
#include <UIlib.h>
using namespace DuiLib;
 
class CMainWindow : public WindowImplBase
{
public:
    CMainWindow(const CDuiString& sUiFolderName,const CDuiString& sUiFileName);
 
    virtual ~CMainWindow();
 
    void setWindowTitle(const CDuiString& sTitle);
    CLabelUI* m_titleLabel;
 
protected:
    virtual LPCTSTR GetWindowClassName() const;
 
    virtual CDuiString GetSkinFile();
 
    virtual void InitWindow();
    virtual CDuiString GetSkinFolder();
 
    void OnFinalMessage(HWND hwnd);
 
    virtual CControlUI* CreateControl(LPCTSTR pstrClass);
    void Notify(TNotifyUI& msg);
 
private:
    CDuiString m_uiFileName;
    CDuiString m_uiFolderName;
 
    CButtonUI* m_minBtn;
    CButtonUI* m_maxBtn;
    CButtonUI* m_restoreBtn;
    CButtonUI* m_closeBtn;
};
#endif // CMAINWINDOW_H
然后是源文件 CMainWindow.cpp
#include "CMainWindow.h"
 
CMainWindow::CMainWindow(const CDuiString& sUiFolderName,const CDuiString& sUiFileName)
    : WindowImplBase(),
      m_uiFolderName(sUiFolderName),
      m_uiFileName(sUiFileName)
{
    m_titleLabel = NULL;
    m_minBtn = NULL;
    m_maxBtn = NULL;
    m_closeBtn = NULL;
    m_restoreBtn = NULL;
}
 
CMainWindow::~CMainWindow()
{
 
}
 
 
CControlUI* CMainWindow::CreateControl(LPCTSTR pstrClass)
{
    //    if(_tcsicmp(pstrClass, L"Your custom clsss name") == 0)
    //    {
    //    }
    return NULL;
}
 
void CMainWindow::OnFinalMessage(HWND hwnd)
{
    delete this;
}
 
LPCTSTR CMainWindow::GetWindowClassName() const
{
    return L"CMainWindow";
}
 
CDuiString CMainWindow::GetSkinFile()
{
    return m_uiFolderName+CDuiString(L"\\")+m_uiFileName;
}
 
CDuiString CMainWindow::GetSkinFolder()
{
    return m_uiFolderName;
}
 
void CMainWindow::setWindowTitle(const CDuiString& sTitle)
{
    if(m_titleLabel)
    {
        m_titleLabel->SetText(sTitle.GetData());
    }
}
 
void CMainWindow::InitWindow()
{
    CControlUI* pControlTitleLabel = m_PaintManager.FindControl(L"apptitle");
    if(pControlTitleLabel)
    {
        m_titleLabel = static_cast<CLabelUI*>(pControlTitleLabel);
        WCHAR sTitle[500];
        memset(sTitle,0,sizeof(WCHAR)*500);
        ::GetWindowTextW(this->m_hWnd,sTitle,500);
        this->setWindowTitle(CDuiString(sTitle));
    }
 
    CControlUI* pControlMin = m_PaintManager.FindControl(L"minbtn");
    if(pControlMin)
        m_minBtn = static_cast<CButtonUI*>(pControlMin);
 
    CControlUI* pControlMax = m_PaintManager.FindControl(L"maxbtn");
    if(pControlMax)
        m_maxBtn = static_cast<CButtonUI*>(pControlMax);
 
    CControlUI* pControlRestore = m_PaintManager.FindControl(L"restorebtn");
    if(pControlRestore)
        m_restoreBtn = static_cast<CButtonUI*>(pControlRestore);
 
    CControlUI*  pControlClose = m_PaintManager.FindControl(L"closebtn");
    if(pControlClose)
        m_closeBtn = static_cast<CButtonUI*>(pControlClose);
}
 
 
void CMainWindow::Notify(TNotifyUI &msg)
{
    if(msg.sType == DUI_MSGTYPE_CLICK)
    {
        //(*
        if(msg.pSender == m_minBtn)
        {this->SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, NULL);}
        if(msg.pSender == m_maxBtn)
        {this->SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, NULL);}
        if(msg.pSender == m_restoreBtn)
        {this->SendMessage(WM_SYSCOMMAND, SC_RESTORE, NULL);}
        if(msg.pSender == m_closeBtn)
        {::PostQuitMessage(0L);}
        //*)
 
        if(msg.pSender->GetName() == L"button1")
        {
            ::MessageBoxW(NULL,L"你好 DuiLib",L"ok",MB_OK);
        }
    }
}
然后是resource.h定义资源类型
#ifndef RESOURCE
#define RESOURCE
#define IDR_SKIN1   10001
#endif // RESOURCE
 
定义一个ID为IDR_SKIN1的SKIN文件
要为这个EXE程序定义一个资源文件,好把ZIP文件添加进去,就叫app.rc吧
#include "winver.h"
#include "resource.h"
 
IDI_ICON1               ICON    DISCARDABLE     "app.ico"
 
IDR_SKIN1               SKIN                     "skin.zip"
 
VS_VERSION_INFO VERSIONINFO
 FILEVERSION 1,0,0,1
 PRODUCTVERSION 1,0,0,1
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x40004L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "080404B0"
        BEGIN
            VALUE "CompanyName", "duilibcn.com"
            VALUE "FileDescription", "DuiLib App"
            VALUE "FileVersion", "1.0.0.1"
            VALUE "InternalName", ""
            VALUE "LegalCopyright", "DuiLibcn.com"
            VALUE "OriginalFilename", ""
            VALUE "ProductName", "DuiLib App"
            VALUE "ProductVersion", "1.0.0.1"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x804, 1200
    END
END
下面就是关键的main.cpp函数了,看如何把zip编译进EXE吧
#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_SEPRECATE
 
#include "resource.h"
#include "cmainwindow.h"
 
 
DWORD g_func_GetResourceDataLength(HINSTANCE hInstance,
                             UINT dwResourceId,
                             const WCHAR* sResourceType)
{
    if(hInstance == NULL)
        return 0;
 
    HRSRC hRsrc = FindResourceW(hInstance,MAKEINTRESOURCEW(dwResourceId), sResourceType);
    if(!hRsrc)
    {
        return 0;
    }
    DWORD dwResSize = SizeofResource(hInstance,hRsrc);
    FreeResource(hRsrc);
    return dwResSize;
}
 
void g_func_GetResourceData(HINSTANCE hInstance,
                            UINT dwResourceId,
                            const WCHAR* sResourceType,
                            char* pRetData,
                            DWORD pRetLength)
{
    if(hInstance == NULL)
        return;
 
    HRSRC hRsrc = FindResourceW(hInstance,MAKEINTRESOURCEW(dwResourceId),sResourceType);
    if(!hRsrc)
    {
        return;
    }
 
    HGLOBAL hGlobal = (char*)LoadResource(hInstance,hRsrc);
 
    char* pData = (char*)LockResource(hGlobal);
    memcpy(pRetData,pData,pRetLength);
 
    FreeResource(hRsrc);
}
 
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    CPaintManagerUI::SetInstance(hInstance);
    CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());
 
    DWORD iLength = g_func_GetResourceDataLength(hInstance,IDR_SKIN1,L"SKIN");
    if(iLength > 0)
    {
        char* pData = (char*)malloc(iLength);
        memset(pData,0,iLength);
        g_func_GetResourceData(hInstance,IDR_SKIN1,L"SKIN",pData,iLength);
 
        CPaintManagerUI::SetResourceZip(pData,iLength);
free(pData);
    }
    else
    {
        ::MessageBoxA(NULL,"Load Skin fail zip in rc size is 0","fail",0);
        return 0;
    }
 
 
    CMainWindow* pFrame = new CMainWindow(L"skin",L"CMainWindow.xml");
 
    pFrame->Create(NULL,L" 你好 DuiLib",UI_WNDSTYLE_FRAME,WS_EX_WINDOWEDGE);
    pFrame->CenterWindow();
    pFrame->ShowWindow();
 
    CPaintManagerUI::MessageLoop();
    delete pFrame;
    return 0;
}
 
首先用g_func_GetResourceDataLength获取RC内ZIP文件的长度,然后
用g_func_GetResourceData来填充ZIP数据,最后用
CPaintManagerUI::SetResourceZip(pData,iLength);来设置ZIP资源数据,这个是关键。
但是这样以后我发现了一个问题,右上角的自定义按钮图片不见了,不知道是路径问题还是duilib的BUG,
如果直接用路径的方式加载ZIP文件倒是能显示。
工程和编译后的EXE可以在这里下载http://download.csdn.net/detail/hats8888/9346953
可以用DuiCreator/QtCreator编译,或则自己用cl.exe编译也行。
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/942886
推荐阅读
  

闽ICP备14008679号