1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008, 2010-2012 - 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 #include "..\Utils\SysInfo.h"
24 #define MYERROR {CUtils::Error(); return FALSE;}
26 CResModule::CResModule(void)
27 : m_bTranslatedStrings(0)
28 , m_bDefaultStrings(0)
29 , m_bTranslatedDialogStrings(0)
30 , m_bDefaultDialogStrings(0)
31 , m_bTranslatedMenuStrings(0)
32 , m_bDefaultMenuStrings(0)
33 , m_bTranslatedAcceleratorStrings(0)
34 , m_bDefaultAcceleratorStrings(0)
40 , m_bAdjustEOLs(false)
44 CResModule::~CResModule(void)
48 BOOL
CResModule::ExtractResources(std::vector
<std::wstring
> filelist
, LPCTSTR lpszPOFilePath
, BOOL bNoUpdate
, LPCTSTR lpszHeaderFile
)
50 for (std::vector
<std::wstring
>::iterator I
= filelist
.begin(); I
!= filelist
.end(); ++I
)
52 m_hResDll
= LoadLibraryEx(I
->c_str(), NULL
, LOAD_LIBRARY_AS_IMAGE_RESOURCE
|LOAD_LIBRARY_AS_DATAFILE
);
53 if (m_hResDll
== NULL
)
56 size_t nEntries
= m_StringEntries
.size();
57 // fill in the std::map with all translatable entries
60 _ftprintf(stdout
, _T("Extracting StringTable...."));
61 EnumResourceNames(m_hResDll
, RT_STRING
, EnumResNameCallback
, (LONG_PTR
)this);
63 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size()-nEntries
);
64 nEntries
= m_StringEntries
.size();
67 _ftprintf(stdout
, _T("Extracting Dialogs........"));
68 EnumResourceNames(m_hResDll
, RT_DIALOG
, EnumResNameCallback
, (LONG_PTR
)this);
70 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size()-nEntries
);
71 nEntries
= m_StringEntries
.size();
74 _ftprintf(stdout
, _T("Extracting Menus.........."));
75 EnumResourceNames(m_hResDll
, RT_MENU
, EnumResNameCallback
, (LONG_PTR
)this);
77 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size()-nEntries
);
78 nEntries
= m_StringEntries
.size();
80 _ftprintf(stdout
, _T("Extracting Accelerators..."));
81 EnumResourceNames(m_hResDll
, RT_ACCELERATOR
, EnumResNameCallback
, (LONG_PTR
)this);
83 _ftprintf(stdout
, _T("%4d Accelerators\n"), m_StringEntries
.size()-nEntries
);
84 nEntries
= m_StringEntries
.size();
86 // parse a probably existing file and update the translations which are
88 m_StringEntries
.ParseFile(lpszPOFilePath
, !bNoUpdate
, m_bAdjustEOLs
);
90 FreeLibrary(m_hResDll
);
93 // at last, save the new file
94 return m_StringEntries
.SaveFile(lpszPOFilePath
, lpszHeaderFile
);
97 BOOL
CResModule::ExtractResources(LPCTSTR lpszSrcLangDllPath
, LPCTSTR lpszPoFilePath
, BOOL bNoUpdate
, LPCTSTR lpszHeaderFile
)
99 m_hResDll
= LoadLibraryEx(lpszSrcLangDllPath
, NULL
, LOAD_LIBRARY_AS_IMAGE_RESOURCE
|LOAD_LIBRARY_AS_DATAFILE
);
100 if (m_hResDll
== NULL
)
104 // fill in the std::map with all translatable entries
107 _ftprintf(stdout
, _T("Extracting StringTable...."));
108 EnumResourceNames(m_hResDll
, RT_STRING
, EnumResNameCallback
, (LONG_PTR
)this);
110 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size());
111 nEntries
= m_StringEntries
.size();
114 _ftprintf(stdout
, _T("Extracting Dialogs........"));
115 EnumResourceNames(m_hResDll
, RT_DIALOG
, EnumResNameCallback
, (LONG_PTR
)this);
117 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size()-nEntries
);
118 nEntries
= m_StringEntries
.size();
121 _ftprintf(stdout
, _T("Extracting Menus.........."));
122 EnumResourceNames(m_hResDll
, RT_MENU
, EnumResNameCallback
, (LONG_PTR
)this);
124 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size()-nEntries
);
125 nEntries
= m_StringEntries
.size();
128 _ftprintf(stdout
, _T("Extracting Accelerators..."));
129 EnumResourceNames(m_hResDll
, RT_ACCELERATOR
, EnumResNameCallback
, (LONG_PTR
)this);
131 _ftprintf(stdout
, _T("%4d Accelerators\n"), m_StringEntries
.size()-nEntries
);
132 nEntries
= m_StringEntries
.size();
134 // parse a probably existing file and update the translations which are
136 m_StringEntries
.ParseFile(lpszPoFilePath
, !bNoUpdate
, m_bAdjustEOLs
);
138 // at last, save the new file
139 if (!m_StringEntries
.SaveFile(lpszPoFilePath
, lpszHeaderFile
))
142 FreeLibrary(m_hResDll
);
147 FreeLibrary(m_hResDll
);
151 BOOL
CResModule::CreateTranslatedResources(LPCTSTR lpszSrcLangDllPath
, LPCTSTR lpszDestLangDllPath
, LPCTSTR lpszPOFilePath
)
153 if (!CopyFile(lpszSrcLangDllPath
, lpszDestLangDllPath
, FALSE
))
159 if (SysInfo::Instance().IsVistaOrLater())
160 m_hResDll
= LoadLibraryEx (lpszSrcLangDllPath
, NULL
, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
|LOAD_LIBRARY_AS_IMAGE_RESOURCE
|LOAD_IGNORE_CODE_AUTHZ_LEVEL
);
162 m_hResDll
= LoadLibraryEx (lpszSrcLangDllPath
, NULL
, LOAD_LIBRARY_AS_IMAGE_RESOURCE
|LOAD_IGNORE_CODE_AUTHZ_LEVEL
);
163 if (m_hResDll
== NULL
)
166 } while ((m_hResDll
== NULL
)&&(count
< 10));
168 if (m_hResDll
== NULL
)
171 sDestFile
= std::wstring(lpszDestLangDllPath
);
173 // get all translated strings
174 if (!m_StringEntries
.ParseFile(lpszPOFilePath
, FALSE
, m_bAdjustEOLs
))
176 m_bTranslatedStrings
= 0;
177 m_bDefaultStrings
= 0;
178 m_bTranslatedDialogStrings
= 0;
179 m_bDefaultDialogStrings
= 0;
180 m_bTranslatedMenuStrings
= 0;
181 m_bDefaultMenuStrings
= 0;
182 m_bTranslatedAcceleratorStrings
= 0;
183 m_bDefaultAcceleratorStrings
= 0;
189 m_hUpdateRes
= BeginUpdateResource(sDestFile
.c_str(), FALSE
);
190 if (m_hUpdateRes
== NULL
)
193 } while ((m_hUpdateRes
== NULL
)&&(count
< 10));
195 if (m_hUpdateRes
== NULL
)
200 _ftprintf(stdout
, _T("Translating StringTable..."));
201 bRes
= EnumResourceNames(m_hResDll
, RT_STRING
, EnumResNameWriteCallback
, (LONG_PTR
)this);
203 _ftprintf(stdout
, _T("%4d translated, %4d not translated\n"), m_bTranslatedStrings
, m_bDefaultStrings
);
206 _ftprintf(stdout
, _T("Translating Dialogs......."));
207 bRes
= EnumResourceNames(m_hResDll
, RT_DIALOG
, EnumResNameWriteCallback
, (LONG_PTR
)this);
209 _ftprintf(stdout
, _T("%4d translated, %4d not translated\n"), m_bTranslatedDialogStrings
, m_bDefaultDialogStrings
);
212 _ftprintf(stdout
, _T("Translating Menus........."));
213 bRes
= EnumResourceNames(m_hResDll
, RT_MENU
, EnumResNameWriteCallback
, (LONG_PTR
)this);
215 _ftprintf(stdout
, _T("%4d translated, %4d not translated\n"), m_bTranslatedMenuStrings
, m_bDefaultMenuStrings
);
218 _ftprintf(stdout
, _T("Translating Accelerators.."));
219 bRes
= EnumResourceNames(m_hResDll
, RT_ACCELERATOR
, EnumResNameWriteCallback
, (LONG_PTR
)this);
221 _ftprintf(stdout
, _T("%4d translated, %4d not translated\n"), m_bTranslatedAcceleratorStrings
, m_bDefaultAcceleratorStrings
);
224 if (!EndUpdateResource(m_hUpdateRes
, !bRes
))
227 FreeLibrary(m_hResDll
);
231 FreeLibrary(m_hResDll
);
235 BOOL
CResModule::ExtractString(LPCTSTR lpszType
)
237 HRSRC hrsrc
= FindResource(m_hResDll
, lpszType
, RT_STRING
);
238 HGLOBAL hglStringTable
;
243 hglStringTable
= LoadResource(m_hResDll
, hrsrc
);
247 p
= (LPWSTR
)LockResource(hglStringTable
);
251 /* [Block of 16 strings. The strings are Pascal style with a WORD
252 length preceding the string. 16 strings are always written, even
253 if not all slots are full. Any slots in the block with no string
254 have a zero WORD for the length.]
257 //first check how much memory we need
259 for (int i
=0; i
<16; ++i
)
261 int len
= GET_WORD(pp
);
263 std::wstring msgid
= std::wstring(pp
, len
);
264 WCHAR
* pBuf
= new WCHAR
[MAX_STRING_LENGTH
*2];
265 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
*2*sizeof(WCHAR
));
266 wcscpy(pBuf
, msgid
.c_str());
267 CUtils::StringExtend(pBuf
);
271 std::wstring str
= std::wstring(pBuf
);
272 RESOURCEENTRY entry
= m_StringEntries
[str
];
273 entry
.resourceIDs
.insert((DWORD
)lpszType
);
274 if (wcschr(str
.c_str(), '%'))
275 entry
.flag
= _T("#, c-format");
276 m_StringEntries
[str
] = entry
;
281 UnlockResource(hglStringTable
);
282 FreeResource(hglStringTable
);
285 UnlockResource(hglStringTable
);
286 FreeResource(hglStringTable
);
290 BOOL
CResModule::ReplaceString(LPCTSTR lpszType
, WORD wLanguage
)
292 HRSRC hrsrc
= FindResourceEx(m_hResDll
, RT_STRING
, lpszType
, wLanguage
);
293 HGLOBAL hglStringTable
;
298 hglStringTable
= LoadResource(m_hResDll
, hrsrc
);
302 p
= (LPWSTR
)LockResource(hglStringTable
);
306 /* [Block of 16 strings. The strings are Pascal style with a WORD
307 length preceding the string. 16 strings are always written, even
308 if not all slots are full. Any slots in the block with no string
309 have a zero WORD for the length.]
312 //first check how much memory we need
315 for (int i
=0; i
<16; ++i
)
318 size_t len
= GET_WORD(pp
);
320 std::wstring msgid
= std::wstring(pp
, len
);
321 WCHAR
* pBuf
= new WCHAR
[MAX_STRING_LENGTH
*2];
322 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
*2*sizeof(WCHAR
));
323 wcscpy(pBuf
, msgid
.c_str());
324 CUtils::StringExtend(pBuf
);
325 msgid
= std::wstring(pBuf
);
327 RESOURCEENTRY resEntry
;
328 resEntry
= m_StringEntries
[msgid
];
329 wcscpy(pBuf
, resEntry
.msgstr
.c_str());
330 CUtils::StringCollapse(pBuf
);
331 size_t newlen
= wcslen(pBuf
);
340 WORD
* newTable
= new WORD
[nMem
+ (nMem
% 2)];
341 SecureZeroMemory(newTable
, (nMem
+ (nMem
% 2))*2);
344 for (int i
=0; i
<16; ++i
)
346 int len
= GET_WORD(p
);
348 std::wstring msgid
= std::wstring(p
, len
);
349 WCHAR
* pBuf
= new WCHAR
[MAX_STRING_LENGTH
*2];
350 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
*2*sizeof(WCHAR
));
351 wcscpy(pBuf
, msgid
.c_str());
352 CUtils::StringExtend(pBuf
);
353 msgid
= std::wstring(pBuf
);
355 RESOURCEENTRY resEntry
;
356 resEntry
= m_StringEntries
[msgid
];
357 wcscpy(pBuf
, resEntry
.msgstr
.c_str());
358 CUtils::StringCollapse(pBuf
);
359 size_t newlen
= wcslen(pBuf
);
362 newTable
[index
++] = (WORD
)newlen
;
363 wcsncpy((wchar_t *)&newTable
[index
], pBuf
, newlen
);
365 m_bTranslatedStrings
++;
369 newTable
[index
++] = (WORD
)len
;
371 wcsncpy((wchar_t *)&newTable
[index
], p
, len
);
380 if (!UpdateResource(m_hUpdateRes
, RT_STRING
, lpszType
, (m_wTargetLang
? m_wTargetLang
: wLanguage
), newTable
, (DWORD
)(nMem
+ (nMem
% 2))*2))
386 if ((m_wTargetLang
)&&(!UpdateResource(m_hUpdateRes
, RT_STRING
, lpszType
, wLanguage
, NULL
, 0)))
392 UnlockResource(hglStringTable
);
393 FreeResource(hglStringTable
);
396 UnlockResource(hglStringTable
);
397 FreeResource(hglStringTable
);
401 BOOL
CResModule::ExtractMenu(LPCTSTR lpszType
)
403 HRSRC hrsrc
= FindResource(m_hResDll
, lpszType
, RT_MENU
);
404 HGLOBAL hglMenuTemplate
;
405 WORD version
, offset
;
411 hglMenuTemplate
= LoadResource(m_hResDll
, hrsrc
);
413 if (!hglMenuTemplate
)
416 p
= (const WORD
*)LockResource(hglMenuTemplate
);
421 // Standard MENU resource
422 //struct MenuHeader {
423 // WORD wVersion; // Currently zero
424 // WORD cbHeaderSize; // Also zero
428 //struct MenuExHeader {
429 // WORD wVersion; // One
434 version
= GET_WORD(p
);
442 offset
= GET_WORD(p
);
445 if (!ParseMenuResource(p
))
451 offset
= GET_WORD(p
);
453 //dwHelpId = GET_DWORD(p);
454 if (!ParseMenuExResource(p0
+ offset
))
462 UnlockResource(hglMenuTemplate
);
463 FreeResource(hglMenuTemplate
);
467 UnlockResource(hglMenuTemplate
);
468 FreeResource(hglMenuTemplate
);
472 BOOL
CResModule::ReplaceMenu(LPCTSTR lpszType
, WORD wLanguage
)
474 HRSRC hrsrc
= FindResourceEx(m_hResDll
, RT_MENU
, lpszType
, wLanguage
);
475 HGLOBAL hglMenuTemplate
;
476 WORD version
, offset
;
481 MYERROR
; //just the language wasn't found
483 hglMenuTemplate
= LoadResource(m_hResDll
, hrsrc
);
485 if (!hglMenuTemplate
)
488 p
= (LPWSTR
)LockResource(hglMenuTemplate
);
493 //struct MenuHeader {
494 // WORD wVersion; // Currently zero
495 // WORD cbHeaderSize; // Also zero
499 //struct MenuExHeader {
500 // WORD wVersion; // One
505 version
= GET_WORD(p
);
513 offset
= GET_WORD(p
);
517 if (!CountMemReplaceMenuResource((WORD
*)p
, &nMem
, NULL
))
519 WORD
* newMenu
= new WORD
[nMem
+ (nMem
% 2)+2];
520 SecureZeroMemory(newMenu
, (nMem
+ (nMem
% 2)+2)*2);
521 size_t index
= 2; // MenuHeader has 2 WORDs zero
522 if (!CountMemReplaceMenuResource((WORD
*)p
, &index
, newMenu
))
528 if (!UpdateResource(m_hUpdateRes
, RT_MENU
, lpszType
, (m_wTargetLang
? m_wTargetLang
: wLanguage
), newMenu
, (DWORD
)(nMem
+ (nMem
% 2)+2)*2))
534 if ((m_wTargetLang
)&&(!UpdateResource(m_hUpdateRes
, RT_MENU
, lpszType
, wLanguage
, NULL
, 0)))
544 offset
= GET_WORD(p
);
546 //dwHelpId = GET_DWORD(p);
548 if (!CountMemReplaceMenuExResource((WORD
*)(p0
+ offset
), &nMem
, NULL
))
550 WORD
* newMenu
= new WORD
[nMem
+ (nMem
% 2) + 4];
551 SecureZeroMemory(newMenu
, (nMem
+ (nMem
% 2) + 4) * 2);
552 CopyMemory(newMenu
, p0
, 2 * sizeof(WORD
) + sizeof(DWORD
));
553 size_t index
= 4; // MenuExHeader has 2 x WORD + 1 x DWORD
554 if (!CountMemReplaceMenuExResource((WORD
*)(p0
+ offset
), &index
, newMenu
))
560 if (!UpdateResource(m_hUpdateRes
, RT_MENU
, lpszType
, (m_wTargetLang
? m_wTargetLang
: wLanguage
), newMenu
, (DWORD
)(nMem
+ (nMem
% 2) + 4) * 2))
566 if ((m_wTargetLang
)&&(!UpdateResource(m_hUpdateRes
, RT_MENU
, lpszType
, wLanguage
, NULL
, 0)))
578 UnlockResource(hglMenuTemplate
);
579 FreeResource(hglMenuTemplate
);
583 UnlockResource(hglMenuTemplate
);
584 FreeResource(hglMenuTemplate
);
588 const WORD
* CResModule::ParseMenuResource(const WORD
* res
)
594 //struct PopupMenuItem {
596 // WCHAR szItemText[];
598 //struct NormalMenuItem {
601 // WCHAR szItemText[];
606 flags
= GET_WORD(res
);
608 if (!(flags
& MF_POPUP
))
610 id
= GET_WORD(res
); //normal menu item
614 id
= (WORD
)-1; //popup menu item
617 size_t l
= wcslen(str
)+1;
620 if (flags
& MF_POPUP
)
622 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
623 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
625 CUtils::StringExtend(pBuf
);
627 std::wstring wstr
= std::wstring(pBuf
);
628 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
630 entry
.resourceIDs
.insert(id
);
632 m_StringEntries
[wstr
] = entry
;
635 if ((res
= ParseMenuResource(res
))==0)
640 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
641 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
643 CUtils::StringExtend(pBuf
);
645 std::wstring wstr
= std::wstring(pBuf
);
646 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
647 entry
.resourceIDs
.insert(id
);
649 TCHAR szTempBuf
[1024];
650 _stprintf(szTempBuf
, _T("#: MenuEntry; ID:%d"), id
);
651 MENUENTRY menu_entry
;
653 menu_entry
.reference
= szTempBuf
;
654 menu_entry
.msgstr
= wstr
;
656 m_StringEntries
[wstr
] = entry
;
657 m_MenuEntries
[id
] = menu_entry
;
660 } while (!(flags
& MF_END
));
664 const WORD
* CResModule::CountMemReplaceMenuResource(const WORD
* res
, size_t * wordcount
, WORD
* newMenu
)
669 //struct PopupMenuItem {
671 // WCHAR szItemText[];
673 //struct NormalMenuItem {
676 // WCHAR szItemText[];
681 flags
= GET_WORD(res
);
686 newMenu
[(*wordcount
)++] = flags
;
687 if (!(flags
& MF_POPUP
))
689 id
= GET_WORD(res
); //normal menu item
694 newMenu
[(*wordcount
)++] = id
;
697 id
= (WORD
)-1; //popup menu item
699 if (flags
& MF_POPUP
)
701 ReplaceStr((LPCWSTR
)res
, newMenu
, wordcount
, &m_bTranslatedMenuStrings
, &m_bDefaultMenuStrings
);
702 res
+= wcslen((LPCWSTR
)res
) + 1;
704 if ((res
= CountMemReplaceMenuResource(res
, wordcount
, newMenu
))==0)
709 ReplaceStr((LPCWSTR
)res
, newMenu
, wordcount
, &m_bTranslatedMenuStrings
, &m_bDefaultMenuStrings
);
710 res
+= wcslen((LPCWSTR
)res
) + 1;
715 wcscpy((wchar_t *)&newMenu
[(*wordcount
)], (LPCWSTR
)res
);
716 (*wordcount
) += wcslen((LPCWSTR
)res
) + 1;
717 res
+= wcslen((LPCWSTR
)res
) + 1;
719 } while (!(flags
& MF_END
));
723 const WORD
* CResModule::ParseMenuExResource(const WORD
* res
)
725 DWORD dwType
, menuId
;
729 //struct MenuExItem {
735 // DWORD dwHelpId; - Popup menu only
740 dwType
= GET_DWORD(res
);
742 //dwState = GET_DWORD(res);
744 menuId
= GET_DWORD(res
);
746 bResInfo
= GET_WORD(res
);
750 size_t l
= wcslen(str
)+1;
752 // Align to DWORD boundary
753 res
+= ((((WORD
)res
+ 3) & ~3) - (WORD
)res
)/sizeof(WORD
);
755 if (dwType
& MFT_SEPARATOR
)
760 // Popup menu - note this can also have a non-zero ID
763 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
764 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
766 CUtils::StringExtend(pBuf
);
768 std::wstring wstr
= std::wstring(pBuf
);
769 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
770 // Popup has a DWORD help entry on a DWORD boundary - skip over it
773 entry
.resourceIDs
.insert(menuId
);
774 TCHAR szTempBuf
[1024];
775 _stprintf(szTempBuf
, _T("#: MenuExPopupEntry; ID:%d"), menuId
);
776 MENUENTRY menu_entry
;
777 menu_entry
.wID
= (WORD
)menuId
;
778 menu_entry
.reference
= szTempBuf
;
779 menu_entry
.msgstr
= wstr
;
780 m_StringEntries
[wstr
] = entry
;
781 m_MenuEntries
[(WORD
)menuId
] = menu_entry
;
784 if ((res
= ParseMenuExResource(res
)) == 0)
786 } else if (menuId
!= 0)
788 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
789 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
791 CUtils::StringExtend(pBuf
);
793 std::wstring wstr
= std::wstring(pBuf
);
794 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
795 entry
.resourceIDs
.insert(menuId
);
797 TCHAR szTempBuf
[1024];
798 _stprintf(szTempBuf
, _T("#: MenuExEntry; ID:%d"), menuId
);
799 MENUENTRY menu_entry
;
800 menu_entry
.wID
= (WORD
)menuId
;
801 menu_entry
.reference
= szTempBuf
;
802 menu_entry
.msgstr
= wstr
;
803 m_StringEntries
[wstr
] = entry
;
804 m_MenuEntries
[(WORD
)menuId
] = menu_entry
;
807 } while (!(bResInfo
& 0x80));
811 const WORD
* CResModule::CountMemReplaceMenuExResource(const WORD
* res
, size_t * wordcount
, WORD
* newMenu
)
813 DWORD dwType
, menuId
;
817 //struct MenuExItem {
823 // DWORD dwHelpId; - Popup menu only
829 dwType
= GET_DWORD(res
);
831 //dwState = GET_DWORD(res);
833 menuId
= GET_DWORD(res
);
835 bResInfo
= GET_WORD(res
);
838 if (newMenu
!= NULL
) {
839 CopyMemory(&newMenu
[*wordcount
], p0
, 7 * sizeof(WORD
));
843 if (dwType
& MFT_SEPARATOR
) {
852 ReplaceStr((LPCWSTR
)res
, newMenu
, wordcount
, &m_bTranslatedMenuStrings
, &m_bDefaultMenuStrings
);
853 res
+= wcslen((LPCWSTR
)res
) + 1;
855 res
+= ((((WORD
)res
+ 3) & ~3) - (WORD
)res
)/sizeof(WORD
);
856 if ((*wordcount
) & 0x01)
860 CopyMemory(&newMenu
[*wordcount
], res
, sizeof(DWORD
)); // Copy Help ID
865 if ((res
= CountMemReplaceMenuExResource(res
, wordcount
, newMenu
)) == 0)
868 else if (menuId
!= 0)
870 ReplaceStr((LPCWSTR
)res
, newMenu
, wordcount
, &m_bTranslatedMenuStrings
, &m_bDefaultMenuStrings
);
871 res
+= wcslen((LPCWSTR
)res
) + 1;
876 wcscpy((wchar_t *)&newMenu
[(*wordcount
)], (LPCWSTR
)res
);
877 (*wordcount
) += wcslen((LPCWSTR
)res
) + 1;
878 res
+= wcslen((LPCWSTR
)res
) + 1;
881 res
+= ((((WORD
)res
+ 3) & ~3) - (WORD
)res
)/sizeof(WORD
);
882 if ((*wordcount
) & 0x01)
884 } while (!(bResInfo
& 0x80));
888 BOOL
CResModule::ExtractAccelerator(LPCTSTR lpszType
)
890 HRSRC hrsrc
= FindResource(m_hResDll
, lpszType
, RT_ACCELERATOR
);
892 WORD fFlags
, wAnsi
, wID
;
899 hglAccTable
= LoadResource(m_hResDll
, hrsrc
);
904 p
= (const WORD
*)LockResource(hglAccTable
);
910 struct ACCELTABLEENTRY
912 WORD fFlags; FVIRTKEY, FSHIFT, FCONTROL, FALT, 0x80 - Last in a table
913 WORD wAnsi; ANSI character
914 WORD wId; Keyboard accelerator passed to windows
915 WORD padding; # bytes added to ensure aligned to DWORD boundary
921 fFlags
= GET_WORD(p
);
927 p
++; // Skip over padding
929 if ((fFlags
& 0x80) == 0x80)
934 if ((wAnsi
< 0x30) ||
936 (wAnsi
>= 0x3A && wAnsi
<= 0x40))
939 TCHAR
* pBuf
= new TCHAR
[1024];
940 SecureZeroMemory(pBuf
, 1024 * sizeof(TCHAR
));
942 // include the menu ID in the msgid to make sure that 'duplicate'
943 // accelerator keys are listed in the po-file.
944 // without this, we would get entries like this:
945 //#. Accelerator Entry for Menu ID:32809; '&Filter'
946 //#. Accelerator Entry for Menu ID:57636; '&Find'
947 //#: Corresponding Menu ID:32771; '&Find'
951 // Since "filter" and "find" are most likely translated to words starting
952 // with different letters, we need to have a separate accelerator entry
954 _stprintf(pBuf
, _T("ID:%d:"), wID
);
956 // EXACTLY 5 characters long "ACS+X"
957 // V = Virtual key (or blank if not used)
958 // A = Alt key (or blank if not used)
959 // C = Ctrl key (or blank if not used)
960 // S = Shift key (or blank if not used)
961 // X = upper case character
962 // e.g. "V CS+Q" == Ctrl + Shift + 'Q'
963 if ((fFlags
& FVIRTKEY
) == FVIRTKEY
) // 0x01
964 _tcscat(pBuf
, _T("V"));
966 _tcscat(pBuf
, _T(" "));
968 if ((fFlags
& FALT
) == FALT
) // 0x10
969 _tcscat(pBuf
, _T("A"));
971 _tcscat(pBuf
, _T(" "));
973 if ((fFlags
& FCONTROL
) == FCONTROL
) // 0x08
974 _tcscat(pBuf
, _T("C"));
976 _tcscat(pBuf
, _T(" "));
978 if ((fFlags
& FSHIFT
) == FSHIFT
) // 0x04
979 _tcscat(pBuf
, _T("S"));
981 _tcscat(pBuf
, _T(" "));
983 _stprintf(pBuf
, _T("%s+%c"), pBuf
, wAnsi
);
985 std::wstring wstr
= std::wstring(pBuf
);
986 RESOURCEENTRY AKey_entry
= m_StringEntries
[wstr
];
988 TCHAR szTempBuf
[1024];
989 SecureZeroMemory(szTempBuf
, sizeof (szTempBuf
));
990 std::wstring wmenu
= _T("");
991 pME_iter
= m_MenuEntries
.find(wID
);
992 if (pME_iter
!= m_MenuEntries
.end())
994 wmenu
= pME_iter
->second
.msgstr
;
996 _stprintf(szTempBuf
, _T("#. Accelerator Entry for Menu ID:%d; '%s'"), wID
, wmenu
.c_str());
997 AKey_entry
.automaticcomments
.push_back(std::wstring(szTempBuf
));
999 m_StringEntries
[wstr
] = AKey_entry
;
1003 UnlockResource(hglAccTable
);
1004 FreeResource(hglAccTable
);
1008 UnlockResource(hglAccTable
);
1009 FreeResource(hglAccTable
);
1013 BOOL
CResModule::ReplaceAccelerator(LPCTSTR lpszType
, WORD wLanguage
)
1015 LPACCEL lpaccelNew
; // pointer to new accelerator table
1016 HACCEL haccelOld
; // handle to old accelerator table
1017 int cAccelerators
; // number of accelerators in table
1018 HGLOBAL hglAccTableNew
;
1022 haccelOld
= LoadAccelerators(m_hResDll
, lpszType
);
1024 if (haccelOld
== NULL
)
1027 cAccelerators
= CopyAcceleratorTable(haccelOld
, NULL
, 0);
1029 lpaccelNew
= (LPACCEL
) LocalAlloc(LPTR
, cAccelerators
* sizeof(ACCEL
));
1031 if (lpaccelNew
== NULL
)
1034 CopyAcceleratorTable(haccelOld
, lpaccelNew
, cAccelerators
);
1036 // Find the accelerator that the user modified
1037 // and change its flags and virtual-key code
1042 static const size_t BufferSize
= 1024;
1043 TCHAR
* pBuf
= new TCHAR
[BufferSize
];
1044 for (i
= 0; i
< cAccelerators
; i
++)
1046 if ((lpaccelNew
[i
].key
< 0x30) ||
1047 (lpaccelNew
[i
].key
> 0x5A) ||
1048 (lpaccelNew
[i
].key
>= 0x3A && lpaccelNew
[i
].key
<= 0x40))
1051 SecureZeroMemory(pBuf
, BufferSize
* sizeof(TCHAR
));
1053 _stprintf(pBuf
, _T("ID:%d:"), lpaccelNew
[i
].cmd
);
1055 // get original key combination
1056 if ((lpaccelNew
[i
].fVirt
& FVIRTKEY
) == FVIRTKEY
) // 0x01
1057 _tcscat(pBuf
, _T("V"));
1059 _tcscat(pBuf
, _T(" "));
1061 if ((lpaccelNew
[i
].fVirt
& FALT
) == FALT
) // 0x10
1062 _tcscat(pBuf
, _T("A"));
1064 _tcscat(pBuf
, _T(" "));
1066 if ((lpaccelNew
[i
].fVirt
& FCONTROL
) == FCONTROL
) // 0x08
1067 _tcscat(pBuf
, _T("C"));
1069 _tcscat(pBuf
, _T(" "));
1071 if ((lpaccelNew
[i
].fVirt
& FSHIFT
) == FSHIFT
) // 0x04
1072 _tcscat(pBuf
, _T("S"));
1074 _tcscat(pBuf
, _T(" "));
1076 _stprintf(pBuf
, _T("%s+%c"), pBuf
, lpaccelNew
[i
].key
);
1079 std::map
<std::wstring
, RESOURCEENTRY
>::iterator pAK_iter
= m_StringEntries
.find(pBuf
);
1080 if (pAK_iter
!= m_StringEntries
.end())
1082 m_bTranslatedAcceleratorStrings
++;
1085 std::wstring wtemp
= pAK_iter
->second
.msgstr
;
1086 wtemp
= wtemp
.substr(wtemp
.find_last_of(':')+1);
1087 if (wtemp
.size() != 6)
1089 if (wtemp
.compare(0, 1, _T("V")) == 0)
1091 else if (wtemp
.compare(0, 1, _T(" ")) != 0)
1092 continue; // not a space - user must have made a mistake when translating
1093 if (wtemp
.compare(1, 1, _T("A")) == 0)
1095 else if (wtemp
.compare(1, 1, _T(" ")) != 0)
1096 continue; // not a space - user must have made a mistake when translating
1097 if (wtemp
.compare(2, 1, _T("C")) == 0)
1099 else if (wtemp
.compare(2, 1, _T(" ")) != 0)
1100 continue; // not a space - user must have made a mistake when translating
1101 if (wtemp
.compare(3, 1, _T("S")) == 0)
1103 else if (wtemp
.compare(3, 1, _T(" ")) != 0)
1104 continue; // not a space - user must have made a mistake when translating
1105 if (wtemp
.compare(4, 1, _T("+")) == 0)
1107 _stscanf(wtemp
.substr(5, 1).c_str(), _T("%c"), &xkey
);
1108 lpaccelNew
[i
].fVirt
= xfVirt
;
1109 lpaccelNew
[i
].key
= xkey
;
1113 m_bDefaultAcceleratorStrings
++;
1118 // Create the new accelerator table
1119 hglAccTableNew
= LocalAlloc(LPTR
, cAccelerators
* 4 * sizeof(WORD
));
1120 p
= (WORD
*)hglAccTableNew
;
1121 lpaccelNew
[cAccelerators
-1].fVirt
|= 0x80;
1122 for (i
= 0; i
< cAccelerators
; i
++)
1124 memcpy((void *)p
, &lpaccelNew
[i
].fVirt
, 1);
1126 memcpy((void *)p
, &lpaccelNew
[i
].key
, sizeof(WORD
));
1128 memcpy((void *)p
, &lpaccelNew
[i
].cmd
, sizeof(WORD
));
1133 if (!UpdateResource(m_hUpdateRes
, RT_ACCELERATOR
, lpszType
,
1134 (m_wTargetLang
? m_wTargetLang
: wLanguage
), hglAccTableNew
/* haccelNew*/, cAccelerators
* 4 * sizeof(WORD
)))
1139 if ((m_wTargetLang
)&&(!UpdateResource(m_hUpdateRes
, RT_ACCELERATOR
, lpszType
, wLanguage
, NULL
, 0)))
1144 LocalFree(hglAccTableNew
);
1145 LocalFree(lpaccelNew
);
1149 LocalFree(hglAccTableNew
);
1150 LocalFree(lpaccelNew
);
1154 BOOL
CResModule::ExtractDialog(LPCTSTR lpszType
)
1157 const WORD
* lpDlgItem
;
1159 DLGITEMINFO dlgItem
;
1162 HGLOBAL hGlblDlgTemplate
;
1164 hrsrc
= FindResource(m_hResDll
, lpszType
, RT_DIALOG
);
1169 hGlblDlgTemplate
= LoadResource(m_hResDll
, hrsrc
);
1170 if (hGlblDlgTemplate
== NULL
)
1173 lpDlg
= (const WORD
*) LockResource(hGlblDlgTemplate
);
1178 lpDlgItem
= (const WORD
*) GetDialogInfo(lpDlg
, &dlg
);
1179 bNumControls
= dlg
.nbItems
;
1183 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
1184 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
1185 _tcscpy(pBuf
, dlg
.caption
);
1186 CUtils::StringExtend(pBuf
);
1188 std::wstring wstr
= std::wstring(pBuf
);
1189 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
1190 entry
.resourceIDs
.insert((DWORD
)lpszType
);
1192 m_StringEntries
[wstr
] = entry
;
1196 while (bNumControls
-- != 0)
1199 SecureZeroMemory(szTitle
, sizeof(szTitle
));
1202 lpDlgItem
= GetControlInfo((WORD
*) lpDlgItem
, &dlgItem
, dlg
.dialogEx
, &bCode
);
1205 _tcscpy(szTitle
, dlgItem
.windowName
);
1207 if (_tcslen(szTitle
) > 0)
1209 CUtils::StringExtend(szTitle
);
1211 std::wstring wstr
= std::wstring(szTitle
);
1212 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
1213 entry
.resourceIDs
.insert(dlgItem
.id
);
1215 m_StringEntries
[wstr
] = entry
;
1219 UnlockResource(hGlblDlgTemplate
);
1220 FreeResource(hGlblDlgTemplate
);
1224 BOOL
CResModule::ReplaceDialog(LPCTSTR lpszType
, WORD wLanguage
)
1228 HGLOBAL hGlblDlgTemplate
;
1230 hrsrc
= FindResourceEx(m_hResDll
, RT_DIALOG
, lpszType
, wLanguage
);
1235 hGlblDlgTemplate
= LoadResource(m_hResDll
, hrsrc
);
1237 if (hGlblDlgTemplate
== NULL
)
1240 lpDlg
= (WORD
*) LockResource(hGlblDlgTemplate
);
1246 const WORD
* p
= lpDlg
;
1247 if (!CountMemReplaceDialogResource(p
, &nMem
, NULL
))
1249 WORD
* newDialog
= new WORD
[nMem
+ (nMem
% 2)];
1250 SecureZeroMemory(newDialog
, (nMem
+ (nMem
% 2))*2);
1253 if (!CountMemReplaceDialogResource(lpDlg
, &index
, newDialog
))
1255 delete [] newDialog
;
1259 if (!UpdateResource(m_hUpdateRes
, RT_DIALOG
, lpszType
, (m_wTargetLang
? m_wTargetLang
: wLanguage
), newDialog
, (DWORD
)(nMem
+ (nMem
% 2))*2))
1261 delete [] newDialog
;
1265 if ((m_wTargetLang
)&&(!UpdateResource(m_hUpdateRes
, RT_DIALOG
, lpszType
, wLanguage
, NULL
, 0)))
1267 delete [] newDialog
;
1271 delete [] newDialog
;
1272 UnlockResource(hGlblDlgTemplate
);
1273 FreeResource(hGlblDlgTemplate
);
1277 UnlockResource(hGlblDlgTemplate
);
1278 FreeResource(hGlblDlgTemplate
);
1282 const WORD
* CResModule::GetDialogInfo(const WORD
* pTemplate
, LPDIALOGINFO lpDlgInfo
)
1284 const WORD
* p
= (const WORD
*)pTemplate
;
1286 lpDlgInfo
->style
= GET_DWORD(p
);
1289 if (lpDlgInfo
->style
== 0xffff0001) // DIALOGEX resource
1291 lpDlgInfo
->dialogEx
= TRUE
;
1292 lpDlgInfo
->helpId
= GET_DWORD(p
);
1294 lpDlgInfo
->exStyle
= GET_DWORD(p
);
1296 lpDlgInfo
->style
= GET_DWORD(p
);
1301 lpDlgInfo
->dialogEx
= FALSE
;
1302 lpDlgInfo
->helpId
= 0;
1303 lpDlgInfo
->exStyle
= GET_DWORD(p
);
1307 lpDlgInfo
->nbItems
= GET_WORD(p
);
1310 lpDlgInfo
->x
= GET_WORD(p
);
1313 lpDlgInfo
->y
= GET_WORD(p
);
1316 lpDlgInfo
->cx
= GET_WORD(p
);
1319 lpDlgInfo
->cy
= GET_WORD(p
);
1322 // Get the menu name
1324 switch (GET_WORD(p
))
1327 lpDlgInfo
->menuName
= NULL
;
1331 lpDlgInfo
->menuName
= (LPCTSTR
) (WORD
) GET_WORD(p
+ 1);
1335 lpDlgInfo
->menuName
= (LPCTSTR
) p
;
1336 p
+= wcslen((LPCWSTR
) p
) + 1;
1340 // Get the class name
1342 switch (GET_WORD(p
))
1345 lpDlgInfo
->className
= (LPCTSTR
)MAKEINTATOM(32770);
1349 lpDlgInfo
->className
= (LPCTSTR
) (WORD
) GET_WORD(p
+ 1);
1353 lpDlgInfo
->className
= (LPCTSTR
) p
;
1354 p
+= wcslen((LPCTSTR
)p
) + 1;
1358 // Get the window caption
1360 lpDlgInfo
->caption
= (LPCTSTR
)p
;
1361 p
+= wcslen((LPCWSTR
) p
) + 1;
1363 // Get the font name
1365 if (lpDlgInfo
->style
& DS_SETFONT
)
1367 lpDlgInfo
->pointSize
= GET_WORD(p
);
1370 if (lpDlgInfo
->dialogEx
)
1372 lpDlgInfo
->weight
= GET_WORD(p
);
1374 lpDlgInfo
->italic
= LOBYTE(GET_WORD(p
));
1379 lpDlgInfo
->weight
= FW_DONTCARE
;
1380 lpDlgInfo
->italic
= FALSE
;
1383 lpDlgInfo
->faceName
= (LPCTSTR
)p
;
1384 p
+= wcslen((LPCWSTR
) p
) + 1;
1386 // First control is on DWORD boundary
1387 p
+= ((((WORD
)p
+ 3) & ~3) - (WORD
)p
)/sizeof(WORD
);
1392 const WORD
* CResModule::GetControlInfo(const WORD
* p
, LPDLGITEMINFO lpDlgItemInfo
, BOOL dialogEx
, LPBOOL bIsID
)
1396 lpDlgItemInfo
->helpId
= GET_DWORD(p
);
1398 lpDlgItemInfo
->exStyle
= GET_DWORD(p
);
1400 lpDlgItemInfo
->style
= GET_DWORD(p
);
1405 lpDlgItemInfo
->helpId
= 0;
1406 lpDlgItemInfo
->style
= GET_DWORD(p
);
1408 lpDlgItemInfo
->exStyle
= GET_DWORD(p
);
1412 lpDlgItemInfo
->x
= GET_WORD(p
);
1415 lpDlgItemInfo
->y
= GET_WORD(p
);
1418 lpDlgItemInfo
->cx
= GET_WORD(p
);
1421 lpDlgItemInfo
->cy
= GET_WORD(p
);
1426 // ID is a DWORD for DIALOGEX
1427 lpDlgItemInfo
->id
= (WORD
) GET_DWORD(p
);
1432 lpDlgItemInfo
->id
= GET_WORD(p
);
1436 if (GET_WORD(p
) == 0xffff)
1444 lpDlgItemInfo
->className
= (LPCTSTR
) p
;
1445 p
+= wcslen((LPCWSTR
) p
) + 1;
1448 if (GET_WORD(p
) == 0xffff) // an integer ID?
1451 lpDlgItemInfo
->windowName
= (LPCTSTR
) (DWORD
) GET_WORD(p
+ 1);
1457 lpDlgItemInfo
->windowName
= (LPCTSTR
) p
;
1458 p
+= wcslen((LPCWSTR
) p
) + 1;
1463 lpDlgItemInfo
->data
= (LPVOID
) (p
+ 1);
1464 p
+= GET_WORD(p
) / sizeof(WORD
);
1467 lpDlgItemInfo
->data
= NULL
;
1470 // Next control is on DWORD boundary
1471 p
+= ((((WORD
)p
+ 3) & ~3) - (WORD
)p
)/sizeof(WORD
);
1475 const WORD
* CResModule::CountMemReplaceDialogResource(const WORD
* res
, size_t * wordcount
, WORD
* newDialog
)
1478 DWORD style
= GET_DWORD(res
);
1481 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1482 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1490 if (style
== 0xffff0001) // DIALOGEX resource
1495 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //help id
1496 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //help id
1497 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1498 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1499 style
= GET_DWORD(res
);
1500 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //style
1501 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //style
1506 style
= GET_DWORD(res
);
1516 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1517 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1518 //style = GET_DWORD(res);
1519 //newDialog[(*wordcount)++] = GET_WORD(res++); //style
1520 //newDialog[(*wordcount)++] = GET_WORD(res++); //style
1530 newDialog
[(*wordcount
)] = GET_WORD(res
);
1531 WORD nbItems
= GET_WORD(res
);
1536 newDialog
[(*wordcount
)] = GET_WORD(res
); //x
1541 newDialog
[(*wordcount
)] = GET_WORD(res
); //y
1546 newDialog
[(*wordcount
)] = GET_WORD(res
); //cx
1551 newDialog
[(*wordcount
)] = GET_WORD(res
); //cy
1555 // Get the menu name
1557 switch (GET_WORD(res
))
1561 newDialog
[(*wordcount
)] = GET_WORD(res
);
1568 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1569 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1580 wcscpy((LPWSTR
)&newDialog
[(*wordcount
)], (LPCWSTR
)res
);
1582 (*wordcount
) += wcslen((LPCWSTR
) res
) + 1;
1583 res
+= wcslen((LPCWSTR
) res
) + 1;
1587 // Get the class name
1589 switch (GET_WORD(res
))
1593 newDialog
[(*wordcount
)] = GET_WORD(res
);
1600 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1601 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1612 wcscpy((LPWSTR
)&newDialog
[(*wordcount
)], (LPCWSTR
)res
);
1614 (*wordcount
) += wcslen((LPCWSTR
) res
) + 1;
1615 res
+= wcslen((LPCWSTR
) res
) + 1;
1619 // Get the window caption
1621 ReplaceStr((LPCWSTR
)res
, newDialog
, wordcount
, &m_bTranslatedDialogStrings
, &m_bDefaultDialogStrings
);
1622 res
+= wcslen((LPCWSTR
)res
) + 1;
1624 // Get the font name
1626 if (style
& DS_SETFONT
)
1629 newDialog
[(*wordcount
)] = GET_WORD(res
);
1637 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1638 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1648 wcscpy((LPWSTR
)&newDialog
[(*wordcount
)], (LPCWSTR
)res
);
1649 (*wordcount
) += wcslen((LPCWSTR
)res
) + 1;
1650 res
+= wcslen((LPCWSTR
)res
) + 1;
1652 // First control is on DWORD boundary
1653 while ((*wordcount
)%2)
1655 while ((ULONG
)res
% 4)
1660 res
= ReplaceControlInfo(res
, wordcount
, newDialog
, bEx
);
1665 const WORD
* CResModule::ReplaceControlInfo(const WORD
* res
, size_t * wordcount
, WORD
* newDialog
, BOOL bEx
)
1671 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //helpid
1672 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //helpid
1682 LONG
* exStyle
= (LONG
*)&newDialog
[(*wordcount
)];
1683 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1684 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1686 *exStyle
|= WS_EX_RTLREADING
;
1696 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //style
1697 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //style
1706 newDialog
[(*wordcount
)] = GET_WORD(res
); //x
1711 newDialog
[(*wordcount
)] = GET_WORD(res
); //y
1716 newDialog
[(*wordcount
)] = GET_WORD(res
); //cx
1721 newDialog
[(*wordcount
)] = GET_WORD(res
); //cy
1727 // ID is a DWORD for DIALOGEX
1730 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1731 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1742 newDialog
[(*wordcount
)] = GET_WORD(res
);
1747 if (GET_WORD(res
) == 0xffff) //classID
1751 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1752 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1763 wcscpy((LPWSTR
)&newDialog
[(*wordcount
)], (LPCWSTR
)res
);
1764 (*wordcount
) += wcslen((LPCWSTR
) res
) + 1;
1765 res
+= wcslen((LPCWSTR
) res
) + 1;
1768 if (GET_WORD(res
) == 0xffff) // an integer ID?
1772 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1773 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1783 ReplaceStr((LPCWSTR
)res
, newDialog
, wordcount
, &m_bTranslatedDialogStrings
, &m_bDefaultDialogStrings
);
1784 res
+= wcslen((LPCWSTR
)res
) + 1;
1788 memcpy(&newDialog
[(*wordcount
)], res
, (GET_WORD(res
)+1)*sizeof(WORD
));
1789 (*wordcount
) += (GET_WORD(res
)+1);
1790 res
+= (GET_WORD(res
)+1);
1791 // Next control is on DWORD boundary
1792 while ((*wordcount
) % 2)
1794 res
+= ((((WORD
)res
+ 3) & ~3) - (WORD
)res
)/sizeof(WORD
);
1799 BOOL CALLBACK
CResModule::EnumResNameCallback(HMODULE
/*hModule*/, LPCTSTR lpszType
, LPTSTR lpszName
, LONG_PTR lParam
)
1801 CResModule
* lpResModule
= (CResModule
*)lParam
;
1803 if (lpszType
== RT_STRING
)
1805 if (IS_INTRESOURCE(lpszName
))
1807 if (!lpResModule
->ExtractString(lpszName
))
1811 else if (lpszType
== RT_MENU
)
1813 if (IS_INTRESOURCE(lpszName
))
1815 if (!lpResModule
->ExtractMenu(lpszName
))
1819 else if (lpszType
== RT_DIALOG
)
1821 if (IS_INTRESOURCE(lpszName
))
1823 if (!lpResModule
->ExtractDialog(lpszName
))
1827 else if (lpszType
== RT_ACCELERATOR
)
1829 if (IS_INTRESOURCE(lpszName
))
1831 if (!lpResModule
->ExtractAccelerator(lpszName
))
1839 #pragma warning(push)
1840 #pragma warning(disable: 4189)
1841 BOOL CALLBACK
CResModule::EnumResNameWriteCallback(HMODULE hModule
, LPCTSTR lpszType
, LPTSTR lpszName
, LONG_PTR lParam
)
1843 CResModule
* lpResModule
= (CResModule
*)lParam
;
1844 return EnumResourceLanguages(hModule
, lpszType
, lpszName
, (ENUMRESLANGPROC
)&lpResModule
->EnumResWriteLangCallback
, lParam
);
1846 #pragma warning(pop)
1848 BOOL CALLBACK
CResModule::EnumResWriteLangCallback(HMODULE
/*hModule*/, LPCTSTR lpszType
, LPTSTR lpszName
, WORD wLanguage
, LONG_PTR lParam
)
1851 CResModule
* lpResModule
= (CResModule
*)lParam
;
1853 if (lpszType
== RT_STRING
)
1855 bRes
= lpResModule
->ReplaceString(lpszName
, wLanguage
);
1857 else if (lpszType
== RT_MENU
)
1859 bRes
= lpResModule
->ReplaceMenu(lpszName
, wLanguage
);
1861 else if (lpszType
== RT_DIALOG
)
1863 bRes
= lpResModule
->ReplaceDialog(lpszName
, wLanguage
);
1865 else if (lpszType
== RT_ACCELERATOR
)
1867 bRes
= lpResModule
->ReplaceAccelerator(lpszName
, wLanguage
);
1874 void CResModule::ReplaceStr(LPCWSTR src
, WORD
* dest
, size_t * count
, int * translated
, int * def
)
1876 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
1877 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
1879 CUtils::StringExtend(pBuf
);
1881 std::wstring wstr
= std::wstring(pBuf
);
1882 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
1883 if (!entry
.msgstr
.empty())
1885 wcscpy(pBuf
, entry
.msgstr
.c_str());
1886 CUtils::StringCollapse(pBuf
);
1888 wcscpy((wchar_t *)&dest
[(*count
)], pBuf
);
1889 (*count
) += wcslen(pBuf
)+1;
1895 wcscpy((wchar_t *)&dest
[(*count
)], src
);
1896 (*count
) += wcslen(src
) + 1;