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