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

对话框与窗口

开发平台:

Visual C++

  1. // ResourceExport.cpp: implementation of the CResourceExport class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "ResourceExport.h"
  6. #include "ResourceViewRecord.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. class CBufferFile  : public CMemFile
  13. {
  14. public:
  15. CBufferFile(int nFileSize = 120000)
  16. : CMemFile(nFileSize)
  17. {
  18. }
  19. public:
  20. LPBYTE GetBuffer() {
  21. return m_lpBuffer + GetPosition();
  22. }
  23. LPBYTE GetBufferHeader() {
  24. return m_lpBuffer;
  25. }
  26. };
  27. #pragma pack(push, 1)
  28. typedef struct
  29. {
  30. WORD dlgVer;
  31. WORD signature;
  32. DWORD helpID;
  33. DWORD exStyle;
  34. DWORD style;
  35. WORD cDlgItems;
  36. short x;
  37. short y;
  38. short cx;
  39. short cy;
  40. } DLLDLGTEMPLATEEX;
  41. typedef struct
  42. {
  43. DWORD helpID;
  44. DWORD exStyle;
  45. DWORD style;
  46. short x;
  47. short y;
  48. short cx;
  49. short cy;
  50. DWORD id;
  51. } DLLDLGITEMTEMPLATEEX;
  52. #pragma pack(pop)
  53. struct DIRECTORY;
  54. typedef CArray<DIRECTORY*, DIRECTORY*> CArrayDirectories;
  55. struct DIRECTORY
  56. {
  57. DIRECTORY()
  58. {
  59. nID  = 0;
  60. nResourceOffset = 0;
  61. lpFatEntry = 0;
  62. lpFatDataEntry = 0;
  63. pResource = NULL;
  64. }
  65. ~DIRECTORY()
  66. {
  67. for (int i = 0; i < arrDirs.GetSize(); i++)
  68. {
  69. delete arrDirs[i];
  70. }
  71. if (pResource)
  72. delete pResource;
  73. }
  74. int GetNumberOfIdEntries()
  75. {
  76. return (int)arrDirs.GetSize() - GetNumberOfNamedEntries();
  77. }
  78. int GetNumberOfNamedEntries()
  79. {
  80. int nCount = 0;
  81. for (int i = 0; i < arrDirs.GetSize(); i++)
  82. {
  83. if (!arrDirs[i]->strName.IsEmpty())
  84. {
  85. nCount++;
  86. }
  87. }
  88. return nCount;
  89. }
  90. DIRECTORY* AddDirectory(CString strSub);
  91. DIRECTORY* AddDirectory(int nSub);
  92. CString strName;
  93. CString strResource;
  94. int nID;
  95. int nResourceOffset;
  96. CBufferFile* pResource;
  97. PIMAGE_RESOURCE_DIRECTORY_ENTRY lpFatEntry;
  98. PIMAGE_RESOURCE_DATA_ENTRY lpFatDataEntry;
  99. CArrayDirectories arrDirs;
  100. };
  101. DIRECTORY* DIRECTORY::AddDirectory(CString strSub)
  102. {
  103. int i;
  104. for (i = 0; i < arrDirs.GetSize(); i++)
  105. {
  106. if (arrDirs[i]->strName.IsEmpty())
  107. break;
  108. if (arrDirs[i]->strName == strSub)
  109. {
  110. return arrDirs[i];
  111. }
  112. if (arrDirs[i]->strName > strSub)
  113. {
  114. break;
  115. }
  116. }
  117. DIRECTORY* pType = new DIRECTORY();
  118. pType->strName = strSub;
  119. arrDirs.InsertAt(i, pType);
  120. return pType;
  121. }
  122. DIRECTORY* DIRECTORY::AddDirectory(int nSub)
  123. {
  124. int i;
  125. for (i = 0; i <arrDirs.GetSize(); i++)
  126. {
  127. if (arrDirs[i]->nID == nSub)
  128. {
  129. return arrDirs[i];
  130. }
  131. if (arrDirs[i]->nID > nSub)
  132. {
  133. break;
  134. }
  135. }
  136. DIRECTORY* pType = new DIRECTORY();
  137. pType->nID = nSub;
  138. arrDirs.InsertAt(i, pType);
  139. return pType;
  140. }
  141. DIRECTORY* AddDirectory(DIRECTORY* pRootDir, CString strType, CString strResourceName, UINT nLocale = 0x409)
  142. {
  143. DIRECTORY* pType = pRootDir->AddDirectory(strType);
  144. DIRECTORY* pResName = pType->AddDirectory(strResourceName);
  145. DIRECTORY* pEntry = pResName->AddDirectory(nLocale);
  146. return pEntry;
  147. }
  148. DIRECTORY* AddDirectory(DIRECTORY* pRootDir, int nID, CString strResourceName, UINT nLocale = 0x409)
  149. {
  150. DIRECTORY* pType = pRootDir->AddDirectory(nID);
  151. DIRECTORY* pResName = pType->AddDirectory(strResourceName);
  152. DIRECTORY* pEntry = pResName->AddDirectory(nLocale);
  153. return pEntry;
  154. }
  155. DIRECTORY* AddDirectory(DIRECTORY* pRootDir, int nID, int nResourceName, UINT nLocale = 0x409)
  156. {
  157. DIRECTORY* pType = pRootDir->AddDirectory(nID);
  158. DIRECTORY* pResName = pType->AddDirectory(nResourceName);
  159. DIRECTORY* pEntry = pResName->AddDirectory(nLocale);
  160. return pEntry;
  161. }
  162. void WriteFAT(CBufferFile* lpFAT, DIRECTORY* pDirectory, CArrayDirectories* pDataDirs)
  163. {
  164. IMAGE_RESOURCE_DIRECTORY dir;
  165. ZeroMemory(&dir, sizeof(IMAGE_RESOURCE_DIRECTORY));
  166. dir.NumberOfIdEntries = (WORD)pDirectory->GetNumberOfIdEntries();
  167. dir.NumberOfNamedEntries = (WORD)pDirectory->GetNumberOfNamedEntries();
  168. lpFAT->Write(&dir, sizeof(IMAGE_RESOURCE_DIRECTORY));
  169. int i;
  170. for (i = 0; i < pDirectory->arrDirs.GetSize(); i++)
  171. {
  172. IMAGE_RESOURCE_DIRECTORY_ENTRY entry;
  173. ZeroMemory(&entry, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
  174. DIRECTORY* pSubDir = pDirectory->arrDirs[i];
  175. if (pSubDir->arrDirs.GetSize() > 0)
  176. {
  177. entry.DataIsDirectory = 1;
  178. }
  179. if (pSubDir->strName.IsEmpty())
  180. {
  181. entry.Id = (WORD)pSubDir->nID;
  182. }
  183. else
  184. {
  185. entry.NameIsString = 1;
  186. }
  187. pSubDir->lpFatEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)lpFAT->GetBuffer();
  188. lpFAT->Write(&entry, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
  189. }
  190. for (i = 0; i < pDirectory->arrDirs.GetSize(); i++)
  191. {
  192. DIRECTORY* pSubDir = pDirectory->arrDirs[i];
  193. PIMAGE_RESOURCE_DIRECTORY_ENTRY lpEntry = pSubDir->lpFatEntry;
  194. if (pSubDir->arrDirs.GetSize() > 0)
  195. {
  196. lpEntry->OffsetToDirectory = lpFAT->GetPosition();
  197. WriteFAT(lpFAT, pSubDir, pDataDirs);
  198. }
  199. else
  200. {
  201. lpEntry->OffsetToData = (DWORD)lpFAT->GetPosition();
  202. IMAGE_RESOURCE_DATA_ENTRY data;
  203. ZeroMemory(&data, sizeof(IMAGE_RESOURCE_DATA_ENTRY));
  204. pSubDir->lpFatDataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)lpFAT->GetBuffer();
  205. lpFAT->Write(&data, sizeof(IMAGE_RESOURCE_DATA_ENTRY));
  206. pDataDirs->Add(pSubDir);
  207. }
  208. }
  209. }
  210. void WriteFATNames(CBufferFile* lpFAT, DIRECTORY* pDirectory)
  211. {
  212. USES_CONVERSION;
  213. int i;
  214. for (i = 0; i < pDirectory->arrDirs.GetSize(); i++)
  215. {
  216. DIRECTORY* pSubDir = pDirectory->arrDirs[i];
  217. if (!pSubDir->strName.IsEmpty())
  218. {
  219. PIMAGE_RESOURCE_DIRECTORY_ENTRY lpEntry = pSubDir->lpFatEntry;
  220. lpEntry->NameOffset = lpFAT->GetPosition();
  221. WORD Length = (WORD)pSubDir->strName.GetLength();
  222. lpFAT->Write(&Length, sizeof(Length));
  223. LPCWSTR lpw = T2W((LPTSTR)(LPCTSTR)pSubDir->strName);
  224. lpFAT->Write(lpw, (pSubDir->strName.GetLength()) * sizeof(WCHAR));
  225. }
  226. }
  227. for (i = 0; i < pDirectory->arrDirs.GetSize(); i++)
  228. {
  229. DIRECTORY* pSubDir = pDirectory->arrDirs[i];
  230. if (pSubDir->arrDirs.GetSize() > 0)
  231. {
  232. WriteFATNames(lpFAT, pSubDir);
  233. }
  234. }
  235. }
  236. //////////////////////////////////////////////////////////////////////
  237. // Construction/Destruction
  238. //////////////////////////////////////////////////////////////////////
  239. CResourceExport::CResourceExport()
  240. {
  241. m_pResources = NULL;
  242. m_pLanguageInfo = 0;
  243. }
  244. CResourceExport::~CResourceExport()
  245. {
  246. }
  247. struct STRINGTABLE
  248. {
  249. STRINGTABLE()
  250. {
  251. ZeroMemory(m_bstr, sizeof(m_bstr));
  252. }
  253. ~STRINGTABLE()
  254. {
  255. for (int i = 0; i < 16; i++)
  256. {
  257. if (m_bstr[i])
  258. {
  259. SysFreeString(m_bstr[i]);
  260. }
  261. }
  262. }
  263. BSTR m_bstr[16];
  264. };
  265. void CResourceExport::ExportDllMenuItems(CMemFile* pFile, CXTPPropExchange* pResourceMenu)
  266. {
  267. CXTPPropExchangeEnumeratorPtr ptrEnumeratorStrings(pResourceMenu->GetEnumerator(_T("menuitem")));
  268. POSITION pos = ptrEnumeratorStrings->GetPosition();
  269. while (pos)
  270. {
  271. CXTPPropExchangeSection ptrSectionMenuItem(ptrEnumeratorStrings->GetNext(pos));
  272. DWORD dwId = 0;
  273. PX_DWord(&ptrSectionMenuItem, _T("id"), dwId);
  274. BSTR bstrValue = 0;
  275. PX_Bstr(&ptrSectionMenuItem, _T("caption"), bstrValue, 0);
  276. BOOL bPopup = (((CXTPPropExchangeXMLNode*)&ptrSectionMenuItem)->IsSectionExists(_T("menuitem")));
  277. WORD mtOption = 0, mtID = 0;
  278. if (bPopup)
  279. mtOption |= MF_POPUP;
  280. if (!pos)
  281. mtOption |= MF_END;
  282. if (!bPopup && dwId == 0)
  283. mtOption |= MF_SEPARATOR;
  284. pFile->Write(&mtOption, sizeof(WORD));
  285. mtID = (WORD)dwId;
  286. if (!bPopup)
  287. pFile->Write(&mtID, sizeof(WORD));
  288. LPCWSTR lpDispalyName = (LPCWSTR)bstrValue;
  289. WORD wLength = 0;
  290. if (lpDispalyName)
  291. {
  292. wLength = (WORD)wcslen(lpDispalyName);
  293. pFile->Write(lpDispalyName, (1 + wLength) * sizeof(WCHAR));
  294. }
  295. else
  296. {
  297. pFile->Write(&wLength, sizeof(WCHAR));
  298. }
  299. if (bstrValue)
  300. {
  301. SysFreeString(bstrValue);
  302. }
  303. if (bPopup)
  304. {
  305. ExportDllMenuItems(pFile, &ptrSectionMenuItem);
  306. }
  307. }
  308. }
  309. AFX_INLINE DWORD AlignDWord(DWORD uLong)  {  return ((uLong + 3) & ~3); }
  310. void CResourceExport::ExportDllMenus(DIRECTORY* pRoot)
  311. {
  312. CXTPPropExchangeEnumeratorPtr ptrEnumeratorMenus(m_pResources->GetEnumerator(_T("menu")));
  313. POSITION pos = ptrEnumeratorMenus->GetPosition();
  314. while (pos)
  315. {
  316. CXTPPropExchangeSection ptrSection(ptrEnumeratorMenus->GetNext(pos));
  317. DWORD dwId = 0;
  318. PX_DWord(&ptrSection, _T("id"), dwId);
  319. if (dwId == 0)
  320. continue;
  321. DIRECTORY* pDirectory = AddDirectory(pRoot, (WORD)(DWORD_PTR)RT_MENU, dwId, m_pLanguageInfo->wLanguage);
  322. CBufferFile* pFile = pDirectory->pResource = new CBufferFile(10000);
  323. WORD wVerison = 0;
  324. WORD wOffset = 0;
  325. pFile->Write(&wVerison, sizeof(WORD));
  326. pFile->Write(&wOffset, sizeof(WORD));
  327. ExportDllMenuItems(pFile, &ptrSection);
  328. AlignFile(pFile, 0);
  329. }
  330. }
  331. int CResourceExport::GetDialogControlsCount(CXTPPropExchange* pResourceDialog)
  332. {
  333. CXTPPropExchangeEnumeratorPtr ptrEnumerator(pResourceDialog->GetEnumerator(_T("control")));
  334. POSITION pos = ptrEnumerator->GetPosition();
  335. int nCount = 0;
  336. while (pos)
  337. {
  338. CXTPPropExchangeSection ptrSection(ptrEnumerator->GetNext(pos));
  339. nCount++;
  340. }
  341. return nCount;
  342. }
  343. void CResourceExport::AlignFile(CMemFile* pFile, DWORD dwPosition)
  344. {
  345. DWORD dwAlign = 0;
  346. DWORD dwSize = DWORD(pFile->GetPosition() - dwPosition);
  347. DWORD dwBytes = AlignDWord(dwSize) - dwSize;
  348. ASSERT(dwBytes >= 0 && dwBytes < 4);
  349. pFile->Write(&dwAlign, dwBytes);
  350. }
  351. void CResourceExport::ExportDllDialogControls(CMemFile* pFile, CXTPPropExchange* pResourceDialog)
  352. {
  353. USES_CONVERSION;
  354. CXTPPropExchangeEnumeratorPtr ptrEnumerator(pResourceDialog->GetEnumerator(_T("control")));
  355. POSITION pos = ptrEnumerator->GetPosition();
  356. while (pos)
  357. {
  358. CXTPPropExchangeSection ptrSection(ptrEnumerator->GetNext(pos));
  359. DLLDLGITEMTEMPLATEEX templ;
  360. ZeroMemory(&templ, sizeof(DLLDLGITEMTEMPLATEEX));
  361. WORD dwEmpty = 0;
  362. DWORD dwPosition = (DWORD)pFile->GetPosition();
  363. RECT rcPos = {0, 0, 0, 0};
  364. PX_Rect(&ptrSection, _T("position"), rcPos, rcPos);
  365. templ.x = (short)rcPos.left;
  366. templ.y = (short)rcPos.top;
  367. templ.cx = (short)rcPos.right;
  368. templ.cy = (short)rcPos.bottom;
  369. PX_DWord(&ptrSection, _T("style"), templ.style, WS_CHILD | WS_VISIBLE | WS_GROUP);
  370. PX_DWord(&ptrSection, _T("styleex"), templ.exStyle, 0);
  371. int id = 0;
  372. PX_Int(&ptrSection, _T("id"), id, 0);
  373. templ.id = id == 0 ? (DWORD)IDC_STATIC : (DWORD)id;
  374. pFile->Write(&templ, sizeof(DLLDLGITEMTEMPLATEEX));
  375. CString strClass;
  376. PX_String(&ptrSection, _T("class"), strClass, _T("STATIC"));
  377. WORD nClass = 0;
  378. if (strClass == _T("BUTTON")) nClass = 0x0080;
  379. if (strClass == _T("EDIT")) nClass = 0x0081;
  380. if (strClass == _T("STATIC")) nClass = 0x0082;
  381. if (strClass == _T("LISTBOX")) nClass = 0x0083;
  382. if (strClass == _T("SCROLLBAR")) nClass = 0x0084;
  383. if (strClass == _T("COMBOBOX")) nClass = 0x0085;
  384. if (nClass != 0)
  385. {
  386. WORD dwSignature = 0xFFFF;
  387. pFile->Write(&dwSignature, sizeof(WORD));
  388. pFile->Write(&nClass, sizeof(WORD));
  389. }
  390. else
  391. {
  392. pFile->Write(T2CW(strClass), (strClass.GetLength() + 1) * sizeof(WCHAR));
  393. }
  394. int nResource = 0;
  395. BOOL bExists = PX_Int(&ptrSection, _T("resource"), nResource);
  396. if (bExists)
  397. {
  398. WORD dwSignature = 0xFFFF;
  399. WORD dwResource = (WORD)nResource;
  400. pFile->Write(&dwSignature, sizeof(WORD));
  401. pFile->Write(&dwResource, sizeof(WORD));
  402. }
  403. else
  404. {
  405. BSTR bstrValue = 0;
  406. PX_Bstr(&ptrSection, _T("caption"), bstrValue, 0);
  407. if (bstrValue)
  408. {
  409. pFile->Write(bstrValue, (1 + (int)wcslen(bstrValue)) * sizeof(WCHAR));
  410. }
  411. else
  412. {
  413. pFile->Write(&dwEmpty, sizeof(WORD));
  414. }
  415. if (bstrValue)
  416. SysFreeString(bstrValue);
  417. }
  418. pFile->Write(&dwEmpty, sizeof(WORD)); // extraCount;
  419. AlignFile(pFile, dwPosition);
  420. }
  421. }
  422. void CResourceExport::ExportDllDialogs(DIRECTORY* pRoot)
  423. {
  424. USES_CONVERSION;
  425. CXTPPropExchangeEnumeratorPtr ptrEnumeratorDialog(m_pResources->GetEnumerator(_T("dialog")));
  426. POSITION pos = ptrEnumeratorDialog->GetPosition();
  427. while (pos)
  428. {
  429. CXTPPropExchangeSection ptrSection(ptrEnumeratorDialog->GetNext(pos));
  430. DWORD dwId = 0;
  431. PX_DWord(&ptrSection, _T("id"), dwId);
  432. if (dwId == 0)
  433. continue;
  434. DIRECTORY* pDirectory = AddDirectory(pRoot, (WORD)(DWORD_PTR)RT_DIALOG, dwId, m_pLanguageInfo->wLanguage);
  435. CBufferFile* pFile = pDirectory->pResource = new CBufferFile(10000);
  436. DLLDLGTEMPLATEEX templ;
  437. ZeroMemory(&templ, sizeof(DLLDLGTEMPLATEEX));
  438. RECT rcPos = {0, 0, 0, 0};
  439. PX_DWord(&ptrSection, _T("style"), templ.style);
  440. PX_DWord(&ptrSection, _T("styleex"), templ.exStyle, 0);
  441. PX_Rect(&ptrSection, _T("position"), rcPos, rcPos);
  442. templ.dlgVer = 1;
  443. templ.signature = 0xFFFF;
  444. templ.cDlgItems = (WORD)GetDialogControlsCount(&ptrSection);
  445. templ.x = (short)rcPos.left;
  446. templ.y = (short)rcPos.top;
  447. templ.cx = (short)rcPos.right;
  448. templ.cy = (short)rcPos.bottom;
  449. templ.style |= DS_SETFONT;
  450. templ.helpID = dwId;
  451. WORD dwEmpty = 0;
  452. pFile->Write(&templ, sizeof(DLLDLGTEMPLATEEX));
  453. pFile->Write(&dwEmpty, sizeof(WORD));  // menu;
  454. pFile->Write(&dwEmpty, sizeof(WORD));  // windowClass;
  455. BSTR bstrValue = 0;
  456. PX_Bstr(&ptrSection, _T("caption"), bstrValue, 0);
  457. if (bstrValue)
  458. {
  459. pFile->Write(bstrValue, (1 + (int)wcslen(bstrValue)) * sizeof(WCHAR));
  460. }
  461. else
  462. {
  463. pFile->Write(&dwEmpty, sizeof(WORD));
  464. }
  465. if (bstrValue)
  466. SysFreeString(bstrValue);
  467. if (templ.style & DS_SETFONT)
  468. {
  469. int nHeight = 8;
  470. PX_Int(&ptrSection, _T("fontsize"), nHeight, 8);
  471. WORD pointsize = (WORD)nHeight, weight = 0;
  472. BYTE bItalic = 0, charset = 0;
  473. pFile->Write(&pointsize, sizeof(WORD));
  474. pFile->Write(&weight, sizeof(WORD));
  475. pFile->Write(&bItalic, sizeof(BYTE));
  476. pFile->Write(&charset, sizeof(BYTE));
  477. CString strFont;
  478. PX_String(&ptrSection, _T("fontface"), strFont, _T("MS Sans Serif"));
  479. if (!strFont.IsEmpty())
  480. {
  481. pFile->Write(T2CW(strFont), (1 + strFont.GetLength()) * sizeof(WCHAR));
  482. }
  483. else
  484. {
  485. pFile->Write(&dwEmpty, sizeof(WORD));
  486. }
  487. }
  488. AlignFile(pFile, 0);
  489. if (templ.cDlgItems > 0)
  490. {
  491. ExportDllDialogControls(pFile, &ptrSection);
  492. }
  493. }
  494. }
  495. void CResourceExport::ExportDllStringTable(DIRECTORY* pRoot)
  496. {
  497. CMap<UINT, UINT, STRINGTABLE*, STRINGTABLE*> mapStrings;
  498. CXTPPropExchangeEnumeratorPtr ptrEnumeratorStrings(m_pResources->GetEnumerator(_T("string")));
  499. POSITION pos = ptrEnumeratorStrings->GetPosition();
  500. while (pos)
  501. {
  502. CXTPPropExchangeSection ptrSectionString(ptrEnumeratorStrings->GetNext(pos));
  503. BSTR bstrValue = 0;
  504. DWORD dwId = 0;
  505. PX_DWord(&ptrSectionString, _T("id"), dwId);
  506. PX_Bstr(&ptrSectionString, _T("value"), bstrValue, 0);
  507. int IdTable = (dwId >> 4) + 1;
  508. STRINGTABLE* pst = NULL;
  509. if (!mapStrings.Lookup(IdTable, pst))
  510. {
  511. pst = new STRINGTABLE;
  512. mapStrings.SetAt(IdTable, pst);
  513. }
  514. int nIndex = dwId - (((IdTable - 1 ) << 4));
  515. ASSERT(nIndex >= 0 && nIndex < 16);
  516. pst->m_bstr[nIndex] = bstrValue;
  517. }
  518. pos = mapStrings.GetStartPosition();
  519. while (pos)
  520. {
  521. UINT Id;
  522. STRINGTABLE* pst;
  523. mapStrings.GetNextAssoc(pos, Id, pst);
  524. DIRECTORY* pDirectory = AddDirectory(pRoot, (WORD)(DWORD_PTR)RT_STRING, Id, m_pLanguageInfo->wLanguage);
  525. CBufferFile* pFile = pDirectory->pResource = new CBufferFile(10000);
  526. for (int i = 0; i < 16; i++)
  527. {
  528. WORD wLength = 0;
  529. if (pst->m_bstr[i] != 0)
  530. {
  531. LPCWSTR lpDispalyName = (LPCWSTR)pst->m_bstr[i];
  532. wLength = (WORD)wcslen(lpDispalyName);
  533. pFile->Write(&wLength, sizeof(WORD));
  534. pFile->Write(lpDispalyName, wLength * sizeof(WCHAR));
  535. }
  536. else
  537. {
  538. pFile->Write(&wLength, sizeof(WORD));
  539. }
  540. }
  541. AlignFile(pFile, 0);
  542. delete pst;
  543. }
  544. }
  545. void CResourceExport::ExportDll(CXTPPropExchangeXMLNode* pResources, LPCTSTR lpszOutput)
  546. {
  547. m_pResources = pResources;
  548. DWORD nLangId = 0;
  549. PX_DWord(m_pResources, _T("LANGID"), nLangId);
  550. m_pLanguageInfo = CXTPResourceManager::GetLanguageInfo(nLangId);
  551. if (!m_pLanguageInfo)
  552. {
  553. m_pResources = NULL;
  554. return;
  555. }
  556. DIRECTORY* pRoot = new DIRECTORY();
  557. ExportDllStringTable(pRoot);
  558. ExportDllDialogs(pRoot);
  559. ExportDllMenus(pRoot);
  560. CString lpszResourcePath = lpszOutput ? lpszOutput : _T("C:\out.dll");
  561. CFile file;
  562. file.Open(lpszResourcePath, CFile::modeWrite | CFile::modeCreate);
  563. PIMAGE_DOS_HEADER pDosExeHdr = (PIMAGE_DOS_HEADER)(_alloca(512));
  564. {
  565. HRSRC hResource = ::FindResource(::GetModuleHandle(NULL), _T("DOSHEADER"), _T("BIN"));
  566. if (hResource == NULL)
  567. return;
  568. HGLOBAL hGlobal = LoadResource(::GetModuleHandle(NULL), hResource);
  569. if (hGlobal == NULL)
  570. return;
  571. LPBYTE pHeader = (LPBYTE)::LockResource(hGlobal);
  572. memcpy(pDosExeHdr, pHeader, 512);
  573. UnlockResource(hGlobal);
  574. FreeResource(hGlobal);
  575. }
  576. PIMAGE_NT_HEADERS pNTHeader = PIMAGE_NT_HEADERS((LPBYTE)pDosExeHdr + (DWORD) pDosExeHdr->e_lfanew);
  577. CBufferFile FAT;
  578. CArrayDirectories DataDirs;
  579. WriteFAT(&FAT, pRoot, &DataDirs);
  580. WriteFATNames(&FAT, pRoot);
  581. file.Write(pDosExeHdr, 512);
  582. file.Write(FAT.GetBufferHeader(), (UINT)FAT.GetLength());
  583. int nOffset = (int)FAT.GetLength();
  584. for (int i = 0; i < DataDirs.GetSize(); i++)
  585. {
  586. DIRECTORY* pSubDir = DataDirs[i];
  587. if (pSubDir->pResource)
  588. {
  589. DWORD dwSize = (DWORD)pSubDir->pResource->GetLength();
  590. pSubDir->lpFatDataEntry->OffsetToData = nOffset + 0x00001000;
  591. pSubDir->lpFatDataEntry->Size = dwSize;
  592. file.Write(pSubDir->pResource->GetBufferHeader(), dwSize);
  593. nOffset += dwSize;
  594. }
  595. else
  596. {
  597. CFile filebmp;
  598. filebmp.Open(pSubDir->strResource, CFile::modeRead);
  599. DWORD dwSize = (DWORD)((int)filebmp.GetLength() - pSubDir->nResourceOffset);
  600. LPBYTE pBitmapInfo =(LPBYTE) malloc(dwSize);
  601. if (pSubDir->nResourceOffset > 0) filebmp.Seek(pSubDir->nResourceOffset, CFile::begin);
  602. filebmp.Read(pBitmapInfo, dwSize);
  603. filebmp.Close();
  604. pSubDir->lpFatDataEntry->OffsetToData = nOffset + 0x00001000;
  605. pSubDir->lpFatDataEntry->Size = dwSize;
  606. file.Write(pBitmapInfo, dwSize);
  607. free(pBitmapInfo);
  608. nOffset += dwSize;
  609. }
  610. }
  611. int nAdd = 0x1000 - (nOffset & 0xFFF);
  612. LPBYTE lpAlign = (LPBYTE)_alloca(0x200 + nAdd);
  613. ZeroMemory(lpAlign, 0x200 + nAdd);
  614. lpAlign[nAdd + 4] = 0x8;
  615. file.Write(lpAlign, 0x200 + nAdd);
  616. nOffset += nAdd;
  617. PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNTHeader );
  618. pSection->Misc.VirtualSize = nOffset;
  619. pSection->SizeOfRawData = nOffset;
  620. pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = nOffset;
  621. pSection++;
  622. pSection->VirtualAddress = nOffset + 0x1000;
  623. pSection->PointerToRawData = nOffset + 0x200;
  624. pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = nOffset + 0x1000;
  625. pNTHeader->OptionalHeader.SizeOfImage = nOffset + 0x2000;
  626. pNTHeader->OptionalHeader.SizeOfInitializedData = nOffset + 0x200;
  627. file.SeekToBegin();
  628. file.Write(pDosExeHdr, 512);
  629. file.Write(FAT.GetBufferHeader(), (UINT)FAT.GetLength());
  630. file.Close();
  631. delete pRoot;
  632. m_pLanguageInfo= NULL;
  633. m_pResources = NULL;
  634. }
  635. void Replace(LPSTR lpszData, LPCSTR lpszOld, LPCSTR lpszNew)
  636. {
  637. int nSourceLen = (int)strlen(lpszOld);
  638. int nReplacementLen = (int)strlen(lpszNew);
  639. int nOldLength = (int)strlen(lpszData);
  640. LPSTR lpszStart = lpszData;
  641. LPSTR lpszTarget;
  642. while ((lpszTarget = strstr(lpszStart, lpszOld)) != NULL)
  643. {
  644. int nBalance = nOldLength - int(lpszTarget - lpszData + nSourceLen);
  645. memmove(lpszTarget + nReplacementLen, lpszTarget + nSourceLen,
  646. nBalance);
  647. memcpy(lpszTarget, lpszNew, nReplacementLen);
  648. lpszStart = lpszTarget + nReplacementLen;
  649. lpszStart[nBalance] = '';
  650. nOldLength += (nReplacementLen - nSourceLen);
  651. }
  652. }
  653. void WriteString(CFile& file, const CString& str)
  654. {
  655. USES_CONVERSION;
  656. file.Write(T2CA((LPCTSTR)str), str.GetLength());
  657. }
  658. void WriteString(CFile& file, LPSTR str)
  659. {
  660. file.Write(str, (int)strlen(str));
  661. }
  662. void CResourceExport::ExchangeString(CXTPPropExchange* pPX, LPCTSTR pszPropName, LPSTR lpString)
  663. {
  664. BSTR bstrValue = 0;
  665. PX_Bstr(pPX, pszPropName, bstrValue, 0);
  666. ASSERT(!bstrValue || wcslen(bstrValue) < 500);
  667. lpString[0] = 0;
  668. WideCharToMultiByte(m_pLanguageInfo->nCodePage, 0, bstrValue, -1, lpString, 512, 0, 0);
  669. Replace(lpString, "\", "\\");
  670. Replace(lpString, "n", "\n");
  671. Replace(lpString, "r", "\r");
  672. Replace(lpString, "t", "\t");
  673. Replace(lpString, """, """");
  674. SysFreeString(bstrValue);
  675. }
  676. void CResourceExport::ExportRcStringTable(CFile& file)
  677. {
  678. LPCSTR lpszHeader = 
  679. "/////////////////////////////////////////////////////////////////////////////rn"
  680. "//rn"
  681. "// String Tablern"
  682. "//rnrn"
  683. "STRINGTABLErn"
  684. "BEGINrn";
  685. WriteString(file, lpszHeader);
  686. CXTPPropExchangeEnumeratorPtr ptrEnumeratorStrings(m_pResources->GetEnumerator(_T("string")));
  687. POSITION pos = ptrEnumeratorStrings->GetPosition();
  688. while (pos)
  689. {
  690. CXTPPropExchangeSection ptrSectionString(ptrEnumeratorStrings->GetNext(pos));
  691. DWORD dwId = 0;
  692. char lpString[512];
  693. PX_DWord(&ptrSectionString, _T("id"), dwId);
  694. ExchangeString(&ptrSectionString, _T("value"), lpString);
  695. WriteString(file, "    ");
  696. CString strResourceName = GetResourceName(dwId);
  697. WriteString(file, strResourceName);
  698. file.Write("                                  ", max(1, 34 - strResourceName.GetLength()));
  699. WriteString(file, """);
  700. WriteString(file, lpString);
  701. WriteString(file, ""rn");
  702. }
  703. WriteString(file, "ENDrnrn");
  704. };
  705. void CResourceExport::ExportRcMenuItems(CFile& file, DWORD dwParent, CXTPPropExchange* pResourceMenu, const CString& strIndent)
  706. {
  707. CXTPPropExchangeEnumeratorPtr ptrEnumeratorStrings(pResourceMenu->GetEnumerator(_T("menuitem")));
  708. POSITION pos = ptrEnumeratorStrings->GetPosition();
  709. while (pos)
  710. {
  711. CXTPPropExchangeSection ptrSectionMenuItem(ptrEnumeratorStrings->GetNext(pos));
  712. DWORD dwId = 0;
  713. PX_DWord(&ptrSectionMenuItem, _T("id"), dwId);
  714. char lpString[512];
  715. ExchangeString(&ptrSectionMenuItem, _T("caption"), lpString);
  716. if (((CXTPPropExchangeXMLNode*)&ptrSectionMenuItem)->IsSectionExists(_T("menuitem")))
  717. {
  718. WriteString(file, strIndent);
  719. WriteString(file, "POPUP "");
  720. WriteString(file, lpString);
  721. WriteString(file, ""rn");
  722. WriteString(file, strIndent);
  723. WriteString(file, "BEGINrn");
  724. ExportRcMenuItems(file, dwParent, &ptrSectionMenuItem, strIndent + _T("    "));
  725. WriteString(file, strIndent);
  726. WriteString(file, "ENDrn");
  727. }
  728. else if (dwId != 0)
  729. {
  730. WriteString(file, strIndent);
  731. WriteString(file, "MENUITEM "");
  732. WriteString(file, lpString);
  733. WriteString(file, "", ");
  734. CString strResourceName = GetResourceName(dwId, dwParent);
  735. WriteString(file, strResourceName);
  736. WriteString(file, "rn");
  737. }
  738. else
  739. {
  740. WriteString(file, strIndent);
  741. WriteString(file, "MENUITEM SEPARATORrn");
  742. }
  743. }
  744. }
  745. void CResourceExport::ExportRcMenus(CFile& file)
  746. {
  747. LPCSTR lpszHeader = 
  748. "/////////////////////////////////////////////////////////////////////////////rn"
  749. "//rn"
  750. "// Menurn"
  751. "//rnrn";
  752. WriteString(file, lpszHeader);
  753. CXTPPropExchangeEnumeratorPtr ptrEnumeratorStrings(m_pResources->GetEnumerator(_T("menu")));
  754. POSITION pos = ptrEnumeratorStrings->GetPosition();
  755. while (pos)
  756. {
  757. CXTPPropExchangeSection ptrSectionMenu(ptrEnumeratorStrings->GetNext(pos));
  758. DWORD dwId = 0;
  759. PX_DWord(&ptrSectionMenu, _T("id"), dwId);
  760. if (dwId == 0)
  761. continue;
  762. CString strResourceName = GetResourceName(dwId);
  763. CString strMenuHeader; 
  764. strMenuHeader.Format(_T("%s MENU DISCARDABLErnBEGINrn"), (LPCTSTR)strResourceName);
  765. WriteString(file, strMenuHeader);
  766. ExportRcMenuItems(file, dwId, &ptrSectionMenu, _T("    "));
  767. WriteString(file, "ENDrnrn");
  768. }
  769. }
  770. void CResourceExport::ExportRcDialogControls(CFile& file, DWORD dwParent, CXTPPropExchange* pResourceDialog)
  771. {
  772. CXTPPropExchangeEnumeratorPtr ptrEnumeratorStrings(pResourceDialog->GetEnumerator(_T("control")));
  773. POSITION pos = ptrEnumeratorStrings->GetPosition();
  774. while (pos)
  775. {
  776. CXTPPropExchangeSection ptrSectionControl(ptrEnumeratorStrings->GetNext(pos));
  777. DWORD dwId = 0;
  778. DWORD dwStyle = 0, styleex = 0;
  779. RECT rc = {0, 0, 0, 0};
  780. CString strClass;
  781. PX_DWord(&ptrSectionControl, _T("id"), dwId);
  782. PX_DWord(&ptrSectionControl, _T("style"), dwStyle, WS_CHILD | WS_VISIBLE | WS_GROUP);
  783. PX_DWord(&ptrSectionControl, _T("styleex"), styleex, 0);
  784. PX_Rect(&ptrSectionControl, _T("position"), rc, rc);
  785. PX_String(&ptrSectionControl, _T("class"), strClass, _T("STATIC"));
  786. CString strResourceName = dwId == 0 ? _T("IDC_STATIC") :
  787. dwId == 1 ? _T("IDOK") : dwId == 2 ? _T("IDCANCEL") : GetResourceName(dwId, dwParent);
  788. char lpCaption[512];
  789. ExchangeString(&ptrSectionControl, _T("caption"), lpCaption);
  790. LPCSTR strType = NULL;
  791. DWORD dwStyleDefault = (WS_CHILD | WS_VISIBLE | WS_TABSTOP);
  792. DWORD bsStyle = dwStyle & 0xF;
  793. BOOL bAddCaption = TRUE;
  794. if (strClass.CompareNoCase(_T("BUTTON")) == 0)
  795. {
  796. if (bsStyle == BS_DEFPUSHBUTTON) strType = "    DEFPUSHBUTTON   "";
  797. if (bsStyle == BS_PUSHBUTTON)    strType = "    PUSHBUTTON      "";
  798. if (bsStyle == BS_RADIOBUTTON)   strType = "    RADIOBUTTON     "";
  799. if (bsStyle == BS_GROUPBOX) 
  800. {
  801. strType = "    GROUPBOX        "";
  802. dwStyleDefault = (WS_CHILD | WS_VISIBLE);
  803. }
  804. dwStyleDefault += bsStyle;
  805. }
  806. else if (strClass.CompareNoCase(_T("STATIC")) == 0)
  807. {
  808. if (bsStyle == SS_LEFT) strType = "    LTEXT           "";
  809. if (bsStyle == SS_RIGHT)strType = "    RTEXT           "";
  810. dwStyleDefault = (WS_CHILD | WS_VISIBLE | WS_GROUP) + bsStyle;
  811. }
  812. else if (strClass.CompareNoCase(_T("COMBOBOX")) == 0)
  813. {
  814. strType = "    COMBOBOX        ";
  815. bAddCaption = FALSE;
  816. }
  817. else if (strClass.CompareNoCase(_T("LISTBOX")) == 0)
  818. {
  819. strType = "    LISTBOX         ";
  820. bAddCaption = FALSE;
  821. }
  822. else if (strClass.CompareNoCase(_T("EDIT")) == 0)
  823. {
  824. strType = "    EDITTEXT        ";
  825. bAddCaption = FALSE;
  826. }
  827. CString str;
  828. if (strType == NULL)
  829. {
  830. WriteString(file, "    CONTROL         "");
  831. WriteString(file, lpCaption);
  832. str.Format(_T("",%s,"%s",0x%x,%i,%i,%i,%i"), (LPCTSTR)strResourceName, 
  833. (LPCTSTR)strClass, dwStyle, 
  834. rc.left, rc.top, rc.right, rc.bottom);
  835. WriteString(file, str);
  836. }
  837. else
  838. {
  839. WriteString(file, strType);
  840. if (bAddCaption)
  841. {
  842. WriteString(file, lpCaption);
  843. WriteString(file, "",");
  844. }
  845. str.Format(_T("%s,%i,%i,%i,%i"), (LPCTSTR)strResourceName,
  846. rc.left, rc.top, rc.right, rc.bottom);
  847. WriteString(file, str);
  848. if (dwStyle != dwStyleDefault || styleex != 0)
  849. {
  850. str.Format(_T(",0x%x"), dwStyle);
  851. WriteString(file, str);
  852. }
  853. }
  854. if (styleex != 0)
  855. {
  856. str.Format(_T(",0x%x"), styleex);
  857. WriteString(file,str);
  858. }
  859. WriteString(file, "rn");
  860. }
  861. }
  862. void CResourceExport::ExportRcDialogs(CFile& file)
  863. {
  864. LPCSTR lpszHeader = 
  865. "/////////////////////////////////////////////////////////////////////////////rn"
  866. "//rn"
  867. "// Dialogrn"
  868. "//rnrn";
  869. WriteString(file, lpszHeader);
  870. CXTPPropExchangeEnumeratorPtr ptrEnumeratorStrings(m_pResources->GetEnumerator(_T("dialog")));
  871. POSITION pos = ptrEnumeratorStrings->GetPosition();
  872. while (pos)
  873. {
  874. CXTPPropExchangeSection ptrSectionDailog(ptrEnumeratorStrings->GetNext(pos));
  875. DWORD dwId = 0;
  876. DWORD dwStyle = 0, dwExStyle = 0;
  877. RECT rc = {0, 0, 0, 0};
  878. CString strFace;
  879. PX_DWord(&ptrSectionDailog, _T("id"), dwId);
  880. PX_DWord(&ptrSectionDailog, _T("style"), dwStyle);
  881. PX_DWord(&ptrSectionDailog, _T("styleex"), dwExStyle, 0);
  882. PX_Rect(&ptrSectionDailog, _T("position"), rc, rc);
  883. PX_String(&ptrSectionDailog, _T("fontface"), strFace, _T("MS Sans Serif"));
  884. char lpCaption[512];
  885. ExchangeString(&ptrSectionDailog, _T("caption"), lpCaption);
  886. if (dwId == 0)
  887. continue;
  888. CString strResourceName = GetResourceName(dwId);
  889. CString strHeader; 
  890. strHeader.Format(_T("%s DIALOGEX DISCARDABLE %i, %i, %i, %irn"), 
  891. (LPCTSTR)strResourceName, rc.left, rc.top, rc.right, rc.bottom);
  892. WriteString(file, strHeader);
  893. if (dwExStyle != 0)
  894. {
  895. strHeader.Format(_T("EXSTYLE 0x%xrn"), dwExStyle);
  896. WriteString(file, strHeader);
  897. }
  898. strHeader.Format(_T("STYLE 0x%xrn"), dwStyle);
  899. WriteString(file, strHeader);
  900. WriteString(file, "CAPTION ""); WriteString(file, lpCaption); WriteString(file, ""rn");
  901. WriteString(file, "FONT 8, ""); WriteString(file, strFace); WriteString(file, ""rn");
  902. WriteString(file, "BEGINrn");
  903. ExportRcDialogControls(file, dwId, &ptrSectionDailog);
  904. WriteString(file, "ENDrnrn");
  905. }
  906. }
  907. void CResourceExport::ExportRc(CXTPPropExchangeXMLNode* pResources, LPCTSTR lpszOutput)
  908. {
  909. m_pResources = pResources;
  910. CString lpszResourcePath = lpszOutput ? lpszOutput : _T("C:\out.rc");
  911. CFile file;
  912. file.Open(lpszResourcePath, CFile::modeWrite | CFile::modeCreate);
  913. DWORD nLangId = 0;
  914. PX_DWord(m_pResources, _T("LANGID"), nLangId);
  915. m_pLanguageInfo = CXTPResourceManager::GetLanguageInfo(nLangId);
  916. if (!m_pLanguageInfo)
  917. {
  918. WriteString(file, "Not found");
  919. m_pResources = NULL;
  920. return;
  921. }
  922. CString strHeader;
  923. strHeader.Format(
  924. _T("// Codejock ResourceEditor generated resource script.rn")
  925. _T("//rnrn#include "afxres.h"rnrn")
  926. _T("/////////////////////////////////////////////////////////////////////////////rn")
  927. _T("// %s resourcesrnrn")
  928. _T("#if !defined(AFX_RESOURCE_DLL)rn")
  929. _T("#ifdef _WIN32rn")
  930. _T("LANGUAGE %s, %srn")
  931. _T("#pragma code_page(%i)rn")
  932. _T("#endif //_WIN32rnrn"), m_pLanguageInfo->lpszCaption, 
  933. m_pLanguageInfo->lpszLang, m_pLanguageInfo->lpszSubLang, m_pLanguageInfo->nCodePage);
  934. WriteString(file, strHeader);
  935. ExportRcDialogs(file);
  936. ExportRcMenus(file);
  937. ExportRcStringTable(file);
  938. WriteString(file, "#endifrn");
  939. file.Close();
  940. m_pLanguageInfo = NULL;
  941. m_pResources = NULL;
  942. }