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"
23 #define MYERROR {CUtils::Error(); return FALSE;}
25 CResModule::CResModule(void)
26 : m_bTranslatedStrings(0)
27 , m_bDefaultStrings(0)
28 , m_bTranslatedDialogStrings(0)
29 , m_bDefaultDialogStrings(0)
30 , m_bTranslatedMenuStrings(0)
31 , m_bDefaultMenuStrings(0)
32 , m_bTranslatedAcceleratorStrings(0)
33 , m_bDefaultAcceleratorStrings(0)
39 , m_bAdjustEOLs(false)
43 CResModule::~CResModule(void)
47 BOOL
CResModule::ExtractResources(std::vector
<std::wstring
> filelist
, LPCTSTR lpszPOFilePath
, BOOL bNoUpdate
, LPCTSTR lpszHeaderFile
)
49 for (std::vector
<std::wstring
>::iterator I
= filelist
.begin(); I
!= filelist
.end(); ++I
)
51 m_hResDll
= LoadLibraryEx(I
->c_str(), NULL
, LOAD_LIBRARY_AS_IMAGE_RESOURCE
|LOAD_LIBRARY_AS_DATAFILE
);
52 if (m_hResDll
== NULL
)
55 size_t nEntries
= m_StringEntries
.size();
56 // fill in the std::map with all translatable entries
59 _ftprintf(stdout
, _T("Extracting StringTable...."));
60 EnumResourceNames(m_hResDll
, RT_STRING
, EnumResNameCallback
, (LONG_PTR
)this);
62 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size()-nEntries
);
63 nEntries
= m_StringEntries
.size();
66 _ftprintf(stdout
, _T("Extracting Dialogs........"));
67 EnumResourceNames(m_hResDll
, RT_DIALOG
, EnumResNameCallback
, (LONG_PTR
)this);
69 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size()-nEntries
);
70 nEntries
= m_StringEntries
.size();
73 _ftprintf(stdout
, _T("Extracting Menus.........."));
74 EnumResourceNames(m_hResDll
, RT_MENU
, EnumResNameCallback
, (LONG_PTR
)this);
76 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size()-nEntries
);
77 nEntries
= m_StringEntries
.size();
79 _ftprintf(stdout
, _T("Extracting Accelerators..."));
80 EnumResourceNames(m_hResDll
, RT_ACCELERATOR
, EnumResNameCallback
, (LONG_PTR
)this);
82 _ftprintf(stdout
, _T("%4d Accelerators\n"), m_StringEntries
.size()-nEntries
);
83 nEntries
= m_StringEntries
.size();
85 // parse a probably existing file and update the translations which are
87 m_StringEntries
.ParseFile(lpszPOFilePath
, !bNoUpdate
, m_bAdjustEOLs
);
89 FreeLibrary(m_hResDll
);
92 // at last, save the new file
93 return m_StringEntries
.SaveFile(lpszPOFilePath
, lpszHeaderFile
);
96 BOOL
CResModule::ExtractResources(LPCTSTR lpszSrcLangDllPath
, LPCTSTR lpszPoFilePath
, BOOL bNoUpdate
, LPCTSTR lpszHeaderFile
)
98 m_hResDll
= LoadLibraryEx(lpszSrcLangDllPath
, NULL
, LOAD_LIBRARY_AS_IMAGE_RESOURCE
|LOAD_LIBRARY_AS_DATAFILE
);
99 if (m_hResDll
== NULL
)
103 // fill in the std::map with all translatable entries
106 _ftprintf(stdout
, _T("Extracting StringTable...."));
107 EnumResourceNames(m_hResDll
, RT_STRING
, EnumResNameCallback
, (LONG_PTR
)this);
109 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size());
110 nEntries
= m_StringEntries
.size();
113 _ftprintf(stdout
, _T("Extracting Dialogs........"));
114 EnumResourceNames(m_hResDll
, RT_DIALOG
, EnumResNameCallback
, (LONG_PTR
)this);
116 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size()-nEntries
);
117 nEntries
= m_StringEntries
.size();
120 _ftprintf(stdout
, _T("Extracting Menus.........."));
121 EnumResourceNames(m_hResDll
, RT_MENU
, EnumResNameCallback
, (LONG_PTR
)this);
123 _ftprintf(stdout
, _T("%4d Strings\n"), m_StringEntries
.size()-nEntries
);
124 nEntries
= m_StringEntries
.size();
127 _ftprintf(stdout
, _T("Extracting Accelerators..."));
128 EnumResourceNames(m_hResDll
, RT_ACCELERATOR
, EnumResNameCallback
, (LONG_PTR
)this);
130 _ftprintf(stdout
, _T("%4d Accelerators\n"), m_StringEntries
.size()-nEntries
);
131 nEntries
= m_StringEntries
.size();
133 // parse a probably existing file and update the translations which are
135 m_StringEntries
.ParseFile(lpszPoFilePath
, !bNoUpdate
, m_bAdjustEOLs
);
137 // at last, save the new file
138 if (!m_StringEntries
.SaveFile(lpszPoFilePath
, lpszHeaderFile
))
141 FreeLibrary(m_hResDll
);
146 FreeLibrary(m_hResDll
);
150 BOOL
CResModule::CreateTranslatedResources(LPCTSTR lpszSrcLangDllPath
, LPCTSTR lpszDestLangDllPath
, LPCTSTR lpszPOFilePath
)
152 if (!CopyFile(lpszSrcLangDllPath
, lpszDestLangDllPath
, FALSE
))
158 m_hResDll
= LoadLibraryEx (lpszSrcLangDllPath
, NULL
, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
|LOAD_LIBRARY_AS_IMAGE_RESOURCE
|LOAD_IGNORE_CODE_AUTHZ_LEVEL
);
159 if (m_hResDll
== NULL
)
162 } while ((m_hResDll
== NULL
)&&(count
< 10));
164 if (m_hResDll
== NULL
)
167 sDestFile
= std::wstring(lpszDestLangDllPath
);
169 // get all translated strings
170 if (!m_StringEntries
.ParseFile(lpszPOFilePath
, FALSE
, m_bAdjustEOLs
))
172 m_bTranslatedStrings
= 0;
173 m_bDefaultStrings
= 0;
174 m_bTranslatedDialogStrings
= 0;
175 m_bDefaultDialogStrings
= 0;
176 m_bTranslatedMenuStrings
= 0;
177 m_bDefaultMenuStrings
= 0;
178 m_bTranslatedAcceleratorStrings
= 0;
179 m_bDefaultAcceleratorStrings
= 0;
185 m_hUpdateRes
= BeginUpdateResource(sDestFile
.c_str(), FALSE
);
186 if (m_hUpdateRes
== NULL
)
189 } while ((m_hUpdateRes
== NULL
)&&(count
< 10));
191 if (m_hUpdateRes
== NULL
)
196 _ftprintf(stdout
, _T("Translating StringTable..."));
197 bRes
= EnumResourceNames(m_hResDll
, RT_STRING
, EnumResNameWriteCallback
, (LONG_PTR
)this);
199 _ftprintf(stdout
, _T("%4d translated, %4d not translated\n"), m_bTranslatedStrings
, m_bDefaultStrings
);
202 _ftprintf(stdout
, _T("Translating Dialogs......."));
203 bRes
= EnumResourceNames(m_hResDll
, RT_DIALOG
, EnumResNameWriteCallback
, (LONG_PTR
)this);
205 _ftprintf(stdout
, _T("%4d translated, %4d not translated\n"), m_bTranslatedDialogStrings
, m_bDefaultDialogStrings
);
208 _ftprintf(stdout
, _T("Translating Menus........."));
209 bRes
= EnumResourceNames(m_hResDll
, RT_MENU
, EnumResNameWriteCallback
, (LONG_PTR
)this);
211 _ftprintf(stdout
, _T("%4d translated, %4d not translated\n"), m_bTranslatedMenuStrings
, m_bDefaultMenuStrings
);
214 _ftprintf(stdout
, _T("Translating Accelerators.."));
215 bRes
= EnumResourceNames(m_hResDll
, RT_ACCELERATOR
, EnumResNameWriteCallback
, (LONG_PTR
)this);
217 _ftprintf(stdout
, _T("%4d translated, %4d not translated\n"), m_bTranslatedAcceleratorStrings
, m_bDefaultAcceleratorStrings
);
220 if (!EndUpdateResource(m_hUpdateRes
, !bRes
))
223 FreeLibrary(m_hResDll
);
227 FreeLibrary(m_hResDll
);
231 BOOL
CResModule::ExtractString(UINT nID
)
233 HRSRC hrsrc
= FindResource(m_hResDll
, MAKEINTRESOURCE(nID
), RT_STRING
);
234 HGLOBAL hglStringTable
;
239 hglStringTable
= LoadResource(m_hResDll
, hrsrc
);
243 p
= (LPWSTR
)LockResource(hglStringTable
);
247 /* [Block of 16 strings. The strings are Pascal style with a WORD
248 length preceding the string. 16 strings are always written, even
249 if not all slots are full. Any slots in the block with no string
250 have a zero WORD for the length.]
253 //first check how much memory we need
255 for (int i
=0; i
<16; ++i
)
257 int len
= GET_WORD(pp
);
259 std::wstring msgid
= std::wstring(pp
, len
);
260 WCHAR
* pBuf
= new WCHAR
[MAX_STRING_LENGTH
*2];
261 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
*2*sizeof(WCHAR
));
262 wcscpy(pBuf
, msgid
.c_str());
263 CUtils::StringExtend(pBuf
);
267 std::wstring str
= std::wstring(pBuf
);
268 RESOURCEENTRY entry
= m_StringEntries
[str
];
269 entry
.resourceIDs
.insert(nID
);
270 if (wcschr(str
.c_str(), '%'))
271 entry
.flag
= _T("#, c-format");
272 m_StringEntries
[str
] = entry
;
277 UnlockResource(hglStringTable
);
278 FreeResource(hglStringTable
);
281 UnlockResource(hglStringTable
);
282 FreeResource(hglStringTable
);
286 BOOL
CResModule::ReplaceString(UINT nID
, WORD wLanguage
)
288 HRSRC hrsrc
= FindResourceEx(m_hResDll
, RT_STRING
, MAKEINTRESOURCE(nID
), wLanguage
);
289 HGLOBAL hglStringTable
;
294 hglStringTable
= LoadResource(m_hResDll
, hrsrc
);
298 p
= (LPWSTR
)LockResource(hglStringTable
);
302 /* [Block of 16 strings. The strings are Pascal style with a WORD
303 length preceding the string. 16 strings are always written, even
304 if not all slots are full. Any slots in the block with no string
305 have a zero WORD for the length.]
308 //first check how much memory we need
311 for (int i
=0; i
<16; ++i
)
314 size_t len
= GET_WORD(pp
);
316 std::wstring msgid
= std::wstring(pp
, len
);
317 WCHAR
* pBuf
= new WCHAR
[MAX_STRING_LENGTH
*2];
318 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
*2*sizeof(WCHAR
));
319 wcscpy(pBuf
, msgid
.c_str());
320 CUtils::StringExtend(pBuf
);
321 msgid
= std::wstring(pBuf
);
323 RESOURCEENTRY resEntry
;
324 resEntry
= m_StringEntries
[msgid
];
325 wcscpy(pBuf
, resEntry
.msgstr
.c_str());
326 CUtils::StringCollapse(pBuf
);
327 size_t newlen
= wcslen(pBuf
);
336 WORD
* newTable
= new WORD
[nMem
+ (nMem
% 2)];
337 SecureZeroMemory(newTable
, (nMem
+ (nMem
% 2))*2);
340 for (int i
=0; i
<16; ++i
)
342 int len
= GET_WORD(p
);
344 std::wstring msgid
= std::wstring(p
, len
);
345 WCHAR
* pBuf
= new WCHAR
[MAX_STRING_LENGTH
*2];
346 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
*2*sizeof(WCHAR
));
347 wcscpy(pBuf
, msgid
.c_str());
348 CUtils::StringExtend(pBuf
);
349 msgid
= std::wstring(pBuf
);
351 RESOURCEENTRY resEntry
;
352 resEntry
= m_StringEntries
[msgid
];
353 wcscpy(pBuf
, resEntry
.msgstr
.c_str());
354 CUtils::StringCollapse(pBuf
);
355 size_t newlen
= wcslen(pBuf
);
358 newTable
[index
++] = (WORD
)newlen
;
359 wcsncpy((wchar_t *)&newTable
[index
], pBuf
, newlen
);
361 m_bTranslatedStrings
++;
365 newTable
[index
++] = (WORD
)len
;
367 wcsncpy((wchar_t *)&newTable
[index
], p
, len
);
376 if (!UpdateResource(m_hUpdateRes
, RT_STRING
, MAKEINTRESOURCE(nID
), (m_wTargetLang
? m_wTargetLang
: wLanguage
), newTable
, (DWORD
)(nMem
+ (nMem
% 2))*2))
382 if ((m_wTargetLang
)&&(!UpdateResource(m_hUpdateRes
, RT_STRING
, MAKEINTRESOURCE(nID
), wLanguage
, NULL
, 0)))
388 UnlockResource(hglStringTable
);
389 FreeResource(hglStringTable
);
392 UnlockResource(hglStringTable
);
393 FreeResource(hglStringTable
);
397 BOOL
CResModule::ExtractMenu(UINT nID
)
399 HRSRC hrsrc
= FindResource(m_hResDll
, MAKEINTRESOURCE(nID
), RT_MENU
);
400 HGLOBAL hglMenuTemplate
;
401 WORD version
, offset
;
408 hglMenuTemplate
= LoadResource(m_hResDll
, hrsrc
);
410 if (!hglMenuTemplate
)
413 p
= (const WORD
*)LockResource(hglMenuTemplate
);
418 // Standard MENU resource
419 //struct MenuHeader {
420 // WORD wVersion; // Currently zero
421 // WORD cbHeaderSize; // Also zero
425 //struct MenuExHeader {
426 // WORD wVersion; // One
431 version
= GET_WORD(p
);
439 offset
= GET_WORD(p
);
442 if (!ParseMenuResource(p
))
448 offset
= GET_WORD(p
);
450 dwHelpId
= GET_DWORD(p
);
451 if (!ParseMenuExResource(p0
+ offset
))
459 UnlockResource(hglMenuTemplate
);
460 FreeResource(hglMenuTemplate
);
464 UnlockResource(hglMenuTemplate
);
465 FreeResource(hglMenuTemplate
);
469 BOOL
CResModule::ReplaceMenu(UINT nID
, WORD wLanguage
)
471 HRSRC hrsrc
= FindResourceEx(m_hResDll
, RT_MENU
, MAKEINTRESOURCE(nID
), wLanguage
);
472 HGLOBAL hglMenuTemplate
;
473 WORD version
, offset
;
479 MYERROR
; //just the language wasn't found
481 hglMenuTemplate
= LoadResource(m_hResDll
, hrsrc
);
483 if (!hglMenuTemplate
)
486 p
= (LPWSTR
)LockResource(hglMenuTemplate
);
491 //struct MenuHeader {
492 // WORD wVersion; // Currently zero
493 // WORD cbHeaderSize; // Also zero
497 //struct MenuExHeader {
498 // WORD wVersion; // One
503 version
= GET_WORD(p
);
511 offset
= GET_WORD(p
);
515 if (!CountMemReplaceMenuResource((WORD
*)p
, &nMem
, NULL
))
517 WORD
* newMenu
= new WORD
[nMem
+ (nMem
% 2)+2];
518 SecureZeroMemory(newMenu
, (nMem
+ (nMem
% 2)+2)*2);
519 size_t index
= 2; // MenuHeader has 2 WORDs zero
520 if (!CountMemReplaceMenuResource((WORD
*)p
, &index
, newMenu
))
526 if (!UpdateResource(m_hUpdateRes
, RT_MENU
, MAKEINTRESOURCE(nID
), (m_wTargetLang
? m_wTargetLang
: wLanguage
), newMenu
, (DWORD
)(nMem
+ (nMem
% 2)+2)*2))
532 if ((m_wTargetLang
)&&(!UpdateResource(m_hUpdateRes
, RT_MENU
, MAKEINTRESOURCE(nID
), wLanguage
, NULL
, 0)))
542 offset
= GET_WORD(p
);
544 dwHelpId
= GET_DWORD(p
);
546 if (!CountMemReplaceMenuExResource((WORD
*)(p0
+ offset
), &nMem
, NULL
))
548 WORD
* newMenu
= new WORD
[nMem
+ (nMem
% 2) + 4];
549 SecureZeroMemory(newMenu
, (nMem
+ (nMem
% 2) + 4) * 2);
550 CopyMemory(newMenu
, p0
, 2 * sizeof(WORD
) + sizeof(DWORD
));
551 size_t index
= 4; // MenuExHeader has 2 x WORD + 1 x DWORD
552 if (!CountMemReplaceMenuExResource((WORD
*)(p0
+ offset
), &index
, newMenu
))
558 if (!UpdateResource(m_hUpdateRes
, RT_MENU
, MAKEINTRESOURCE(nID
), (m_wTargetLang
? m_wTargetLang
: wLanguage
), newMenu
, (DWORD
)(nMem
+ (nMem
% 2) + 4) * 2))
564 if ((m_wTargetLang
)&&(!UpdateResource(m_hUpdateRes
, RT_MENU
, MAKEINTRESOURCE(nID
), wLanguage
, NULL
, 0)))
576 UnlockResource(hglMenuTemplate
);
577 FreeResource(hglMenuTemplate
);
581 UnlockResource(hglMenuTemplate
);
582 FreeResource(hglMenuTemplate
);
586 const WORD
* CResModule::ParseMenuResource(const WORD
* res
)
592 //struct PopupMenuItem {
594 // WCHAR szItemText[];
596 //struct NormalMenuItem {
599 // WCHAR szItemText[];
604 flags
= GET_WORD(res
);
606 if (!(flags
& MF_POPUP
))
608 id
= GET_WORD(res
); //normal menu item
612 id
= (WORD
)-1; //popup menu item
615 size_t l
= wcslen(str
)+1;
618 if (flags
& MF_POPUP
)
620 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
621 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
623 CUtils::StringExtend(pBuf
);
625 std::wstring wstr
= std::wstring(pBuf
);
626 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
628 entry
.resourceIDs
.insert(id
);
630 m_StringEntries
[wstr
] = entry
;
633 if ((res
= ParseMenuResource(res
))==0)
638 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
639 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
641 CUtils::StringExtend(pBuf
);
643 std::wstring wstr
= std::wstring(pBuf
);
644 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
645 entry
.resourceIDs
.insert(id
);
647 TCHAR szTempBuf
[1024];
648 _stprintf(szTempBuf
, _T("#: MenuEntry; ID:%d"), id
);
649 MENUENTRY menu_entry
;
651 menu_entry
.reference
= szTempBuf
;
652 menu_entry
.msgstr
= wstr
;
654 m_StringEntries
[wstr
] = entry
;
655 m_MenuEntries
[id
] = menu_entry
;
658 } while (!(flags
& MF_END
));
662 const WORD
* CResModule::CountMemReplaceMenuResource(const WORD
* res
, size_t * wordcount
, WORD
* newMenu
)
667 //struct PopupMenuItem {
669 // WCHAR szItemText[];
671 //struct NormalMenuItem {
674 // WCHAR szItemText[];
679 flags
= GET_WORD(res
);
684 newMenu
[(*wordcount
)++] = flags
;
685 if (!(flags
& MF_POPUP
))
687 id
= GET_WORD(res
); //normal menu item
692 newMenu
[(*wordcount
)++] = id
;
695 id
= (WORD
)-1; //popup menu item
697 if (flags
& MF_POPUP
)
699 ReplaceStr((LPCWSTR
)res
, newMenu
, wordcount
, &m_bTranslatedMenuStrings
, &m_bDefaultMenuStrings
);
700 res
+= wcslen((LPCWSTR
)res
) + 1;
702 if ((res
= CountMemReplaceMenuResource(res
, wordcount
, newMenu
))==0)
707 ReplaceStr((LPCWSTR
)res
, newMenu
, wordcount
, &m_bTranslatedMenuStrings
, &m_bDefaultMenuStrings
);
708 res
+= wcslen((LPCWSTR
)res
) + 1;
713 wcscpy((wchar_t *)&newMenu
[(*wordcount
)], (LPCWSTR
)res
);
714 (*wordcount
) += wcslen((LPCWSTR
)res
) + 1;
715 res
+= wcslen((LPCWSTR
)res
) + 1;
717 } while (!(flags
& MF_END
));
721 const WORD
* CResModule::ParseMenuExResource(const WORD
* res
)
723 DWORD dwType
, dwState
, menuId
;
727 //struct MenuExItem {
733 // DWORD dwHelpId; - Popup menu only
738 dwType
= GET_DWORD(res
);
740 dwState
= GET_DWORD(res
);
742 menuId
= GET_DWORD(res
);
744 bResInfo
= GET_WORD(res
);
748 size_t l
= wcslen(str
)+1;
750 // Align to DWORD boundary
751 res
+= ((((WORD
)res
+ 3) & ~3) - (WORD
)res
)/sizeof(WORD
);
753 if (dwType
& MFT_SEPARATOR
)
758 // Popup menu - note this can also have a non-zero ID
761 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
762 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
764 CUtils::StringExtend(pBuf
);
766 std::wstring wstr
= std::wstring(pBuf
);
767 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
768 // Popup has a DWORD help entry on a DWORD boundary - skip over it
771 entry
.resourceIDs
.insert(menuId
);
772 TCHAR szTempBuf
[1024];
773 _stprintf(szTempBuf
, _T("#: MenuExPopupEntry; ID:%d"), menuId
);
774 MENUENTRY menu_entry
;
775 menu_entry
.wID
= (WORD
)menuId
;
776 menu_entry
.reference
= szTempBuf
;
777 menu_entry
.msgstr
= wstr
;
778 m_StringEntries
[wstr
] = entry
;
779 m_MenuEntries
[(WORD
)menuId
] = menu_entry
;
782 if ((res
= ParseMenuExResource(res
)) == 0)
784 } else if (menuId
!= 0)
786 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
787 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
789 CUtils::StringExtend(pBuf
);
791 std::wstring wstr
= std::wstring(pBuf
);
792 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
793 entry
.resourceIDs
.insert(menuId
);
795 TCHAR szTempBuf
[1024];
796 _stprintf(szTempBuf
, _T("#: MenuExEntry; ID:%d"), menuId
);
797 MENUENTRY menu_entry
;
798 menu_entry
.wID
= (WORD
)menuId
;
799 menu_entry
.reference
= szTempBuf
;
800 menu_entry
.msgstr
= wstr
;
801 m_StringEntries
[wstr
] = entry
;
802 m_MenuEntries
[(WORD
)menuId
] = menu_entry
;
805 } while (!(bResInfo
& 0x80));
809 const WORD
* CResModule::CountMemReplaceMenuExResource(const WORD
* res
, size_t * wordcount
, WORD
* newMenu
)
811 DWORD dwType
, dwState
, menuId
;
815 //struct MenuExItem {
821 // DWORD dwHelpId; - Popup menu only
827 dwType
= GET_DWORD(res
);
829 dwState
= GET_DWORD(res
);
831 menuId
= GET_DWORD(res
);
833 bResInfo
= GET_WORD(res
);
836 if (newMenu
!= NULL
) {
837 CopyMemory(&newMenu
[*wordcount
], p0
, 7 * sizeof(WORD
));
841 if (dwType
& MFT_SEPARATOR
) {
850 ReplaceStr((LPCWSTR
)res
, newMenu
, wordcount
, &m_bTranslatedMenuStrings
, &m_bDefaultMenuStrings
);
851 res
+= wcslen((LPCWSTR
)res
) + 1;
853 res
+= ((((WORD
)res
+ 3) & ~3) - (WORD
)res
)/sizeof(WORD
);
854 if ((*wordcount
) & 0x01)
858 CopyMemory(&newMenu
[*wordcount
], res
, sizeof(DWORD
)); // Copy Help ID
863 if ((res
= CountMemReplaceMenuExResource(res
, wordcount
, newMenu
)) == 0)
866 else if (menuId
!= 0)
868 ReplaceStr((LPCWSTR
)res
, newMenu
, wordcount
, &m_bTranslatedMenuStrings
, &m_bDefaultMenuStrings
);
869 res
+= wcslen((LPCWSTR
)res
) + 1;
874 wcscpy((wchar_t *)&newMenu
[(*wordcount
)], (LPCWSTR
)res
);
875 (*wordcount
) += wcslen((LPCWSTR
)res
) + 1;
876 res
+= wcslen((LPCWSTR
)res
) + 1;
879 res
+= ((((WORD
)res
+ 3) & ~3) - (WORD
)res
)/sizeof(WORD
);
880 if ((*wordcount
) & 0x01)
882 } while (!(bResInfo
& 0x80));
886 BOOL
CResModule::ExtractAccelerator(UINT nID
)
888 HRSRC hrsrc
= FindResource(m_hResDll
, MAKEINTRESOURCE(nID
), RT_ACCELERATOR
);
890 WORD fFlags
, wAnsi
, wID
;
897 hglAccTable
= LoadResource(m_hResDll
, hrsrc
);
902 p
= (const WORD
*)LockResource(hglAccTable
);
908 struct ACCELTABLEENTRY
910 WORD fFlags; FVIRTKEY, FSHIFT, FCONTROL, FALT, 0x80 - Last in a table
911 WORD wAnsi; ANSI character
912 WORD wId; Keyboard accelerator passed to windows
913 WORD padding; # bytes added to ensure aligned to DWORD boundary
919 fFlags
= GET_WORD(p
);
925 p
++; // Skip over padding
927 if ((fFlags
& 0x80) == 0x80)
932 if ((wAnsi
< 0x30) ||
934 (wAnsi
>= 0x3A && wAnsi
<= 0x40))
937 TCHAR
* pBuf
= new TCHAR
[1024];
938 SecureZeroMemory(pBuf
, 1024 * sizeof(TCHAR
));
940 // include the menu ID in the msgid to make sure that 'duplicate'
941 // accelerator keys are listed in the po-file.
942 // without this, we would get entries like this:
943 //#. Accelerator Entry for Menu ID:32809; '&Filter'
944 //#. Accelerator Entry for Menu ID:57636; '&Find'
945 //#: Corresponding Menu ID:32771; '&Find'
949 // Since "filter" and "find" are most likely translated to words starting
950 // with different letters, we need to have a separate accelerator entry
952 _stprintf(pBuf
, _T("ID:%d:"), wID
);
954 // EXACTLY 5 characters long "ACS+X"
955 // V = Virtual key (or blank if not used)
956 // A = Alt key (or blank if not used)
957 // C = Ctrl key (or blank if not used)
958 // S = Shift key (or blank if not used)
959 // X = upper case character
960 // e.g. "V CS+Q" == Ctrl + Shift + 'Q'
961 if ((fFlags
& FVIRTKEY
) == FVIRTKEY
) // 0x01
962 _tcscat(pBuf
, _T("V"));
964 _tcscat(pBuf
, _T(" "));
966 if ((fFlags
& FALT
) == FALT
) // 0x10
967 _tcscat(pBuf
, _T("A"));
969 _tcscat(pBuf
, _T(" "));
971 if ((fFlags
& FCONTROL
) == FCONTROL
) // 0x08
972 _tcscat(pBuf
, _T("C"));
974 _tcscat(pBuf
, _T(" "));
976 if ((fFlags
& FSHIFT
) == FSHIFT
) // 0x04
977 _tcscat(pBuf
, _T("S"));
979 _tcscat(pBuf
, _T(" "));
981 _stprintf(pBuf
, _T("%s+%c"), pBuf
, wAnsi
);
983 std::wstring wstr
= std::wstring(pBuf
);
984 RESOURCEENTRY AKey_entry
= m_StringEntries
[wstr
];
986 TCHAR szTempBuf
[1024];
987 SecureZeroMemory(szTempBuf
, sizeof (szTempBuf
));
988 std::wstring wmenu
= _T("");
989 pME_iter
= m_MenuEntries
.find(wID
);
990 if (pME_iter
!= m_MenuEntries
.end())
992 wmenu
= pME_iter
->second
.msgstr
;
994 _stprintf(szTempBuf
, _T("#. Accelerator Entry for Menu ID:%d; '%s'"), wID
, wmenu
.c_str());
995 AKey_entry
.automaticcomments
.push_back(std::wstring(szTempBuf
));
997 m_StringEntries
[wstr
] = AKey_entry
;
1001 UnlockResource(hglAccTable
);
1002 FreeResource(hglAccTable
);
1006 UnlockResource(hglAccTable
);
1007 FreeResource(hglAccTable
);
1011 BOOL
CResModule::ReplaceAccelerator(UINT nID
, WORD wLanguage
)
1013 LPACCEL lpaccelNew
; // pointer to new accelerator table
1014 HACCEL haccelOld
; // handle to old accelerator table
1015 int cAccelerators
; // number of accelerators in table
1016 HGLOBAL hglAccTableNew
;
1020 haccelOld
= LoadAccelerators(m_hResDll
, MAKEINTRESOURCE(nID
));
1022 if (haccelOld
== NULL
)
1025 cAccelerators
= CopyAcceleratorTable(haccelOld
, NULL
, 0);
1027 lpaccelNew
= (LPACCEL
) LocalAlloc(LPTR
, cAccelerators
* sizeof(ACCEL
));
1029 if (lpaccelNew
== NULL
)
1032 CopyAcceleratorTable(haccelOld
, lpaccelNew
, cAccelerators
);
1034 // Find the accelerator that the user modified
1035 // and change its flags and virtual-key code
1040 static const size_t BufferSize
= 1024;
1041 TCHAR
* pBuf
= new TCHAR
[BufferSize
];
1042 for (i
= 0; i
< cAccelerators
; i
++)
1044 if ((lpaccelNew
[i
].key
< 0x30) ||
1045 (lpaccelNew
[i
].key
> 0x5A) ||
1046 (lpaccelNew
[i
].key
>= 0x3A && lpaccelNew
[i
].key
<= 0x40))
1049 SecureZeroMemory(pBuf
, BufferSize
* sizeof(TCHAR
));
1051 _stprintf(pBuf
, _T("ID:%d:"), lpaccelNew
[i
].cmd
);
1053 // get original key combination
1054 if ((lpaccelNew
[i
].fVirt
& FVIRTKEY
) == FVIRTKEY
) // 0x01
1055 _tcscat(pBuf
, _T("V"));
1057 _tcscat(pBuf
, _T(" "));
1059 if ((lpaccelNew
[i
].fVirt
& FALT
) == FALT
) // 0x10
1060 _tcscat(pBuf
, _T("A"));
1062 _tcscat(pBuf
, _T(" "));
1064 if ((lpaccelNew
[i
].fVirt
& FCONTROL
) == FCONTROL
) // 0x08
1065 _tcscat(pBuf
, _T("C"));
1067 _tcscat(pBuf
, _T(" "));
1069 if ((lpaccelNew
[i
].fVirt
& FSHIFT
) == FSHIFT
) // 0x04
1070 _tcscat(pBuf
, _T("S"));
1072 _tcscat(pBuf
, _T(" "));
1074 _stprintf(pBuf
, _T("%s+%c"), pBuf
, lpaccelNew
[i
].key
);
1077 std::map
<std::wstring
, RESOURCEENTRY
>::iterator pAK_iter
= m_StringEntries
.find(pBuf
);
1078 if (pAK_iter
!= m_StringEntries
.end())
1080 m_bTranslatedAcceleratorStrings
++;
1083 std::wstring wtemp
= pAK_iter
->second
.msgstr
;
1084 wtemp
= wtemp
.substr(wtemp
.find_last_of(':')+1);
1085 if (wtemp
.size() != 6)
1087 if (wtemp
.compare(0, 1, _T("V")) == 0)
1089 else if (wtemp
.compare(0, 1, _T(" ")) != 0)
1090 continue; // not a space - user must have made a mistake when translating
1091 if (wtemp
.compare(1, 1, _T("A")) == 0)
1093 else if (wtemp
.compare(1, 1, _T(" ")) != 0)
1094 continue; // not a space - user must have made a mistake when translating
1095 if (wtemp
.compare(2, 1, _T("C")) == 0)
1097 else if (wtemp
.compare(2, 1, _T(" ")) != 0)
1098 continue; // not a space - user must have made a mistake when translating
1099 if (wtemp
.compare(3, 1, _T("S")) == 0)
1101 else if (wtemp
.compare(3, 1, _T(" ")) != 0)
1102 continue; // not a space - user must have made a mistake when translating
1103 if (wtemp
.compare(4, 1, _T("+")) == 0)
1105 _stscanf(wtemp
.substr(5, 1).c_str(), _T("%c"), &xkey
);
1106 lpaccelNew
[i
].fVirt
= xfVirt
;
1107 lpaccelNew
[i
].key
= xkey
;
1111 m_bDefaultAcceleratorStrings
++;
1116 // Create the new accelerator table
1117 hglAccTableNew
= LocalAlloc(LPTR
, cAccelerators
* 4 * sizeof(WORD
));
1118 p
= (WORD
*)hglAccTableNew
;
1119 lpaccelNew
[cAccelerators
-1].fVirt
|= 0x80;
1120 for (i
= 0; i
< cAccelerators
; i
++)
1122 memcpy((void *)p
, &lpaccelNew
[i
].fVirt
, 1);
1124 memcpy((void *)p
, &lpaccelNew
[i
].key
, sizeof(WORD
));
1126 memcpy((void *)p
, &lpaccelNew
[i
].cmd
, sizeof(WORD
));
1131 if (!UpdateResource(m_hUpdateRes
, RT_ACCELERATOR
, MAKEINTRESOURCE(nID
),
1132 (m_wTargetLang
? m_wTargetLang
: wLanguage
), hglAccTableNew
/* haccelNew*/, cAccelerators
* 4 * sizeof(WORD
)))
1137 if ((m_wTargetLang
)&&(!UpdateResource(m_hUpdateRes
, RT_ACCELERATOR
, MAKEINTRESOURCE(nID
), wLanguage
, NULL
, 0)))
1142 LocalFree(hglAccTableNew
);
1143 LocalFree(lpaccelNew
);
1147 LocalFree(hglAccTableNew
);
1148 LocalFree(lpaccelNew
);
1152 BOOL
CResModule::ExtractDialog(UINT nID
)
1155 const WORD
* lpDlgItem
;
1157 DLGITEMINFO dlgItem
;
1160 HGLOBAL hGlblDlgTemplate
;
1162 hrsrc
= FindResource(m_hResDll
, MAKEINTRESOURCE(nID
), RT_DIALOG
);
1167 hGlblDlgTemplate
= LoadResource(m_hResDll
, hrsrc
);
1168 if (hGlblDlgTemplate
== NULL
)
1171 lpDlg
= (const WORD
*) LockResource(hGlblDlgTemplate
);
1176 lpDlgItem
= (const WORD
*) GetDialogInfo(lpDlg
, &dlg
);
1177 bNumControls
= dlg
.nbItems
;
1181 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
1182 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
1183 _tcscpy(pBuf
, dlg
.caption
);
1184 CUtils::StringExtend(pBuf
);
1186 std::wstring wstr
= std::wstring(pBuf
);
1187 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
1188 entry
.resourceIDs
.insert(nID
);
1190 m_StringEntries
[wstr
] = entry
;
1194 while (bNumControls
-- != 0)
1197 SecureZeroMemory(szTitle
, sizeof(szTitle
));
1200 lpDlgItem
= GetControlInfo((WORD
*) lpDlgItem
, &dlgItem
, dlg
.dialogEx
, &bCode
);
1203 _tcscpy(szTitle
, dlgItem
.windowName
);
1205 if (_tcslen(szTitle
) > 0)
1207 CUtils::StringExtend(szTitle
);
1209 std::wstring wstr
= std::wstring(szTitle
);
1210 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
1211 entry
.resourceIDs
.insert(dlgItem
.id
);
1213 m_StringEntries
[wstr
] = entry
;
1217 UnlockResource(hGlblDlgTemplate
);
1218 FreeResource(hGlblDlgTemplate
);
1222 BOOL
CResModule::ReplaceDialog(UINT nID
, WORD wLanguage
)
1226 HGLOBAL hGlblDlgTemplate
;
1228 hrsrc
= FindResourceEx(m_hResDll
, RT_DIALOG
, MAKEINTRESOURCE(nID
), wLanguage
);
1233 hGlblDlgTemplate
= LoadResource(m_hResDll
, hrsrc
);
1235 if (hGlblDlgTemplate
== NULL
)
1238 lpDlg
= (WORD
*) LockResource(hGlblDlgTemplate
);
1244 const WORD
* p
= lpDlg
;
1245 if (!CountMemReplaceDialogResource(p
, &nMem
, NULL
))
1247 WORD
* newDialog
= new WORD
[nMem
+ (nMem
% 2)];
1248 SecureZeroMemory(newDialog
, (nMem
+ (nMem
% 2))*2);
1251 if (!CountMemReplaceDialogResource(lpDlg
, &index
, newDialog
))
1253 delete [] newDialog
;
1257 if (!UpdateResource(m_hUpdateRes
, RT_DIALOG
, MAKEINTRESOURCE(nID
), (m_wTargetLang
? m_wTargetLang
: wLanguage
), newDialog
, (DWORD
)(nMem
+ (nMem
% 2))*2))
1259 delete [] newDialog
;
1263 if ((m_wTargetLang
)&&(!UpdateResource(m_hUpdateRes
, RT_DIALOG
, MAKEINTRESOURCE(nID
), wLanguage
, NULL
, 0)))
1265 delete [] newDialog
;
1269 delete [] newDialog
;
1270 UnlockResource(hGlblDlgTemplate
);
1271 FreeResource(hGlblDlgTemplate
);
1275 UnlockResource(hGlblDlgTemplate
);
1276 FreeResource(hGlblDlgTemplate
);
1280 const WORD
* CResModule::GetDialogInfo(const WORD
* pTemplate
, LPDIALOGINFO lpDlgInfo
)
1282 const WORD
* p
= (const WORD
*)pTemplate
;
1284 lpDlgInfo
->style
= GET_DWORD(p
);
1287 if (lpDlgInfo
->style
== 0xffff0001) // DIALOGEX resource
1289 lpDlgInfo
->dialogEx
= TRUE
;
1290 lpDlgInfo
->helpId
= GET_DWORD(p
);
1292 lpDlgInfo
->exStyle
= GET_DWORD(p
);
1294 lpDlgInfo
->style
= GET_DWORD(p
);
1299 lpDlgInfo
->dialogEx
= FALSE
;
1300 lpDlgInfo
->helpId
= 0;
1301 lpDlgInfo
->exStyle
= GET_DWORD(p
);
1305 lpDlgInfo
->nbItems
= GET_WORD(p
);
1308 lpDlgInfo
->x
= GET_WORD(p
);
1311 lpDlgInfo
->y
= GET_WORD(p
);
1314 lpDlgInfo
->cx
= GET_WORD(p
);
1317 lpDlgInfo
->cy
= GET_WORD(p
);
1320 // Get the menu name
1322 switch (GET_WORD(p
))
1325 lpDlgInfo
->menuName
= NULL
;
1329 lpDlgInfo
->menuName
= (LPCTSTR
) (WORD
) GET_WORD(p
+ 1);
1333 lpDlgInfo
->menuName
= (LPCTSTR
) p
;
1334 p
+= wcslen((LPCWSTR
) p
) + 1;
1338 // Get the class name
1340 switch (GET_WORD(p
))
1343 lpDlgInfo
->className
= (LPCTSTR
)MAKEINTATOM(32770);
1347 lpDlgInfo
->className
= (LPCTSTR
) (WORD
) GET_WORD(p
+ 1);
1351 lpDlgInfo
->className
= (LPCTSTR
) p
;
1352 p
+= wcslen((LPCTSTR
)p
) + 1;
1356 // Get the window caption
1358 lpDlgInfo
->caption
= (LPCTSTR
)p
;
1359 p
+= wcslen((LPCWSTR
) p
) + 1;
1361 // Get the font name
1363 if (lpDlgInfo
->style
& DS_SETFONT
)
1365 lpDlgInfo
->pointSize
= GET_WORD(p
);
1368 if (lpDlgInfo
->dialogEx
)
1370 lpDlgInfo
->weight
= GET_WORD(p
);
1372 lpDlgInfo
->italic
= LOBYTE(GET_WORD(p
));
1377 lpDlgInfo
->weight
= FW_DONTCARE
;
1378 lpDlgInfo
->italic
= FALSE
;
1381 lpDlgInfo
->faceName
= (LPCTSTR
)p
;
1382 p
+= wcslen((LPCWSTR
) p
) + 1;
1384 // First control is on DWORD boundary
1385 p
+= ((((WORD
)p
+ 3) & ~3) - (WORD
)p
)/sizeof(WORD
);
1390 const WORD
* CResModule::GetControlInfo(const WORD
* p
, LPDLGITEMINFO lpDlgItemInfo
, BOOL dialogEx
, LPBOOL bIsID
)
1394 lpDlgItemInfo
->helpId
= GET_DWORD(p
);
1396 lpDlgItemInfo
->exStyle
= GET_DWORD(p
);
1398 lpDlgItemInfo
->style
= GET_DWORD(p
);
1403 lpDlgItemInfo
->helpId
= 0;
1404 lpDlgItemInfo
->style
= GET_DWORD(p
);
1406 lpDlgItemInfo
->exStyle
= GET_DWORD(p
);
1410 lpDlgItemInfo
->x
= GET_WORD(p
);
1413 lpDlgItemInfo
->y
= GET_WORD(p
);
1416 lpDlgItemInfo
->cx
= GET_WORD(p
);
1419 lpDlgItemInfo
->cy
= GET_WORD(p
);
1424 // ID is a DWORD for DIALOGEX
1425 lpDlgItemInfo
->id
= (WORD
) GET_DWORD(p
);
1430 lpDlgItemInfo
->id
= GET_WORD(p
);
1434 if (GET_WORD(p
) == 0xffff)
1442 lpDlgItemInfo
->className
= (LPCTSTR
) p
;
1443 p
+= wcslen((LPCWSTR
) p
) + 1;
1446 if (GET_WORD(p
) == 0xffff) // an integer ID?
1449 lpDlgItemInfo
->windowName
= (LPCTSTR
) (DWORD
) GET_WORD(p
+ 1);
1455 lpDlgItemInfo
->windowName
= (LPCTSTR
) p
;
1456 p
+= wcslen((LPCWSTR
) p
) + 1;
1461 lpDlgItemInfo
->data
= (LPVOID
) (p
+ 1);
1462 p
+= GET_WORD(p
) / sizeof(WORD
);
1465 lpDlgItemInfo
->data
= NULL
;
1468 // Next control is on DWORD boundary
1469 p
+= ((((WORD
)p
+ 3) & ~3) - (WORD
)p
)/sizeof(WORD
);
1473 const WORD
* CResModule::CountMemReplaceDialogResource(const WORD
* res
, size_t * wordcount
, WORD
* newDialog
)
1476 DWORD style
= GET_DWORD(res
);
1479 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1480 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1488 if (style
== 0xffff0001) // DIALOGEX resource
1493 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //help id
1494 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //help id
1495 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1496 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1497 style
= GET_DWORD(res
);
1498 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //style
1499 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //style
1504 style
= GET_DWORD(res
);
1514 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1515 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1516 //style = GET_DWORD(res);
1517 //newDialog[(*wordcount)++] = GET_WORD(res++); //style
1518 //newDialog[(*wordcount)++] = GET_WORD(res++); //style
1528 newDialog
[(*wordcount
)] = GET_WORD(res
);
1529 WORD nbItems
= GET_WORD(res
);
1534 newDialog
[(*wordcount
)] = GET_WORD(res
); //x
1539 newDialog
[(*wordcount
)] = GET_WORD(res
); //y
1544 newDialog
[(*wordcount
)] = GET_WORD(res
); //cx
1549 newDialog
[(*wordcount
)] = GET_WORD(res
); //cy
1553 // Get the menu name
1555 switch (GET_WORD(res
))
1559 newDialog
[(*wordcount
)] = GET_WORD(res
);
1566 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1567 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1578 wcscpy((LPWSTR
)&newDialog
[(*wordcount
)], (LPCWSTR
)res
);
1580 (*wordcount
) += wcslen((LPCWSTR
) res
) + 1;
1581 res
+= wcslen((LPCWSTR
) res
) + 1;
1585 // Get the class name
1587 switch (GET_WORD(res
))
1591 newDialog
[(*wordcount
)] = GET_WORD(res
);
1598 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1599 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1610 wcscpy((LPWSTR
)&newDialog
[(*wordcount
)], (LPCWSTR
)res
);
1612 (*wordcount
) += wcslen((LPCWSTR
) res
) + 1;
1613 res
+= wcslen((LPCWSTR
) res
) + 1;
1617 // Get the window caption
1619 ReplaceStr((LPCWSTR
)res
, newDialog
, wordcount
, &m_bTranslatedDialogStrings
, &m_bDefaultDialogStrings
);
1620 res
+= wcslen((LPCWSTR
)res
) + 1;
1622 // Get the font name
1624 if (style
& DS_SETFONT
)
1627 newDialog
[(*wordcount
)] = GET_WORD(res
);
1635 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1636 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1646 wcscpy((LPWSTR
)&newDialog
[(*wordcount
)], (LPCWSTR
)res
);
1647 (*wordcount
) += wcslen((LPCWSTR
)res
) + 1;
1648 res
+= wcslen((LPCWSTR
)res
) + 1;
1650 // First control is on DWORD boundary
1651 while ((*wordcount
)%2)
1653 while ((ULONG
)res
% 4)
1658 res
= ReplaceControlInfo(res
, wordcount
, newDialog
, bEx
);
1663 const WORD
* CResModule::ReplaceControlInfo(const WORD
* res
, size_t * wordcount
, WORD
* newDialog
, BOOL bEx
)
1669 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //helpid
1670 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //helpid
1680 LONG
* exStyle
= (LONG
*)&newDialog
[(*wordcount
)];
1681 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1682 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //exStyle
1684 *exStyle
|= WS_EX_RTLREADING
;
1694 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //style
1695 newDialog
[(*wordcount
)++] = GET_WORD(res
++); //style
1704 newDialog
[(*wordcount
)] = GET_WORD(res
); //x
1709 newDialog
[(*wordcount
)] = GET_WORD(res
); //y
1714 newDialog
[(*wordcount
)] = GET_WORD(res
); //cx
1719 newDialog
[(*wordcount
)] = GET_WORD(res
); //cy
1725 // ID is a DWORD for DIALOGEX
1728 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1729 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1740 newDialog
[(*wordcount
)] = GET_WORD(res
);
1745 if (GET_WORD(res
) == 0xffff) //classID
1749 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1750 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1761 wcscpy((LPWSTR
)&newDialog
[(*wordcount
)], (LPCWSTR
)res
);
1762 (*wordcount
) += wcslen((LPCWSTR
) res
) + 1;
1763 res
+= wcslen((LPCWSTR
) res
) + 1;
1766 if (GET_WORD(res
) == 0xffff) // an integer ID?
1770 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1771 newDialog
[(*wordcount
)++] = GET_WORD(res
++);
1781 ReplaceStr((LPCWSTR
)res
, newDialog
, wordcount
, &m_bTranslatedDialogStrings
, &m_bDefaultDialogStrings
);
1782 res
+= wcslen((LPCWSTR
)res
) + 1;
1786 memcpy(&newDialog
[(*wordcount
)], res
, (GET_WORD(res
)+1)*sizeof(WORD
));
1787 (*wordcount
) += (GET_WORD(res
)+1);
1788 res
+= (GET_WORD(res
)+1);
1789 // Next control is on DWORD boundary
1790 while ((*wordcount
) % 2)
1792 res
+= ((((WORD
)res
+ 3) & ~3) - (WORD
)res
)/sizeof(WORD
);
1797 BOOL CALLBACK
CResModule::EnumResNameCallback(HMODULE
/*hModule*/, LPCTSTR lpszType
, LPTSTR lpszName
, LONG_PTR lParam
)
1799 CResModule
* lpResModule
= (CResModule
*)lParam
;
1801 if (lpszType
== RT_STRING
)
1803 if (IS_INTRESOURCE(lpszName
))
1805 if (!lpResModule
->ExtractString(LOWORD(lpszName
)))
1809 else if (lpszType
== RT_MENU
)
1811 if (IS_INTRESOURCE(lpszName
))
1813 if (!lpResModule
->ExtractMenu(LOWORD(lpszName
)))
1817 else if (lpszType
== RT_DIALOG
)
1819 if (IS_INTRESOURCE(lpszName
))
1821 if (!lpResModule
->ExtractDialog(LOWORD(lpszName
)))
1825 else if (lpszType
== RT_ACCELERATOR
)
1827 if (IS_INTRESOURCE(lpszName
))
1829 if (!lpResModule
->ExtractAccelerator(LOWORD(lpszName
)))
1837 #pragma warning(push)
1838 #pragma warning(disable: 4189)
1839 BOOL CALLBACK
CResModule::EnumResNameWriteCallback(HMODULE hModule
, LPCTSTR lpszType
, LPTSTR lpszName
, LONG_PTR lParam
)
1841 CResModule
* lpResModule
= (CResModule
*)lParam
;
1842 return EnumResourceLanguages(hModule
, lpszType
, lpszName
, (ENUMRESLANGPROC
)&lpResModule
->EnumResWriteLangCallback
, lParam
);
1844 #pragma warning(pop)
1846 BOOL CALLBACK
CResModule::EnumResWriteLangCallback(HMODULE
/*hModule*/, LPCTSTR lpszType
, LPTSTR lpszName
, WORD wLanguage
, LONG_PTR lParam
)
1849 CResModule
* lpResModule
= (CResModule
*)lParam
;
1851 if (lpszType
== RT_STRING
)
1853 if (IS_INTRESOURCE(lpszName
))
1855 bRes
= lpResModule
->ReplaceString(LOWORD(lpszName
), wLanguage
);
1858 else if (lpszType
== RT_MENU
)
1860 if (IS_INTRESOURCE(lpszName
))
1862 bRes
= lpResModule
->ReplaceMenu(LOWORD(lpszName
), wLanguage
);
1865 else if (lpszType
== RT_DIALOG
)
1867 if (IS_INTRESOURCE(lpszName
))
1869 bRes
= lpResModule
->ReplaceDialog(LOWORD(lpszName
), wLanguage
);
1872 else if (lpszType
== RT_ACCELERATOR
)
1874 if (IS_INTRESOURCE(lpszName
))
1876 bRes
= lpResModule
->ReplaceAccelerator(LOWORD(lpszName
), wLanguage
);
1884 void CResModule::ReplaceStr(LPCWSTR src
, WORD
* dest
, size_t * count
, int * translated
, int * def
)
1886 TCHAR
* pBuf
= new TCHAR
[MAX_STRING_LENGTH
];
1887 SecureZeroMemory(pBuf
, MAX_STRING_LENGTH
* sizeof(TCHAR
));
1889 CUtils::StringExtend(pBuf
);
1891 std::wstring wstr
= std::wstring(pBuf
);
1892 RESOURCEENTRY entry
= m_StringEntries
[wstr
];
1893 if (entry
.msgstr
.size())
1895 wcscpy(pBuf
, entry
.msgstr
.c_str());
1896 CUtils::StringCollapse(pBuf
);
1898 wcscpy((wchar_t *)&dest
[(*count
)], pBuf
);
1899 (*count
) += wcslen(pBuf
)+1;
1905 wcscpy((wchar_t *)&dest
[(*count
)], src
);
1906 (*count
) += wcslen(src
) + 1;