1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2003-2008 - TortoiseSVN
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
20 #include ".\resmodule.h"
\r
22 #define MYERROR {CUtils::Error(); return FALSE;}
\r
24 CResModule::CResModule(void)
\r
25 : m_bTranslatedStrings(0)
\r
26 , m_bDefaultStrings(0)
\r
27 , m_bTranslatedDialogStrings(0)
\r
28 , m_bDefaultDialogStrings(0)
\r
29 , m_bTranslatedMenuStrings(0)
\r
30 , m_bDefaultMenuStrings(0)
\r
31 , m_bTranslatedAcceleratorStrings(0)
\r
32 , m_bDefaultAcceleratorStrings(0)
\r
35 , m_hUpdateRes(NULL)
\r
41 CResModule::~CResModule(void)
\r
45 BOOL CResModule::ExtractResources(std::vector<std::wstring> filelist, LPCTSTR lpszPOFilePath, BOOL bNoUpdate)
\r
48 for (std::vector<std::wstring>::iterator I = filelist.begin(); I != filelist.end(); ++I)
\r
50 m_hResDll = LoadLibrary(I->c_str());
\r
51 if (m_hResDll == NULL)
\r
54 size_t nEntries = m_StringEntries.size();
\r
55 // fill in the std::map with all translatable entries
\r
58 _ftprintf(stdout, _T("Extracting StringTable...."));
\r
59 EnumResourceNames(m_hResDll, RT_STRING, EnumResNameCallback, (long)this);
\r
61 _ftprintf(stdout, _T("%4d Strings\n"), m_StringEntries.size()-nEntries);
\r
62 nEntries = m_StringEntries.size();
\r
65 _ftprintf(stdout, _T("Extracting Dialogs........"));
\r
66 EnumResourceNames(m_hResDll, RT_DIALOG, EnumResNameCallback, (long)this);
\r
68 _ftprintf(stdout, _T("%4d Strings\n"), m_StringEntries.size()-nEntries);
\r
69 nEntries = m_StringEntries.size();
\r
72 _ftprintf(stdout, _T("Extracting Menus.........."));
\r
73 EnumResourceNames(m_hResDll, RT_MENU, EnumResNameCallback, (long)this);
\r
75 _ftprintf(stdout, _T("%4d Strings\n"), m_StringEntries.size()-nEntries);
\r
76 nEntries = m_StringEntries.size();
\r
78 _ftprintf(stdout, _T("Extracting Accelerators..."));
\r
79 EnumResourceNames(m_hResDll, RT_ACCELERATOR, EnumResNameCallback, (long)this);
\r
81 _ftprintf(stdout, _T("%4d Accelerators\n"), m_StringEntries.size()-nEntries);
\r
82 nEntries = m_StringEntries.size();
\r
84 // parse a probably existing file and update the translations which are
\r
86 m_StringEntries.ParseFile(lpszPOFilePath, !bNoUpdate);
\r
88 FreeLibrary(m_hResDll);
\r
92 // at last, save the new file
\r
94 return m_StringEntries.SaveFile(lpszPOFilePath);
\r
98 BOOL CResModule::ExtractResources(LPCTSTR lpszSrcLangDllPath, LPCTSTR lpszPoFilePath, BOOL bNoUpdate)
\r
100 m_hResDll = LoadLibrary(lpszSrcLangDllPath);
\r
101 if (m_hResDll == NULL)
\r
104 size_t nEntries = 0;
\r
105 // fill in the std::map with all translatable entries
\r
108 _ftprintf(stdout, _T("Extracting StringTable...."));
\r
109 EnumResourceNames(m_hResDll, RT_STRING, EnumResNameCallback, (long)this);
\r
111 _ftprintf(stdout, _T("%4d Strings\n"), m_StringEntries.size());
\r
112 nEntries = m_StringEntries.size();
\r
115 _ftprintf(stdout, _T("Extracting Dialogs........"));
\r
116 EnumResourceNames(m_hResDll, RT_DIALOG, EnumResNameCallback, (long)this);
\r
118 _ftprintf(stdout, _T("%4d Strings\n"), m_StringEntries.size()-nEntries);
\r
119 nEntries = m_StringEntries.size();
\r
122 _ftprintf(stdout, _T("Extracting Menus.........."));
\r
123 EnumResourceNames(m_hResDll, RT_MENU, EnumResNameCallback, (long)this);
\r
125 _ftprintf(stdout, _T("%4d Strings\n"), m_StringEntries.size()-nEntries);
\r
126 nEntries = m_StringEntries.size();
\r
129 _ftprintf(stdout, _T("Extracting Accelerators..."));
\r
130 EnumResourceNames(m_hResDll, RT_ACCELERATOR, EnumResNameCallback, (long)this);
\r
132 _ftprintf(stdout, _T("%4d Accelerators\n"), m_StringEntries.size()-nEntries);
\r
133 nEntries = m_StringEntries.size();
\r
135 // parse a probably existing file and update the translations which are
\r
137 m_StringEntries.ParseFile(lpszPoFilePath, !bNoUpdate);
\r
139 // at last, save the new file
\r
140 if (!m_StringEntries.SaveFile(lpszPoFilePath))
\r
143 FreeLibrary(m_hResDll);
\r
148 FreeLibrary(m_hResDll);
\r
152 BOOL CResModule::CreateTranslatedResources(LPCTSTR lpszSrcLangDllPath, LPCTSTR lpszDestLangDllPath, LPCTSTR lpszPOFilePath)
\r
154 if (!CopyFile(lpszSrcLangDllPath, lpszDestLangDllPath, FALSE))
\r
160 m_hResDll = LoadLibraryEx (lpszSrcLangDllPath, NULL, LOAD_LIBRARY_AS_DATAFILE|LOAD_IGNORE_CODE_AUTHZ_LEVEL);
\r
161 if (m_hResDll == NULL)
\r
164 } while ((m_hResDll == NULL)&&(count < 5));
\r
166 if (m_hResDll == NULL)
\r
169 sDestFile = std::wstring(lpszDestLangDllPath);
\r
171 // get all translated strings
\r
172 if (!m_StringEntries.ParseFile(lpszPOFilePath, FALSE))
\r
174 m_bTranslatedStrings = 0;
\r
175 m_bDefaultStrings = 0;
\r
176 m_bTranslatedDialogStrings = 0;
\r
177 m_bDefaultDialogStrings = 0;
\r
178 m_bTranslatedMenuStrings = 0;
\r
179 m_bDefaultMenuStrings = 0;
\r
180 m_bTranslatedAcceleratorStrings = 0;
\r
181 m_bDefaultAcceleratorStrings = 0;
\r
184 _ftprintf(stdout, _T("Translating StringTable..."));
\r
185 EnumResourceNames(m_hResDll, RT_STRING, EnumResNameWriteCallback, (long)this);
\r
187 _ftprintf(stdout, _T("%4d translated, %4d not translated\n"), m_bTranslatedStrings, m_bDefaultStrings);
\r
190 _ftprintf(stdout, _T("Translating Dialogs......."));
\r
191 EnumResourceNames(m_hResDll, RT_DIALOG, EnumResNameWriteCallback, (long)this);
\r
193 _ftprintf(stdout, _T("%4d translated, %4d not translated\n"), m_bTranslatedDialogStrings, m_bDefaultDialogStrings);
\r
196 _ftprintf(stdout, _T("Translating Menus........."));
\r
197 EnumResourceNames(m_hResDll, RT_MENU, EnumResNameWriteCallback, (long)this);
\r
199 _ftprintf(stdout, _T("%4d translated, %4d not translated\n"), m_bTranslatedMenuStrings, m_bDefaultMenuStrings);
\r
202 _ftprintf(stdout, _T("Translating Accelerators.."));
\r
203 EnumResourceNames(m_hResDll, RT_ACCELERATOR, EnumResNameWriteCallback, (long)this);
\r
205 _ftprintf(stdout, _T("%4d translated, %4d not translated\n"), m_bTranslatedAcceleratorStrings, m_bDefaultAcceleratorStrings);
\r
207 FreeLibrary(m_hResDll);
\r
211 FreeLibrary(m_hResDll);
\r
215 BOOL CResModule::ExtractString(UINT nID)
\r
217 HRSRC hrsrc = FindResource(m_hResDll, MAKEINTRESOURCE(nID), RT_STRING);
\r
218 HGLOBAL hglStringTable;
\r
223 hglStringTable = LoadResource(m_hResDll, hrsrc);
\r
225 if (!hglStringTable)
\r
227 p = (LPWSTR)LockResource(hglStringTable);
\r
231 /* [Block of 16 strings. The strings are Pascal style with a WORD
\r
232 length preceding the string. 16 strings are always written, even
\r
233 if not all slots are full. Any slots in the block with no string
\r
234 have a zero WORD for the length.]
\r
237 //first check how much memory we need
\r
239 for (int i=0; i<16; ++i)
\r
241 int len = GET_WORD(pp);
\r
243 std::wstring msgid = std::wstring(pp, len);
\r
244 WCHAR * pBuf = new WCHAR[MAX_STRING_LENGTH*2];
\r
245 SecureZeroMemory(pBuf, MAX_STRING_LENGTH*2*sizeof(WCHAR));
\r
246 wcscpy(pBuf, msgid.c_str());
\r
247 CUtils::StringExtend(pBuf);
\r
251 std::wstring str = std::wstring(pBuf);
\r
252 RESOURCEENTRY entry = m_StringEntries[str];
\r
253 entry.resourceIDs.insert(nID);
\r
254 if (wcschr(str.c_str(), '%'))
\r
255 entry.flag = _T("#, c-format");
\r
256 m_StringEntries[str] = entry;
\r
261 UnlockResource(hglStringTable);
\r
262 FreeResource(hglStringTable);
\r
265 UnlockResource(hglStringTable);
\r
266 FreeResource(hglStringTable);
\r
270 BOOL CResModule::ReplaceString(UINT nID, WORD wLanguage)
\r
272 HRSRC hrsrc = FindResourceEx(m_hResDll, RT_STRING, MAKEINTRESOURCE(nID), wLanguage);
\r
273 HGLOBAL hglStringTable;
\r
278 hglStringTable = LoadResource(m_hResDll, hrsrc);
\r
280 if (!hglStringTable)
\r
282 p = (LPWSTR)LockResource(hglStringTable);
\r
286 /* [Block of 16 strings. The strings are Pascal style with a WORD
\r
287 length preceding the string. 16 strings are always written, even
\r
288 if not all slots are full. Any slots in the block with no string
\r
289 have a zero WORD for the length.]
\r
292 //first check how much memory we need
\r
295 for (int i=0; i<16; ++i)
\r
298 size_t len = GET_WORD(pp);
\r
300 std::wstring msgid = std::wstring(pp, len);
\r
301 WCHAR * pBuf = new WCHAR[MAX_STRING_LENGTH*2];
\r
302 SecureZeroMemory(pBuf, MAX_STRING_LENGTH*2*sizeof(WCHAR));
\r
303 wcscpy(pBuf, msgid.c_str());
\r
304 CUtils::StringExtend(pBuf);
\r
305 msgid = std::wstring(pBuf);
\r
307 RESOURCEENTRY resEntry;
\r
308 resEntry = m_StringEntries[msgid];
\r
309 wcscpy(pBuf, resEntry.msgstr.c_str());
\r
310 CUtils::StringCollapse(pBuf);
\r
311 size_t newlen = wcslen(pBuf);
\r
320 WORD * newTable = new WORD[nMem + (nMem % 2)];
\r
321 SecureZeroMemory(newTable, (nMem + (nMem % 2))*2);
\r
324 for (int i=0; i<16; ++i)
\r
326 int len = GET_WORD(p);
\r
328 std::wstring msgid = std::wstring(p, len);
\r
329 WCHAR * pBuf = new WCHAR[MAX_STRING_LENGTH*2];
\r
330 SecureZeroMemory(pBuf, MAX_STRING_LENGTH*2*sizeof(WCHAR));
\r
331 wcscpy(pBuf, msgid.c_str());
\r
332 CUtils::StringExtend(pBuf);
\r
333 msgid = std::wstring(pBuf);
\r
335 RESOURCEENTRY resEntry;
\r
336 resEntry = m_StringEntries[msgid];
\r
337 wcscpy(pBuf, resEntry.msgstr.c_str());
\r
338 CUtils::StringCollapse(pBuf);
\r
339 size_t newlen = wcslen(pBuf);
\r
342 newTable[index++] = (WORD)newlen;
\r
343 wcsncpy((wchar_t *)&newTable[index], pBuf, newlen);
\r
345 m_bTranslatedStrings++;
\r
349 newTable[index++] = (WORD)len;
\r
351 wcsncpy((wchar_t *)&newTable[index], p, len);
\r
354 m_bDefaultStrings++;
\r
360 if (!UpdateResource(m_hUpdateRes, RT_STRING, MAKEINTRESOURCE(nID), (m_wTargetLang ? m_wTargetLang : wLanguage), newTable, (DWORD)(nMem + (nMem % 2))*2))
\r
362 delete [] newTable;
\r
366 if ((m_wTargetLang)&&(!UpdateResource(m_hUpdateRes, RT_STRING, MAKEINTRESOURCE(nID), wLanguage, NULL, 0)))
\r
368 delete [] newTable;
\r
371 delete [] newTable;
\r
372 UnlockResource(hglStringTable);
\r
373 FreeResource(hglStringTable);
\r
376 UnlockResource(hglStringTable);
\r
377 FreeResource(hglStringTable);
\r
381 BOOL CResModule::ExtractMenu(UINT nID)
\r
383 HRSRC hrsrc = FindResource(m_hResDll, MAKEINTRESOURCE(nID), RT_MENU);
\r
384 HGLOBAL hglMenuTemplate;
\r
385 WORD version, offset;
\r
387 const WORD *p, *p0;
\r
392 hglMenuTemplate = LoadResource(m_hResDll, hrsrc);
\r
394 if (!hglMenuTemplate)
\r
397 p = (const WORD*)LockResource(hglMenuTemplate);
\r
402 // Standard MENU resource
\r
403 //struct MenuHeader {
\r
404 // WORD wVersion; // Currently zero
\r
405 // WORD cbHeaderSize; // Also zero
\r
409 //struct MenuExHeader {
\r
410 // WORD wVersion; // One
\r
415 version = GET_WORD(p);
\r
423 offset = GET_WORD(p);
\r
426 if (!ParseMenuResource(p))
\r
432 offset = GET_WORD(p);
\r
434 dwHelpId = GET_DWORD(p);
\r
435 if (!ParseMenuExResource(p0 + offset))
\r
443 UnlockResource(hglMenuTemplate);
\r
444 FreeResource(hglMenuTemplate);
\r
448 UnlockResource(hglMenuTemplate);
\r
449 FreeResource(hglMenuTemplate);
\r
453 BOOL CResModule::ReplaceMenu(UINT nID, WORD wLanguage)
\r
455 HRSRC hrsrc = FindResourceEx(m_hResDll, RT_MENU, MAKEINTRESOURCE(nID), wLanguage);
\r
456 HGLOBAL hglMenuTemplate;
\r
457 WORD version, offset;
\r
463 MYERROR; //just the language wasn't found
\r
465 hglMenuTemplate = LoadResource(m_hResDll, hrsrc);
\r
467 if (!hglMenuTemplate)
\r
470 p = (LPWSTR)LockResource(hglMenuTemplate);
\r
475 //struct MenuHeader {
\r
476 // WORD wVersion; // Currently zero
\r
477 // WORD cbHeaderSize; // Also zero
\r
481 //struct MenuExHeader {
\r
482 // WORD wVersion; // One
\r
487 version = GET_WORD(p);
\r
495 offset = GET_WORD(p);
\r
499 if (!CountMemReplaceMenuResource((WORD *)p, &nMem, NULL))
\r
501 WORD * newMenu = new WORD[nMem + (nMem % 2)+2];
\r
502 SecureZeroMemory(newMenu, (nMem + (nMem % 2)+2)*2);
\r
503 size_t index = 2; // MenuHeader has 2 WORDs zero
\r
504 if (!CountMemReplaceMenuResource((WORD *)p, &index, newMenu))
\r
510 if (!UpdateResource(m_hUpdateRes, RT_MENU, MAKEINTRESOURCE(nID), (m_wTargetLang ? m_wTargetLang : wLanguage), newMenu, (DWORD)(nMem + (nMem % 2)+2)*2))
\r
516 if ((m_wTargetLang)&&(!UpdateResource(m_hUpdateRes, RT_MENU, MAKEINTRESOURCE(nID), wLanguage, NULL, 0)))
\r
526 offset = GET_WORD(p);
\r
528 dwHelpId = GET_DWORD(p);
\r
530 if (!CountMemReplaceMenuExResource((WORD *)(p0 + offset), &nMem, NULL))
\r
532 WORD * newMenu = new WORD[nMem + (nMem % 2) + 4];
\r
533 SecureZeroMemory(newMenu, (nMem + (nMem % 2) + 4) * 2);
\r
534 CopyMemory(newMenu, p0, 2 * sizeof(WORD) + sizeof(DWORD));
\r
535 size_t index = 4; // MenuExHeader has 2 x WORD + 1 x DWORD
\r
536 if (!CountMemReplaceMenuExResource((WORD *)(p0 + offset), &index, newMenu))
\r
542 if (!UpdateResource(m_hUpdateRes, RT_MENU, MAKEINTRESOURCE(nID), (m_wTargetLang ? m_wTargetLang : wLanguage), newMenu, (DWORD)(nMem + (nMem % 2) + 4) * 2))
\r
548 if ((m_wTargetLang)&&(!UpdateResource(m_hUpdateRes, RT_MENU, MAKEINTRESOURCE(nID), wLanguage, NULL, 0)))
\r
560 UnlockResource(hglMenuTemplate);
\r
561 FreeResource(hglMenuTemplate);
\r
565 UnlockResource(hglMenuTemplate);
\r
566 FreeResource(hglMenuTemplate);
\r
570 const WORD* CResModule::ParseMenuResource(const WORD * res)
\r
577 //struct PopupMenuItem {
\r
578 // WORD fItemFlags;
\r
579 // WCHAR szItemText[];
\r
581 //struct NormalMenuItem {
\r
582 // WORD fItemFlags;
\r
584 // WCHAR szItemText[];
\r
590 flags = GET_WORD(res);
\r
592 if (!(flags & MF_POPUP))
\r
594 id = GET_WORD(res); //normal menu item
\r
598 id = (WORD)-1; //popup menu item
\r
600 str = (LPCWSTR)res;
\r
601 size_t l = wcslen(str)+1;
\r
604 if (flags & MF_POPUP)
\r
606 TCHAR * pBuf = new TCHAR[MAX_STRING_LENGTH];
\r
607 SecureZeroMemory(pBuf, MAX_STRING_LENGTH * sizeof(TCHAR));
\r
608 _tcscpy(pBuf, str);
\r
609 CUtils::StringExtend(pBuf);
\r
611 std::wstring wstr = std::wstring(pBuf);
\r
612 RESOURCEENTRY entry = m_StringEntries[wstr];
\r
614 entry.resourceIDs.insert(id);
\r
616 m_StringEntries[wstr] = entry;
\r
619 if ((res = ParseMenuResource(res))==0)
\r
624 TCHAR * pBuf = new TCHAR[MAX_STRING_LENGTH];
\r
625 SecureZeroMemory(pBuf, MAX_STRING_LENGTH * sizeof(TCHAR));
\r
626 _tcscpy(pBuf, str);
\r
627 CUtils::StringExtend(pBuf);
\r
629 std::wstring wstr = std::wstring(pBuf);
\r
630 RESOURCEENTRY entry = m_StringEntries[wstr];
\r
631 entry.resourceIDs.insert(id);
\r
633 TCHAR szTempBuf[1024];
\r
634 _stprintf(szTempBuf, _T("#: MenuEntry; ID:%d"), id);
\r
635 MENUENTRY menu_entry;
\r
636 menu_entry.wID = id;
\r
637 menu_entry.reference = szTempBuf;
\r
638 menu_entry.msgstr = wstr;
\r
640 m_StringEntries[wstr] = entry;
\r
641 m_MenuEntries[id] = menu_entry;
\r
644 } while (!(flags & MF_END));
\r
648 const WORD* CResModule::CountMemReplaceMenuResource(const WORD * res, size_t * wordcount, WORD * newMenu)
\r
653 //struct PopupMenuItem {
\r
654 // WORD fItemFlags;
\r
655 // WCHAR szItemText[];
\r
657 //struct NormalMenuItem {
\r
658 // WORD fItemFlags;
\r
660 // WCHAR szItemText[];
\r
665 flags = GET_WORD(res);
\r
667 if (newMenu == NULL)
\r
670 newMenu[(*wordcount)++] = flags;
\r
671 if (!(flags & MF_POPUP))
\r
673 id = GET_WORD(res); //normal menu item
\r
675 if (newMenu == NULL)
\r
678 newMenu[(*wordcount)++] = id;
\r
681 id = (WORD)-1; //popup menu item
\r
683 if (flags & MF_POPUP)
\r
685 ReplaceStr((LPCWSTR)res, newMenu, wordcount, &m_bTranslatedMenuStrings, &m_bDefaultMenuStrings);
\r
686 res += wcslen((LPCWSTR)res) + 1;
\r
688 if ((res = CountMemReplaceMenuResource(res, wordcount, newMenu))==0)
\r
693 ReplaceStr((LPCWSTR)res, newMenu, wordcount, &m_bTranslatedMenuStrings, &m_bDefaultMenuStrings);
\r
694 res += wcslen((LPCWSTR)res) + 1;
\r
699 wcscpy((wchar_t *)&newMenu[(*wordcount)], (LPCWSTR)res);
\r
700 (*wordcount) += wcslen((LPCWSTR)res) + 1;
\r
701 res += wcslen((LPCWSTR)res) + 1;
\r
703 } while (!(flags & MF_END));
\r
707 const WORD* CResModule::ParseMenuExResource(const WORD * res)
\r
709 DWORD dwType, dwState, menuId;
\r
714 //struct MenuExItem {
\r
720 // DWORD dwHelpId; - Popup menu only
\r
726 dwType = GET_DWORD(res);
\r
728 dwState = GET_DWORD(res);
\r
730 menuId = GET_DWORD(res);
\r
732 bResInfo = GET_WORD(res);
\r
735 str = (LPCWSTR)res;
\r
736 size_t l = wcslen(str)+1;
\r
738 // Align to DWORD boundary
\r
739 res += ((((WORD)res + 3) & ~3) - (WORD)res)/sizeof(WORD);
\r
741 if (dwType & MFT_SEPARATOR)
\r
744 if (bResInfo & 0x01)
\r
746 // Popup menu - note this can also have a non-zero ID
\r
749 TCHAR * pBuf = new TCHAR[MAX_STRING_LENGTH];
\r
750 SecureZeroMemory(pBuf, MAX_STRING_LENGTH * sizeof(TCHAR));
\r
751 _tcscpy(pBuf, str);
\r
752 CUtils::StringExtend(pBuf);
\r
754 std::wstring wstr = std::wstring(pBuf);
\r
755 RESOURCEENTRY entry = m_StringEntries[wstr];
\r
756 // Popup has a DWORD help entry on a DWORD boundary - skip over it
\r
759 entry.resourceIDs.insert(menuId);
\r
760 TCHAR szTempBuf[1024];
\r
761 _stprintf(szTempBuf, _T("#: MenuExPopupEntry; ID:%d"), menuId);
\r
762 MENUENTRY menu_entry;
\r
763 menu_entry.wID = (WORD)menuId;
\r
764 menu_entry.reference = szTempBuf;
\r
765 menu_entry.msgstr = wstr;
\r
766 m_StringEntries[wstr] = entry;
\r
767 m_MenuEntries[(WORD)menuId] = menu_entry;
\r
770 if ((res = ParseMenuExResource(res)) == 0)
\r
772 } else if (menuId != 0)
\r
774 TCHAR * pBuf = new TCHAR[MAX_STRING_LENGTH];
\r
775 SecureZeroMemory(pBuf, MAX_STRING_LENGTH * sizeof(TCHAR));
\r
776 _tcscpy(pBuf, str);
\r
777 CUtils::StringExtend(pBuf);
\r
779 std::wstring wstr = std::wstring(pBuf);
\r
780 RESOURCEENTRY entry = m_StringEntries[wstr];
\r
781 entry.resourceIDs.insert(menuId);
\r
783 TCHAR szTempBuf[1024];
\r
784 _stprintf(szTempBuf, _T("#: MenuExEntry; ID:%d"), menuId);
\r
785 MENUENTRY menu_entry;
\r
786 menu_entry.wID = (WORD)menuId;
\r
787 menu_entry.reference = szTempBuf;
\r
788 menu_entry.msgstr = wstr;
\r
789 m_StringEntries[wstr] = entry;
\r
790 m_MenuEntries[(WORD)menuId] = menu_entry;
\r
793 } while (!(bResInfo & 0x80));
\r
797 const WORD* CResModule::CountMemReplaceMenuExResource(const WORD * res, size_t * wordcount, WORD * newMenu)
\r
799 DWORD dwType, dwState, menuId;
\r
803 //struct MenuExItem {
\r
809 // DWORD dwHelpId; - Popup menu only
\r
815 dwType = GET_DWORD(res);
\r
817 dwState = GET_DWORD(res);
\r
819 menuId = GET_DWORD(res);
\r
821 bResInfo = GET_WORD(res);
\r
824 if (newMenu != NULL) {
\r
825 CopyMemory(&newMenu[*wordcount], p0, 7 * sizeof(WORD));
\r
829 if (dwType & MFT_SEPARATOR) {
\r
836 if (bResInfo & 0x01)
\r
838 ReplaceStr((LPCWSTR)res, newMenu, wordcount, &m_bTranslatedMenuStrings, &m_bDefaultMenuStrings);
\r
839 res += wcslen((LPCWSTR)res) + 1;
\r
841 res += ((((WORD)res + 3) & ~3) - (WORD)res)/sizeof(WORD);
\r
842 if ((*wordcount) & 0x01)
\r
845 if (newMenu != NULL)
\r
846 CopyMemory(&newMenu[*wordcount], res, sizeof(DWORD)); // Copy Help ID
\r
851 if ((res = CountMemReplaceMenuExResource(res, wordcount, newMenu)) == 0)
\r
854 else if (menuId != 0)
\r
856 ReplaceStr((LPCWSTR)res, newMenu, wordcount, &m_bTranslatedMenuStrings, &m_bDefaultMenuStrings);
\r
857 res += wcslen((LPCWSTR)res) + 1;
\r
862 wcscpy((wchar_t *)&newMenu[(*wordcount)], (LPCWSTR)res);
\r
863 (*wordcount) += wcslen((LPCWSTR)res) + 1;
\r
864 res += wcslen((LPCWSTR)res) + 1;
\r
867 res += ((((WORD)res + 3) & ~3) - (WORD)res)/sizeof(WORD);
\r
868 if ((*wordcount) & 0x01)
\r
870 } while (!(bResInfo & 0x80));
\r
874 BOOL CResModule::ExtractAccelerator(UINT nID)
\r
876 HRSRC hrsrc = FindResource(m_hResDll, MAKEINTRESOURCE(nID), RT_ACCELERATOR);
\r
877 HGLOBAL hglAccTable;
\r
878 WORD fFlags, wAnsi, wID;
\r
885 hglAccTable = LoadResource(m_hResDll, hrsrc);
\r
890 p = (const WORD*)LockResource(hglAccTable);
\r
896 struct ACCELTABLEENTRY
\r
898 WORD fFlags; FVIRTKEY, FSHIFT, FCONTROL, FALT, 0x80 - Last in a table
\r
899 WORD wAnsi; ANSI character
\r
900 WORD wId; Keyboard accelerator passed to windows
\r
901 WORD padding; # bytes added to ensure aligned to DWORD boundary
\r
907 fFlags = GET_WORD(p);
\r
909 wAnsi = GET_WORD(p);
\r
913 p++; // Skip over padding
\r
915 if ((fFlags & 0x80) == 0x80)
\r
920 if ((wAnsi < 0x30) ||
\r
922 (wAnsi >= 0x3A && wAnsi <= 0x40))
\r
925 TCHAR * pBuf = new TCHAR[1024];
\r
926 SecureZeroMemory(pBuf, 1024 * sizeof(TCHAR));
\r
928 // include the menu ID in the msgid to make sure that 'duplicate'
\r
929 // accelerator keys are listed in the po-file.
\r
930 // without this, we would get entries like this:
\r
931 //#. Accelerator Entry for Menu ID:32809; '&Filter'
\r
932 //#. Accelerator Entry for Menu ID:57636; '&Find'
\r
933 //#: Corresponding Menu ID:32771; '&Find'
\r
937 // Since "filter" and "find" are most likely translated to words starting
\r
938 // with different letters, we need to have a separate accelerator entry
\r
939 // for each of those
\r
940 _stprintf(pBuf, _T("ID:%d:"), wID);
\r
942 // EXACTLY 5 characters long "ACS+X"
\r
943 // V = Virtual key (or blank if not used)
\r
944 // A = Alt key (or blank if not used)
\r
945 // C = Ctrl key (or blank if not used)
\r
946 // S = Shift key (or blank if not used)
\r
947 // X = upper case character
\r
948 // e.g. "V CS+Q" == Ctrl + Shift + 'Q'
\r
949 if ((fFlags & FVIRTKEY) == FVIRTKEY) // 0x01
\r
950 _tcscat(pBuf, _T("V"));
\r
952 _tcscat(pBuf, _T(" "));
\r
954 if ((fFlags & FALT) == FALT) // 0x10
\r
955 _tcscat(pBuf, _T("A"));
\r
957 _tcscat(pBuf, _T(" "));
\r
959 if ((fFlags & FCONTROL) == FCONTROL) // 0x08
\r
960 _tcscat(pBuf, _T("C"));
\r
962 _tcscat(pBuf, _T(" "));
\r
964 if ((fFlags & FSHIFT) == FSHIFT) // 0x04
\r
965 _tcscat(pBuf, _T("S"));
\r
967 _tcscat(pBuf, _T(" "));
\r
969 _stprintf(pBuf, _T("%s+%c"), pBuf, wAnsi);
\r
971 std::wstring wstr = std::wstring(pBuf);
\r
972 RESOURCEENTRY AKey_entry = m_StringEntries[wstr];
\r
974 TCHAR szTempBuf[1024];
\r
975 SecureZeroMemory(szTempBuf, 1024 * sizeof(TCHAR));
\r
976 std::wstring wmenu = _T("");
\r
977 pME_iter = m_MenuEntries.find(wID);
\r
978 if (pME_iter != m_MenuEntries.end())
\r
980 wmenu = pME_iter->second.msgstr;
\r
982 _stprintf(szTempBuf, _T("#. Accelerator Entry for Menu ID:%d; '%s'"), wID, wmenu.c_str());
\r
983 AKey_entry.automaticcomments.push_back(std::wstring(szTempBuf));
\r
985 m_StringEntries[wstr] = AKey_entry;
\r
989 UnlockResource(hglAccTable);
\r
990 FreeResource(hglAccTable);
\r
994 UnlockResource(hglAccTable);
\r
995 FreeResource(hglAccTable);
\r
999 BOOL CResModule::ReplaceAccelerator(UINT nID, WORD wLanguage)
\r
1001 LPACCEL lpaccelNew; // pointer to new accelerator table
\r
1002 HACCEL haccelOld; // handle to old accelerator table
\r
1003 int cAccelerators; // number of accelerators in table
\r
1004 HGLOBAL hglAccTableNew;
\r
1008 haccelOld = LoadAccelerators(m_hResDll, MAKEINTRESOURCE(nID));
\r
1010 if (haccelOld == NULL)
\r
1013 cAccelerators = CopyAcceleratorTable(haccelOld, NULL, 0);
\r
1015 lpaccelNew = (LPACCEL) LocalAlloc(LPTR, cAccelerators * sizeof(ACCEL));
\r
1017 if (lpaccelNew == NULL)
\r
1020 CopyAcceleratorTable(haccelOld, lpaccelNew, cAccelerators);
\r
1022 // Find the accelerator that the user modified
\r
1023 // and change its flags and virtual-key code
\r
1024 // as appropriate.
\r
1028 for (i = 0; i < cAccelerators; i++)
\r
1030 m_bDefaultAcceleratorStrings++;
\r
1031 if ((lpaccelNew[i].key < 0x30) ||
\r
1032 (lpaccelNew[i].key > 0x5A) ||
\r
1033 (lpaccelNew[i].key >= 0x3A && lpaccelNew[i].key <= 0x40))
\r
1036 TCHAR * pBuf = new TCHAR[1024];
\r
1037 SecureZeroMemory(pBuf, 1024 * sizeof(TCHAR));
\r
1039 _stprintf(pBuf, _T("ID:%d:"), lpaccelNew[i].cmd);
\r
1041 // get original key combination
\r
1042 if ((lpaccelNew[i].fVirt & FVIRTKEY) == FVIRTKEY) // 0x01
\r
1043 _tcscat(pBuf, _T("V"));
\r
1045 _tcscat(pBuf, _T(" "));
\r
1047 if ((lpaccelNew[i].fVirt & FALT) == FALT) // 0x10
\r
1048 _tcscat(pBuf, _T("A"));
\r
1050 _tcscat(pBuf, _T(" "));
\r
1052 if ((lpaccelNew[i].fVirt & FCONTROL) == FCONTROL) // 0x08
\r
1053 _tcscat(pBuf, _T("C"));
\r
1055 _tcscat(pBuf, _T(" "));
\r
1057 if ((lpaccelNew[i].fVirt & FSHIFT) == FSHIFT) // 0x04
\r
1058 _tcscat(pBuf, _T("S"));
\r
1060 _tcscat(pBuf, _T(" "));
\r
1062 _stprintf(pBuf, _T("%s+%c"), pBuf, lpaccelNew[i].key);
\r
1065 std::map<std::wstring, RESOURCEENTRY>::iterator pAK_iter = m_StringEntries.find(pBuf);
\r
1066 if (pAK_iter != m_StringEntries.end())
\r
1068 m_bTranslatedAcceleratorStrings++;
\r
1071 std::wstring wtemp = pAK_iter->second.msgstr;
\r
1072 wtemp = wtemp.substr(wtemp.find_last_of(':')+1);
\r
1073 if (wtemp.size() != 6)
\r
1075 if (wtemp.compare(0, 1, _T("V")) == 0)
\r
1076 xfVirt |= FVIRTKEY;
\r
1077 else if (wtemp.compare(0, 1, _T(" ")) != 0)
\r
1078 continue; // not a space - user must have made a mistake when translating
\r
1079 if (wtemp.compare(1, 1, _T("A")) == 0)
\r
1081 else if (wtemp.compare(1, 1, _T(" ")) != 0)
\r
1082 continue; // not a space - user must have made a mistake when translating
\r
1083 if (wtemp.compare(2, 1, _T("C")) == 0)
\r
1084 xfVirt |= FCONTROL;
\r
1085 else if (wtemp.compare(2, 1, _T(" ")) != 0)
\r
1086 continue; // not a space - user must have made a mistake when translating
\r
1087 if (wtemp.compare(3, 1, _T("S")) == 0)
\r
1089 else if (wtemp.compare(3, 1, _T(" ")) != 0)
\r
1090 continue; // not a space - user must have made a mistake when translating
\r
1091 if (wtemp.compare(4, 1, _T("+")) == 0)
\r
1093 _stscanf(wtemp.substr(5, 1).c_str(), _T("%c"), &xkey);
\r
1094 lpaccelNew[i].fVirt = xfVirt;
\r
1095 lpaccelNew[i].key = xkey;
\r
1100 // Create the new accelerator table
\r
1101 hglAccTableNew = LocalAlloc(LPTR, cAccelerators * 4 * sizeof(WORD));
\r
1102 p = (WORD *)hglAccTableNew;
\r
1103 lpaccelNew[cAccelerators-1].fVirt |= 0x80;
\r
1104 for (i = 0; i < cAccelerators; i++)
\r
1106 memcpy((void *)p, &lpaccelNew[i].fVirt, 1);
\r
1108 memcpy((void *)p, &lpaccelNew[i].key, sizeof(WORD));
\r
1110 memcpy((void *)p, &lpaccelNew[i].cmd, sizeof(WORD));
\r
1115 if (!UpdateResource(m_hUpdateRes, RT_ACCELERATOR, MAKEINTRESOURCE(nID),
\r
1116 (m_wTargetLang ? m_wTargetLang : wLanguage), hglAccTableNew /* haccelNew*/, cAccelerators * 4 * sizeof(WORD)))
\r
1121 if ((m_wTargetLang)&&(!UpdateResource(m_hUpdateRes, RT_ACCELERATOR, MAKEINTRESOURCE(nID), wLanguage, NULL, 0)))
\r
1126 LocalFree(lpaccelNew);
\r
1130 LocalFree(lpaccelNew);
\r
1134 BOOL CResModule::ExtractDialog(UINT nID)
\r
1136 const WORD* lpDlg;
\r
1137 const WORD* lpDlgItem;
\r
1139 DLGITEMINFO dlgItem;
\r
1140 WORD bNumControls;
\r
1142 HGLOBAL hGlblDlgTemplate;
\r
1144 hrsrc = FindResource(m_hResDll, MAKEINTRESOURCE(nID), RT_DIALOG);
\r
1146 if (hrsrc == NULL)
\r
1149 hGlblDlgTemplate = LoadResource(m_hResDll, hrsrc);
\r
1150 if (hGlblDlgTemplate == NULL)
\r
1153 lpDlg = (const WORD*) LockResource(hGlblDlgTemplate);
\r
1155 if (lpDlg == NULL)
\r
1158 lpDlgItem = (const WORD*) GetDialogInfo(lpDlg, &dlg);
\r
1159 bNumControls = dlg.nbItems;
\r
1163 TCHAR * pBuf = new TCHAR[MAX_STRING_LENGTH];
\r
1164 SecureZeroMemory(pBuf, MAX_STRING_LENGTH * sizeof(TCHAR));
\r
1165 _tcscpy(pBuf, dlg.caption);
\r
1166 CUtils::StringExtend(pBuf);
\r
1168 std::wstring wstr = std::wstring(pBuf);
\r
1169 RESOURCEENTRY entry = m_StringEntries[wstr];
\r
1170 entry.resourceIDs.insert(nID);
\r
1172 m_StringEntries[wstr] = entry;
\r
1176 while (bNumControls-- != 0)
\r
1178 TCHAR szTitle[500];
\r
1179 SecureZeroMemory(szTitle, sizeof(szTitle));
\r
1182 lpDlgItem = GetControlInfo((WORD *) lpDlgItem, &dlgItem, dlg.dialogEx, &bCode);
\r
1184 if (bCode == FALSE)
\r
1185 _tcscpy(szTitle, dlgItem.windowName);
\r
1187 if (_tcslen(szTitle) > 0)
\r
1189 CUtils::StringExtend(szTitle);
\r
1191 std::wstring wstr = std::wstring(szTitle);
\r
1192 RESOURCEENTRY entry = m_StringEntries[wstr];
\r
1193 entry.resourceIDs.insert(dlgItem.id);
\r
1195 m_StringEntries[wstr] = entry;
\r
1199 UnlockResource(hGlblDlgTemplate);
\r
1200 FreeResource(hGlblDlgTemplate);
\r
1204 BOOL CResModule::ReplaceDialog(UINT nID, WORD wLanguage)
\r
1206 const WORD* lpDlg;
\r
1208 HGLOBAL hGlblDlgTemplate;
\r
1210 hrsrc = FindResourceEx(m_hResDll, RT_DIALOG, MAKEINTRESOURCE(nID), wLanguage);
\r
1212 if (hrsrc == NULL)
\r
1215 hGlblDlgTemplate = LoadResource(m_hResDll, hrsrc);
\r
1217 if (hGlblDlgTemplate == NULL)
\r
1220 lpDlg = (WORD *) LockResource(hGlblDlgTemplate);
\r
1222 if (lpDlg == NULL)
\r
1226 const WORD * p = lpDlg;
\r
1227 if (!CountMemReplaceDialogResource(p, &nMem, NULL))
\r
1229 WORD * newDialog = new WORD[nMem + (nMem % 2)];
\r
1230 SecureZeroMemory(newDialog, (nMem + (nMem % 2))*2);
\r
1233 if (!CountMemReplaceDialogResource(lpDlg, &index, newDialog))
\r
1235 delete [] newDialog;
\r
1239 if (!UpdateResource(m_hUpdateRes, RT_DIALOG, MAKEINTRESOURCE(nID), (m_wTargetLang ? m_wTargetLang : wLanguage), newDialog, (DWORD)(nMem + (nMem % 2))*2))
\r
1241 delete [] newDialog;
\r
1245 if ((m_wTargetLang)&&(!UpdateResource(m_hUpdateRes, RT_DIALOG, MAKEINTRESOURCE(nID), wLanguage, NULL, 0)))
\r
1247 delete [] newDialog;
\r
1251 delete [] newDialog;
\r
1252 UnlockResource(hGlblDlgTemplate);
\r
1253 FreeResource(hGlblDlgTemplate);
\r
1257 UnlockResource(hGlblDlgTemplate);
\r
1258 FreeResource(hGlblDlgTemplate);
\r
1262 const WORD* CResModule::GetDialogInfo(const WORD * pTemplate, LPDIALOGINFO lpDlgInfo)
\r
1264 const WORD* p = (const WORD *)pTemplate;
\r
1266 lpDlgInfo->style = GET_DWORD(p);
\r
1269 if (lpDlgInfo->style == 0xffff0001) // DIALOGEX resource
\r
1271 lpDlgInfo->dialogEx = TRUE;
\r
1272 lpDlgInfo->helpId = GET_DWORD(p);
\r
1274 lpDlgInfo->exStyle = GET_DWORD(p);
\r
1276 lpDlgInfo->style = GET_DWORD(p);
\r
1281 lpDlgInfo->dialogEx = FALSE;
\r
1282 lpDlgInfo->helpId = 0;
\r
1283 lpDlgInfo->exStyle = GET_DWORD(p);
\r
1287 lpDlgInfo->nbItems = GET_WORD(p);
\r
1290 lpDlgInfo->x = GET_WORD(p);
\r
1293 lpDlgInfo->y = GET_WORD(p);
\r
1296 lpDlgInfo->cx = GET_WORD(p);
\r
1299 lpDlgInfo->cy = GET_WORD(p);
\r
1302 // Get the menu name
\r
1304 switch (GET_WORD(p))
\r
1307 lpDlgInfo->menuName = NULL;
\r
1311 lpDlgInfo->menuName = (LPCTSTR) (WORD) GET_WORD(p + 1);
\r
1315 lpDlgInfo->menuName = (LPCTSTR) p;
\r
1316 p += wcslen((LPCWSTR) p) + 1;
\r
1320 // Get the class name
\r
1322 switch (GET_WORD(p))
\r
1325 lpDlgInfo->className = (LPCTSTR)MAKEINTATOM(32770);
\r
1329 lpDlgInfo->className = (LPCTSTR) (WORD) GET_WORD(p + 1);
\r
1333 lpDlgInfo->className = (LPCTSTR) p;
\r
1334 p += wcslen((LPCTSTR)p) + 1;
\r
1338 // Get the window caption
\r
1340 lpDlgInfo->caption = (LPCTSTR)p;
\r
1341 p += wcslen((LPCWSTR) p) + 1;
\r
1343 // Get the font name
\r
1345 if (lpDlgInfo->style & DS_SETFONT)
\r
1347 lpDlgInfo->pointSize = GET_WORD(p);
\r
1350 if (lpDlgInfo->dialogEx)
\r
1352 lpDlgInfo->weight = GET_WORD(p);
\r
1354 lpDlgInfo->italic = LOBYTE(GET_WORD(p));
\r
1359 lpDlgInfo->weight = FW_DONTCARE;
\r
1360 lpDlgInfo->italic = FALSE;
\r
1363 lpDlgInfo->faceName = (LPCTSTR)p;
\r
1364 p += wcslen((LPCWSTR) p) + 1;
\r
1366 // First control is on DWORD boundary
\r
1367 return (const WORD *) ((((long)p) + 3) & ~3);
\r
1370 const WORD* CResModule::GetControlInfo(const WORD* p, LPDLGITEMINFO lpDlgItemInfo, BOOL dialogEx, LPBOOL bIsID)
\r
1374 lpDlgItemInfo->helpId = GET_DWORD(p);
\r
1376 lpDlgItemInfo->exStyle = GET_DWORD(p);
\r
1378 lpDlgItemInfo->style = GET_DWORD(p);
\r
1383 lpDlgItemInfo->helpId = 0;
\r
1384 lpDlgItemInfo->style = GET_DWORD(p);
\r
1386 lpDlgItemInfo->exStyle = GET_DWORD(p);
\r
1390 lpDlgItemInfo->x = GET_WORD(p);
\r
1393 lpDlgItemInfo->y = GET_WORD(p);
\r
1396 lpDlgItemInfo->cx = GET_WORD(p);
\r
1399 lpDlgItemInfo->cy = GET_WORD(p);
\r
1404 // ID is a DWORD for DIALOGEX
\r
1405 lpDlgItemInfo->id = (WORD) GET_DWORD(p);
\r
1410 lpDlgItemInfo->id = GET_WORD(p);
\r
1414 if (GET_WORD(p) == 0xffff)
\r
1422 lpDlgItemInfo->className = (LPCTSTR) p;
\r
1423 p += wcslen((LPCWSTR) p) + 1;
\r
1426 if (GET_WORD(p) == 0xffff) // an integer ID?
\r
1429 lpDlgItemInfo->windowName = (LPCTSTR) (DWORD) GET_WORD(p + 1);
\r
1435 lpDlgItemInfo->windowName = (LPCTSTR) p;
\r
1436 p += wcslen((LPCWSTR) p) + 1;
\r
1441 lpDlgItemInfo->data = (LPVOID) (p + 1);
\r
1442 p += GET_WORD(p) / sizeof(WORD);
\r
1445 lpDlgItemInfo->data = NULL;
\r
1448 // Next control is on DWORD boundary
\r
1449 return (const WORD *)((((long)p) + 3) & ~3);
\r
1452 const WORD * CResModule::CountMemReplaceDialogResource(const WORD * res, size_t * wordcount, WORD * newDialog)
\r
1455 DWORD style = GET_DWORD(res);
\r
1458 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1459 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1464 (*wordcount) += 2;
\r
1467 if (style == 0xffff0001) // DIALOGEX resource
\r
1472 newDialog[(*wordcount)++] = GET_WORD(res++); //help id
\r
1473 newDialog[(*wordcount)++] = GET_WORD(res++); //help id
\r
1474 newDialog[(*wordcount)++] = GET_WORD(res++); //exStyle
\r
1475 newDialog[(*wordcount)++] = GET_WORD(res++); //exStyle
\r
1476 style = GET_DWORD(res);
\r
1477 newDialog[(*wordcount)++] = GET_WORD(res++); //style
\r
1478 newDialog[(*wordcount)++] = GET_WORD(res++); //style
\r
1483 style = GET_DWORD(res);
\r
1485 (*wordcount) += 6;
\r
1493 newDialog[(*wordcount)++] = GET_WORD(res++); //exStyle
\r
1494 newDialog[(*wordcount)++] = GET_WORD(res++); //exStyle
\r
1495 //style = GET_DWORD(res);
\r
1496 //newDialog[(*wordcount)++] = GET_WORD(res++); //style
\r
1497 //newDialog[(*wordcount)++] = GET_WORD(res++); //style
\r
1502 (*wordcount) += 2;
\r
1507 newDialog[(*wordcount)] = GET_WORD(res);
\r
1508 WORD nbItems = GET_WORD(res);
\r
1513 newDialog[(*wordcount)] = GET_WORD(res); //x
\r
1518 newDialog[(*wordcount)] = GET_WORD(res); //y
\r
1523 newDialog[(*wordcount)] = GET_WORD(res); //cx
\r
1528 newDialog[(*wordcount)] = GET_WORD(res); //cy
\r
1532 // Get the menu name
\r
1534 switch (GET_WORD(res))
\r
1538 newDialog[(*wordcount)] = GET_WORD(res);
\r
1545 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1546 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1550 (*wordcount) += 2;
\r
1557 wcscpy((LPWSTR)&newDialog[(*wordcount)], (LPCWSTR)res);
\r
1559 (*wordcount) += wcslen((LPCWSTR) res) + 1;
\r
1560 res += wcslen((LPCWSTR) res) + 1;
\r
1564 // Get the class name
\r
1566 switch (GET_WORD(res))
\r
1570 newDialog[(*wordcount)] = GET_WORD(res);
\r
1577 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1578 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1582 (*wordcount) += 2;
\r
1589 wcscpy((LPWSTR)&newDialog[(*wordcount)], (LPCWSTR)res);
\r
1591 (*wordcount) += wcslen((LPCWSTR) res) + 1;
\r
1592 res += wcslen((LPCWSTR) res) + 1;
\r
1596 // Get the window caption
\r
1598 ReplaceStr((LPCWSTR)res, newDialog, wordcount, &m_bTranslatedDialogStrings, &m_bDefaultDialogStrings);
\r
1599 res += wcslen((LPCWSTR)res) + 1;
\r
1601 // Get the font name
\r
1603 if (style & DS_SETFONT)
\r
1606 newDialog[(*wordcount)] = GET_WORD(res);
\r
1614 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1615 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1620 (*wordcount) += 2;
\r
1625 wcscpy((LPWSTR)&newDialog[(*wordcount)], (LPCWSTR)res);
\r
1626 (*wordcount) += wcslen((LPCWSTR)res) + 1;
\r
1627 res += wcslen((LPCWSTR)res) + 1;
\r
1629 // First control is on DWORD boundary
\r
1630 while ((*wordcount)%2)
\r
1632 while ((ULONG)res % 4)
\r
1637 res = ReplaceControlInfo(res, wordcount, newDialog, bEx);
\r
1642 const WORD* CResModule::ReplaceControlInfo(const WORD * res, size_t * wordcount, WORD * newDialog, BOOL bEx)
\r
1648 newDialog[(*wordcount)++] = GET_WORD(res++); //helpid
\r
1649 newDialog[(*wordcount)++] = GET_WORD(res++); //helpid
\r
1654 (*wordcount) += 2;
\r
1659 LONG * exStyle = (LONG*)&newDialog[(*wordcount)];
\r
1660 newDialog[(*wordcount)++] = GET_WORD(res++); //exStyle
\r
1661 newDialog[(*wordcount)++] = GET_WORD(res++); //exStyle
\r
1663 *exStyle |= WS_EX_RTLREADING;
\r
1668 (*wordcount) += 2;
\r
1673 newDialog[(*wordcount)++] = GET_WORD(res++); //style
\r
1674 newDialog[(*wordcount)++] = GET_WORD(res++); //style
\r
1679 (*wordcount) += 2;
\r
1683 newDialog[(*wordcount)] = GET_WORD(res); //x
\r
1688 newDialog[(*wordcount)] = GET_WORD(res); //y
\r
1693 newDialog[(*wordcount)] = GET_WORD(res); //cx
\r
1698 newDialog[(*wordcount)] = GET_WORD(res); //cy
\r
1704 // ID is a DWORD for DIALOGEX
\r
1707 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1708 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1713 (*wordcount) += 2;
\r
1719 newDialog[(*wordcount)] = GET_WORD(res);
\r
1724 if (GET_WORD(res) == 0xffff) //classID
\r
1728 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1729 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1734 (*wordcount) += 2;
\r
1740 wcscpy((LPWSTR)&newDialog[(*wordcount)], (LPCWSTR)res);
\r
1741 (*wordcount) += wcslen((LPCWSTR) res) + 1;
\r
1742 res += wcslen((LPCWSTR) res) + 1;
\r
1745 if (GET_WORD(res) == 0xffff) // an integer ID?
\r
1749 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1750 newDialog[(*wordcount)++] = GET_WORD(res++);
\r
1755 (*wordcount) += 2;
\r
1760 ReplaceStr((LPCWSTR)res, newDialog, wordcount, &m_bTranslatedDialogStrings, &m_bDefaultDialogStrings);
\r
1761 res += wcslen((LPCWSTR)res) + 1;
\r
1765 memcpy(&newDialog[(*wordcount)], res, (GET_WORD(res)+1)*sizeof(WORD));
\r
1766 (*wordcount) += (GET_WORD(res)+1);
\r
1767 res += (GET_WORD(res)+1);
\r
1768 // Next control is on DWORD boundary
\r
1769 while ((*wordcount) % 2)
\r
1771 return (const WORD *)((((long)res) + 3) & ~3);
\r
1774 BOOL CALLBACK CResModule::EnumResNameCallback(HMODULE /*hModule*/, LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam)
\r
1776 CResModule* lpResModule = (CResModule*)lParam;
\r
1778 if (lpszType == RT_STRING)
\r
1780 if (IS_INTRESOURCE(lpszName))
\r
1782 if (!lpResModule->ExtractString(LOWORD(lpszName)))
\r
1786 else if (lpszType == RT_MENU)
\r
1788 if (IS_INTRESOURCE(lpszName))
\r
1790 if (!lpResModule->ExtractMenu(LOWORD(lpszName)))
\r
1794 else if (lpszType == RT_DIALOG)
\r
1796 if (IS_INTRESOURCE(lpszName))
\r
1798 if (!lpResModule->ExtractDialog(LOWORD(lpszName)))
\r
1802 else if (lpszType == RT_ACCELERATOR)
\r
1804 if (IS_INTRESOURCE(lpszName))
\r
1806 if (!lpResModule->ExtractAccelerator(LOWORD(lpszName)))
\r
1814 #pragma warning(push)
\r
1815 #pragma warning(disable: 4189)
\r
1816 BOOL CALLBACK CResModule::EnumResNameWriteCallback(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam)
\r
1818 CResModule* lpResModule = (CResModule*)lParam;
\r
1819 return EnumResourceLanguages(hModule, lpszType, lpszName, (ENUMRESLANGPROC)&lpResModule->EnumResWriteLangCallback, lParam);
\r
1821 #pragma warning(pop)
\r
1823 BOOL CALLBACK CResModule::EnumResWriteLangCallback(HMODULE /*hModule*/, LPCTSTR lpszType, LPTSTR lpszName, WORD wLanguage, LONG_PTR lParam)
\r
1825 BOOL bRes = FALSE;
\r
1826 CResModule* lpResModule = (CResModule*)lParam;
\r
1832 lpResModule->m_hUpdateRes = BeginUpdateResource(lpResModule->sDestFile.c_str(), FALSE);
\r
1833 if (lpResModule->m_hUpdateRes == NULL)
\r
1836 } while ((lpResModule->m_hUpdateRes == NULL)&&(count < 5));
\r
1838 if (lpszType == RT_STRING)
\r
1840 if (IS_INTRESOURCE(lpszName))
\r
1842 bRes = lpResModule->ReplaceString(LOWORD(lpszName), wLanguage);
\r
1845 else if (lpszType == RT_MENU)
\r
1847 if (IS_INTRESOURCE(lpszName))
\r
1849 bRes = lpResModule->ReplaceMenu(LOWORD(lpszName), wLanguage);
\r
1852 else if (lpszType == RT_DIALOG)
\r
1854 if (IS_INTRESOURCE(lpszName))
\r
1856 bRes = lpResModule->ReplaceDialog(LOWORD(lpszName), wLanguage);
\r
1859 else if (lpszType == RT_ACCELERATOR)
\r
1861 if (IS_INTRESOURCE(lpszName))
\r
1863 bRes = lpResModule->ReplaceAccelerator(LOWORD(lpszName), wLanguage);
\r
1867 if (!EndUpdateResource(lpResModule->m_hUpdateRes, !bRes))
\r
1873 void CResModule::ReplaceStr(LPCWSTR src, WORD * dest, size_t * count, int * translated, int * def)
\r
1875 TCHAR * pBuf = new TCHAR[MAX_STRING_LENGTH];
\r
1876 SecureZeroMemory(pBuf, MAX_STRING_LENGTH * sizeof(TCHAR));
\r
1877 wcscpy(pBuf, src);
\r
1878 CUtils::StringExtend(pBuf);
\r
1880 std::wstring wstr = std::wstring(pBuf);
\r
1881 RESOURCEENTRY entry = m_StringEntries[wstr];
\r
1882 if (entry.msgstr.size())
\r
1884 wcscpy(pBuf, entry.msgstr.c_str());
\r
1885 CUtils::StringCollapse(pBuf);
\r
1887 wcscpy((wchar_t *)&dest[(*count)], pBuf);
\r
1888 (*count) += wcslen(pBuf)+1;
\r
1894 wcscpy((wchar_t *)&dest[(*count)], src);
\r
1895 (*count) += wcslen(src) + 1;
\r