ResourceImport.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:12k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // ResourceImport.cpp: implementation of the CResourceImport class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "ResourceImport.h"
  6. #include "ResourceExport.h"
  7. //////////////////////////////////////////////////////////////////////
  8. // Construction/Destruction
  9. //////////////////////////////////////////////////////////////////////
  10. CResourceImport::CResourceImport()
  11. {
  12. m_pResources = NULL;
  13. m_bDelete = TRUE;
  14. }
  15. CResourceImport::~CResourceImport()
  16. {
  17. if (m_bDelete)
  18. {
  19. SAFE_DELETE(m_pResources);
  20. }
  21. }
  22. #pragma pack(push, 1)
  23. typedef struct
  24. {
  25. WORD dlgVer;
  26. WORD signature;
  27. DWORD helpID;
  28. DWORD exStyle;
  29. DWORD style;
  30. WORD cDlgItems;
  31. short x;
  32. short y;
  33. short cx;
  34. short cy;
  35. } DLGTEMPLATEEX;
  36. typedef struct
  37. {
  38. DWORD helpID;
  39. DWORD exStyle;
  40. DWORD style;
  41. short x;
  42. short y;
  43. short cx;
  44. short cy;
  45. DWORD id;
  46. } DLGITEMTEMPLATEEX;
  47. #pragma pack(pop)
  48. AFX_INLINE int REPLACEW_S(LPWSTR strReplace, LPCWSTR lpszOld, LPCWSTR lpszNew)
  49. {
  50. int nOldLength = (strReplace == NULL) ? 0 : (int)wcslen(strReplace);
  51. int nSourceLen = (lpszOld == NULL) ? 0 : (int)wcslen(lpszOld);
  52. if (nSourceLen == 0 || nOldLength == 0)
  53. return 0;
  54. int nReplacementLen = (lpszNew == NULL) ? 0 : (int)wcslen(lpszNew);
  55. // loop once to figure out the size of the result string
  56. int nCount = 0;
  57. LPWSTR lpszStart = strReplace;
  58. LPWSTR lpszTarget;
  59. while ((lpszTarget = wcsstr(lpszStart, lpszOld)) != NULL)
  60. {
  61. nCount++;
  62. lpszStart = lpszTarget + nSourceLen;
  63. }
  64. // if any changes were made, make them
  65. if (nCount > 0)
  66. {
  67. int nNewLength = nOldLength + (nReplacementLen-nSourceLen)*nCount;
  68. //ASSERT(nNewLength <= nOldLength); // not implemented
  69. lpszStart = strReplace;
  70. // loop again to actually do the work
  71. while ((lpszTarget = wcsstr(lpszStart, lpszOld)) != NULL)
  72. {
  73. int nBalance = nOldLength - int(lpszTarget - strReplace + nSourceLen);
  74. MEMMOVE_S(lpszTarget + nReplacementLen, lpszTarget + nSourceLen,
  75. nBalance * sizeof(WORD));
  76. MEMCPY_S(lpszTarget, lpszNew, nReplacementLen*sizeof(WORD));
  77. lpszStart = lpszTarget + nReplacementLen;
  78. lpszStart[nBalance] = '';
  79. nOldLength += (nReplacementLen - nSourceLen);
  80. }
  81. ASSERT(strReplace[nNewLength] == '');
  82. }
  83. return nCount;
  84. }
  85. void PreformatString(LPWSTR strValue)
  86. {
  87. REPLACEW_S(strValue, L"\", L"\\");
  88. REPLACEW_S(strValue, L"n", L"\n");
  89. REPLACEW_S(strValue, L"r", L"\r");
  90. REPLACEW_S(strValue, L"t", L"\t");
  91. }
  92. AFX_INLINE ULONG_PTR AlignDWord(ULONG_PTR uLong)  {  return ((uLong + 3) & ~3); }
  93. void PX_StringW(CXTPPropExchange* pPX, LPCTSTR pszPropName, LPWSTR str, LPWSTR lpDefault = 0)
  94. {
  95. if (!str || str[0] == 0)
  96. return;
  97. WORD dwLength = (WORD)wcslen(str);
  98. LPWSTR lpwString = new WCHAR[(dwLength + 1) * 2 * 2];
  99. memcpy(lpwString, str, (dwLength + 1) * 2);
  100. PreformatString(lpwString);
  101. BSTR bstrValue = (BSTR)lpwString;
  102. PX_Bstr(pPX, pszPropName, bstrValue, (BSTR)lpDefault);
  103. delete[] lpwString;
  104. }
  105. void PutDialogTemplate(CXTPPropExchange* pPX, DLGTEMPLATE* pTemplate)
  106. {
  107. DLGTEMPLATEEX* pTemplateEx = (DLGTEMPLATEEX*)pTemplate;
  108. BOOL bTemplateEx = pTemplateEx->signature == 0xFFFF;
  109. int style, styleex, x, y, cx, cy, id;
  110. LPWORD pItems;
  111. if (bTemplateEx)
  112. {
  113. style = pTemplateEx->style;
  114. styleex = pTemplateEx->exStyle;
  115. x = pTemplateEx->x;
  116. y = pTemplateEx->y;
  117. cx = pTemplateEx->cx;
  118. cy = pTemplateEx->cy;
  119. pItems = (LPWORD)((LPBYTE)pTemplate + sizeof(DLGTEMPLATEEX));
  120. }
  121. else
  122. {
  123. style = pTemplate->style;
  124. styleex = pTemplate->dwExtendedStyle;
  125. x = pTemplate->x;
  126. y = pTemplate->y;
  127. cx = pTemplate->cx;
  128. cy = pTemplate->cy;
  129. pItems = (LPWORD)((LPBYTE)pTemplate + sizeof(DLGTEMPLATE));
  130. }
  131. ASSERT(*pItems == 0);
  132. ASSERT(*(pItems + 1) == 0);
  133. pItems += 2;
  134. if (pItems)
  135. {
  136. PX_StringW(pPX, _T("caption"), (LPWSTR)pItems);
  137. pItems += wcslen((LPWSTR)pItems);
  138. }
  139. pItems += 1;
  140. if (style & DS_SETFONT)
  141. {
  142. int nHeight = *pItems;
  143. PX_Int(pPX, _T("fontsize"), nHeight, 8);
  144. pItems += bTemplateEx? 3: 1;
  145. PX_StringW(pPX, _T("fontface"), (LPWSTR)pItems, L"MS Sans Serif");
  146. pItems += wcslen((LPWSTR)pItems) + 1;
  147. }
  148. CString strPos;
  149. strPos.Format(_T("%i, %i, %i, %i"), x, y, cx, cy);
  150. PX_Int(pPX, _T("style"), style);
  151. PX_Int(pPX, _T("styleex"), styleex, 0);
  152. PX_String(pPX, _T("position"), strPos);
  153. pItems = LPWORD((LPBYTE)pTemplate + AlignDWord((LPBYTE)pItems - (LPBYTE)pTemplate));
  154. CXTPPropExchangeEnumeratorPtr secControl(pPX->GetEnumerator(_T("control")));
  155. POSITION pos = secControl->GetPosition(32000);
  156. int nCount = bTemplateEx? pTemplateEx->cDlgItems:  pTemplate->cdit;
  157. for (int i = 0; i < nCount; i++)
  158. {
  159. DLGITEMTEMPLATE* pItemTemplate = (DLGITEMTEMPLATE*)pItems;
  160. DLGITEMTEMPLATEEX* pItemTemplateEx = (DLGITEMTEMPLATEEX*)pItems;
  161. CXTPPropExchangeSection sec(secControl->GetNext(pos));
  162. if (bTemplateEx)
  163. {
  164. style = pItemTemplateEx->style;
  165. styleex = pItemTemplateEx->exStyle;
  166. x = pItemTemplateEx->x;
  167. y = pItemTemplateEx->y;
  168. cx = pItemTemplateEx->cx;
  169. cy = pItemTemplateEx->cy;
  170. id = pItemTemplateEx->id;
  171. pItems = LPWORD((LPBYTE)pItemTemplate + sizeof(DLGITEMTEMPLATEEX));
  172. }
  173. else
  174. {
  175. style = pItemTemplate->style;
  176. styleex = pItemTemplate->dwExtendedStyle;
  177. x = pItemTemplate->x;
  178. y = pItemTemplate->y;
  179. cx = pItemTemplate->cx;
  180. cy = pItemTemplate->cy;
  181. id = pItemTemplate->id;
  182. pItems = LPWORD((LPBYTE)pItemTemplate + sizeof(DLGITEMTEMPLATE));
  183. }
  184. CString strPos;
  185. strPos.Format(_T("%i, %i, %i, %i"), x, y, cx, cy);
  186. if (id == 65535 || id == -1) id = 0;
  187. PX_Int(&sec, _T("id"), id, 0);
  188. CString strClass;
  189. if (*pItems == 0xFFFF)
  190. {
  191. switch (*(pItems + 1))
  192. {
  193. case 0x0080: strClass = _T("BUTTON"); break;
  194. case 0x0081: strClass = _T("EDIT"); break;
  195. case 0x0082: strClass = _T("STATIC"); break;
  196. case 0x0083: strClass = _T("LISTBOX"); break;
  197. case 0x0084: strClass = _T("SCROLLBAR"); break;
  198. case 0x0085: strClass = _T("COMBOBOX"); break;
  199. }
  200. pItems += 2;
  201. }
  202. else
  203. {
  204. strClass  = (LPWSTR)pItems;
  205. pItems += strClass.GetLength() + 1;
  206. }
  207. PX_String(&sec, _T("class"), strClass, _T("STATIC"));
  208. if (*pItems == 0xFFFF)
  209. {
  210. int nResource = *(pItems + 1);
  211. PX_Int(&sec, _T("resource"), nResource);
  212. pItems += 2;
  213. }
  214. else
  215. {
  216. PX_StringW(&sec, _T("caption"), (LPWSTR)pItems);
  217. pItems += wcslen((LPWSTR)pItems) + 1;
  218. }
  219. PX_Int(&sec, _T("style"), style, WS_CHILD | WS_VISIBLE | WS_GROUP);
  220. PX_Int(&sec, _T("styleex"), styleex, 0);
  221. PX_String(&sec, _T("position"), strPos);
  222. ASSERT(*pItems == 0);
  223. pItems += 1;
  224. pItems = LPWORD((LPBYTE)pItemTemplate + AlignDWord((LPBYTE)pItems - (LPBYTE)pItemTemplate));
  225. }
  226. }
  227. void PutMenuItems(CXTPPropExchange* pPX, MENUITEMTEMPLATE*& pItem)
  228. {
  229. CXTPPropExchangeEnumeratorPtr secMenuItem(pPX->GetEnumerator(_T("menuitem")));
  230. POSITION posMenuItem = secMenuItem->GetPosition(32000);
  231. while (TRUE)
  232. {
  233. CXTPPropExchangeSection sec(secMenuItem->GetNext(posMenuItem));
  234. BOOL bPopup = (pItem->mtOption & MF_POPUP) != 0;
  235. BOOL bEnd = (pItem->mtOption & MF_END) != 0;
  236. int nID = !bPopup? (int)pItem->mtID: 0;
  237. PX_Int(&sec, _T("id"), nID, 0);
  238. int nCaptionSize = (int)wcslen(bPopup? pItem->mtString - 1: pItem->mtString);
  239. WCHAR* pCaption = !bPopup? pItem->mtString: (WCHAR*)&pItem->mtID;
  240. if (pCaption)
  241. {
  242. PX_StringW(&sec, _T("caption"), pCaption);
  243. }
  244. pItem = (MENUITEMTEMPLATE*)((LPBYTE)pItem + (pItem->mtOption & MF_POPUP? sizeof(WORD) * 2: sizeof(WORD) * 3) + (nCaptionSize) * 2);
  245. if (bPopup)
  246. {
  247. PutMenuItems(&sec, pItem);
  248. }
  249. if (bEnd) break;
  250. }
  251. }
  252. struct PROPEXCHANGEENUM
  253. {
  254. CXTPPropExchangeEnumerator* pEnumerator;
  255. POSITION pos;
  256. }; 
  257. BOOL CALLBACK EnumResStringProc(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam)
  258. {
  259. PROPEXCHANGEENUM* pxEnum = (PROPEXCHANGEENUM*)lParam;
  260. ASSERT(pxEnum);
  261. if (!pxEnum)
  262. return FALSE;
  263. HRSRC hRsrc = FindResource(hModule, lpszName, lpszType);
  264. if (!hRsrc)
  265. return FALSE;
  266. HGLOBAL hRsrcData = LoadResource(hModule, hRsrc);
  267. LPWSTR lpszData = (LPWSTR)LockResource(hRsrcData);
  268. for (int i = 0; i < 16; i++)
  269. {
  270. if (*lpszData)
  271. {
  272. CXTPPropExchangeSection sec(pxEnum->pEnumerator->GetNext(pxEnum->pos));
  273. WORD dwLength = *lpszData;
  274. LPWSTR lpwString = new WCHAR[(dwLength + 1) * 2 * 2];
  275. memcpy(lpwString, lpszData + 1, dwLength * 2);
  276. lpwString[dwLength] = 0;
  277. PreformatString(lpwString);
  278. BSTR bstrString = (BSTR)lpwString;
  279. int nResource = (((UINT)(UINT_PTR)lpszName - 1) * 16 + i);
  280. PX_Int(&sec, _T("id"), nResource);
  281. PX_Bstr(&sec, _T("value"), bstrString, 0);
  282. delete[] lpwString;
  283. lpszData = lpszData + dwLength + 1;
  284. }
  285. else
  286. {
  287. lpszData += 1;
  288. }
  289. }
  290. return TRUE;
  291. }
  292. void ConvertStrings(HMODULE hModule, CXTPPropExchange* pPX)
  293. {
  294. PROPEXCHANGEENUM pxenum;
  295. pxenum.pEnumerator = pPX->GetEnumerator(_T("string"));
  296. pxenum.pos = pxenum.pEnumerator->GetPosition(32000);
  297. ::EnumResourceNames(hModule, RT_STRING, &EnumResStringProc, (LONG_PTR)&pxenum);
  298. delete pxenum.pEnumerator;
  299. }
  300. BOOL CALLBACK EnumResMenuProc(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam)
  301. {
  302. PROPEXCHANGEENUM* pxEnum = (PROPEXCHANGEENUM*)lParam;
  303. ASSERT(pxEnum);
  304. if (!pxEnum)
  305. return FALSE;
  306. HRSRC hRsrc = FindResource(hModule, lpszName, lpszType);
  307. if (!hRsrc)
  308. return FALSE;
  309. HGLOBAL hRsrcData = LoadResource(hModule, hRsrc);
  310. LPBYTE lpszData = (LPBYTE)LockResource(hRsrcData);
  311. CXTPPropExchangeSection sec(pxEnum->pEnumerator->GetNext(pxEnum->pos));
  312. int nResource = (UINT)(UINT_PTR)lpszName;
  313. PX_Int(&sec, _T("id"), nResource);
  314. lpszData += 4;
  315. MENUITEMTEMPLATE* pItem = (MENUITEMTEMPLATE*)lpszData;
  316. PutMenuItems(&sec, pItem);
  317. return TRUE;
  318. }
  319. void ConvertMenus(HMODULE hModule, CXTPPropExchange* pPX)
  320. {
  321. PROPEXCHANGEENUM pxenum;
  322. pxenum.pEnumerator = pPX->GetEnumerator(_T("menu"));
  323. pxenum.pos = pxenum.pEnumerator->GetPosition(32000);
  324. ::EnumResourceNames(hModule, RT_MENU, &EnumResMenuProc, (LONG_PTR)&pxenum);
  325. delete pxenum.pEnumerator;
  326. }
  327. BOOL CALLBACK EnumResDialogProc(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam)
  328. {
  329. PROPEXCHANGEENUM* pxEnum = (PROPEXCHANGEENUM*)lParam;
  330. ASSERT(pxEnum);
  331. if (!pxEnum)
  332. return FALSE;
  333. HRSRC hRsrc = FindResource(hModule, lpszName, lpszType);
  334. if (!hRsrc)
  335. return FALSE;
  336. HGLOBAL hRsrcData = LoadResource(hModule, hRsrc);
  337. LPBYTE lpszData = (LPBYTE)LockResource(hRsrcData);
  338. CXTPPropExchangeSection sec(pxEnum->pEnumerator->GetNext(pxEnum->pos));
  339. int nResource = (UINT)(UINT_PTR)lpszName;
  340. PX_Int(&sec, _T("id"), nResource);
  341. DLGTEMPLATE* pItem = (DLGTEMPLATE*)lpszData;
  342. PutDialogTemplate(&sec, pItem);
  343. return TRUE;
  344. }
  345. void ConvertDialogs(HMODULE hModule, CXTPPropExchange* pPX)
  346. {
  347. PROPEXCHANGEENUM pxenum;
  348. pxenum.pEnumerator = pPX->GetEnumerator(_T("dialog"));
  349. pxenum.pos = pxenum.pEnumerator->GetPosition(32000);
  350. ::EnumResourceNames(hModule, RT_DIALOG, &EnumResDialogProc, (LONG_PTR)&pxenum);
  351. delete pxenum.pEnumerator;
  352. }
  353. BOOL CResourceImport::Import(LPCTSTR lpszFileName)
  354. {
  355. HMODULE hModule =  LoadLibrary(lpszFileName);
  356. if (!hModule)
  357. return FALSE;
  358. m_pResources = new CXTPPropExchangeXMLNode(FALSE, 0, _T("resource"));
  359. if (!m_pResources->OnBeforeExchange())
  360. return FALSE;
  361. long wLanguage = CXTPResourceManager::GetResourceLanguage(hModule);
  362. if (wLanguage == 0)
  363. return FALSE;
  364. XTP_RESOURCEMANAGER_LANGINFO* lan = CXTPResourceManager::GetLanguageInfo(wLanguage);
  365. if (!lan)
  366. return FALSE;
  367. m_pResources->SetEncoding(lan->lpszEncoding);
  368. CString strCaption(lan->lpszCaption);
  369. PX_String(m_pResources, _T("Language"), strCaption);
  370. PX_Long(m_pResources, _T("LANGID"), wLanguage);
  371. ConvertStrings(hModule, m_pResources);
  372. ConvertMenus(hModule, m_pResources);
  373. ConvertDialogs(hModule, m_pResources);
  374. FreeLibrary(hModule);
  375. return TRUE;
  376. }