duilib给我提供了4中加载资源的方式:
1、直接读xml文件
2、读zip资源压缩包
3、读rc资源
4、读dll中的rc资源
前三种方法比较简单,稍微复杂点的方法3,在demo里面都有。
方法4,其实和方法3差不多,在铅笔君和黎明的马蹄声帮助下,大致搞明白是怎么回事了。
现在就把这个技巧写下来把:
1、制作dll资源包
把资源打包成zip,然后添加资源,资源名为ZIPRES,然后编译成动态库
2、duilib调用dll资源
WindowImplBase已经实现了接口,那我们的窗口就继承WindowImplBase吧。
实现GetResourceID
1
2
3
4
|
LPCTSTR CMyDialog::GetResourceID() const
{
return MAKEINTRESOURCE(104);
}
|
104对应的是dll里面,zip资源的ID
实现GetResourceType
1 UILIB_RESOURCETYPE CMyDialog::GetResourceType() const
2 {
3 return UILIB_ZIPRESOURCE;
4 }
然后再main里面添加
HINSTANCE hDll = ::LoadLibrary(_T("DllResource.dll"));
if (hDll)
{
CPaintManagerUI::SetResourceDll(hDll);
}
好了,我们的窗口就可以调用dll里面的资源了。
这几个方法都在WindowImplBase::OnCreate(...)里面
1 LRESULT WindowImplBase::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
2 {
3 LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
4 styleValue &= ~WS_CAPTION;
5 ::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
6
7 RECT rcClient;
8 ::GetClientRect(*this, &rcClient);
9 ::SetWindowPos(*this, NULL, rcClient.left, rcClient.top, rcClient.right - rcClient.left, \
10 rcClient.bottom - rcClient.top, SWP_FRAMECHANGED);
11
12 m_PaintManager.Init(m_hWnd);
13 m_PaintManager.AddPreMessageFilter(this);
14
15 CDialogBuilder builder;
16 if (m_PaintManager.GetResourcePath().IsEmpty())
17 { // 允许更灵活的资源路径定义
18 CDuiString strResourcePath=m_PaintManager.GetInstancePath();
19 strResourcePath+=GetSkinFolder().GetData();
20 m_PaintManager.SetResourcePath(strResourcePath.GetData());
21 }
22
23 switch(GetResourceType())
24 {
25 case UILIB_ZIP:
26 m_PaintManager.SetResourceZip(GetZIPFileName().GetData(), true);
27 break;
28 case UILIB_ZIPRESOURCE:
29 {
30 HRSRC hResource = ::FindResource(m_PaintManager.GetResourceDll(), GetResourceID(), _T("ZIPRES"));
31 if( hResource == NULL )
32 return 0L;
33 DWORD dwSize = 0;
34 HGLOBAL hGlobal = ::LoadResource(m_PaintManager.GetResourceDll(), hResource);
35 if( hGlobal == NULL )
36 {
37 #if defined(WIN32) && !defined(UNDER_CE)
38 ::FreeResource(hResource);
39 #endif
40 return 0L;
41 }
42 dwSize = ::SizeofResource(m_PaintManager.GetResourceDll(), hResource);
43 if( dwSize == 0 )
44 return 0L;
45 m_lpResourceZIPBuffer = new BYTE[ dwSize ];
46 if (m_lpResourceZIPBuffer != NULL)
47 {
48 ::CopyMemory(m_lpResourceZIPBuffer, (LPBYTE)::LockResource(hGlobal), dwSize);
49 }
50 #if defined(WIN32) && !defined(UNDER_CE)
51 ::FreeResource(hResource);
52 #endif
53 m_PaintManager.SetResourceZip(m_lpResourceZIPBuffer, dwSize);
54 }
55 break;
56 }
57
58 CControlUI* pRoot=NULL;
59 if (GetResourceType()==UILIB_RESOURCE)
60 {
61 STRINGorID xml(_ttoi(GetSkinFile().GetData()));
62 pRoot = builder.Create(xml, _T("xml"), this, &m_PaintManager);
63 }
64 else
65 pRoot = builder.Create(GetSkinFile().GetData(), (UINT)0, this, &m_PaintManager);
66 ASSERT(pRoot);
67 if (pRoot==NULL)
68 {
69 MessageBox(NULL,_T("加载资源文件失败"),_T("Duilib"),MB_OK|MB_ICONERROR);
70 ExitProcess(1);
71 return 0;
72 }
73 m_PaintManager.AttachDialog(pRoot);
74 m_PaintManager.AddNotifier(this);
75
76 InitWindow();
77 return 0;
78 }
好了,就这样了