duilib使用源码编译动态库静态库

duilib编译教程-visual studio 2013 professional版本

首先下载duilib源码准备进行编译,源码地址:https://github.com/duilib/duilib

duilib编译动态库

下载源码以后解压,直接使用vs2013打开DuiLib.vcxproj项目,然后检查平台工具集,project-properties选择本机已安装的工具集和对应的编码。
20230215152757
然后选择build-build solution完成编译

duilib编译静态库

静态库要自己手动改一些东西。官方的项目目录下有一个DuiLib_Static.vcxproj文件,这就是静态库的配置文件,但是其缺少一个DuiLib_Static.vcxproj.filters的描述文件。
不过没关系,我们复制一份 DuiLib.vcxproj.filters 然后改名为DuiLib_Static.vcxproj.filters就可以用了,后缀为.filters的文件主要作用就是描述项目在 VS 开发环境中的目录结构信息,LIB 和 DLL 的目录结构是一样的,所以用一个文件不同名字即可。复制以后如下
20230215153923
然后同样使用vs2013打开DuiLib_Static.vcxproj,然后检查平台工具集,project-properties选择本机已安装的工具集和对应的直接编码。
然后还有一步骤,需要对比一下动态库的项目和静态库的项目,发现静态库的 Utils 缺少一个 WndShadow.h 和 WndShadow.cpp文件,我们给静态库工程导入这两个文件就可以了。不然后面用到的时候会提示没有导出这里面的相关功能。
20230215035020
如果需要编译Unicode编码在Configuration Manager选择UnicodeDebug或者UnicodeRelease即可
20230215160533

新建Duilib项目

直接点击file-new-project选择Win32 Project输入项目名称,然后点击OK,在向导里勾选ATL,点击完成。
20230215164725
然后把Duilib文件夹移入新建的工程目录下
20230215174018
转到vs2013,鼠标选中当前工程鼠标右键-add-existing project,选择刚才的Duilib目录,选择DuiLib_Static.vcxproj,添加进工程,然后别忘记添加WndShadow.h 和 WndShadow.cpp文件,然后选择项目属性,检查平台工具集,成功之后工程结构是这样的。
20230215173726
确认能够编译duilib工程之后就可以在主工程下写代码了。

在主工程下主文件添加代码

Hello.cpp

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Hello.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "Hello.h"
#include "..\DuiLib\UIlib.h"

using namespace DuiLib;

#ifdef _DEBUG
# ifdef _UNICODE
# pragma comment(lib, "..\\DuiLib\\Build\\Debug_u\\DuiLib_Static_ud.lib")
# else
# pragma comment(lib, "..\\DuiLib\\Build\\Debug\\DuiLib_Static_d.lib")
# endif
#else
# ifdef _UNICODE
# pragma comment(lib, "..\\DuiLib\\Build\\Release_u\\DuiLib_u.lib")
# else
# pragma comment(lib, "..\\DuiLib\\Build\\Release\\DuiLib.lib")
# endif
#endif

class CDuiFrameWnd : public WindowImplBase
{
public:
virtual void InitWindow()
{
m_pMinBtn = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(TEXT("btn_wnd_min")));
m_pMaxBtn = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(TEXT("btn_wnd_max")));
m_pRestoreBtn = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(TEXT("btn_wnd_restore")));
m_pCloseBtn = dynamic_cast<CButtonUI*>(m_PaintManager.FindControl(TEXT("btn_wnd_close")));
}
virtual void Notify(TNotifyUI& msg)
{
if (msg.sType == DUI_MSGTYPE_CLICK)
{
CDuiString strName = msg.pSender->GetName();
if (strName == TEXT("btn_wnd_min"))
{
SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
}
else if (strName == TEXT("btn_wnd_max"))
{
SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
}
else if (strName == TEXT("btn_wnd_restore"))
{
SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
}
else if (strName == TEXT("btn_wnd_close"))
{
SendMessage(WM_SYSCOMMAND, SC_CLOSE, 0);
}
}
__super::Notify(msg);
}
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if ((uMsg == WM_KEYDOWN) && (wParam == VK_ESCAPE))
{
return TRUE;
}
return __super::HandleMessage(uMsg, wParam, lParam);
}
virtual LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
BOOL bZoomed = IsZoomed(*this);
LRESULT lRes = CWindowWnd::HandleMessage(uMsg, wParam, lParam);
// 切换最大化按钮和还原按钮的状态
if (IsZoomed(*this) != bZoomed)
{
m_pMaxBtn->SetVisible(TRUE == bZoomed);
m_pRestoreBtn->SetVisible(FALSE == bZoomed);
}
return lRes;
}
virtual LPCTSTR GetWindowClassName() const { return TEXT("DUIMainFrame"); }
virtual CDuiString GetSkinFile() { return TEXT("duilib.xml"); }
virtual CDuiString GetSkinFolder() { return TEXT(""); }
virtual LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (uMsg == WM_CLOSE)
{
PostQuitMessage(0L);
}
return __super::OnClose(uMsg, wParam, lParam, bHandled);
}

private:
CButtonUI* m_pMinBtn = nullptr;
CButtonUI* m_pMaxBtn = nullptr;
CButtonUI* m_pRestoreBtn = nullptr;
CButtonUI* m_pCloseBtn = nullptr;
};

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

CPaintManagerUI::SetInstance(hInstance);
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());

CDuiFrameWnd duiFrame;
duiFrame.Create(NULL, TEXT("DUIWnd"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
duiFrame.InitWindow();
duiFrame.CenterWindow();
duiFrame.ShowModal();
return 0;
}

新建duilib.xml文件放在生成的exe目录下

duilib.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<Window size="500,300" mininfo="256,64" caption="0,0,0,64" sizebox="10,4,10,10" roundcorner="16,16">
<Font shared="true" id="1" name="微软雅黑" size="18"></Font>
<VerticalLayout>
<!-- 标题栏 -->
<HorizontalLayout height="64" bkcolor="#FFD3D3D3" inset="8,8,8,0">
<HorizontalLayout width="128">
<Label text="main" height="24" padding="8" font="1"></Label>
</HorizontalLayout>
<Control></Control>
<HorizontalLayout childpadding="3" width="80">
<Button name="btn_wnd_min" height="24" width="24" bkcolor="#FF00FF00" hotbkcolor="#FF00DD00" borderround="24,24"></Button>
<Button name="btn_wnd_max" height="24" width="24" bkcolor="#FFFFEE00" hotbkcolor="#FFFFCC00" borderround="24,24"></Button>
<Button name="btn_wnd_restore" height="24" width="24" bkcolor="#FFFFFF00" hotbkcolor="#FFFFDD00" borderround="24,24" visible="false"></Button>
<Button name="btn_wnd_close" height="24" width="24" bkcolor="#FFFF0000" hotbkcolor="#FFDD0000" borderround="24,24"></Button>
</HorizontalLayout>
</HorizontalLayout>
<!-- 窗口内容区域 -->
<HorizontalLayout bkcolor="#FFFFFFFF">
</HorizontalLayout>
</VerticalLayout>
</Window>

在主工程下stdafx.h文件添加代码

在此之前编译会报错,如下所示

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
1>Hello.obj : warning LNK4217: locally defined symbol ??0CDuiString@DuiLib@@QAE@PB_WH@Z (public: __thiscall DuiLib::CDuiString::CDuiString(wchar_t const *,int)) imported in function "public: virtual class DuiLib::CDuiString __thiscall CDuiFrameWnd::GetSkinFile(void)" (?GetSkinFile@CDuiFrameWnd@@UAE?AVCDuiString@DuiLib@@XZ)
1>Hello.obj : warning LNK4217: locally defined symbol ??1CDuiString@DuiLib@@QAE@XZ (public: __thiscall DuiLib::CDuiString::~CDuiString(void)) imported in function "public: virtual void __thiscall CDuiFrameWnd::Notify(struct DuiLib::tagTNotifyUI &)" (?Notify@CDuiFrameWnd@@UAEXAAUtagTNotifyUI@DuiLib@@@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ??BCDuiString@DuiLib@@QBEPB_WXZ (public: __thiscall DuiLib::CDuiString::operator wchar_t const *(void)const ) imported in function _wWinMain@16
1>Hello.obj : warning LNK4217: locally defined symbol ??8CDuiString@DuiLib@@QBE_NPB_W@Z (public: bool __thiscall DuiLib::CDuiString::operator==(wchar_t const *)const ) imported in function "public: virtual void __thiscall CDuiFrameWnd::Notify(struct DuiLib::tagTNotifyUI &)" (?Notify@CDuiFrameWnd@@UAEXAAUtagTNotifyUI@DuiLib@@@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ?GetPaintWindow@CPaintManagerUI@DuiLib@@QBEPAUHWND__@@XZ (public: struct HWND__ * __thiscall DuiLib::CPaintManagerUI::GetPaintWindow(void)const ) imported in function "public: virtual class DuiLib::CControlUI * __thiscall CDuiFrameWnd::CreateControl(wchar_t const *)" (?CreateControl@CDuiFrameWnd@@UAEPAVCControlUI@DuiLib@@PB_W@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ?GetInstancePath@CPaintManagerUI@DuiLib@@SA?AVCDuiString@2@XZ (public: static class DuiLib::CDuiString __cdecl DuiLib::CPaintManagerUI::GetInstancePath(void)) imported in function _wWinMain@16
1>Hello.obj : warning LNK4217: locally defined symbol ?SetInstance@CPaintManagerUI@DuiLib@@SAXPAUHINSTANCE__@@@Z (public: static void __cdecl DuiLib::CPaintManagerUI::SetInstance(struct HINSTANCE__ *)) imported in function _wWinMain@16
1>Hello.obj : warning LNK4217: locally defined symbol ?SetResourcePath@CPaintManagerUI@DuiLib@@SAXPB_W@Z (public: static void __cdecl DuiLib::CPaintManagerUI::SetResourcePath(wchar_t const *)) imported in function _wWinMain@16
1>Hello.obj : warning LNK4217: locally defined symbol ?FindControl@CPaintManagerUI@DuiLib@@QBEPAVCControlUI@2@PB_W@Z (public: class DuiLib::CControlUI * __thiscall DuiLib::CPaintManagerUI::FindControl(wchar_t const *)const ) imported in function "public: virtual void __thiscall CDuiFrameWnd::InitWindow(void)" (?InitWindow@CDuiFrameWnd@@UAEXXZ)
1>Hello.obj : warning LNK4217: locally defined symbol ?GetHWND@CWindowWnd@DuiLib@@QBEPAUHWND__@@XZ (public: struct HWND__ * __thiscall DuiLib::CWindowWnd::GetHWND(void)const ) imported in function "public: virtual void __thiscall CDuiFrameWnd::InitWindow(void)" (?InitWindow@CDuiFrameWnd@@UAEXXZ)
1>Hello.obj : warning LNK4217: locally defined symbol ??BCWindowWnd@DuiLib@@QBEPAUHWND__@@XZ (public: __thiscall DuiLib::CWindowWnd::operator struct HWND__ *(void)const ) imported in function "public: virtual long __thiscall CDuiFrameWnd::OnSysCommand(unsigned int,unsigned int,long,int &)" (?OnSysCommand@CDuiFrameWnd@@UAEJIIJAAH@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ?Create@CWindowWnd@DuiLib@@QAEPAUHWND__@@PAU3@PB_WKKHHHHPAUHMENU__@@@Z (public: struct HWND__ * __thiscall DuiLib::CWindowWnd::Create(struct HWND__ *,wchar_t const *,unsigned long,unsigned long,int,int,int,int,struct HMENU__ *)) imported in function _wWinMain@16
1>Hello.obj : warning LNK4217: locally defined symbol ?ShowModal@CWindowWnd@DuiLib@@QAEIXZ (public: unsigned int __thiscall DuiLib::CWindowWnd::ShowModal(void)) imported in function _wWinMain@16
1>Hello.obj : warning LNK4217: locally defined symbol ?CenterWindow@CWindowWnd@DuiLib@@QAEXXZ (public: void __thiscall DuiLib::CWindowWnd::CenterWindow(void)) imported in function _wWinMain@16
1>Hello.obj : warning LNK4217: locally defined symbol ?SendMessageW@CWindowWnd@DuiLib@@QAEJIIJ@Z (public: long __thiscall DuiLib::CWindowWnd::SendMessageW(unsigned int,unsigned int,long)) imported in function "public: virtual void __thiscall CDuiFrameWnd::Notify(struct DuiLib::tagTNotifyUI &)" (?Notify@CDuiFrameWnd@@UAEXAAUtagTNotifyUI@DuiLib@@@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ?HandleMessage@CWindowWnd@DuiLib@@MAEJIIJ@Z (protected: virtual long __thiscall DuiLib::CWindowWnd::HandleMessage(unsigned int,unsigned int,long)) imported in function "public: virtual long __thiscall CDuiFrameWnd::OnSysCommand(unsigned int,unsigned int,long,int &)" (?OnSysCommand@CDuiFrameWnd@@UAEJIIJAAH@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ??0CControlUI@DuiLib@@QAE@XZ (public: __thiscall DuiLib::CControlUI::CControlUI(void)) imported in function "public: __thiscall CWndUI::CWndUI(void)" (??0CWndUI@@QAE@XZ)
1>Hello.obj : warning LNK4217: locally defined symbol ??1CControlUI@DuiLib@@MAE@XZ (protected: virtual __thiscall DuiLib::CControlUI::~CControlUI(void)) imported in function "public: virtual __thiscall CWndUI::~CWndUI(void)" (??1CWndUI@@UAE@XZ)
1>Hello.obj : warning LNK4217: locally defined symbol ?SetPos@CControlUI@DuiLib@@UAEXUtagRECT@@_N@Z (public: virtual void __thiscall DuiLib::CControlUI::SetPos(struct tagRECT,bool)) imported in function "public: virtual void __thiscall CWndUI::SetPos(struct tagRECT)" (?SetPos@CWndUI@@UAEXUtagRECT@@@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ?SetVisible@CControlUI@DuiLib@@UAEX_N@Z (public: virtual void __thiscall DuiLib::CControlUI::SetVisible(bool)) imported in function "public: virtual void __thiscall CWndUI::SetVisible(bool)" (?SetVisible@CWndUI@@UAEX_N@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ?SetInternVisible@CControlUI@DuiLib@@UAEX_N@Z (public: virtual void __thiscall DuiLib::CControlUI::SetInternVisible(bool)) imported in function "public: virtual void __thiscall CWndUI::SetInternVisible(bool)" (?SetInternVisible@CWndUI@@UAEX_N@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ??0CDialogBuilder@DuiLib@@QAE@XZ (public: __thiscall DuiLib::CDialogBuilder::CDialogBuilder(void)) imported in function "public: virtual class DuiLib::CControlUI * __thiscall CDuiFrameWnd::CreateControl(wchar_t const *)" (?CreateControl@CDuiFrameWnd@@UAEPAVCControlUI@DuiLib@@PB_W@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ??1CDialogBuilder@DuiLib@@QAE@XZ (public: __thiscall DuiLib::CDialogBuilder::~CDialogBuilder(void)) imported in function "public: virtual class DuiLib::CControlUI * __thiscall CDuiFrameWnd::CreateControl(wchar_t const *)" (?CreateControl@CDuiFrameWnd@@UAEPAVCControlUI@DuiLib@@PB_W@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ?Notify@WindowImplBase@DuiLib@@UAEXAAUtagTNotifyUI@2@@Z (public: virtual void __thiscall DuiLib::WindowImplBase::Notify(struct DuiLib::tagTNotifyUI &)) imported in function "public: virtual void __thiscall CDuiFrameWnd::Notify(struct DuiLib::tagTNotifyUI &)" (?Notify@CDuiFrameWnd@@UAEXAAUtagTNotifyUI@DuiLib@@@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ?CreateControl@WindowImplBase@DuiLib@@UAEPAVCControlUI@2@PB_W@Z (public: virtual class DuiLib::CControlUI * __thiscall DuiLib::WindowImplBase::CreateControl(wchar_t const *)) imported in function "public: virtual class DuiLib::CControlUI * __thiscall CDuiFrameWnd::CreateControl(wchar_t const *)" (?CreateControl@CDuiFrameWnd@@UAEPAVCControlUI@DuiLib@@PB_W@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ?OnClose@WindowImplBase@DuiLib@@UAEJIIJAAH@Z (public: virtual long __thiscall DuiLib::WindowImplBase::OnClose(unsigned int,unsigned int,long,int &)) imported in function "public: virtual long __thiscall CDuiFrameWnd::OnClose(unsigned int,unsigned int,long,int &)" (?OnClose@CDuiFrameWnd@@UAEJIIJAAH@Z)
1>Hello.obj : warning LNK4217: locally defined symbol ?HandleMessage@WindowImplBase@DuiLib@@UAEJIIJ@Z (public: virtual long __thiscall DuiLib::WindowImplBase::HandleMessage(unsigned int,unsigned int,long)) imported in function "public: virtual long __thiscall CDuiFrameWnd::HandleMessage(unsigned int,unsigned int,long)" (?HandleMessage@CDuiFrameWnd@@UAEJIIJ@Z)
1>Hello.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall DuiLib::WindowImplBase::WindowImplBase(void)" (__imp_??0WindowImplBase@DuiLib@@QAE@XZ) referenced in function "public: __thiscall CDuiFrameWnd::CDuiFrameWnd(void)" (??0CDuiFrameWnd@@QAE@XZ)
1>Hello.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall DuiLib::WindowImplBase::~WindowImplBase(void)" (__imp_??1WindowImplBase@DuiLib@@UAE@XZ) referenced in function "public: virtual __thiscall CDuiFrameWnd::~CDuiFrameWnd(void)" (??1CDuiFrameWnd@@UAE@XZ)
1>D:\Code\AUtils\Hello\Debug\Hello.exe : fatal error LNK1120: 2 unresolved externals

很明显,程序不知道到哪里去找我们用到的这些函数,换句话说还没告诉程序要用 DuiLib 的动态库还是静态库,这个好解决。如果你想使用动态库,那么首先保证 EXE 目录下有动态库的文件,其次在项目的 属性->C/C++->预处理器 中增加 UILIB_EXPORTS 的预定义宏,这是告诉 DuiLib 你需要把我们用到的接口按动态库的方式导出。其实搜索一下 UILIB_EXPORTS 就可以看到具体的定义了。
如果你想使用静态库,同样,定义一个 UILIB_STATIC 的预定义宏然后在项目 属性->连接器->输入 中,输入附加依赖库的 lib 文件名字就可以啦。当你定义完预定义宏后再次编译就可以编译通过了,运行程序后窗口就显示出来了。
下面我使用的时静态库,只需要在stdafx.h文件中最后一行添加以下宏定义即可。

1
#define UILIB_STATIC

运行结果:
20230215170504

Author: chacebai
Link: http://www.spyhex.com/2023/duilib使用源码编译动态库静态库/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.