天天看點

在DLL中使用duilib,并把ZIP皮膚編譯進DLL中

轉自: 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