轉自: http://www.duilibcn.com/ziliao/240.html
在DLL中使用duilib,并把ZIP皮膚編譯進DLL中 很顯然,本文說明的目的是在DLL中使用duilib,并把ZIP皮膚編譯進DLL中去。 首先你應該能建立一個在DLL中使用duilib的工程并且編譯成功,而且duilib也應該是 靜态編譯的,這樣最後生成的DLL才不會依賴其他無關的DLL和檔案。 這裡我隻列出來關鍵代碼,具體的代碼可以在最後面的下載下傳位址中找到。 class CMainWindow : public WindowImplBase 首先主窗體內建自WindowImplBase,并且不需要實作GetResourceID和GetResourceType, 否則加載DLL時程式會崩潰,謹記。 resource.h中定義ZIP檔案的ID #define IDR_SKIN1 10001 app.rc檔案中定義ZIP的類型為SKIN,這裡千萬不要定義成ZIPRES。 IDR_SKIN1 SKIN "skin.zip" 下面列出main.cpp關鍵實作代碼 #define EXPORT_API __declspec(dllexport) 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) { ::MessageBoxA(NULL,"hRsrc iS NULL","Fail",0); 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); } extern "C" void EXPORT_API ShowDuiWindow() { HMODULE h = ::GetModuleHandleW(0); CPaintManagerUI::SetInstance(h); HMODULE hDll = ::GetModuleHandleW(L"untitled100.dll"); DWORD iLength = g_func_GetResourceDataLength(hDll,IDR_SKIN1,L"SKIN"); if(iLength > 0) { char* pData = (char*)malloc(iLength); memset(pData,0,iLength); g_func_GetResourceData(hDll,IDR_SKIN1,L"SKIN",pData,iLength); CPaintManagerUI::SetResourceZip(pData,iLength); } else { ::MessageBoxA(NULL,"Load Skin fail zip in rc size is 0","fail",0); } CMainWindow* pFrame = new CMainWindow(L"skin",L"CMainWindow.xml"); pFrame->Create(NULL,L" 你好 DuiLib",UI_WNDSTYLE_FRAME,WS_EX_WINDOWEDGE); pFrame->CenterWindow(); pFrame->ShowModal(); } 關鍵代碼分析 HMODULE h = ::GetModuleHandleW(0); CPaintManagerUI::SetInstance(h); 設定執行個體句柄為主EXE的 HMODULE hDll = ::GetModuleHandleW(L"untitled100.dll"); DWORD iLength = g_func_GetResourceDataLength(hDll,IDR_SKIN1,L"SKIN"); if(iLength > 0) { char* pData = (char*)malloc(iLength); memset(pData,0,iLength); g_func_GetResourceData(hDll,IDR_SKIN1,L"SKIN",pData,iLength); CPaintManagerUI::SetResourceZip(pData,iLength); } else { ::MessageBoxA(NULL,"Load Skin fail zip in rc size is 0","fail",0); } g_func_GetResourceDataLength 和g_func_GetResourceData擷取了rc中的ZIp資料 CPaintManagerUI::SetResourceZip(pData,iLength);則是把資料填充到了duilib需要的内容中去。 HMODULE hDll = ::GetModuleHandleW(L"untitled100.dll");則是提供擷取rc資料時所需的DLL句柄 untitled100.dll是生成的DLL名稱。 這樣一來,就可以用duilib生成一個單一的DLL供其他程式調用了。 事實上duicreator 1.1.1已經包含了這個工程的模闆。
源碼下載下傳:http://download.csdn.net/detail/hats8888/9358159