Commented out unused variables to prevent needless compiler warnings.
[wine.git] / dlls / comctl32 / comctl32undoc.c
blobcd1759937d1848aa1cbbbb9f0b59cb56e182701e
1 /*
2 * Undocumented functions from COMCTL32.DLL
4 * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
5 * 1998 Juergen Schmied <j.schmied@metronet.de>
6 * NOTES
7 * All of these functions are UNDOCUMENTED!! And I mean UNDOCUMENTED!!!!
8 * Do NOT rely on names or contents of undocumented structures and types!!!
9 * These functions are used by EXPLORER.EXE, IEXPLORE.EXE and
10 * COMCTL32.DLL (internally).
12 * TODO
13 * - Add more functions.
14 * - Write some documentation.
17 #include <string.h>
18 #include <stdlib.h>
19 #include <ctype.h>
20 #include "windows.h"
21 #include "commctrl.h"
22 #include "heap.h"
23 #include "debug.h"
26 extern HANDLE32 COMCTL32_hHeap; /* handle to the private heap */
29 * We put some function prototypes here that don't seem to belong in
30 * any header file. When they find their place, we can remove them.
32 extern LPWSTR __cdecl CRTDLL_wcschr(LPCWSTR, WCHAR);
33 extern LPSTR WINAPI lstrrchr(LPCSTR, LPCSTR, WORD);
34 extern LPWSTR WINAPI lstrrchrw(LPCWSTR, LPCWSTR, WORD);
35 extern LPWSTR WINAPI strstrw(LPCWSTR, LPCWSTR);
38 /**************************************************************************
39 * DPA_Merge [COMCTL32.11]
41 * PARAMS
42 * hdpa1 [I] handle to a dynamic pointer array
43 * hdpa2 [I] handle to a dynamic pointer array
44 * dwFlags [I] flags
45 * pfnSort [I] pointer to sort function
46 * dwParam5 [I]
47 * lParam [I] application specific value
49 * NOTES
50 * No more information available yet!
53 BOOL32 WINAPI
54 DPA_Merge (const HDPA hdpa1, const HDPA hdpa2, DWORD dwFlags,
55 PFNDPACOMPARE pfnCompare, LPVOID pfnParam5, LPARAM lParam)
57 /* LPVOID *pWork1, *pWork2; */
58 INT32 nCount1, nCount2;
60 TRACE (commctrl, "(%p %p %08lx %p %p %08lx): stub!\n",
61 hdpa1, hdpa2, dwFlags, pfnCompare, pfnParam5, lParam);
63 if (IsBadWritePtr32 (hdpa1, sizeof(DPA)))
64 return FALSE;
66 if (IsBadWritePtr32 (hdpa2, sizeof(DPA)))
67 return FALSE;
69 if (IsBadCodePtr32 ((FARPROC32)pfnCompare))
70 return FALSE;
72 if (IsBadCodePtr32 ((FARPROC32)pfnParam5))
73 return FALSE;
75 if (dwFlags & DPAM_SORT) {
76 TRACE (commctrl, "sorting dpa's!\n");
77 DPA_Sort (hdpa1, pfnCompare, lParam);
78 DPA_Sort (hdpa2, pfnCompare, lParam);
81 if (hdpa2->nItemCount <= 0)
82 return TRUE;
84 nCount1 = hdpa1->nItemCount - 1;
86 nCount2 = hdpa2->nItemCount - 1;
88 FIXME (commctrl, "nCount1=%d nCount2=%d\n", nCount1, nCount2);
89 FIXME (commctrl, "semi stub!\n");
90 #if 0
92 do {
95 if (nResult == 0) {
98 else if (nResult > 0) {
101 else {
106 while (nCount2 >= 0);
108 #endif
111 return TRUE;
115 /**************************************************************************
116 * Alloc [COMCTL32.71]
118 * Allocates memory block from the dll's private heap
120 * PARAMS
121 * dwSize [I] size of the allocated memory block
123 * RETURNS
124 * Success: pointer to allocated memory block
125 * Failure: NULL
128 LPVOID WINAPI
129 COMCTL32_Alloc (DWORD dwSize)
131 LPVOID lpPtr;
133 TRACE (commctrl, "(0x%lx)\n", dwSize);
135 lpPtr = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
137 TRACE (commctrl, "-- ret=%p\n", lpPtr);
139 return lpPtr;
143 /**************************************************************************
144 * ReAlloc [COMCTL32.72]
146 * Changes the size of an allocated memory block or allocates a memory
147 * block using the dll's private heap.
149 * PARAMS
150 * lpSrc [I] pointer to memory block which will be resized
151 * dwSize [I] new size of the memory block.
153 * RETURNS
154 * Success: pointer to the resized memory block
155 * Failure: NULL
157 * NOTES
158 * If lpSrc is a NULL-pointer, then COMCTL32_ReAlloc allocates a memory
159 * block like COMCTL32_Alloc.
162 LPVOID WINAPI
163 COMCTL32_ReAlloc (LPVOID lpSrc, DWORD dwSize)
165 LPVOID lpDest;
167 TRACE (commctrl, "(%p 0x%08lx)\n", lpSrc, dwSize);
169 if (lpSrc)
170 lpDest = HeapReAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, lpSrc, dwSize);
171 else
172 lpDest = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
174 TRACE (commctrl, "-- ret=%p\n", lpDest);
176 return lpDest;
180 /**************************************************************************
181 * Free [COMCTL32.73]
183 * Frees an allocated memory block from the dll's private heap.
185 * PARAMS
186 * lpMem [I] pointer to memory block which will be freed
188 * RETURNS
189 * Success: TRUE
190 * Failure: FALSE
193 BOOL32 WINAPI
194 COMCTL32_Free (LPVOID lpMem)
196 TRACE (commctrl, "(%p)\n", lpMem);
198 return HeapFree (COMCTL32_hHeap, 0, lpMem);
202 /**************************************************************************
203 * GetSize [COMCTL32.74]
205 * Retrieves the size of the specified memory block from the dll's
206 * private heap.
208 * PARAMS
209 * lpMem [I] pointer to an allocated memory block
211 * RETURNS
212 * Success: size of the specified memory block
213 * Failure: 0
216 DWORD WINAPI
217 COMCTL32_GetSize (LPVOID lpMem)
219 TRACE (commctrl, "(%p)\n", lpMem);
221 return HeapSize (COMCTL32_hHeap, 0, lpMem);
225 /**************************************************************************
226 * The MRU-API is a set of functions to manipulate MRU(Most Recently Used)
227 * lists.
232 typedef struct tagMRUINFO
234 DWORD dwParam1;
235 DWORD dwParam2;
236 DWORD dwParam3;
237 HKEY hkeyMain;
238 LPCSTR lpszSubKey;
239 DWORD dwParam6;
240 } MRUINFO, *LPMRUINFO;
243 typedef struct tagMRU
245 DWORD dwParam1; /* some kind of flag */
246 DWORD dwParam2;
247 DWORD dwParam3;
248 HKEY hkeyMRU;
249 LPCSTR lpszSubKey;
250 DWORD dwParam6;
251 } MRU, *HMRU;
253 LPVOID WINAPI
254 CreateMRUListLazy32A (LPMRUINFO lpmi, DWORD dwParam2,
255 DWORD dwParam3, DWORD dwParam4);
258 /**************************************************************************
259 * CreateMRUListA [COMCTL32.151]
261 * PARAMS
262 * dwParam
264 * RETURNS
267 LPVOID WINAPI
268 CreateMRUList32A (LPMRUINFO lpmi)
270 return CreateMRUListLazy32A (lpmi, 0, 0, 0);
274 DWORD WINAPI
275 FreeMRUList32A (HMRU hmru)
277 FIXME (commctrl, "(%p) empty stub!\n", hmru);
279 #if 0
280 if (!(hmru->dwParam1 & 1001)) {
281 RegSetValueEx32A (hmru->hKeyMRU, "MRUList", 0, REG_SZ,
282 hmru->lpszMRUString,
283 lstrlen32A (hmru->lpszMRUString));
287 RegClosKey32 (hmru->hkeyMRU
288 COMCTL32_Free32 (hmru->lpszMRUString);
289 #endif
291 return COMCTL32_Free (hmru);
296 DWORD WINAPI
297 AddMRUData (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
300 FIXME (commctrl, "(%lx %lx %lx) empty stub!\n",
301 dwParam1, dwParam2, dwParam3);
303 return 0;
307 DWORD WINAPI
308 FindMRUData (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
311 FIXME (commctrl, "(%lx %lx %lx %lx) empty stub!\n",
312 dwParam1, dwParam2, dwParam3, dwParam4);
314 return TRUE;
318 LPVOID WINAPI
319 CreateMRUListLazy32A (LPMRUINFO lpmi, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
321 /* DWORD dwLocal1; *
322 * HKEY hkeyResult; *
323 * DWORD dwLocal3; *
324 * LPVOID lMRU; *
325 * DWORD dwLocal5; *
326 * DWORD dwLocal6; *
327 * DWORD dwLocal7; *
328 * DWORD dwDisposition; */
330 /* internal variables */
331 LPVOID ptr;
333 FIXME (commctrl, "(%p) empty stub!\n", lpmi);
335 if (lpmi) {
336 FIXME (commctrl, "(%lx %lx %lx %lx \"%s\" %lx)\n",
337 lpmi->dwParam1, lpmi->dwParam2, lpmi->dwParam3,
338 lpmi->hkeyMain, lpmi->lpszSubKey, lpmi->dwParam6);
341 /* dummy pointer creation */
342 ptr = COMCTL32_Alloc (32);
344 FIXME (commctrl, "-- ret = %p\n", ptr);
346 return ptr;
352 /**************************************************************************
353 * Str_GetPtrA [COMCTL32.233]
355 * PARAMS
356 * lpSrc [I]
357 * lpDest [O]
358 * nMaxLen [I]
360 * RETURNS
363 INT32 WINAPI
364 Str_GetPtr32A (LPCSTR lpSrc, LPSTR lpDest, INT32 nMaxLen)
366 INT32 len;
368 TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
370 if (!lpDest && lpSrc)
371 return lstrlen32A (lpSrc);
373 if (nMaxLen == 0)
374 return 0;
376 if (lpSrc == NULL) {
377 lpDest[0] = '\0';
378 return 0;
381 len = lstrlen32A (lpSrc);
382 if (len >= nMaxLen)
383 len = nMaxLen - 1;
385 RtlMoveMemory (lpDest, lpSrc, len);
386 lpDest[len] = '\0';
388 return len;
392 /**************************************************************************
393 * Str_SetPtrA [COMCTL32.234]
395 * PARAMS
396 * lppDest [O]
397 * lpSrc [I]
399 * RETURNS
402 BOOL32 WINAPI
403 Str_SetPtr32A (LPSTR *lppDest, LPCSTR lpSrc)
405 TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc);
407 if (lpSrc) {
408 LPSTR ptr = COMCTL32_ReAlloc (*lppDest, lstrlen32A (lpSrc) + 1);
409 if (!ptr)
410 return FALSE;
411 lstrcpy32A (ptr, lpSrc);
412 *lppDest = ptr;
414 else {
415 if (*lppDest) {
416 COMCTL32_Free (*lppDest);
417 *lppDest = NULL;
421 return TRUE;
425 /**************************************************************************
426 * Str_GetPtrW [COMCTL32.235]
428 * PARAMS
429 * lpSrc [I]
430 * lpDest [O]
431 * nMaxLen [I]
433 * RETURNS
436 INT32 WINAPI
437 Str_GetPtr32W (LPCWSTR lpSrc, LPWSTR lpDest, INT32 nMaxLen)
439 INT32 len;
441 TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
443 if (!lpDest && lpSrc)
444 return lstrlen32W (lpSrc);
446 if (nMaxLen == 0)
447 return 0;
449 if (lpSrc == NULL) {
450 lpDest[0] = L'\0';
451 return 0;
454 len = lstrlen32W (lpSrc);
455 if (len >= nMaxLen)
456 len = nMaxLen - 1;
458 RtlMoveMemory (lpDest, lpSrc, len*sizeof(WCHAR));
459 lpDest[len] = L'\0';
461 return len;
465 /**************************************************************************
466 * Str_SetPtrW [COMCTL32.236]
468 * PARAMS
469 * lpDest [O]
470 * lpSrc [I]
472 * RETURNS
475 BOOL32 WINAPI
476 Str_SetPtr32W (LPWSTR *lppDest, LPCWSTR lpSrc)
478 TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc);
480 if (lpSrc) {
481 INT32 len = lstrlen32W (lpSrc) + 1;
482 LPWSTR ptr = COMCTL32_ReAlloc (*lppDest, len * sizeof(WCHAR));
483 if (!ptr)
484 return FALSE;
485 lstrcpy32W (ptr, lpSrc);
486 *lppDest = ptr;
488 else {
489 if (*lppDest) {
490 COMCTL32_Free (*lppDest);
491 *lppDest = NULL;
495 return TRUE;
499 /**************************************************************************
500 * The DSA-API is a set of functions to create and manipulate arrays of
501 * fix sized memory blocks. These arrays can store any kind of data
502 * (strings, icons...).
505 /**************************************************************************
506 * DSA_Create [COMCTL32.320] Creates a dynamic storage array
508 * PARAMS
509 * nSize [I] size of the array elements
510 * nGrow [I] number of elements by which the array grows when it is filled
512 * RETURNS
513 * Success: pointer to a array control structure. use this like a handle.
514 * Failure: NULL
517 HDSA WINAPI
518 DSA_Create (INT32 nSize, INT32 nGrow)
520 HDSA hdsa;
522 TRACE (commctrl, "(size=%d grow=%d)\n", nSize, nGrow);
524 hdsa = (HDSA)COMCTL32_Alloc (sizeof(DSA));
525 if (hdsa)
527 hdsa->nItemCount = 0;
528 hdsa->pData = NULL;
529 hdsa->nMaxCount = 0;
530 hdsa->nItemSize = nSize;
531 hdsa->nGrow = MAX(1, nGrow);
534 return hdsa;
538 /**************************************************************************
539 * DSA_Destroy [COMCTL32.321] Destroys a dynamic storage array
541 * PARAMS
542 * hdsa [I] pointer to the array control structure
544 * RETURNS
545 * Success: TRUE
546 * Failure: FALSE
549 BOOL32 WINAPI
550 DSA_Destroy (const HDSA hdsa)
552 TRACE (commctrl, "(%p)\n", hdsa);
554 if (!hdsa)
555 return FALSE;
557 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
558 return FALSE;
560 return COMCTL32_Free (hdsa);
564 /**************************************************************************
565 * DSA_GetItem [COMCTL32.322]
567 * PARAMS
568 * hdsa [I] pointer to the array control structure
569 * nIndex [I] number of the Item to get
570 * pDest [O] destination buffer. Has to be >= dwElementSize.
572 * RETURNS
573 * Success: TRUE
574 * Failure: FALSE
577 BOOL32 WINAPI
578 DSA_GetItem (const HDSA hdsa, INT32 nIndex, LPVOID pDest)
580 LPVOID pSrc;
582 TRACE (commctrl, "(%p %d %p)\n", hdsa, nIndex, pDest);
584 if (!hdsa)
585 return FALSE;
586 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
587 return FALSE;
589 pSrc = hdsa->pData + (hdsa->nItemSize * nIndex);
590 memmove (pDest, pSrc, hdsa->nItemSize);
592 return TRUE;
596 /**************************************************************************
597 * DSA_GetItemPtr [COMCTL32.323]
599 * Retrieves a pointer to the specified item.
601 * PARAMS
602 * hdsa [I] pointer to the array control structure
603 * nIndex [I] index of the desired item
605 * RETURNS
606 * Success: pointer to an item
607 * Failure: NULL
610 LPVOID WINAPI
611 DSA_GetItemPtr (const HDSA hdsa, INT32 nIndex)
613 LPVOID pSrc;
615 TRACE (commctrl, "(%p %d)\n", hdsa, nIndex);
617 if (!hdsa)
618 return NULL;
619 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
620 return NULL;
622 pSrc = hdsa->pData + (hdsa->nItemSize * nIndex);
624 TRACE (commctrl, "-- ret=%p\n", pSrc);
626 return pSrc;
630 /**************************************************************************
631 * DSA_SetItem [COMCTL32.325]
633 * Sets the contents of an item in the array.
635 * PARAMS
636 * hdsa [I] pointer to the array control structure
637 * nIndex [I] index for the item
638 * pSrc [I] pointer to the new item data
640 * RETURNS
641 * Success: TRUE
642 * Failure: FALSE
645 BOOL32 WINAPI
646 DSA_SetItem (const HDSA hdsa, INT32 nIndex, LPVOID pSrc)
648 INT32 nSize, nNewItems;
649 LPVOID pDest, lpTemp;
651 TRACE (commctrl, "(%p %d %p)\n", hdsa, nIndex, pSrc);
653 if ((!hdsa) || nIndex < 0)
654 return FALSE;
656 if (hdsa->nItemCount <= nIndex) {
657 /* within the old array */
658 if (hdsa->nMaxCount > nIndex) {
659 /* within the allocated space, set a new boundary */
660 hdsa->nItemCount = nIndex;
662 else {
663 /* resize the block of memory */
664 nNewItems =
665 hdsa->nGrow * ((INT32)((nIndex - 1) / hdsa->nGrow) + 1);
666 nSize = hdsa->nItemSize * nNewItems;
668 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
669 if (!lpTemp)
670 return FALSE;
672 hdsa->nMaxCount = nNewItems;
673 hdsa->pData = lpTemp;
677 /* put the new entry in */
678 pDest = hdsa->pData + (hdsa->nItemSize * nIndex);
679 TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
680 pDest, pSrc, hdsa->nItemSize);
681 memmove (pDest, pSrc, hdsa->nItemSize);
683 return TRUE;
687 /**************************************************************************
688 * DSA_InsertItem [COMCTL32.325]
690 * PARAMS
691 * hdsa [I] pointer to the array control structure
692 * nIndex [I] index for the new item
693 * pSrc [I] pointer to the element
695 * RETURNS
696 * Success: position of the new item
697 * Failure: -1
700 INT32 WINAPI
701 DSA_InsertItem (const HDSA hdsa, INT32 nIndex, LPVOID pSrc)
703 INT32 nNewItems, nSize, i;
704 LPVOID lpTemp, lpDest;
705 LPDWORD p;
707 TRACE(commctrl, "(%p %d %p)\n", hdsa, nIndex, pSrc);
709 if ((!hdsa) || nIndex < 0)
710 return -1;
712 for (i = 0; i < hdsa->nItemSize; i += 4) {
713 p = *(DWORD**)(pSrc + i);
714 if (IsBadStringPtr32A ((char*)p, 256))
715 TRACE (commctrl, "-- %d=%p\n", i, (DWORD*)p);
716 else
717 TRACE (commctrl, "-- %d=%p [%s]\n", i, p, debugstr_a((char*)p));
720 /* when nIndex > nItemCount then append */
721 if (nIndex >= hdsa->nItemCount)
722 nIndex = hdsa->nItemCount;
724 /* do we need to resize ? */
725 if (hdsa->nItemCount >= hdsa->nMaxCount) {
726 nNewItems = hdsa->nMaxCount + hdsa->nGrow;
727 nSize = hdsa->nItemSize * nNewItems;
729 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
730 if (!lpTemp)
731 return -1;
733 hdsa->nMaxCount = nNewItems;
734 hdsa->pData = lpTemp;
737 /* do we need to move elements ? */
738 if (nIndex < hdsa->nItemCount) {
739 lpTemp = hdsa->pData + (hdsa->nItemSize * nIndex);
740 lpDest = lpTemp + hdsa->nItemSize;
741 nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize;
742 TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
743 lpDest, lpTemp, nSize);
744 memmove (lpDest, lpTemp, nSize);
747 /* ok, we can put the new Item in */
748 hdsa->nItemCount++;
749 lpDest = hdsa->pData + (hdsa->nItemSize * nIndex);
750 TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
751 lpDest, pSrc, hdsa->nItemSize);
752 memmove (lpDest, pSrc, hdsa->nItemSize);
754 return hdsa->nItemCount;
758 /**************************************************************************
759 * DSA_DeleteItem [COMCTL32.326]
761 * PARAMS
762 * hdsa [I] pointer to the array control structure
763 * nIndex [I] index for the element to delete
765 * RETURNS
766 * Success: number of the deleted element
767 * Failure: -1
770 INT32 WINAPI
771 DSA_DeleteItem (const HDSA hdsa, INT32 nIndex)
773 LPVOID lpDest,lpSrc;
774 INT32 nSize;
776 TRACE (commctrl, "(%p %d)\n", hdsa, nIndex);
778 if (!hdsa)
779 return -1;
780 if (nIndex < 0 || nIndex >= hdsa->nItemCount)
781 return -1;
783 /* do we need to move ? */
784 if (nIndex < hdsa->nItemCount - 1) {
785 lpDest = hdsa->pData + (hdsa->nItemSize * nIndex);
786 lpSrc = lpDest + hdsa->nItemSize;
787 nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1);
788 TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
789 lpDest, lpSrc, nSize);
790 memmove (lpDest, lpSrc, nSize);
793 hdsa->nItemCount--;
795 /* free memory ? */
796 if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) {
797 nSize = hdsa->nItemSize * hdsa->nItemCount;
799 lpDest = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
800 if (!lpDest)
801 return -1;
803 hdsa->nMaxCount = hdsa->nItemCount;
804 hdsa->pData = lpDest;
807 return nIndex;
811 /**************************************************************************
812 * DSA_DeleteAllItems [COMCTL32.326]
814 * Removes all items and reinitializes the array.
816 * PARAMS
817 * hdsa [I] pointer to the array control structure
819 * RETURNS
820 * Success: TRUE
821 * Failure: FALSE
824 BOOL32 WINAPI
825 DSA_DeleteAllItems (const HDSA hdsa)
827 TRACE (commctrl, "(%p)\n", hdsa);
829 if (!hdsa)
830 return FALSE;
831 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
832 return FALSE;
834 hdsa->nItemCount = 0;
835 hdsa->pData = NULL;
836 hdsa->nMaxCount = 0;
838 return TRUE;
842 /**************************************************************************
843 * The DPA-API is a set of functions to create and manipulate arrays of
844 * pointers.
847 /**************************************************************************
848 * DPA_Create [COMCTL32.328] Creates a dynamic pointer array
850 * PARAMS
851 * nGrow [I] number of items by which the array grows when it is filled
853 * RETURNS
854 * Success: handle (pointer) to the pointer array.
855 * Failure: NULL
858 HDPA WINAPI
859 DPA_Create (INT32 nGrow)
861 HDPA hdpa;
863 TRACE (commctrl, "(%d)\n", nGrow);
865 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
866 if (hdpa) {
867 hdpa->nGrow = MAX(8, nGrow);
868 hdpa->hHeap = COMCTL32_hHeap;
869 hdpa->nMaxCount = hdpa->nGrow * 2;
870 hdpa->ptrs =
871 (LPVOID*)COMCTL32_Alloc (hdpa->nMaxCount * sizeof(LPVOID));
874 TRACE (commctrl, "-- %p\n", hdpa);
876 return hdpa;
880 /**************************************************************************
881 * DPA_Destroy [COMCTL32.329] Destroys a dynamic pointer array
883 * PARAMS
884 * hdpa [I] handle (pointer) to the pointer array
886 * RETURNS
887 * Success: TRUE
888 * Failure: FALSE
891 BOOL32 WINAPI
892 DPA_Destroy (const HDPA hdpa)
894 TRACE (commctrl, "(%p)\n", hdpa);
896 if (!hdpa)
897 return FALSE;
899 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
900 return FALSE;
902 return HeapFree (hdpa->hHeap, 0, hdpa);
906 /**************************************************************************
907 * DPA_Grow [COMCTL32.330]
909 * Sets the growth amount.
911 * PARAMS
912 * hdpa [I] handle (pointer) to the existing (source) pointer array
913 * nGrow [I] number of items, the array grows, when it's too small
915 * RETURNS
916 * Success: TRUE
917 * Failure: FALSE
920 BOOL32 WINAPI
921 DPA_Grow (const HDPA hdpa, INT32 nGrow)
923 TRACE (commctrl, "(%p %d)\n", hdpa, nGrow);
925 if (!hdpa)
926 return FALSE;
928 hdpa->nGrow = MAX(8, nGrow);
930 return TRUE;
934 /**************************************************************************
935 * DPA_Clone [COMCTL32.331]
937 * Copies a pointer array to an other one or creates a copy
939 * PARAMS
940 * hdpa [I] handle (pointer) to the existing (source) pointer array
941 * hdpaNew [O] handle (pointer) to the destination pointer array
943 * RETURNS
944 * Success: pointer to the destination pointer array.
945 * Failure: NULL
947 * NOTES
948 * - If the 'hdpaNew' is a NULL-Pointer, a copy of the source pointer
949 * array will be created and it's handle (pointer) is returned.
950 * - If 'hdpa' is a NULL-Pointer, the original implementation crashes,
951 * this implementation just returns NULL.
954 HDPA WINAPI
955 DPA_Clone (const HDPA hdpa, const HDPA hdpaNew)
957 INT32 nNewItems, nSize;
958 HDPA hdpaTemp;
960 if (!hdpa)
961 return NULL;
963 TRACE (commctrl, "(%p %p)\n", hdpa, hdpaNew);
965 if (!hdpaNew) {
966 /* create a new DPA */
967 hdpaTemp = (HDPA)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
968 sizeof(DPA));
969 hdpaTemp->hHeap = hdpa->hHeap;
970 hdpaTemp->nGrow = hdpa->nGrow;
972 else
973 hdpaTemp = hdpaNew;
975 if (hdpaTemp->ptrs) {
976 /* remove old pointer array */
977 HeapFree (hdpaTemp->hHeap, 0, hdpaTemp->ptrs);
978 hdpaTemp->ptrs = NULL;
979 hdpaTemp->nItemCount = 0;
980 hdpaTemp->nMaxCount = 0;
983 /* create a new pointer array */
984 nNewItems = hdpaTemp->nGrow *
985 ((INT32)((hdpa->nItemCount - 1) / hdpaTemp->nGrow) + 1);
986 nSize = nNewItems * sizeof(LPVOID);
987 hdpaTemp->ptrs =
988 (LPVOID*)HeapAlloc (hdpaTemp->hHeap, HEAP_ZERO_MEMORY, nSize);
989 hdpaTemp->nMaxCount = nNewItems;
991 /* clone the pointer array */
992 hdpaTemp->nItemCount = hdpa->nItemCount;
993 memmove (hdpaTemp->ptrs, hdpa->ptrs,
994 hdpaTemp->nItemCount * sizeof(LPVOID));
996 return hdpaTemp;
1000 /**************************************************************************
1001 * DPA_GetPtr [COMCTL32.332]
1003 * Retrieves a pointer from a dynamic pointer array
1005 * PARAMS
1006 * hdpa [I] handle (pointer) to the pointer array
1007 * nIndex [I] array index of the desired pointer
1009 * RETURNS
1010 * Success: pointer
1011 * Failure: NULL
1014 LPVOID WINAPI
1015 DPA_GetPtr (const HDPA hdpa, INT32 i)
1017 TRACE (commctrl, "(%p %d)\n", hdpa, i);
1019 if (!hdpa)
1020 return NULL;
1021 if (!hdpa->ptrs)
1022 return NULL;
1023 if ((i < 0) || (i >= hdpa->nItemCount))
1024 return NULL;
1026 TRACE (commctrl, "-- %p\n", hdpa->ptrs[i]);
1028 return hdpa->ptrs[i];
1032 /**************************************************************************
1033 * DPA_GetPtrIndex [COMCTL32.333]
1035 * Retrieves the index of the specified pointer
1037 * PARAMS
1038 * hdpa [I] handle (pointer) to the pointer array
1039 * p [I] pointer
1041 * RETURNS
1042 * Success: index of the specified pointer
1043 * Failure: -1
1046 INT32 WINAPI
1047 DPA_GetPtrIndex (const HDPA hdpa, LPVOID p)
1049 INT32 i;
1051 if (!hdpa->ptrs)
1052 return -1;
1054 for (i = 0; i < hdpa->nItemCount; i++) {
1055 if (hdpa->ptrs[i] == p)
1056 return i;
1059 return -1;
1063 /**************************************************************************
1064 * DPA_InsertPtr [COMCTL32.334]
1066 * Inserts a pointer into a dynamic pointer array
1068 * PARAMS
1069 * hdpa [I] handle (pointer) to the array
1070 * i [I] array index
1071 * p [I] pointer to insert
1073 * RETURNS
1074 * Success: index of the inserted pointer
1075 * Failure: -1
1078 INT32 WINAPI
1079 DPA_InsertPtr (const HDPA hdpa, INT32 i, LPVOID p)
1081 INT32 nNewItems, nSize, nIndex = 0;
1082 LPVOID *lpTemp, *lpDest;
1084 TRACE (commctrl, "(%p %d %p)\n", hdpa, i, p);
1086 if ((!hdpa) || (i < 0))
1087 return -1;
1089 if (!hdpa->ptrs) {
1090 hdpa->ptrs =
1091 (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1092 2 * hdpa->nGrow * sizeof(LPVOID));
1093 if (!hdpa->ptrs)
1094 return -1;
1095 hdpa->nMaxCount = hdpa->nGrow * 2;
1096 nIndex = 0;
1098 else {
1099 if (hdpa->nItemCount >= hdpa->nMaxCount) {
1100 TRACE (commctrl, "-- resizing\n");
1101 nNewItems = hdpa->nMaxCount + hdpa->nGrow;
1102 nSize = nNewItems * sizeof(LPVOID);
1104 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1105 hdpa->ptrs, nSize);
1106 if (!lpTemp)
1107 return -1;
1108 hdpa->nMaxCount = nNewItems;
1109 hdpa->ptrs = lpTemp;
1112 if (i >= hdpa->nItemCount) {
1113 nIndex = hdpa->nItemCount;
1114 TRACE (commctrl, "-- appending at %d\n", nIndex);
1116 else {
1117 TRACE (commctrl, "-- inserting at %d\n", i);
1118 lpTemp = hdpa->ptrs + i;
1119 lpDest = lpTemp + 1;
1120 nSize = (hdpa->nItemCount - i) * sizeof(LPVOID);
1121 TRACE (commctrl, "-- move dest=%p src=%p size=%x\n",
1122 lpDest, lpTemp, nSize);
1123 memmove (lpDest, lpTemp, nSize);
1124 nIndex = i;
1128 /* insert item */
1129 hdpa->nItemCount++;
1130 hdpa->ptrs[nIndex] = p;
1132 return nIndex;
1136 /**************************************************************************
1137 * DPA_SetPtr [COMCTL32.335]
1139 * Sets a pointer in the pointer array
1141 * PARAMS
1142 * hdpa [I] handle (pointer) to the pointer array
1143 * i [I] index of the pointer that will be set
1144 * p [I] pointer to be set
1146 * RETURNS
1147 * Success: TRUE
1148 * Failure: FALSE
1151 BOOL32 WINAPI
1152 DPA_SetPtr (const HDPA hdpa, INT32 i, LPVOID p)
1154 LPVOID *lpTemp;
1156 TRACE (commctrl, "(%p %d %p)\n", hdpa, i, p);
1158 if ((!hdpa) || i < 0)
1159 return FALSE;
1161 if (hdpa->nItemCount <= i) {
1162 /* within the old array */
1163 if (hdpa->nMaxCount > i) {
1164 /* within the allocated space, set a new boundary */
1165 hdpa->nItemCount = i;
1167 else {
1168 /* resize the block of memory */
1169 INT32 nNewItems =
1170 hdpa->nGrow * ((INT32)((i - 1) / hdpa->nGrow) + 1);
1171 INT32 nSize = nNewItems * sizeof(LPVOID);
1173 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1174 hdpa->ptrs, nSize);
1175 if (!lpTemp)
1176 return FALSE;
1178 hdpa->nItemCount = nNewItems;
1179 hdpa->ptrs = lpTemp;
1183 /* put the new entry in */
1184 hdpa->ptrs[i] = p;
1186 return TRUE;
1190 /**************************************************************************
1191 * DPA_DeletePtr [COMCTL32.336]
1193 * Removes a pointer from the pointer array.
1195 * PARAMS
1196 * hdpa [I] handle (pointer) to the pointer array
1197 * i [I] index of the pointer that will be deleted
1199 * RETURNS
1200 * Success: deleted pointer
1201 * Failure: NULL
1204 LPVOID WINAPI
1205 DPA_DeletePtr (const HDPA hdpa, INT32 i)
1207 LPVOID lpDest, lpSrc, lpTemp = NULL;
1208 INT32 nSize;
1210 TRACE (commctrl, "(%p %d)\n", hdpa, i);
1212 if ((!hdpa) || i < 0 || i >= hdpa->nItemCount)
1213 return NULL;
1215 lpTemp = hdpa->ptrs[i];
1217 /* do we need to move ?*/
1218 if (i < hdpa->nItemCount - 1) {
1219 lpDest = hdpa->ptrs + i;
1220 lpSrc = lpDest + 1;
1221 nSize = (hdpa->nItemCount - i - 1) * sizeof(LPVOID);
1222 TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",
1223 lpDest, lpSrc, nSize);
1224 memmove (lpDest, lpSrc, nSize);
1227 hdpa->nItemCount --;
1229 /* free memory ?*/
1230 if ((hdpa->nMaxCount - hdpa->nItemCount) >= hdpa->nGrow) {
1231 INT32 nNewItems = MIN(hdpa->nGrow * 2, hdpa->nItemCount);
1232 nSize = nNewItems * sizeof(LPVOID);
1233 lpDest = (LPVOID)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1234 hdpa->ptrs, nSize);
1235 if (!lpDest)
1236 return NULL;
1238 hdpa->nMaxCount = nNewItems;
1239 hdpa->ptrs = (LPVOID*)lpDest;
1242 return lpTemp;
1246 /**************************************************************************
1247 * DPA_DeleteAllPtrs [COMCTL32.337]
1249 * Removes all pointers and reinitializes the array.
1251 * PARAMS
1252 * hdpa [I] handle (pointer) to the pointer array
1254 * RETURNS
1255 * Success: TRUE
1256 * Failure: FALSE
1259 BOOL32 WINAPI
1260 DPA_DeleteAllPtrs (const HDPA hdpa)
1262 TRACE (commctrl, "(%p)\n", hdpa);
1264 if (!hdpa)
1265 return FALSE;
1267 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
1268 return FALSE;
1270 hdpa->nItemCount = 0;
1271 hdpa->nMaxCount = hdpa->nGrow * 2;
1272 hdpa->ptrs = (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1273 hdpa->nMaxCount * sizeof(LPVOID));
1275 return TRUE;
1279 /**************************************************************************
1280 * DPA_QuickSort [Internal]
1282 * Ordinary quicksort (used by DPA_Sort).
1284 * PARAMS
1285 * lpPtrs [I] pointer to the pointer array
1286 * l [I] index of the "left border" of the partition
1287 * r [I] index of the "right border" of the partition
1288 * pfnCompare [I] pointer to the compare function
1289 * lParam [I] user defined value (3rd parameter in compare function)
1291 * RETURNS
1292 * NONE
1295 static VOID
1296 DPA_QuickSort (LPVOID *lpPtrs, INT32 l, INT32 r,
1297 PFNDPACOMPARE pfnCompare, LPARAM lParam)
1299 LPVOID t, v;
1300 INT32 i, j;
1302 TRACE (commctrl, "l=%i r=%i\n", l, r);
1304 i = l;
1305 j = r;
1306 v = lpPtrs[(int)(l+r)/2];
1307 do {
1308 while ((pfnCompare)(lpPtrs[i], v, lParam) < 0) i++;
1309 while ((pfnCompare)(lpPtrs[j], v, lParam) > 0) j--;
1310 if (i <= j)
1312 t = lpPtrs[i];
1313 lpPtrs[i++] = lpPtrs[j];
1314 lpPtrs[j--] = t;
1316 } while (i <= j);
1317 if (l < j) DPA_QuickSort (lpPtrs, l, j, pfnCompare, lParam);
1318 if (i < r) DPA_QuickSort (lpPtrs, i, r, pfnCompare, lParam);
1322 /**************************************************************************
1323 * DPA_Sort [COMCTL32.338]
1325 * Sorts a pointer array using a user defined compare function
1327 * PARAMS
1328 * hdpa [I] handle (pointer) to the pointer array
1329 * pfnCompare [I] pointer to the compare function
1330 * lParam [I] user defined value (3rd parameter of compare function)
1332 * RETURNS
1333 * Success: TRUE
1334 * Failure: FALSE
1337 BOOL32 WINAPI
1338 DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
1340 if (!hdpa || !pfnCompare)
1341 return FALSE;
1343 TRACE (commctrl, "(%p %p 0x%lx)\n", hdpa, pfnCompare, lParam);
1345 if ((hdpa->nItemCount > 1) && (hdpa->ptrs))
1346 DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1,
1347 pfnCompare, lParam);
1349 return TRUE;
1353 /**************************************************************************
1354 * DPA_Search [COMCTL32.339]
1356 * Searches a pointer array for a specified pointer
1358 * PARAMS
1359 * hdpa [I] handle (pointer) to the pointer array
1360 * pFind [I] pointer to search for
1361 * nStart [I] start index
1362 * pfnCompare [I] pointer to the compare function
1363 * lParam [I] user defined value (3rd parameter of compare function)
1364 * uOptions [I] search options
1366 * RETURNS
1367 * Success: index of the pointer in the array.
1368 * Failure: -1
1370 * NOTES
1371 * Binary search taken from R.Sedgewick "Algorithms in C"!
1372 * Function is NOT tested!
1373 * If something goes wrong, blame HIM not ME! (Eric Kohl)
1376 INT32 WINAPI
1377 DPA_Search (const HDPA hdpa, LPVOID pFind, INT32 nStart,
1378 PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT32 uOptions)
1380 if (!hdpa || !pfnCompare || !pFind)
1381 return -1;
1383 TRACE (commctrl, "(%p %p %d %p 0x%08lx 0x%08x)\n",
1384 hdpa, pFind, nStart, pfnCompare, lParam, uOptions);
1386 if (uOptions & DPAS_SORTED) {
1387 /* array is sorted --> use binary search */
1388 INT32 l, r, x, n;
1389 LPVOID *lpPtr;
1391 TRACE (commctrl, "binary search\n");
1393 l = (nStart == -1) ? 0 : nStart;
1394 r = hdpa->nItemCount - 1;
1395 lpPtr = hdpa->ptrs;
1396 while (r >= l) {
1397 x = (l + r) / 2;
1398 n = (pfnCompare)(pFind, lpPtr[x], lParam);
1399 if (n < 0)
1400 r = x - 1;
1401 else
1402 l = x + 1;
1403 if (n == 0) {
1404 TRACE (commctrl, "-- ret=%d\n", n);
1405 return n;
1409 if (uOptions & DPAS_INSERTBEFORE) {
1410 TRACE (commctrl, "-- ret=%d\n", r);
1411 return r;
1414 if (uOptions & DPAS_INSERTAFTER) {
1415 TRACE (commctrl, "-- ret=%d\n", l);
1416 return l;
1419 else {
1420 /* array is not sorted --> use linear search */
1421 LPVOID *lpPtr;
1422 INT32 nIndex;
1424 TRACE (commctrl, "linear search\n");
1426 nIndex = (nStart == -1)? 0 : nStart;
1427 lpPtr = hdpa->ptrs;
1428 for (; nIndex < hdpa->nItemCount; nIndex++) {
1429 if ((pfnCompare)(pFind, lpPtr[nIndex], lParam) == 0) {
1430 TRACE (commctrl, "-- ret=%d\n", nIndex);
1431 return nIndex;
1436 TRACE (commctrl, "-- not found: ret=-1\n");
1437 return -1;
1441 /**************************************************************************
1442 * DPA_CreateEx [COMCTL32.340]
1444 * Creates a dynamic pointer array using the specified size and heap.
1446 * PARAMS
1447 * nGrow [I] number of items by which the array grows when it is filled
1448 * hHeap [I] handle to the heap where the array is stored
1450 * RETURNS
1451 * Success: handle (pointer) to the pointer array.
1452 * Failure: NULL
1455 HDPA WINAPI
1456 DPA_CreateEx (INT32 nGrow, HANDLE32 hHeap)
1458 HDPA hdpa;
1460 TRACE (commctrl, "(%d 0x%x)\n", nGrow, hHeap);
1462 if (hHeap)
1463 hdpa = (HDPA)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, sizeof(DPA));
1464 else
1465 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
1467 if (hdpa) {
1468 hdpa->nGrow = MIN(8, nGrow);
1469 hdpa->hHeap = hHeap ? hHeap : COMCTL32_hHeap;
1470 hdpa->nMaxCount = hdpa->nGrow * 2;
1471 hdpa->ptrs =
1472 (LPVOID*)HeapAlloc (hHeap, HEAP_ZERO_MEMORY,
1473 hdpa->nMaxCount * sizeof(LPVOID));
1476 TRACE (commctrl, "-- %p\n", hdpa);
1478 return hdpa;
1482 /**************************************************************************
1483 * Notification functions
1486 typedef struct tagNOTIFYDATA
1488 HWND32 hwndFrom;
1489 HWND32 hwndTo;
1490 DWORD dwParam3;
1491 DWORD dwParam4;
1492 DWORD dwParam5;
1493 DWORD dwParam6;
1494 } NOTIFYDATA, *LPNOTIFYDATA;
1497 /**************************************************************************
1498 * DoNotify [Internal]
1501 static LRESULT
1502 DoNotify (LPNOTIFYDATA lpNotify, UINT32 uCode, LPNMHDR lpHdr)
1504 NMHDR nmhdr;
1505 LPNMHDR lpNmh = NULL;
1506 UINT32 idFrom = 0;
1508 TRACE (commctrl, "(0x%04x 0x%04x %d %p 0x%08lx)\n",
1509 lpNotify->hwndFrom, lpNotify->hwndTo, uCode, lpHdr,
1510 lpNotify->dwParam5);
1512 if (!lpNotify->hwndTo)
1513 return 0;
1515 if (lpNotify->hwndFrom == -1) {
1516 lpNmh = lpHdr;
1517 idFrom = lpHdr->idFrom;
1519 else {
1520 if (lpNotify->hwndFrom) {
1521 HWND32 hwndParent = GetParent32 (lpNotify->hwndFrom);
1522 if (hwndParent) {
1523 hwndParent = GetWindow32 (lpNotify->hwndFrom, GW_OWNER);
1524 if (hwndParent)
1525 idFrom = GetDlgCtrlID32 (lpNotify->hwndFrom);
1529 lpNmh = (lpHdr) ? lpHdr : &nmhdr;
1531 lpNmh->hwndFrom = lpNotify->hwndFrom;
1532 lpNmh->idFrom = idFrom;
1533 lpNmh->code = uCode;
1536 return SendMessage32A (lpNotify->hwndTo, WM_NOTIFY, idFrom, (LPARAM)lpNmh);
1540 /**************************************************************************
1541 * SendNotify [COMCTL32.341]
1543 * PARAMS
1544 * hwndFrom [I]
1545 * hwndTo [I]
1546 * uCode [I]
1547 * lpHdr [I]
1549 * RETURNS
1550 * Success: return value from notification
1551 * Failure: 0
1554 LRESULT WINAPI
1555 COMCTL32_SendNotify (HWND32 hwndFrom, HWND32 hwndTo,
1556 UINT32 uCode, LPNMHDR lpHdr)
1558 NOTIFYDATA notify;
1560 TRACE (commctrl, "(0x%04x 0x%04x %d %p)\n",
1561 hwndFrom, hwndTo, uCode, lpHdr);
1563 notify.hwndFrom = hwndFrom;
1564 notify.hwndTo = hwndTo;
1565 notify.dwParam5 = 0;
1566 notify.dwParam6 = 0;
1568 return DoNotify (&notify, uCode, lpHdr);
1572 /**************************************************************************
1573 * SendNotifyEx [COMCTL32.342]
1575 * PARAMS
1576 * hwndFrom [I]
1577 * hwndTo [I]
1578 * uCode [I]
1579 * lpHdr [I]
1580 * dwParam5 [I]
1582 * RETURNS
1583 * Success: return value from notification
1584 * Failure: 0
1587 LRESULT WINAPI
1588 COMCTL32_SendNotifyEx (HWND32 hwndTo, HWND32 hwndFrom, UINT32 uCode,
1589 LPNMHDR lpHdr, DWORD dwParam5)
1591 NOTIFYDATA notify;
1592 HWND32 hwndNotify;
1594 TRACE (commctrl, "(0x%04x 0x%04x %d %p 0x%08lx)\n",
1595 hwndFrom, hwndTo, uCode, lpHdr, dwParam5);
1597 hwndNotify = hwndTo;
1598 if (!hwndTo) {
1599 if (IsWindow32 (hwndFrom)) {
1600 hwndNotify = GetParent32 (hwndFrom);
1601 if (!hwndNotify)
1602 return 0;
1606 notify.hwndFrom = hwndFrom;
1607 notify.hwndTo = hwndNotify;
1608 notify.dwParam5 = dwParam5;
1609 notify.dwParam6 = 0;
1611 return DoNotify (&notify, uCode, lpHdr);
1615 /**************************************************************************
1616 * StrChrA [COMCTL32.350]
1620 LPSTR WINAPI
1621 COMCTL32_StrChrA (LPCSTR lpString, CHAR cChar)
1623 return strchr (lpString, cChar);
1627 /**************************************************************************
1628 * StrStrIA [COMCTL32.355]
1631 LPSTR WINAPI
1632 COMCTL32_StrStrIA (LPCSTR lpStr1, LPCSTR lpStr2)
1634 INT32 len1, len2, i;
1635 CHAR first;
1637 if (*lpStr2 == 0)
1638 return ((LPSTR)lpStr1);
1639 len1 = 0;
1640 while (lpStr1[len1] != 0) ++len1;
1641 len2 = 0;
1642 while (lpStr2[len2] != 0) ++len2;
1643 if (len2 == 0)
1644 return ((LPSTR)(lpStr1 + len1));
1645 first = tolower (*lpStr2);
1646 while (len1 >= len2) {
1647 if (tolower(*lpStr1) == first) {
1648 for (i = 1; i < len2; ++i)
1649 if (tolower (lpStr1[i]) != tolower(lpStr2[i]))
1650 break;
1651 if (i >= len2)
1652 return ((LPSTR)lpStr1);
1654 ++lpStr1; --len1;
1656 return (NULL);
1660 /**************************************************************************
1661 * StrToIntA [COMCTL32.357] Converts a string to a signed integer.
1664 INT32 WINAPI
1665 COMCTL32_StrToIntA (LPSTR lpString)
1667 return atoi(lpString);
1671 /**************************************************************************
1672 * DPA_EnumCallback [COMCTL32.385]
1674 * Enumerates all items in a dynamic pointer array.
1676 * PARAMS
1677 * hdpa [I] handle to the dynamic pointer array
1678 * enumProc [I]
1679 * lParam [I]
1681 * RETURNS
1682 * none
1685 VOID WINAPI
1686 DPA_EnumCallback (const HDPA hdpa, DPAENUMPROC enumProc, LPARAM lParam)
1688 INT32 i;
1690 TRACE (commctrl, "(%p %p %08lx)\n", hdpa, enumProc, lParam);
1692 if (!hdpa)
1693 return;
1694 if (hdpa->nItemCount <= 0)
1695 return;
1697 for (i = 0; i < hdpa->nItemCount; i++) {
1698 if ((enumProc)(hdpa->ptrs[i], lParam) == 0)
1699 return;
1702 return;
1706 /**************************************************************************
1707 * DPA_DestroyCallback [COMCTL32.386]
1709 * Enumerates all items in a dynamic pointer array and destroys it.
1711 * PARAMS
1712 * hdpa [I] handle to the dynamic pointer array
1713 * enumProc [I]
1714 * lParam [I]
1716 * RETURNS
1717 * Success: TRUE
1718 * Failure: FALSE
1721 BOOL32 WINAPI
1722 DPA_DestroyCallback (const HDPA hdpa, DPAENUMPROC enumProc, LPARAM lParam)
1724 TRACE (commctrl, "(%p %p %08lx)\n", hdpa, enumProc, lParam);
1726 DPA_EnumCallback (hdpa, enumProc, lParam);
1728 return DPA_Destroy (hdpa);
1732 /**************************************************************************
1733 * DSA_EnumCallback [COMCTL32.387]
1735 * Enumerates all items in a dynamic storage array.
1737 * PARAMS
1738 * hdsa [I] handle to the dynamic storage array
1739 * enumProc [I]
1740 * lParam [I]
1742 * RETURNS
1743 * none
1746 VOID WINAPI
1747 DSA_EnumCallback (const HDSA hdsa, DSAENUMPROC enumProc, LPARAM lParam)
1749 INT32 i;
1751 TRACE (commctrl, "(%p %p %08lx)\n", hdsa, enumProc, lParam);
1753 if (!hdsa)
1754 return;
1755 if (hdsa->nItemCount <= 0)
1756 return;
1758 for (i = 0; i < hdsa->nItemCount; i++) {
1759 LPVOID lpItem = DSA_GetItemPtr (hdsa, i);
1760 if ((enumProc)(lpItem, lParam) == 0)
1761 return;
1764 return;
1768 /**************************************************************************
1769 * DSA_DestroyCallback [COMCTL32.388]
1771 * Enumerates all items in a dynamic storage array and destroys it.
1773 * PARAMS
1774 * hdsa [I] handle to the dynamic storage array
1775 * enumProc [I]
1776 * lParam [I]
1778 * RETURNS
1779 * Success: TRUE
1780 * Failure: FALSE
1783 BOOL32 WINAPI
1784 DSA_DestroyCallback (const HDSA hdsa, DSAENUMPROC enumProc, LPARAM lParam)
1786 TRACE (commctrl, "(%p %p %08lx)\n", hdsa, enumProc, lParam);
1788 DSA_EnumCallback (hdsa, enumProc, lParam);
1790 return DSA_Destroy (hdsa);
1793 /**************************************************************************
1794 * StrCSpnA [COMCTL32.356]
1797 INT32 WINAPI COMCTL32_StrCSpnA( LPCSTR lpStr, LPCSTR lpSet) {
1798 return strcspn(lpStr, lpSet);
1801 /**************************************************************************
1802 * StrChrW [COMCTL32.358]
1805 LPWSTR WINAPI COMCTL32_StrChrW( LPCWSTR lpStart, WORD wMatch) {
1806 return CRTDLL_wcschr(lpStart, wMatch);
1809 /**************************************************************************
1810 * StrCmpNA [COMCTL32.352]
1813 INT32 WINAPI COMCTL32_StrCmpNA( LPCSTR lpStr1, LPCSTR lpStr2, int nChar) {
1814 return lstrncmp32A(lpStr1, lpStr2, nChar);
1817 /**************************************************************************
1818 * StrCmpNW [COMCTL32.360]
1821 INT32 WINAPI COMCTL32_StrCmpNW( LPCWSTR lpStr1, LPCWSTR lpStr2, int nChar) {
1822 return lstrncmp32W(lpStr1, lpStr2, nChar);
1825 /**************************************************************************
1826 * StrRChrA [COMCTL32.351]
1829 LPSTR WINAPI COMCTL32_StrRChrA( LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch) {
1830 return lstrrchr(lpStart, lpEnd, wMatch);
1833 /**************************************************************************
1834 * StrRChrW [COMCTL32.359]
1837 LPWSTR WINAPI COMCTL32_StrRChrW( LPCWSTR lpStart, LPCWSTR lpEnd, WORD wMatch) {
1838 return lstrrchrw(lpStart, lpEnd, wMatch);
1841 /**************************************************************************
1842 * StrStrA [COMCTL32.354]
1845 LPSTR WINAPI COMCTL32_StrStrA( LPCSTR lpFirst, LPCSTR lpSrch) {
1846 return strstr(lpFirst, lpSrch);
1849 /**************************************************************************
1850 * StrStrW [COMCTL32.362]
1853 LPWSTR WINAPI COMCTL32_StrStrW( LPCWSTR lpFirst, LPCWSTR lpSrch) {
1854 return strstrw(lpFirst, lpSrch);
1857 /**************************************************************************
1858 * StrSpnW [COMCTL32.364]
1861 INT32 WINAPI COMCTL32_StrSpnW( LPWSTR lpStr, LPWSTR lpSet) {
1862 LPWSTR lpLoop = lpStr;
1864 /* validate ptr */
1865 if ((lpStr == 0) || (lpSet == 0)) return 0;
1867 /* while(*lpLoop) { if lpLoop++; } */
1869 for(; (*lpLoop != 0); lpLoop++)
1870 if( CRTDLL_wcschr(lpSet, *(WORD*)lpLoop))
1871 return (INT32)(lpLoop-lpStr);
1873 return (INT32)(lpLoop-lpStr);