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
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 }
好了,就這樣了