If the dibsection is based on a file-mapping object, then make sure
[wine.git] / dlls / comctl32 / string.c
blob45163fedc062c880c36e959fa92976a8937aff98
1 /*
2 * String manipulation functions
4 * Copyright 1998 Eric Kohl
5 * 1998 Juergen Schmied <j.schmied@metronet.de>
6 * 2000 Eric Kohl for CodeWeavers
7 * Copyright 2002 Jon Griffiths
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <stdarg.h>
26 #include <string.h>
27 #include <stdlib.h> /* atoi */
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "winnls.h"
34 #include "wine/unicode.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
40 /*************************************************************************
41 * COMCTL32_ChrCmpHelperA
43 * Internal helper for ChrCmpA/COMCTL32_ChrCmpIA.
45 * NOTES
46 * Both this function and its Unicode counterpart are very inneficient. To
47 * fix this, CompareString must be completely implemented and optimised
48 * first. Then the core character test can be taken out of that function and
49 * placed here, so that it need never be called at all. Until then, do not
50 * attempt to optimise this code unless you are willing to test that it
51 * still performs correctly.
53 static BOOL COMCTL32_ChrCmpHelperA(WORD ch1, WORD ch2, DWORD dwFlags)
55 char str1[3], str2[3];
57 str1[0] = LOBYTE(ch1);
58 if (IsDBCSLeadByte(str1[0]))
60 str1[1] = HIBYTE(ch1);
61 str1[2] = '\0';
63 else
64 str1[1] = '\0';
66 str2[0] = LOBYTE(ch2);
67 if (IsDBCSLeadByte(str2[0]))
69 str2[1] = HIBYTE(ch2);
70 str2[2] = '\0';
72 else
73 str2[1] = '\0';
75 return CompareStringA(GetThreadLocale(), dwFlags, str1, -1, str2, -1) - 2;
78 /*************************************************************************
79 * COMCTL32_ChrCmpHelperW
81 * Internal helper for COMCTL32_ChrCmpW/ChrCmpIW.
83 static BOOL COMCTL32_ChrCmpHelperW(WCHAR ch1, WCHAR ch2, DWORD dwFlags)
85 WCHAR str1[2], str2[2];
87 str1[0] = ch1;
88 str1[1] = '\0';
89 str2[0] = ch2;
90 str2[1] = '\0';
91 return CompareStringW(GetThreadLocale(), dwFlags, str1, 2, str2, 2) - 2;
94 /*************************************************************************
95 * COMCTL32_ChrCmpA (internal)
97 * Internal helper function.
99 static BOOL COMCTL32_ChrCmpA(WORD ch1, WORD ch2)
101 return COMCTL32_ChrCmpHelperA(ch1, ch2, 0);
104 /*************************************************************************
105 * COMCTL32_ChrCmpIA (internal)
107 * Compare two characters, ignoring case.
109 * PARAMS
110 * ch1 [I] First character to compare
111 * ch2 [I] Second character to compare
113 * RETURNS
114 * FALSE, if the characters are equal.
115 * Non-zero otherwise.
117 static BOOL COMCTL32_ChrCmpIA(WORD ch1, WORD ch2)
119 TRACE("(%d,%d)\n", ch1, ch2);
121 return COMCTL32_ChrCmpHelperA(ch1, ch2, NORM_IGNORECASE);
124 /*************************************************************************
125 * COMCTL32_ChrCmpW
127 * Internal helper function.
129 static BOOL COMCTL32_ChrCmpW(WCHAR ch1, WCHAR ch2)
131 return COMCTL32_ChrCmpHelperW(ch1, ch2, 0);
134 /*************************************************************************
135 * COMCTL32_ChrCmpIW
137 * Internal helper function.
139 static BOOL COMCTL32_ChrCmpIW(WCHAR ch1, WCHAR ch2)
141 return COMCTL32_ChrCmpHelperW(ch1, ch2, NORM_IGNORECASE);
144 /**************************************************************************
145 * StrChrA [COMCTL32.350]
147 * Find a given character in a string.
149 * PARAMS
150 * lpszStr [I] String to search in.
151 * ch [I] Character to search for.
153 * RETURNS
154 * Success: A pointer to the first occurrence of ch in lpszStr, or NULL if
155 * not found.
156 * Failure: NULL, if any arguments are invalid.
158 LPSTR WINAPI StrChrA(LPCSTR lpszStr, WORD ch)
160 TRACE("(%s,%i)\n", debugstr_a(lpszStr), ch);
162 if (lpszStr)
164 while (*lpszStr)
166 if (!COMCTL32_ChrCmpA(*lpszStr, ch))
167 return (LPSTR)lpszStr;
168 lpszStr = CharNextA(lpszStr);
171 return NULL;
174 /*************************************************************************
175 * COMCTL32_StrStrHelperA
177 * Internal implementation of StrStrA/StrStrIA
179 static LPSTR COMCTL32_StrStrHelperA(LPCSTR lpszStr, LPCSTR lpszSearch,
180 int (*pStrCmpFn)(LPCSTR,LPCSTR,size_t))
182 size_t iLen;
184 if (!lpszStr || !lpszSearch || !*lpszSearch)
185 return NULL;
187 iLen = strlen(lpszSearch);
189 while (*lpszStr)
191 if (!pStrCmpFn(lpszStr, lpszSearch, iLen))
192 return (LPSTR)lpszStr;
193 lpszStr = CharNextA(lpszStr);
195 return NULL;
198 /*************************************************************************
199 * COMCTL32_StrStrHelperW
201 * Internal implementation of StrStrW/StrStrIW
203 static LPWSTR COMCTL32_StrStrHelperW(LPCWSTR lpszStr, LPCWSTR lpszSearch,
204 int (*pStrCmpFn)(LPCWSTR,LPCWSTR,int))
206 int iLen;
208 if (!lpszStr || !lpszSearch || !*lpszSearch)
209 return NULL;
211 iLen = strlenW(lpszSearch);
213 while (*lpszStr)
215 if (!pStrCmpFn(lpszStr, lpszSearch, iLen))
216 return (LPWSTR)lpszStr;
217 lpszStr = CharNextW(lpszStr);
219 return NULL;
222 /**************************************************************************
223 * StrStrIA [COMCTL32.355]
225 * Find a substring within a string, ignoring case.
227 * PARAMS
228 * lpszStr [I] String to search in
229 * lpszSearch [I] String to look for
231 * RETURNS
232 * The start of lpszSearch within lpszStr, or NULL if not found.
234 LPSTR WINAPI StrStrIA(LPCSTR lpszStr, LPCSTR lpszSearch)
236 TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
238 return COMCTL32_StrStrHelperA(lpszStr, lpszSearch, strncasecmp);
241 /**************************************************************************
242 * StrToIntA [COMCTL32.357]
244 * Read a signed integer from a string.
246 * PARAMS
247 * lpszStr [I] String to read integer from
249 * RETURNS
250 * The signed integer value represented by the string, or 0 if no integer is
251 * present.
253 INT WINAPI StrToIntA (LPSTR lpszStr)
255 return atoi(lpszStr);
258 /**************************************************************************
259 * StrStrIW [COMCTL32.363]
261 * See StrStrIA.
263 LPWSTR WINAPI StrStrIW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
265 TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
267 return COMCTL32_StrStrHelperW(lpszStr, lpszSearch, strncmpiW);
270 /**************************************************************************
271 * StrToIntW [COMCTL32.365]
273 * See StrToIntA.
275 INT WINAPI StrToIntW (LPWSTR lpString)
277 return atoiW(lpString);
280 /*************************************************************************
281 * COMCTL32_StrSpnHelperA (internal)
283 * Internal implementation of StrSpnA/StrCSpnA/StrCSpnIA
285 static int COMCTL32_StrSpnHelperA(LPCSTR lpszStr, LPCSTR lpszMatch,
286 LPSTR (WINAPI *pStrChrFn)(LPCSTR,WORD),
287 BOOL bInvert)
289 LPCSTR lpszRead = lpszStr;
290 if (lpszStr && *lpszStr && lpszMatch)
292 while (*lpszRead)
294 LPCSTR lpszTest = pStrChrFn(lpszMatch, *lpszRead);
296 if (!bInvert && !lpszTest)
297 break;
298 if (bInvert && lpszTest)
299 break;
300 lpszRead = CharNextA(lpszRead);
303 return lpszRead - lpszStr;
306 /**************************************************************************
307 * StrCSpnA [COMCTL32.356]
309 * Find the length of the start of a string that does not contain certain
310 * characters.
312 * PARAMS
313 * lpszStr [I] String to search
314 * lpszMatch [I] Characters that cannot be in the substring
316 * RETURNS
317 * The length of the part of lpszStr containing only chars not in lpszMatch,
318 * or 0 if any parameter is invalid.
320 int WINAPI StrCSpnA(LPCSTR lpszStr, LPCSTR lpszMatch)
322 TRACE("(%s,%s)\n",debugstr_a(lpszStr), debugstr_a(lpszMatch));
324 return COMCTL32_StrSpnHelperA(lpszStr, lpszMatch, StrChrA, TRUE);
327 /**************************************************************************
328 * StrChrW [COMCTL32.358]
330 * See StrChrA.
332 LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
334 LPWSTR lpszRet = NULL;
336 TRACE("(%s,%i)\n", debugstr_w(lpszStr), ch);
338 if (lpszStr)
339 lpszRet = strchrW(lpszStr, ch);
340 return lpszRet;
343 /**************************************************************************
344 * StrCmpNA [COMCTL32.352]
346 * Compare two strings, up to a maximum length.
348 * PARAMS
349 * lpszStr [I] First string to compare
350 * lpszComp [I] Second string to compare
351 * iLen [I] Maximum number of chars to compare.
353 * RETURNS
354 * An integer less than, equal to or greater than 0, indicating that
355 * lpszStr is less than, the same, or greater than lpszComp.
357 INT WINAPI StrCmpNA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen)
359 INT iRet;
361 TRACE("(%s,%s,%i)\n", debugstr_a(lpszStr), debugstr_a(lpszComp), iLen);
363 iRet = CompareStringA(GetThreadLocale(), 0, lpszStr, iLen, lpszComp, iLen);
364 return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0;
367 /**************************************************************************
368 * StrCmpNIA [COMCTL32.353]
370 * Compare two strings, up to a maximum length, ignoring case.
372 * PARAMS
373 * lpszStr [I] First string to compare
374 * lpszComp [I] Second string to compare
375 * iLen [I] Maximum number of chars to compare.
377 * RETURNS
378 * An integer less than, equal to or greater than 0, indicating that
379 * lpszStr is less than, the same, or greater than lpszComp.
381 int WINAPI StrCmpNIA(LPCSTR lpszStr, LPCSTR lpszComp, int iLen)
383 INT iRet;
385 TRACE("(%s,%s,%i)\n", debugstr_a(lpszStr), debugstr_a(lpszComp), iLen);
387 iRet = CompareStringA(GetThreadLocale(), NORM_IGNORECASE, lpszStr, iLen, lpszComp, iLen);
388 return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0;
391 /*************************************************************************
392 * StrCmpNIW [COMCTL32.361]
394 * See StrCmpNIA.
396 INT WINAPI StrCmpNIW(LPCWSTR lpszStr, LPCWSTR lpszComp, int iLen)
398 INT iRet;
400 TRACE("(%s,%s,%i)\n", debugstr_w(lpszStr), debugstr_w(lpszComp), iLen);
402 iRet = CompareStringW(GetThreadLocale(), NORM_IGNORECASE, lpszStr, iLen, lpszComp, iLen);
403 return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0;
406 /**************************************************************************
407 * StrCmpNW [COMCTL32.360]
409 * See StrCmpNA.
411 INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
413 INT iRet;
415 TRACE("(%s,%s,%i)\n", debugstr_w(lpszStr), debugstr_w(lpszComp), iLen);
417 iRet = CompareStringW(GetThreadLocale(), 0, lpszStr, iLen, lpszComp, iLen);
418 return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0;
421 /**************************************************************************
422 * StrRChrA [COMCTL32.351]
424 * Find the last occurrence of a character in string.
426 * PARAMS
427 * lpszStr [I] String to search in
428 * lpszEnd [I] Place to end search, or NULL to search until the end of lpszStr
429 * ch [I] Character to search for.
431 * RETURNS
432 * Success: A pointer to the last occurrence of ch in lpszStr before lpszEnd,
433 * or NULL if not found.
434 * Failure: NULL, if any arguments are invalid.
436 LPSTR WINAPI StrRChrA(LPCSTR lpszStr, LPCSTR lpszEnd, WORD ch)
438 LPCSTR lpszRet = NULL;
440 TRACE("(%s,%s,%x)\n", debugstr_a(lpszStr), debugstr_a(lpszEnd), ch);
442 if (lpszStr)
444 WORD ch2;
446 if (!lpszEnd)
447 lpszEnd = lpszStr + lstrlenA(lpszStr);
449 while (*lpszStr && lpszStr <= lpszEnd)
451 ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | lpszStr[1] : *lpszStr;
453 if (!COMCTL32_ChrCmpA(ch, ch2))
454 lpszRet = lpszStr;
455 lpszStr = CharNextA(lpszStr);
458 return (LPSTR)lpszRet;
462 /**************************************************************************
463 * StrRChrW [COMCTL32.359]
465 * See StrRChrA.
467 LPWSTR WINAPI StrRChrW(LPCWSTR lpszStr, LPCWSTR lpszEnd, WORD ch)
469 LPCWSTR lpszRet = NULL;
471 TRACE("(%s,%s,%x)\n", debugstr_w(lpszStr), debugstr_w(lpszEnd), ch);
473 if (lpszStr)
475 if (!lpszEnd)
476 lpszEnd = lpszStr + strlenW(lpszStr);
478 while (*lpszStr && lpszStr <= lpszEnd)
480 if (!COMCTL32_ChrCmpW(ch, *lpszStr))
481 lpszRet = lpszStr;
482 lpszStr = CharNextW(lpszStr);
485 return (LPWSTR)lpszRet;
488 /**************************************************************************
489 * StrStrA [COMCTL32.354]
491 * Find a substring within a string.
493 * PARAMS
494 * lpszStr [I] String to search in
495 * lpszSearch [I] String to look for
497 * RETURNS
498 * The start of lpszSearch within lpszStr, or NULL if not found.
500 LPSTR WINAPI StrStrA(LPCSTR lpszStr, LPCSTR lpszSearch)
502 TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
504 return COMCTL32_StrStrHelperA(lpszStr, lpszSearch, strncmp);
507 /**************************************************************************
508 * StrStrW [COMCTL32.362]
510 * See StrStrA.
512 LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
514 TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
516 return COMCTL32_StrStrHelperW(lpszStr, lpszSearch, strncmpW);
519 /*************************************************************************
520 * StrChrIA [COMCTL32.366]
522 * Find a given character in a string, ignoring case.
524 * PARAMS
525 * lpszStr [I] String to search in.
526 * ch [I] Character to search for.
528 * RETURNS
529 * Success: A pointer to the first occurrence of ch in lpszStr, or NULL if
530 * not found.
531 * Failure: NULL, if any arguments are invalid.
533 LPSTR WINAPI StrChrIA(LPCSTR lpszStr, WORD ch)
535 TRACE("(%s,%i)\n", debugstr_a(lpszStr), ch);
537 if (lpszStr)
539 while (*lpszStr)
541 if (!COMCTL32_ChrCmpIA(*lpszStr, ch))
542 return (LPSTR)lpszStr;
543 lpszStr = CharNextA(lpszStr);
546 return NULL;
549 /*************************************************************************
550 * StrChrIW [COMCTL32.367]
552 * See StrChrA.
554 LPWSTR WINAPI StrChrIW(LPCWSTR lpszStr, WCHAR ch)
556 TRACE("(%s,%i)\n", debugstr_w(lpszStr), ch);
558 if (lpszStr)
560 ch = toupperW(ch);
561 while (*lpszStr)
563 if (toupperW(*lpszStr) == ch)
564 return (LPWSTR)lpszStr;
565 lpszStr = CharNextW(lpszStr);
567 lpszStr = NULL;
569 return (LPWSTR)lpszStr;
572 /*************************************************************************
573 * StrRStrIA [COMCTL32.372]
575 * Find the last occurrence of a substring within a string.
577 * PARAMS
578 * lpszStr [I] String to search in
579 * lpszEnd [I] End of lpszStr
580 * lpszSearch [I] String to look for
582 * RETURNS
583 * The last occurrence lpszSearch within lpszStr, or NULL if not found.
585 LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch)
587 LPSTR lpszRet = NULL;
588 WORD ch1, ch2;
589 INT iLen;
591 TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
593 if (!lpszStr || !lpszSearch || !*lpszSearch)
594 return NULL;
596 if (!lpszEnd)
597 lpszEnd = lpszStr + lstrlenA(lpszStr);
599 if (IsDBCSLeadByte(*lpszSearch))
600 ch1 = *lpszSearch << 8 | lpszSearch[1];
601 else
602 ch1 = *lpszSearch;
603 iLen = lstrlenA(lpszSearch);
605 while (lpszStr <= lpszEnd && *lpszStr)
607 ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | lpszStr[1] : *lpszStr;
608 if (!COMCTL32_ChrCmpIA(ch1, ch2))
610 if (!StrCmpNIA(lpszStr, lpszSearch, iLen))
611 lpszRet = (LPSTR)lpszStr;
613 lpszStr = CharNextA(lpszStr);
615 return lpszRet;
618 /*************************************************************************
619 * StrRStrIW [COMCTL32.373]
621 * See StrRStrIA.
623 LPWSTR WINAPI StrRStrIW(LPCWSTR lpszStr, LPCWSTR lpszEnd, LPCWSTR lpszSearch)
625 LPWSTR lpszRet = NULL;
626 INT iLen;
628 TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
630 if (!lpszStr || !lpszSearch || !*lpszSearch)
631 return NULL;
633 if (!lpszEnd)
634 lpszEnd = lpszStr + strlenW(lpszStr);
636 iLen = strlenW(lpszSearch);
638 while (lpszStr <= lpszEnd && *lpszStr)
640 if (!COMCTL32_ChrCmpIW(*lpszSearch, *lpszStr))
642 if (!StrCmpNIW(lpszStr, lpszSearch, iLen))
643 lpszRet = (LPWSTR)lpszStr;
645 lpszStr = CharNextW(lpszStr);
647 return lpszRet;
650 /*************************************************************************
651 * COMCTL32_StrSpnHelperW
653 * Internal implementation of StrSpnW/StrCSpnW/StrCSpnIW
655 static int COMCTL32_StrSpnHelperW(LPCWSTR lpszStr, LPCWSTR lpszMatch,
656 LPWSTR (WINAPI *pStrChrFn)(LPCWSTR,WCHAR),
657 BOOL bInvert)
659 LPCWSTR lpszRead = lpszStr;
660 if (lpszStr && *lpszStr && lpszMatch)
662 while (*lpszRead)
664 LPCWSTR lpszTest = pStrChrFn(lpszMatch, *lpszRead);
666 if (!bInvert && !lpszTest)
667 break;
668 if (bInvert && lpszTest)
669 break;
670 lpszRead = CharNextW(lpszRead);
673 return lpszRead - lpszStr;
676 /*************************************************************************
677 * StrCSpnIA [COMCTL32.374]
679 * Find the length of the start of a string that does not contain certain
680 * characters, ignoring case.
682 * PARAMS
683 * lpszStr [I] String to search
684 * lpszMatch [I] Characters that cannot be in the substring
686 * RETURNS
687 * The length of the part of lpszStr containing only chars not in lpszMatch,
688 * or 0 if any parameter is invalid.
690 int WINAPI StrCSpnIA(LPCSTR lpszStr, LPCSTR lpszMatch)
692 TRACE("(%s,%s)\n",debugstr_a(lpszStr), debugstr_a(lpszMatch));
694 return COMCTL32_StrSpnHelperA(lpszStr, lpszMatch, StrChrIA, TRUE);
697 /*************************************************************************
698 * StrCSpnIW [COMCTL32.375]
700 * See StrCSpnIA.
702 int WINAPI StrCSpnIW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
704 TRACE("(%s,%s)\n",debugstr_w(lpszStr), debugstr_w(lpszMatch));
706 return COMCTL32_StrSpnHelperW(lpszStr, lpszMatch, StrChrIW, TRUE);
709 /**************************************************************************
710 * StrRChrIA [COMCTL32.368]
712 * Find the last occurrence of a character in string, ignoring case.
714 * PARAMS
715 * lpszStr [I] String to search in
716 * lpszEnd [I] Place to end search, or NULL to search until the end of lpszStr
717 * ch [I] Character to search for.
719 * RETURNS
720 * Success: A pointer to the last occurrence of ch in lpszStr before lpszEnd,
721 * or NULL if not found.
722 * Failure: NULL, if any arguments are invalid.
724 LPSTR WINAPI StrRChrIA(LPCSTR lpszStr, LPCSTR lpszEnd, WORD ch)
726 LPCSTR lpszRet = NULL;
728 TRACE("(%s,%s,%x)\n", debugstr_a(lpszStr), debugstr_a(lpszEnd), ch);
730 if (lpszStr)
732 WORD ch2;
734 if (!lpszEnd)
735 lpszEnd = lpszStr + lstrlenA(lpszStr);
737 while (*lpszStr && lpszStr <= lpszEnd)
739 ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | lpszStr[1] : *lpszStr;
741 if (ch == ch2)
742 lpszRet = lpszStr;
743 lpszStr = CharNextA(lpszStr);
746 return (LPSTR)lpszRet;
749 /**************************************************************************
750 * StrRChrIW [COMCTL32.369]
752 * See StrRChrIA.
754 LPWSTR WINAPI StrRChrIW(LPCWSTR lpszStr, LPCWSTR lpszEnd, WORD ch)
756 LPCWSTR lpszRet = NULL;
758 TRACE("(%s,%s,%x)\n", debugstr_w(lpszStr), debugstr_w(lpszEnd), ch);
760 if (lpszStr)
762 if (!lpszEnd)
763 lpszEnd = lpszStr + strlenW(lpszStr);
765 while (*lpszStr && lpszStr <= lpszEnd)
767 if (ch == *lpszStr)
768 lpszRet = lpszStr;
769 lpszStr = CharNextW(lpszStr);
772 return (LPWSTR)lpszRet;
775 /*************************************************************************
776 * StrCSpnW [COMCTL32.364]
778 * See StrCSpnA.
780 int WINAPI StrCSpnW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
782 TRACE("(%s,%s)\n",debugstr_w(lpszStr), debugstr_w(lpszMatch));
784 return COMCTL32_StrSpnHelperW(lpszStr, lpszMatch, StrChrW, TRUE);
787 /*************************************************************************
788 * IntlStrEqWorkerA [COMCTL32.376]
790 * Compare two strings.
792 * PARAMS
793 * bCase [I] Whether to compare case sensitively
794 * lpszStr [I] First string to compare
795 * lpszComp [I] Second string to compare
796 * iLen [I] Length to compare
798 * RETURNS
799 * TRUE If the strings are equal.
800 * FALSE Otherwise.
802 BOOL WINAPI IntlStrEqWorkerA(BOOL bCase, LPCSTR lpszStr, LPCSTR lpszComp,
803 int iLen)
805 DWORD dwFlags = LOCALE_USE_CP_ACP;
806 int iRet;
808 TRACE("(%d,%s,%s,%d)\n", bCase,
809 debugstr_a(lpszStr), debugstr_a(lpszComp), iLen);
811 /* FIXME: These flags are undocumented and unknown by our CompareString.
812 * We need defines for them.
814 dwFlags |= bCase ? 0x10000000 : 0x10000001;
816 iRet = CompareStringA(GetThreadLocale(),
817 dwFlags, lpszStr, iLen, lpszComp, iLen);
819 if (!iRet)
820 iRet = CompareStringA(2048, dwFlags, lpszStr, iLen, lpszComp, iLen);
822 return iRet == 2 ? TRUE : FALSE;
825 /*************************************************************************
826 * IntlStrEqWorkerW [COMCTL32.377]
828 * See IntlStrEqWorkerA.
830 BOOL WINAPI IntlStrEqWorkerW(BOOL bCase, LPCWSTR lpszStr, LPCWSTR lpszComp,
831 int iLen)
833 DWORD dwFlags;
834 int iRet;
836 TRACE("(%d,%s,%s,%d)\n", bCase,
837 debugstr_w(lpszStr),debugstr_w(lpszComp), iLen);
839 /* FIXME: These flags are undocumented and unknown by our CompareString.
840 * We need defines for them.
842 dwFlags = bCase ? 0x10000000 : 0x10000001;
844 iRet = CompareStringW(GetThreadLocale(),
845 dwFlags, lpszStr, iLen, lpszComp, iLen);
847 if (!iRet)
848 iRet = CompareStringW(2048, dwFlags, lpszStr, iLen, lpszComp, iLen);
850 return iRet == 2 ? TRUE : FALSE;