搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
木道寻08
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
零基础5分钟上手亚马逊云科技AWS核心云架构知识-用S3桶托管静态网页
2
五大AI绘画神器:Midjourney、Stable Diffusion、DALL·E 3、文心_dall·e 3 部署
3
k8s 攻击面
4
Pytorch 中计算Flops和Params_flops, params = profile(model, inputs=(input, )
5
ClickHouse 基础(一)_clickhouse arm
6
Linux- 源码软件包安装_linux 离线安装bc
7
web2.0 详解_2001年秋天互联网公司(dot-com)泡沫的破灭是互联网的一个转折点。许多人断定互联
8
数字IC/FPGA——锁存器/触发器/寄存器_钟控rs触发器
9
数据处理(一)数据清洗_如果要按内逻辑清洗数据
10
Vue中使用animate.css_vue使用animate.css
当前位置:
article
> 正文
duilib把ZIP皮肤编译进EXE_duilib skin编译进去
作者:木道寻08 | 2024-08-07 14:01:51
赞
踩
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
推荐阅读
article
网易
Duilib
:
功能
全面的开源桌面
UI
开发
框架
_
duilib
跨平台...
01
网易
Duilib
框架
概述
Duilib
是 Windows 系统下的开源的 Direct
UI
界面库(遵循 BS...
赞
踩
article
C++
:使用
DuiLib
开发
一个
简易
的
登录
功能_
duilib
的
用法...
使用
DuiLib
开发
一个
简易
的
登录
功能_
duilib
的
用法
duilib
的
用法 ...
赞
踩
article
Duilib
的
简单使用(
一
、
duilib
demo
)...
一
、前言MFC做出来
的
界面有点接受不了
的
丑,想要做好看还要搞什么第三方界面库,所以找个第三方
的
duilib
开源界面库来尝...
赞
踩
article
DUILIB
-编译
ZIP
皮肤到程序中_
duilib
getskinfile
() 例子
csdn
博客...
为了防止客户随意的修改皮肤文件或则可以的去隐藏资源,可以把皮肤文件打包为
ZIP
编译到程序中。虽说不能阻止牛掰软件的自由提...
赞
踩
article
正确
编译
DuiLib
静态
库的方法_
duilib
多
字节
版本
...
使用
DuiLib
做过一个非常小的项目,当时因为没有研究清楚如何
编译
为
静态
库遂使用了
DuiLib
.dll 的动态库来...
赞
踩
article
正确
编译
Duilib
静态
库的方法_
duilib
静态
编译
...
本文详细介绍了如何正确
编译
Duilib
静态
库,并提供了Windows项目中所需的头文件包含、预处理器设置、代码生成选项、...
赞
踩
相关标签
前端
duilib
window
c++
login
界面设计