1 #ifndef NULLSOFT_API_LANGUAGE_H
2 #define NULLSOFT_API_LANGUAGE_H
3 
4 #include <bfc/dispatch.h>
5 #include "lang.h"
6 #include <locale.h>
7 
8 #if (_MSC_VER <= 1200)
9 	struct threadlocaleinfostruct;
10 	struct threadmbcinfostruct;
11 	typedef struct threadlocaleinfostruct * pthreadlocinfo;
12 	typedef struct threadmbcinfostruct * pthreadmbcinfo;
13 
14 	typedef struct localeinfo_struct
15 	{
16 		pthreadlocinfo locinfo;
17 		pthreadmbcinfo mbcinfo;
18 	} _locale_tstruct, *_locale_t;
19 #endif
20 
21 class api_language : public Dispatchable
22 {
23 protected:
api_language()24 	api_language() {}
~api_language()25 	~api_language() {}
26 public:
27 	char *GetString(HINSTANCE hinst, HINSTANCE owner, UINT uID, char *str=NULL, size_t maxlen=0);
28 	wchar_t *GetStringW(HINSTANCE hinst, HINSTANCE owner, UINT uID, wchar_t *str=NULL, size_t maxlen=0);
29 
30 	char *GetStringFromGUID(const GUID guid, HINSTANCE owner, UINT uID, char *str=NULL, size_t maxlen=0);
31 	wchar_t *GetStringFromGUIDW(const GUID guid, HINSTANCE owner, UINT uID, wchar_t *str=NULL, size_t maxlen=0);
32 
33 	HINSTANCE FindDllHandleByGUID(GUID guid);
34 	HINSTANCE FindDllHandleByString(const char* str);
35 	HINSTANCE FindDllHandleByStringW(const wchar_t* str);
36 	HINSTANCE StartLanguageSupport(HINSTANCE hinstance, const GUID guid);
37 
38 	const wchar_t *GetLanguageFolder();
39 
40 	#define LANG_IDENT_STR 0
41 	#define LANG_LANG_CODE 1
42 	#define LANG_COUNTRY_CODE 2
43 	const wchar_t *GetLanguageIdentifier(int mode);
44 
45 	HWND CreateLDialogParam(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param);
46 	INT_PTR LDialogBoxParam(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param);
47 	HMENU LoadLMenu(HINSTANCE localised, HINSTANCE original, UINT id);
48 
49 	HWND CreateLDialogParamW(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param);
50 	INT_PTR LDialogBoxParamW(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param);
51 	HMENU LoadLMenuW(HINSTANCE localised, HINSTANCE original, UINT id);
52 
53 	void* LoadResourceFromFile(HINSTANCE hinst, HINSTANCE owner, LPCTSTR lpType, LPCTSTR lpName, DWORD* size);
54 	void* LoadResourceFromFileW(HINSTANCE hinst, HINSTANCE owner, LPCWSTR lpType, LPCWSTR lpName, DWORD* size);
55 
56 	HACCEL LoadAcceleratorsA(HINSTANCE hinst, HINSTANCE owner, LPCSTR lpTableName);
57 	HACCEL LoadAcceleratorsW(HINSTANCE hinst, HINSTANCE owner, LPCWSTR lpTableName);
58 
59 	// Implemented in 5.58+
60 	// When called this will attempt to set the locale used for numeric representation
61 	// to that of the user running the current Winamp instance as long as the language
62 	// and country identifiers match those reported within the language pack (if used)
63 	//
64 	// If you're running under a different thread then this will need to be called as
65 	// the locale is set on a per thread basis which generally means anything under the
66 	// Winamp process will be handled correctly unless a UI aspect is running under a
67 	// different thread. Internally this is called within winamp.exe and vis_milk2.dll
68 	BOOL UseUserNumericLocale();
69 
70 	// Get_C_NumericLocale() is a wrapper for _create_locale(LC_NUMERIC, "C") which can
71 	// then be used in _atof_l(..), _sscanf_l(..) or other locale based functions when
72 	// you need to process numbers without localisation handling ie the "C" locale.
73 	// This function is provided for convenience unless you want to do it all manually.
74 	_locale_t Get_C_NumericLocale();
75 
76 	// Implemented in 5.7+
77 	wchar_t* FormattedSizeString(wchar_t *out, int cchLen, __int64 size);
78 
79 public:
80 	DISPATCH_CODES
81 	{
82 	    API_LANGUAGE_GETSTRING = 10,
83 		API_LANGUAGE_GETSTRINGW = 11,
84 
85 	    API_LANGUAGE_GETSTRINGFROMGUID = 12,
86 		API_LANGUAGE_GETSTRINGFROMGUIDW = 13,
87 
88 		API_LANGUAGE_GETHINSTANCEBYGUID = 20,
89 		API_LANGUAGE_GETHINSTANCEBYNAME = 21,
90 		API_LANGUAGE_GETHINSTANCEBYNAMEW = 22,
91 
92 		API_LANGUAGE_STARTUP = 30,
93 		API_LANGUAGE_SHUTDOWN = 31,
94 
95 		API_LANGUAGE_GETLANGUAGEFOLDER = 40,
96 
97 		API_LANGUAGE_CREATELDIALOGPARAM = 50,
98 		API_LANGUAGE_LDIALOGBOXPARAM = 51,
99 		API_LANGUAGE_LOADLMENU = 52,
100 		API_LANGUAGE_CREATELDIALOGPARAMW = 53,
101 		API_LANGUAGE_LDIALOGBOXPARAMW = 54,
102 		API_LANGUAGE_LOADLMENUW = 55,
103 
104 		API_LANGUAGE_GETLANGUAGEIDENTIFIER = 60,
105 
106 		API_LANGUAGE_LOADRESOURCEFROMFILE = 70,
107 		API_LANGUAGE_LOADRESOURCEFROMFILEW = 71,
108 
109 		API_LANGUAGE_LOADACCELERATORSA = 80,
110 		API_LANGUAGE_LOADACCELERATORSW = 81,
111 
112 		// Implemented in 5.58+
113 		// See UseUserNumericLocale notes
114 		API_LANGUAGE_USEUSERNUMERICLOCALE = 90,
115 		API_LANGUAGE_GET_C_NUMERICLOCALE = 91,
116 
117 		// Implemented in 5.7+
118 		API_LANGUAGE_FORMATTEDSIZESTRING = 100,
119 	};
120 };
121 
GetString(HINSTANCE hinst,HINSTANCE owner,UINT uID,char * str,size_t maxlen)122 inline char *api_language::GetString(HINSTANCE hinst, HINSTANCE owner, UINT uID, char *str, size_t maxlen)
123 {
124 	return _call(API_LANGUAGE_GETSTRING, (char * )0, hinst, owner, uID, str, maxlen);
125 }
126 
GetStringW(HINSTANCE hinst,HINSTANCE owner,UINT uID,wchar_t * str,size_t maxlen)127 inline wchar_t *api_language::GetStringW(HINSTANCE hinst, HINSTANCE owner, UINT uID, wchar_t *str, size_t maxlen)
128 {
129 	return _call(API_LANGUAGE_GETSTRINGW, (wchar_t * )0, hinst, owner, uID, str, maxlen);
130 }
131 
GetStringFromGUID(const GUID guid,HINSTANCE owner,UINT uID,char * str,size_t maxlen)132 inline char *api_language::GetStringFromGUID(const GUID guid, HINSTANCE owner, UINT uID, char *str, size_t maxlen)
133 {
134 	return _call(API_LANGUAGE_GETSTRINGFROMGUID, (char * )0, guid, owner, uID, str, maxlen);
135 }
136 
GetStringFromGUIDW(const GUID guid,HINSTANCE owner,UINT uID,wchar_t * str,size_t maxlen)137 inline wchar_t *api_language::GetStringFromGUIDW(const GUID guid, HINSTANCE owner, UINT uID, wchar_t *str, size_t maxlen)
138 {
139 	return _call(API_LANGUAGE_GETSTRINGFROMGUIDW, (wchar_t * )0, guid, owner, uID, str, maxlen);
140 }
141 
FindDllHandleByGUID(const GUID guid)142 inline HINSTANCE api_language::FindDllHandleByGUID(const GUID guid)
143 {
144 	return _call(API_LANGUAGE_GETHINSTANCEBYGUID, (HINSTANCE )0, guid);
145 }
146 
FindDllHandleByString(const char * str)147 inline HINSTANCE api_language::FindDllHandleByString(const char* str)
148 {
149 	return _call(API_LANGUAGE_GETHINSTANCEBYNAME, (HINSTANCE )0, str);
150 }
151 
FindDllHandleByStringW(const wchar_t * str)152 inline HINSTANCE api_language::FindDllHandleByStringW(const wchar_t* str)
153 {
154 	return _call(API_LANGUAGE_GETHINSTANCEBYNAMEW, (HINSTANCE )0, str);
155 }
156 
StartLanguageSupport(HINSTANCE hinstance,const GUID guid)157 inline HINSTANCE api_language::StartLanguageSupport(HINSTANCE hinstance, const GUID guid)
158 {
159 	return _call(API_LANGUAGE_STARTUP, (HINSTANCE )0, hinstance, guid);
160 }
161 
GetLanguageFolder()162 inline const wchar_t *api_language::GetLanguageFolder()
163 {
164 	return _call(API_LANGUAGE_GETLANGUAGEFOLDER, (const wchar_t *)0);
165 }
166 
CreateLDialogParam(HINSTANCE localised,HINSTANCE original,UINT id,HWND parent,DLGPROC proc,LPARAM param)167 inline HWND api_language::CreateLDialogParam(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param)
168 {
169 	return _call(API_LANGUAGE_CREATELDIALOGPARAM, (HWND)0, localised, original, id, parent, proc, param);
170 }
171 
LDialogBoxParam(HINSTANCE localised,HINSTANCE original,UINT id,HWND parent,DLGPROC proc,LPARAM param)172 inline INT_PTR api_language::LDialogBoxParam(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param)
173 {
174 	return _call(API_LANGUAGE_LDIALOGBOXPARAM, (INT_PTR)0, localised, original, id, parent, proc, param);
175 }
176 
LoadLMenu(HINSTANCE localised,HINSTANCE original,UINT id)177 inline HMENU api_language::LoadLMenu(HINSTANCE localised, HINSTANCE original, UINT id)
178 {
179 	return _call(API_LANGUAGE_LOADLMENU, (HMENU)0, localised, original, id);
180 }
181 
CreateLDialogParamW(HINSTANCE localised,HINSTANCE original,UINT id,HWND parent,DLGPROC proc,LPARAM param)182 inline HWND api_language::CreateLDialogParamW(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param)
183 {
184 	return _call(API_LANGUAGE_CREATELDIALOGPARAMW, (HWND)0, localised, original, id, parent, proc, param);
185 }
186 
LDialogBoxParamW(HINSTANCE localised,HINSTANCE original,UINT id,HWND parent,DLGPROC proc,LPARAM param)187 inline INT_PTR api_language::LDialogBoxParamW(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param)
188 {
189 	return _call(API_LANGUAGE_LDIALOGBOXPARAMW, (INT_PTR)0, localised, original, id, parent, proc, param);
190 }
191 
LoadLMenuW(HINSTANCE localised,HINSTANCE original,UINT id)192 inline HMENU api_language::LoadLMenuW(HINSTANCE localised, HINSTANCE original, UINT id)
193 {
194 	return _call(API_LANGUAGE_LOADLMENUW, (HMENU)0, localised, original, id);
195 }
196 
GetLanguageIdentifier(int mode)197 inline const wchar_t *api_language::GetLanguageIdentifier(int mode)
198 {
199 	return _call(API_LANGUAGE_GETLANGUAGEIDENTIFIER, (const wchar_t *)0, mode);
200 }
201 
LoadResourceFromFile(HINSTANCE hinst,HINSTANCE owner,LPCTSTR lpType,LPCTSTR lpName,DWORD * size)202 inline void *api_language::LoadResourceFromFile(HINSTANCE hinst, HINSTANCE owner, LPCTSTR lpType, LPCTSTR lpName, DWORD* size)
203 {
204 	return _call(API_LANGUAGE_LOADRESOURCEFROMFILE, (void*)0, hinst, owner, lpType, lpName, size);
205 }
206 
LoadResourceFromFileW(HINSTANCE hinst,HINSTANCE owner,LPCWSTR lpType,LPCWSTR lpName,DWORD * size)207 inline void *api_language::LoadResourceFromFileW(HINSTANCE hinst, HINSTANCE owner, LPCWSTR lpType, LPCWSTR lpName, DWORD* size)
208 {
209 	return _call(API_LANGUAGE_LOADRESOURCEFROMFILEW, (void*)0, hinst, owner, lpType, lpName, size);
210 }
211 
LoadAcceleratorsA(HINSTANCE hinst,HINSTANCE owner,LPCSTR lpTableName)212 inline HACCEL api_language::LoadAcceleratorsA(HINSTANCE hinst, HINSTANCE owner, LPCSTR lpTableName)
213 {
214 	return _call(API_LANGUAGE_LOADACCELERATORSA, (HACCEL)NULL, hinst, owner, lpTableName);
215 }
216 
LoadAcceleratorsW(HINSTANCE hinst,HINSTANCE owner,LPCWSTR lpTableName)217 inline HACCEL api_language::LoadAcceleratorsW(HINSTANCE hinst, HINSTANCE owner, LPCWSTR lpTableName)
218 {
219 	return _call(API_LANGUAGE_LOADACCELERATORSA, (HACCEL)NULL, hinst, owner, lpTableName);
220 }
221 
UseUserNumericLocale()222 inline BOOL api_language::UseUserNumericLocale()
223 {
224 	return _call(API_LANGUAGE_USEUSERNUMERICLOCALE, (BOOL)0);
225 }
226 
Get_C_NumericLocale()227 inline _locale_t api_language::Get_C_NumericLocale()
228 {
229 	return _call(API_LANGUAGE_GET_C_NUMERICLOCALE, (_locale_t)0);
230 }
231 
FormattedSizeString(wchar_t * out,int cchLen,__int64 size)232 inline wchar_t *api_language::FormattedSizeString(wchar_t *out, int cchLen, __int64 size)
233 {
234 	return _call(API_LANGUAGE_FORMATTEDSIZESTRING, (wchar_t*)0, out, cchLen, size);
235 }
236 
237 
238 // utility macros and relevant predefined variables for use with the service + macros
239 extern api_language *languageManager;
240 #define WASABI_API_LNG languageManager
241 
242 extern HINSTANCE api_localised_hinstance;
243 #define WASABI_API_LNG_HINST api_localised_hinstance
244 
245 extern HINSTANCE api_orig_hinstance;
246 #define WASABI_API_ORIG_HINST api_orig_hinstance
247 
248 #define WASABI_API_LNGSTR WASABI_API_LNG->GetString
249 // use this is you want a temp copy of the string
250 #define WASABI_API_LNGSTRING(uID) \
251 		WASABI_API_LNGSTR(WASABI_API_LNG_HINST,WASABI_API_ORIG_HINST,uID)
252 // use this is you want a temp copy of the string but need it to fallback to a different module
253 #define WASABI_API_LNGSTRING_HINST(hinst,uID) \
254 		WASABI_API_LNGSTR(WASABI_API_LNG_HINST,hinst,uID)
255 // use this is you want a copy of the string
256 #define WASABI_API_LNGSTRING_BUF(uID,buf,len) \
257 		WASABI_API_LNGSTR(WASABI_API_LNG_HINST,WASABI_API_ORIG_HINST,uID,buf,len)
258 // use this is you want a copy of the string but need it to fallback to a different module
259 #define WASABI_API_LNGSTRING_HINST_BUF(hinst,uID,buf,len) \
260 		WASABI_API_LNGSTR(WASABI_API_LNG_HINST,hinst,uID,buf,len)
261 
262 // unicode versions of the above macros
263 #define WASABI_API_LNGSTRW WASABI_API_LNG->GetStringW
264 #define WASABI_API_LNGSTRINGW(uID) \
265 		WASABI_API_LNGSTRW(WASABI_API_LNG_HINST,WASABI_API_ORIG_HINST,uID)
266 #define WASABI_API_LNGSTRINGW_HINST(hinst,uID) \
267 		WASABI_API_LNGSTRW(WASABI_API_LNG_HINST,hinst,uID)
268 #define WASABI_API_LNGSTRINGW_BUF(uID,buf,len) \
269 		WASABI_API_LNGSTRW(WASABI_API_LNG_HINST,WASABI_API_ORIG_HINST,uID,buf,len)
270 #define WASABI_API_LNGSTRINGW_BUF_HINST(hinst,uID,buf,len) \
271 		WASABI_API_LNGSTRW(WASABI_API_LNG_HINST,hinst,uID,buf,len)
272 
273 // Dialog handling functions (will revert back to the non-localised version if not valid/present)
274 #define WASABI_API_CREATEDIALOGPARAM(id, parent, proc, param) \
275 		WASABI_API_LNG->CreateLDialogParam(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, param)
276 #define WASABI_API_CREATEDIALOG(id, parent, proc) \
277 		WASABI_API_LNG->CreateLDialogParam(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, 0)
278 
279 #define WASABI_API_CREATEDIALOGPARAMW(id, parent, proc, param) \
280 		WASABI_API_LNG->CreateLDialogParamW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, param)
281 #define WASABI_API_CREATEDIALOGW(id, parent, proc) \
282 		WASABI_API_LNG->CreateLDialogParamW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, 0)
283 
284 #define WASABI_API_DIALOGBOXPARAM(id, parent, proc, param) \
285 		WASABI_API_LNG->LDialogBoxParam(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, param)
286 #define WASABI_API_DIALOGBOX(id, parent, proc) \
287 		WASABI_API_LNG->LDialogBoxParam(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, 0)
288 
289 #define WASABI_API_DIALOGBOXPARAMW(id, parent, proc, param) \
290 		WASABI_API_LNG->LDialogBoxParamW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, param)
291 #define WASABI_API_DIALOGBOXW(id, parent, proc) \
292 		WASABI_API_LNG->LDialogBoxParamW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, 0)
293 
294 #define WASABI_API_LOADMENU(id) \
295 		WASABI_API_LNG->LoadLMenu(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id)
296 #define WASABI_API_LOADMENUW(id) \
297 		WASABI_API_LNG->LoadLMenuW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id)
298 
299 
300 #define WASABI_API_LOADACCELERATORSA(__id) \
301 		WASABI_API_LNG->LoadAcceleratorsA(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, MAKEINTRESOURCEA(__id))
302 #define WASABI_API_LOADACCELERATORSW(__id) \
303 		WASABI_API_LNG->LoadAcceleratorsW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, MAKEINTRESOURCEW(__id))
304 
305 #ifdef UNICODE
306 #define WASABI_API_LOADACCELERATORS WASABI_API_LOADACCELERATORSW
307 #else
308 #define WASABI_API_LOADACCELERATORS WASABI_API_LOADACCELERATORSA
309 #endif
310 
311 #define WASABI_API_START_LANG(orig_hinst, guid) \
312 { \
313 	WASABI_API_ORIG_HINST = orig_hinst; \
314 	WASABI_API_LNG_HINST = WASABI_API_LNG->StartLanguageSupport(WASABI_API_ORIG_HINST,guid); \
315 }
316 
317 #define WASABI_API_LOADRESFROMFILE(lpType, lpName, size) \
318 		WASABI_API_LNG->LoadResourceFromFile(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, lpType, lpName, size)
319 #define WASABI_API_LOADRESFROMFILEW(lpType, lpName, size) \
320 		WASABI_API_LNG->LoadResourceFromFileW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, lpType, lpName, size)
321 
322 // {30AED4E5-EF10-4277-8D49-27AB5570E891}
323 static const GUID languageApiGUID =
324 { 0x30aed4e5, 0xef10, 0x4277, { 0x8d, 0x49, 0x27, 0xab, 0x55, 0x70, 0xe8, 0x91 } };
325 
326 #endif