user32: Activate an MDI child on WM_SETFOCUS as well as on WM_CHILDACTIVATE.
[wine] / dlls / user32 / lstr.c
1 /*
2  * USER string functions
3  *
4  * Copyright 1993 Yngvi Sigurjonsson (yngvi@hafro.is)
5  * Copyright 1996 Alexandre Julliard
6  * Copyright 1996 Marcus Meissner
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include "config.h"
24 #include "wine/port.h"
25
26 #include <ctype.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 #include "windef.h"
33 #include "winbase.h"
34 #include "winuser.h"
35 #include "winerror.h"
36
37 #include "wine/exception.h"
38 #include "wine/unicode.h"
39 #include "excpt.h"
40
41
42 /***********************************************************************
43  *           CharNextA   (USER32.@)
44  */
45 LPSTR WINAPI CharNextA( LPCSTR ptr )
46 {
47     if (!*ptr) return (LPSTR)ptr;
48     if (IsDBCSLeadByte( ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
49     return (LPSTR)(ptr + 1);
50 }
51
52
53 /***********************************************************************
54  *           CharNextExA   (USER32.@)
55  */
56 LPSTR WINAPI CharNextExA( WORD codepage, LPCSTR ptr, DWORD flags )
57 {
58     if (!*ptr) return (LPSTR)ptr;
59     if (IsDBCSLeadByteEx( codepage, ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
60     return (LPSTR)(ptr + 1);
61 }
62
63
64 /***********************************************************************
65  *           CharNextExW   (USER32.@)
66  */
67 LPWSTR WINAPI CharNextExW( WORD codepage, LPCWSTR ptr, DWORD flags )
68 {
69     /* doesn't make sense, there are no codepages for Unicode */
70     return NULL;
71 }
72
73
74 /***********************************************************************
75  *           CharNextW   (USER32.@)
76  */
77 LPWSTR WINAPI CharNextW(LPCWSTR x)
78 {
79     if (*x) x++;
80
81     return (LPWSTR)x;
82 }
83
84
85 /***********************************************************************
86  *           CharPrevA   (USER32.@)
87  */
88 LPSTR WINAPI CharPrevA( LPCSTR start, LPCSTR ptr )
89 {
90     while (*start && (start < ptr))
91     {
92         LPCSTR next = CharNextA( start );
93         if (next >= ptr) break;
94         start = next;
95     }
96     return (LPSTR)start;
97 }
98
99
100 /***********************************************************************
101  *           CharPrevExA   (USER32.@)
102  */
103 LPSTR WINAPI CharPrevExA( WORD codepage, LPCSTR start, LPCSTR ptr, DWORD flags )
104 {
105     while (*start && (start < ptr))
106     {
107         LPCSTR next = CharNextExA( codepage, start, flags );
108         if (next >= ptr) break;
109         start = next;
110     }
111     return (LPSTR)start;
112 }
113
114
115 /***********************************************************************
116  *           CharPrevExW   (USER32.@)
117  */
118 LPSTR WINAPI CharPrevExW( WORD codepage, LPCWSTR start, LPCWSTR ptr, DWORD flags )
119 {
120     /* doesn't make sense, there are no codepages for Unicode */
121     return NULL;
122 }
123
124
125 /***********************************************************************
126  *           CharPrevW   (USER32.@)
127  */
128 LPWSTR WINAPI CharPrevW(LPCWSTR start,LPCWSTR x)
129 {
130     if (x>start) return (LPWSTR)(x-1);
131     else return (LPWSTR)x;
132 }
133
134
135 /***********************************************************************
136  *           CharToOemA   (USER32.@)
137  */
138 BOOL WINAPI CharToOemA( LPCSTR s, LPSTR d )
139 {
140     if ( !s || !d ) return TRUE;
141     return CharToOemBuffA( s, d, strlen( s ) + 1 );
142 }
143
144
145 /***********************************************************************
146  *           CharToOemBuffA   (USER32.@)
147  */
148 BOOL WINAPI CharToOemBuffA( LPCSTR s, LPSTR d, DWORD len )
149 {
150     WCHAR *bufW;
151
152     bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
153     if( bufW )
154     {
155         MultiByteToWideChar( CP_ACP, 0, s, len, bufW, len );
156         WideCharToMultiByte( CP_OEMCP, 0, bufW, len, d, len, NULL, NULL );
157         HeapFree( GetProcessHeap(), 0, bufW );
158     }
159     return TRUE;
160 }
161
162
163 /***********************************************************************
164  *           CharToOemBuffW   (USER32.@)
165  */
166 BOOL WINAPI CharToOemBuffW( LPCWSTR s, LPSTR d, DWORD len )
167 {
168    if ( !s || !d ) return TRUE;
169     WideCharToMultiByte( CP_OEMCP, 0, s, len, d, len, NULL, NULL );
170     return TRUE;
171 }
172
173
174 /***********************************************************************
175  *           CharToOemW   (USER32.@)
176  */
177 BOOL WINAPI CharToOemW( LPCWSTR s, LPSTR d )
178 {
179     return CharToOemBuffW( s, d, strlenW( s ) + 1 );
180 }
181
182
183 /***********************************************************************
184  *           OemToCharA   (USER32.@)
185  */
186 BOOL WINAPI OemToCharA( LPCSTR s, LPSTR d )
187 {
188     return OemToCharBuffA( s, d, strlen( s ) + 1 );
189 }
190
191
192 /***********************************************************************
193  *           OemToCharBuffA   (USER32.@)
194  */
195 BOOL WINAPI OemToCharBuffA( LPCSTR s, LPSTR d, DWORD len )
196 {
197     WCHAR *bufW;
198
199     bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
200     if( bufW )
201     {
202         MultiByteToWideChar( CP_OEMCP, 0, s, len, bufW, len );
203         WideCharToMultiByte( CP_ACP, 0, bufW, len, d, len, NULL, NULL );
204         HeapFree( GetProcessHeap(), 0, bufW );
205     }
206     return TRUE;
207 }
208
209
210 /***********************************************************************
211  *           OemToCharBuffW   (USER32.@)
212  */
213 BOOL WINAPI OemToCharBuffW( LPCSTR s, LPWSTR d, DWORD len )
214 {
215     MultiByteToWideChar( CP_OEMCP, 0, s, len, d, len );
216     return TRUE;
217 }
218
219
220 /***********************************************************************
221  *           OemToCharW   (USER32.@)
222  */
223 BOOL WINAPI OemToCharW( LPCSTR s, LPWSTR d )
224 {
225     return OemToCharBuffW( s, d, strlen( s ) + 1 );
226 }
227
228
229 /***********************************************************************
230  *           CharLowerA   (USER32.@)
231  */
232 LPSTR WINAPI CharLowerA(LPSTR str)
233 {
234     if (!HIWORD(str))
235     {
236         char ch = LOWORD(str);
237         CharLowerBuffA( &ch, 1 );
238         return (LPSTR)(UINT_PTR)(BYTE)ch;
239     }
240
241     __TRY
242     {
243         CharLowerBuffA( str, strlen(str) );
244     }
245     __EXCEPT_PAGE_FAULT
246     {
247         SetLastError( ERROR_INVALID_PARAMETER );
248         return NULL;
249     }
250     __ENDTRY
251     return str;
252 }
253
254
255 /***********************************************************************
256  *           CharUpperA   (USER32.@)
257  */
258 LPSTR WINAPI CharUpperA(LPSTR str)
259 {
260     if (!HIWORD(str))
261     {
262         char ch = LOWORD(str);
263         CharUpperBuffA( &ch, 1 );
264         return (LPSTR)(UINT_PTR)(BYTE)ch;
265     }
266
267     __TRY
268     {
269         CharUpperBuffA( str, strlen(str) );
270     }
271     __EXCEPT_PAGE_FAULT
272     {
273         SetLastError( ERROR_INVALID_PARAMETER );
274         return NULL;
275     }
276     __ENDTRY
277     return str;
278 }
279
280
281 /***********************************************************************
282  *           CharLowerW   (USER32.@)
283  */
284 LPWSTR WINAPI CharLowerW(LPWSTR x)
285 {
286     if (HIWORD(x)) return strlwrW(x);
287     else return (LPWSTR)((UINT_PTR)tolowerW(LOWORD(x)));
288 }
289
290
291 /***********************************************************************
292  *           CharUpperW   (USER32.@)
293  */
294 LPWSTR WINAPI CharUpperW(LPWSTR x)
295 {
296     if (HIWORD(x)) return struprW(x);
297     else return (LPWSTR)((UINT_PTR)toupperW(LOWORD(x)));
298 }
299
300
301 /***********************************************************************
302  *           CharLowerBuffA   (USER32.@)
303  */
304 DWORD WINAPI CharLowerBuffA( LPSTR str, DWORD len )
305 {
306     DWORD lenW;
307     WCHAR buffer[32];
308     WCHAR *strW = buffer;
309
310     if (!str) return 0; /* YES */
311
312     lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
313     if (lenW > sizeof(buffer)/sizeof(WCHAR))
314     {
315         strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
316         if (!strW) return 0;
317     }
318     MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
319     CharLowerBuffW(strW, lenW);
320     len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
321     if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
322     return len;
323 }
324
325
326 /***********************************************************************
327  *           CharLowerBuffW   (USER32.@)
328  */
329 DWORD WINAPI CharLowerBuffW( LPWSTR str, DWORD len )
330 {
331     DWORD ret = len;
332     if (!str) return 0; /* YES */
333     for (; len; len--, str++) *str = tolowerW(*str);
334     return ret;
335 }
336
337
338 /***********************************************************************
339  *           CharUpperBuffA   (USER32.@)
340  */
341 DWORD WINAPI CharUpperBuffA( LPSTR str, DWORD len )
342 {
343     DWORD lenW;
344     WCHAR buffer[32];
345     WCHAR *strW = buffer;
346
347     if (!str) return 0; /* YES */
348
349     lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
350     if (lenW > sizeof(buffer)/sizeof(WCHAR))
351     {
352         strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
353         if (!strW) return 0;
354     }
355     MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
356     CharUpperBuffW(strW, lenW);
357     len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
358     if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
359     return len;
360 }
361
362
363 /***********************************************************************
364  *           CharUpperBuffW   (USER32.@)
365  */
366 DWORD WINAPI CharUpperBuffW( LPWSTR str, DWORD len )
367 {
368     DWORD ret = len;
369     if (!str) return 0; /* YES */
370     for (; len; len--, str++) *str = toupperW(*str);
371     return ret;
372 }
373
374
375 /***********************************************************************
376  *           IsCharLower    (USER.436)
377  *           IsCharLowerA   (USER32.@)
378  */
379 BOOL WINAPI IsCharLowerA(CHAR x)
380 {
381     WCHAR wch;
382     MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
383     return IsCharLowerW(wch);
384 }
385
386
387 /***********************************************************************
388  *           IsCharLowerW   (USER32.@)
389  */
390 BOOL WINAPI IsCharLowerW(WCHAR x)
391 {
392     return (get_char_typeW(x) & C1_LOWER) != 0;
393 }
394
395
396 /***********************************************************************
397  *           IsCharUpper    (USER.435)
398  *           IsCharUpperA   (USER32.@)
399  */
400 BOOL WINAPI IsCharUpperA(CHAR x)
401 {
402     WCHAR wch;
403     MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
404     return IsCharUpperW(wch);
405 }
406
407
408 /***********************************************************************
409  *           IsCharUpperW   (USER32.@)
410  */
411 BOOL WINAPI IsCharUpperW(WCHAR x)
412 {
413     return (get_char_typeW(x) & C1_UPPER) != 0;
414 }
415
416
417 /***********************************************************************
418  *           IsCharAlphaNumeric    (USER.434)
419  *           IsCharAlphaNumericA   (USER32.@)
420  */
421 BOOL WINAPI IsCharAlphaNumericA(CHAR x)
422 {
423     WCHAR wch;
424     MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
425     return IsCharAlphaNumericW(wch);
426 }
427
428
429 /***********************************************************************
430  *           IsCharAlphaNumericW   (USER32.@)
431  */
432 BOOL WINAPI IsCharAlphaNumericW(WCHAR x)
433 {
434     return (get_char_typeW(x) & (C1_ALPHA|C1_DIGIT)) != 0;
435 }
436
437
438 /***********************************************************************
439  *           IsCharAlpha    (USER.433)
440  *           IsCharAlphaA   (USER32.@)
441  */
442 BOOL WINAPI IsCharAlphaA(CHAR x)
443 {
444     WCHAR wch;
445     MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
446     return IsCharAlphaW(wch);
447 }
448
449
450 /***********************************************************************
451  *           IsCharAlphaW   (USER32.@)
452  */
453 BOOL WINAPI IsCharAlphaW(WCHAR x)
454 {
455     return (get_char_typeW(x) & C1_ALPHA) != 0;
456 }