Fixed some undocumented functions.
[wine.git] / dlls / comctl32 / comctl32undoc.c
blobb51c65b4b08b2c7c98acab08f9eb898ba50fa9df
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 /**************************************************************************
30 * COMCTL32_11 [COMCTL32.11]
32 * PARAMS
33 * hdpa1 [I] handle to a dynamic pointer array
34 * hdpa2 [I] handle to a dynamic pointer array
35 * dwParam3
36 * dwParam4
37 * dwParam5
38 * dwParam6
40 * NOTES
41 * No more information available yet!
44 DWORD WINAPI
45 COMCTL32_11 (HDPA hdpa1, HDPA hdpa2, DWORD dwParam3,
46 DWORD dwParam4, DWORD dwParam5, DWORD dwParam6)
49 FIXME (commctrl, "(%p %p %08lx %08lx %08lx %08lx): empty stub\n",
50 hdpa1, hdpa2, dwParam3, dwParam4, dwParam5, dwParam6);
52 return 0;
56 /**************************************************************************
57 * Alloc [COMCTL32.71]
59 * Allocates memory block from the dll's private heap
61 * PARAMS
62 * dwSize [I] size of the allocated memory block
64 * RETURNS
65 * Success: pointer to allocated memory block
66 * Failure: NULL
69 LPVOID WINAPI
70 COMCTL32_Alloc (DWORD dwSize)
72 LPVOID lpPtr;
74 TRACE (commctrl, "(0x%lx)\n", dwSize);
76 lpPtr = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
78 TRACE (commctrl, "-- ret=%p\n", lpPtr);
80 return lpPtr;
84 /**************************************************************************
85 * ReAlloc [COMCTL32.72]
87 * Changes the size of an allocated memory block or allocates a memory
88 * block using the dll's private heap.
90 * PARAMS
91 * lpSrc [I] pointer to memory block which will be resized
92 * dwSize [I] new size of the memory block.
94 * RETURNS
95 * Success: pointer to the resized memory block
96 * Failure: NULL
98 * NOTES
99 * If lpSrc is a NULL-pointer, then COMCTL32_ReAlloc allocates a memory
100 * block like COMCTL32_Alloc.
103 LPVOID WINAPI
104 COMCTL32_ReAlloc (LPVOID lpSrc, DWORD dwSize)
106 LPVOID lpDest;
108 TRACE (commctrl, "(%p 0x%08lx)\n", lpSrc, dwSize);
110 if (lpSrc)
111 lpDest = HeapReAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, lpSrc, dwSize);
112 else
113 lpDest = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
115 TRACE (commctrl, "-- ret=%p\n", lpDest);
117 return lpDest;
121 /**************************************************************************
122 * Free [COMCTL32.73]
124 * Frees an allocated memory block from the dll's private heap.
126 * PARAMS
127 * lpMem [I] pointer to memory block which will be freed
129 * RETURNS
130 * Success: TRUE
131 * Failure: FALSE
134 BOOL32 WINAPI
135 COMCTL32_Free (LPVOID lpMem)
137 TRACE (commctrl, "(%p)\n", lpMem);
139 return HeapFree (COMCTL32_hHeap, 0, lpMem);
143 /**************************************************************************
144 * GetSize [COMCTL32.74]
146 * Retrieves the size of the specified memory block from the dll's
147 * private heap.
149 * PARAMS
150 * lpMem [I] pointer to an allocated memory block
152 * RETURNS
153 * Success: size of the specified memory block
154 * Failure: 0
157 DWORD WINAPI
158 COMCTL32_GetSize (LPVOID lpMem)
160 TRACE (commctrl, "(%p)\n", lpMem);
162 return HeapSize (COMCTL32_hHeap, 0, lpMem);
166 /**************************************************************************
167 * The MRU-API is a set of functions to manipulate MRU(Most Recently Used)
168 * lists.
173 typedef struct tagMRUINFO
175 DWORD dwParam1;
176 DWORD dwParam2;
177 DWORD dwParam3;
178 HKEY hkeyMain;
179 LPCSTR lpszSubKey;
180 DWORD dwParam6;
181 } MRUINFO, *LPMRUINFO;
184 typedef struct tagMRU
186 DWORD dwParam1; /* some kind of flag */
187 DWORD dwParam2;
188 DWORD dwParam3;
189 HKEY hkeyMRU;
190 LPCSTR lpszSubKey;
191 DWORD dwParam6;
192 } MRU, *HMRU;
194 LPVOID WINAPI
195 CreateMRUListEx32A (LPMRUINFO lpmi, DWORD dwParam2,
196 DWORD dwParam3, DWORD dwParam4);
199 /**************************************************************************
200 * CreateMRUListA [COMCTL32.151]
202 * PARAMS
203 * dwParam
205 * RETURNS
208 LPVOID WINAPI
209 CreateMRUList32A (LPMRUINFO lpmi)
211 return CreateMRUListEx32A (lpmi, 0, 0, 0);
215 DWORD WINAPI
216 FreeMRUList32A (HMRU hmru)
218 FIXME (commctrl, "(%p) empty stub!\n", hmru);
220 #if 0
221 if (!(hmru->dwParam1 & 1001)) {
222 RegSetValueEx32A (hmru->hKeyMRU, "MRUList", 0, REG_SZ,
223 hmru->lpszMRUString,
224 lstrlen32A (hmru->lpszMRUString));
228 RegClosKey32 (hmru->hkeyMRU
229 COMCTL32_Free32 (hmru->lpszMRUString);
230 #endif
232 return COMCTL32_Free (hmru);
237 DWORD WINAPI
238 AddMRUData (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
241 FIXME (commctrl, "(%lx %lx %lx) empty stub!\n",
242 dwParam1, dwParam2, dwParam3);
244 return 0;
248 DWORD WINAPI
249 FindMRUData (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
252 FIXME (commctrl, "(%lx %lx %lx %lx) empty stub!\n",
253 dwParam1, dwParam2, dwParam3, dwParam4);
255 return -1;
259 LPVOID WINAPI
260 CreateMRUListEx32A (LPMRUINFO lpmi, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
262 DWORD dwLocal1;
263 HKEY hkeyResult;
264 DWORD dwLocal3;
265 LPVOID lMRU;
266 DWORD dwLocal5;
267 DWORD dwLocal6;
268 DWORD dwLocal7;
269 DWORD dwDisposition;
271 /* internal variables */
272 LPVOID ptr;
274 FIXME (commctrl, "(%p) empty stub!\n", lpmi);
276 if (lpmi) {
277 FIXME (commctrl, "(%lx %lx %lx %lx \"%s\" %lx)\n",
278 lpmi->dwParam1, lpmi->dwParam2, lpmi->dwParam3,
279 lpmi->hkeyMain, lpmi->lpszSubKey, lpmi->dwParam6);
282 /* dummy pointer creation */
283 ptr = COMCTL32_Alloc (32);
285 FIXME (commctrl, "-- ret = %p\n", ptr);
287 return ptr;
293 /**************************************************************************
294 * Str_GetPtrA [COMCTL32.233]
296 * PARAMS
297 * lpSrc [I]
298 * lpDest [O]
299 * nMaxLen [I]
301 * RETURNS
304 INT32 WINAPI
305 Str_GetPtr32A (LPCSTR lpSrc, LPSTR lpDest, INT32 nMaxLen)
307 INT32 len;
309 TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
311 if (!lpDest && lpSrc)
312 return lstrlen32A (lpSrc);
314 if (nMaxLen == 0)
315 return 0;
317 if (lpSrc == NULL) {
318 lpDest[0] = '\0';
319 return 0;
322 len = lstrlen32A (lpSrc);
323 if (len >= nMaxLen)
324 len = nMaxLen - 1;
326 RtlMoveMemory (lpDest, lpSrc, len);
327 lpDest[len] = '\0';
329 return len;
333 /**************************************************************************
334 * Str_SetPtrA [COMCTL32.234]
336 * PARAMS
337 * lppDest [O]
338 * lpSrc [I]
340 * RETURNS
343 BOOL32 WINAPI
344 Str_SetPtr32A (LPSTR *lppDest, LPCSTR lpSrc)
346 TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc);
348 if (lpSrc) {
349 LPSTR ptr = COMCTL32_ReAlloc (lppDest, lstrlen32A (lpSrc) + 1);
350 if (!ptr)
351 return FALSE;
352 lstrcpy32A (ptr, lpSrc);
353 *lppDest = ptr;
355 else {
356 if (*lppDest) {
357 COMCTL32_Free (*lppDest);
358 *lppDest = NULL;
362 return TRUE;
366 /**************************************************************************
367 * Str_GetPtrW [COMCTL32.235]
369 * PARAMS
370 * lpSrc [I]
371 * lpDest [O]
372 * nMaxLen [I]
374 * RETURNS
377 INT32 WINAPI
378 Str_GetPtr32W (LPCWSTR lpSrc, LPWSTR lpDest, INT32 nMaxLen)
380 INT32 len;
382 TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
384 if (!lpDest && lpSrc)
385 return lstrlen32W (lpSrc);
387 if (nMaxLen == 0)
388 return 0;
390 if (lpSrc == NULL) {
391 lpDest[0] = L'\0';
392 return 0;
395 len = lstrlen32W (lpSrc);
396 if (len >= nMaxLen)
397 len = nMaxLen - 1;
399 RtlMoveMemory (lpDest, lpSrc, len*sizeof(WCHAR));
400 lpDest[len] = L'\0';
402 return len;
406 /**************************************************************************
407 * Str_SetPtrW [COMCTL32.236]
409 * PARAMS
410 * lpDest [O]
411 * lpSrc [I]
413 * RETURNS
416 BOOL32 WINAPI
417 Str_SetPtr32W (LPWSTR *lppDest, LPCWSTR lpSrc)
419 TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc);
421 if (lpSrc) {
422 INT32 len = lstrlen32W (lpSrc) + 1;
423 LPWSTR ptr = COMCTL32_ReAlloc (lppDest, len * sizeof(WCHAR));
424 if (!ptr)
425 return FALSE;
426 lstrcpy32W (ptr, lpSrc);
427 *lppDest = ptr;
429 else {
430 if (*lppDest) {
431 COMCTL32_Free (*lppDest);
432 *lppDest = NULL;
436 return TRUE;
440 /**************************************************************************
441 * The DSA-API is a set of functions to create and manipulate arrays of
442 * fix sized memory blocks. These arrays can store any kind of data
443 * (strings, icons...).
446 /**************************************************************************
447 * DSA_Create [COMCTL32.320] Creates a dynamic storage array
449 * PARAMS
450 * nSize [I] size of the array elements
451 * nGrow [I] number of elements by which the array grows when it is filled
453 * RETURNS
454 * Success: pointer to a array control structure. use this like a handle.
455 * Failure: NULL
458 HDSA WINAPI
459 DSA_Create (INT32 nSize, INT32 nGrow)
461 HDSA hdsa;
463 TRACE (commctrl, "(size=%d grow=%d)\n", nSize, nGrow);
465 hdsa = (HDSA)COMCTL32_Alloc (sizeof(DSA));
466 if (hdsa)
468 hdsa->nItemCount = 0;
469 hdsa->pData = NULL;
470 hdsa->nMaxCount = 0;
471 hdsa->nItemSize = nSize;
472 hdsa->nGrow = MAX(1, nGrow);
475 return hdsa;
479 /**************************************************************************
480 * DSA_Destroy [COMCTL32.321] Destroys a dynamic storage array
482 * PARAMS
483 * hdsa [I] pointer to the array control structure
485 * RETURNS
486 * Success: TRUE
487 * Failure: FALSE
490 BOOL32 WINAPI
491 DSA_Destroy (const HDSA hdsa)
493 TRACE (commctrl, "(%p)\n", hdsa);
495 if (!hdsa)
496 return FALSE;
498 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
499 return FALSE;
501 return COMCTL32_Free (hdsa);
505 /**************************************************************************
506 * DSA_GetItem [COMCTL32.322]
508 * PARAMS
509 * hdsa [I] pointer to the array control structure
510 * nIndex [I] number of the Item to get
511 * pDest [O] destination buffer. Has to be >= dwElementSize.
513 * RETURNS
514 * Success: TRUE
515 * Failure: FALSE
518 BOOL32 WINAPI
519 DSA_GetItem (const HDSA hdsa, INT32 nIndex, LPVOID pDest)
521 LPVOID pSrc;
523 TRACE (commctrl, "(%p %d %p)\n", hdsa, nIndex, pDest);
525 if (!hdsa)
526 return FALSE;
527 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
528 return FALSE;
530 pSrc = hdsa->pData + (hdsa->nItemSize * nIndex);
531 memmove (pDest, pSrc, hdsa->nItemSize);
533 return TRUE;
537 /**************************************************************************
538 * DSA_GetItemPtr [COMCTL32.323]
540 * Retrieves a pointer to the specified item.
542 * PARAMS
543 * hdsa [I] pointer to the array control structure
544 * nIndex [I] index of the desired item
546 * RETURNS
547 * Success: pointer to an item
548 * Failure: NULL
551 LPVOID WINAPI
552 DSA_GetItemPtr (const HDSA hdsa, INT32 nIndex)
554 LPVOID pSrc;
556 TRACE (commctrl, "(%p %d)\n", hdsa, nIndex);
558 if (!hdsa)
559 return NULL;
560 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
561 return NULL;
563 pSrc = hdsa->pData + (hdsa->nItemSize * nIndex);
565 TRACE (commctrl, "-- ret=%p\n", pSrc);
567 return pSrc;
571 /**************************************************************************
572 * DSA_SetItem [COMCTL32.325]
574 * Sets the contents of an item in the array.
576 * PARAMS
577 * hdsa [I] pointer to the array control structure
578 * nIndex [I] index for the item
579 * pSrc [I] pointer to the new item data
581 * RETURNS
582 * Success: TRUE
583 * Failure: FALSE
586 BOOL32 WINAPI
587 DSA_SetItem (const HDSA hdsa, INT32 nIndex, LPVOID pSrc)
589 INT32 nSize, nNewItems;
590 LPVOID pDest, lpTemp;
592 TRACE (commctrl, "(%p %d %p)\n", hdsa, nIndex, pSrc);
594 if ((!hdsa) || nIndex < 0)
595 return FALSE;
597 if (hdsa->nItemCount <= nIndex) {
598 /* within the old array */
599 if (hdsa->nMaxCount > nIndex) {
600 /* within the allocated space, set a new boundary */
601 hdsa->nItemCount = nIndex;
603 else {
604 /* resize the block of memory */
605 nNewItems =
606 hdsa->nGrow * ((INT32)((nIndex - 1) / hdsa->nGrow) + 1);
607 nSize = hdsa->nItemSize * nNewItems;
609 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
610 if (!lpTemp)
611 return FALSE;
613 hdsa->nMaxCount = nNewItems;
614 hdsa->pData = lpTemp;
618 /* put the new entry in */
619 pDest = hdsa->pData + (hdsa->nItemSize * nIndex);
620 TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
621 pDest, pSrc, hdsa->nItemSize);
622 memmove (pDest, pSrc, hdsa->nItemSize);
624 return TRUE;
628 /**************************************************************************
629 * DSA_InsertItem [COMCTL32.325]
631 * PARAMS
632 * hdsa [I] pointer to the array control structure
633 * nIndex [I] index for the new item
634 * pSrc [I] pointer to the element
636 * RETURNS
637 * Success: position of the new item
638 * Failure: -1
641 INT32 WINAPI
642 DSA_InsertItem (const HDSA hdsa, INT32 nIndex, LPVOID pSrc)
644 INT32 nNewItems, nSize, i;
645 LPVOID lpTemp, lpDest;
646 LPDWORD p;
648 TRACE(commctrl, "(%p %d %p)\n", hdsa, nIndex, pSrc);
650 if ((!hdsa) || nIndex < 0)
651 return -1;
653 for (i = 0; i < hdsa->nItemSize; i += 4) {
654 p = *(DWORD**)(pSrc + i);
655 if (IsBadStringPtr32A ((char*)p, 256))
656 TRACE (commctrl, "-- %d=%p\n", i, (DWORD*)p);
657 else
658 TRACE (commctrl, "-- %d=%p [%s]\n", i, p, debugstr_a((char*)p));
661 /* when nIndex > nItemCount then append */
662 if (nIndex >= hdsa->nItemCount)
663 nIndex = hdsa->nItemCount;
665 /* do we need to resize ? */
666 if (hdsa->nItemCount >= hdsa->nMaxCount) {
667 nNewItems = hdsa->nMaxCount + hdsa->nGrow;
668 nSize = hdsa->nItemSize * nNewItems;
670 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
671 if (!lpTemp)
672 return -1;
674 hdsa->nMaxCount = nNewItems;
675 hdsa->pData = lpTemp;
678 /* do we need to move elements ? */
679 if (nIndex < hdsa->nItemCount) {
680 lpTemp = hdsa->pData + (hdsa->nItemSize * nIndex);
681 lpDest = lpTemp + hdsa->nItemSize;
682 nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize;
683 TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
684 lpDest, lpTemp, nSize);
685 memmove (lpDest, lpTemp, nSize);
688 /* ok, we can put the new Item in */
689 hdsa->nItemCount++;
690 lpDest = hdsa->pData + (hdsa->nItemSize * nIndex);
691 TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
692 lpDest, pSrc, hdsa->nItemSize);
693 memmove (lpDest, pSrc, hdsa->nItemSize);
695 return hdsa->nItemCount;
699 /**************************************************************************
700 * DSA_DeleteItem [COMCTL32.326]
702 * PARAMS
703 * hdsa [I] pointer to the array control structure
704 * nIndex [I] index for the element to delete
706 * RETURNS
707 * Success: number of the deleted element
708 * Failure: -1
711 INT32 WINAPI
712 DSA_DeleteItem (const HDSA hdsa, INT32 nIndex)
714 LPVOID lpDest,lpSrc;
715 INT32 nSize;
717 TRACE (commctrl, "(%p %d)\n", hdsa, nIndex);
719 if (!hdsa)
720 return -1;
721 if (nIndex < 0 || nIndex >= hdsa->nItemCount)
722 return -1;
724 /* do we need to move ? */
725 if (nIndex < hdsa->nItemCount - 1) {
726 lpDest = hdsa->pData + (hdsa->nItemSize * nIndex);
727 lpSrc = lpDest + hdsa->nItemSize;
728 nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1);
729 TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
730 lpDest, lpSrc, nSize);
731 memmove (lpDest, lpSrc, nSize);
734 hdsa->nItemCount--;
736 /* free memory ? */
737 if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) {
738 nSize = hdsa->nItemSize * hdsa->nItemCount;
740 lpDest = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
741 if (!lpDest)
742 return -1;
744 hdsa->nMaxCount = hdsa->nItemCount;
745 hdsa->pData = lpDest;
748 return nIndex;
752 /**************************************************************************
753 * DSA_DeleteAllItems [COMCTL32.326]
755 * Removes all items and reinitializes the array.
757 * PARAMS
758 * hdsa [I] pointer to the array control structure
760 * RETURNS
761 * Success: TRUE
762 * Failure: FALSE
765 BOOL32 WINAPI
766 DSA_DeleteAllItems (const HDSA hdsa)
768 TRACE (commctrl, "(%p)\n", hdsa);
770 if (!hdsa)
771 return FALSE;
772 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
773 return FALSE;
775 hdsa->nItemCount = 0;
776 hdsa->pData = NULL;
777 hdsa->nMaxCount = 0;
779 return TRUE;
783 /**************************************************************************
784 * The DPA-API is a set of functions to create and manipulate arrays of
785 * pointers.
788 /**************************************************************************
789 * DPA_Create [COMCTL32.328] Creates a dynamic pointer array
791 * PARAMS
792 * nGrow [I] number of items by which the array grows when it is filled
794 * RETURNS
795 * Success: handle (pointer) to the pointer array.
796 * Failure: NULL
799 HDPA WINAPI
800 DPA_Create (INT32 nGrow)
802 HDPA hdpa;
804 TRACE (commctrl, "(%d)\n", nGrow);
806 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
807 if (hdpa) {
808 hdpa->nGrow = MAX(8, nGrow);
809 hdpa->hHeap = COMCTL32_hHeap;
810 hdpa->nMaxCount = hdpa->nGrow * 2;
811 hdpa->ptrs =
812 (LPVOID*)COMCTL32_Alloc (hdpa->nMaxCount * sizeof(LPVOID));
815 TRACE (commctrl, "-- %p\n", hdpa);
817 return hdpa;
821 /**************************************************************************
822 * DPA_Destroy [COMCTL32.329] Destroys a dynamic pointer array
824 * PARAMS
825 * hdpa [I] handle (pointer) to the pointer array
827 * RETURNS
828 * Success: TRUE
829 * Failure: FALSE
832 BOOL32 WINAPI
833 DPA_Destroy (const HDPA hdpa)
835 TRACE (commctrl, "(%p)\n", hdpa);
837 if (!hdpa)
838 return FALSE;
840 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
841 return FALSE;
843 return HeapFree (hdpa->hHeap, 0, hdpa);
847 /**************************************************************************
848 * DPA_Grow [COMCTL32.330]
850 * Sets the growth amount.
852 * PARAMS
853 * hdpa [I] handle (pointer) to the existing (source) pointer array
854 * nGrow [I] number of items, the array grows, when it's too small
856 * RETURNS
857 * Success: TRUE
858 * Failure: FALSE
861 BOOL32 WINAPI
862 DPA_Grow (const HDPA hdpa, INT32 nGrow)
864 TRACE (commctrl, "(%p %d)\n", hdpa, nGrow);
866 if (!hdpa)
867 return FALSE;
869 hdpa->nGrow = MAX(8, nGrow);
871 return TRUE;
875 /**************************************************************************
876 * DPA_Clone [COMCTL32.331]
878 * Copies a pointer array to an other one or creates a copy
880 * PARAMS
881 * hdpa [I] handle (pointer) to the existing (source) pointer array
882 * hdpaNew [O] handle (pointer) to the destination pointer array
884 * RETURNS
885 * Success: pointer to the destination pointer array.
886 * Failure: NULL
888 * NOTES
889 * - If the 'hdpaNew' is a NULL-Pointer, a copy of the source pointer
890 * array will be created and it's handle (pointer) is returned.
891 * - If 'hdpa' is a NULL-Pointer, the original implementation crashes,
892 * this implementation just returns NULL.
895 HDPA WINAPI
896 DPA_Clone (const HDPA hdpa, const HDPA hdpaNew)
898 INT32 nNewItems, nSize;
899 HDPA hdpaTemp;
901 if (!hdpa)
902 return NULL;
904 TRACE (commctrl, "(%p %p)\n", hdpa, hdpaNew);
906 if (!hdpaNew) {
907 /* create a new DPA */
908 hdpaTemp = (HDPA)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
909 sizeof(DPA));
910 hdpaTemp->hHeap = hdpa->hHeap;
911 hdpaTemp->nGrow = hdpa->nGrow;
913 else
914 hdpaTemp = hdpaNew;
916 if (hdpaTemp->ptrs) {
917 /* remove old pointer array */
918 HeapFree (hdpaTemp->hHeap, 0, hdpaTemp->ptrs);
919 hdpaTemp->ptrs = NULL;
920 hdpaTemp->nItemCount = 0;
921 hdpaTemp->nMaxCount = 0;
924 /* create a new pointer array */
925 nNewItems = hdpaTemp->nGrow *
926 ((INT32)((hdpa->nItemCount - 1) / hdpaTemp->nGrow) + 1);
927 nSize = nNewItems * sizeof(LPVOID);
928 hdpaTemp->ptrs =
929 (LPVOID*)HeapAlloc (hdpaTemp->hHeap, HEAP_ZERO_MEMORY, nSize);
930 hdpaTemp->nMaxCount = nNewItems;
932 /* clone the pointer array */
933 hdpaTemp->nItemCount = hdpa->nItemCount;
934 memmove (hdpaTemp->ptrs, hdpa->ptrs,
935 hdpaTemp->nItemCount * sizeof(LPVOID));
937 return hdpaTemp;
941 /**************************************************************************
942 * DPA_GetPtr [COMCTL32.332]
944 * Retrieves a pointer from a dynamic pointer array
946 * PARAMS
947 * hdpa [I] handle (pointer) to the pointer array
948 * nIndex [I] array index of the desired pointer
950 * RETURNS
951 * Success: pointer
952 * Failure: NULL
955 LPVOID WINAPI
956 DPA_GetPtr (const HDPA hdpa, INT32 i)
958 TRACE (commctrl, "(%p %d)\n", hdpa, i);
960 if (!hdpa)
961 return NULL;
962 if (!hdpa->ptrs)
963 return NULL;
964 if ((i < 0) || (i >= hdpa->nItemCount))
965 return NULL;
967 TRACE (commctrl, "-- %p\n", hdpa->ptrs[i]);
969 return hdpa->ptrs[i];
973 /**************************************************************************
974 * DPA_GetPtrIndex [COMCTL32.333]
976 * Retrieves the index of the specified pointer
978 * PARAMS
979 * hdpa [I] handle (pointer) to the pointer array
980 * p [I] pointer
982 * RETURNS
983 * Success: index of the specified pointer
984 * Failure: -1
987 INT32 WINAPI
988 DPA_GetPtrIndex (const HDPA hdpa, LPVOID p)
990 INT32 i;
992 if (!hdpa->ptrs)
993 return -1;
995 for (i = 0; i < hdpa->nItemCount; i++) {
996 if (hdpa->ptrs[i] == p)
997 return i;
1000 return -1;
1004 /**************************************************************************
1005 * DPA_InsertPtr [COMCTL32.334]
1007 * Inserts a pointer into a dynamic pointer array
1009 * PARAMS
1010 * hdpa [I] handle (pointer) to the array
1011 * i [I] array index
1012 * p [I] pointer to insert
1014 * RETURNS
1015 * Success: index of the inserted pointer
1016 * Failure: -1
1019 INT32 WINAPI
1020 DPA_InsertPtr (const HDPA hdpa, INT32 i, LPVOID p)
1022 INT32 nNewItems, nSize, nIndex = 0;
1023 LPVOID *lpTemp, *lpDest;
1025 TRACE (commctrl, "(%p %d %p)\n", hdpa, i, p);
1027 if ((!hdpa) || (i < 0))
1028 return -1;
1030 if (!hdpa->ptrs) {
1031 hdpa->ptrs =
1032 (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1033 2 * hdpa->nGrow * sizeof(LPVOID));
1034 if (!hdpa->ptrs)
1035 return -1;
1036 hdpa->nMaxCount = hdpa->nGrow * 2;
1037 nIndex = 0;
1039 else {
1040 if (hdpa->nItemCount >= hdpa->nMaxCount) {
1041 TRACE (commctrl, "-- resizing\n");
1042 nNewItems = hdpa->nMaxCount + hdpa->nGrow;
1043 nSize = nNewItems * sizeof(LPVOID);
1045 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1046 hdpa->ptrs, nSize);
1047 if (!lpTemp)
1048 return -1;
1049 hdpa->nMaxCount = nNewItems;
1050 hdpa->ptrs = lpTemp;
1053 if (i >= hdpa->nItemCount) {
1054 nIndex = hdpa->nItemCount;
1055 TRACE (commctrl, "-- appending at %d\n", nIndex);
1057 else {
1058 TRACE (commctrl, "-- inserting at %d\n", i);
1059 lpTemp = hdpa->ptrs + (sizeof(LPVOID) * i);
1060 lpDest = lpTemp + sizeof(LPVOID);
1061 nSize = (hdpa->nItemCount - i) * sizeof(LPVOID);
1062 TRACE (commctrl, "-- move dest=%p src=%p size=%x\n",
1063 lpDest, lpTemp, nSize);
1064 memmove (lpDest, lpTemp, nSize);
1065 nIndex = i;
1069 /* insert item */
1070 hdpa->nItemCount++;
1071 hdpa->ptrs[nIndex] = p;
1073 return nIndex;
1077 /**************************************************************************
1078 * DPA_SetPtr [COMCTL32.335]
1080 * Sets a pointer in the pointer array
1082 * PARAMS
1083 * hdpa [I] handle (pointer) to the pointer array
1084 * i [I] index of the pointer that will be set
1085 * p [I] pointer to be set
1087 * RETURNS
1088 * Success: TRUE
1089 * Failure: FALSE
1092 BOOL32 WINAPI
1093 DPA_SetPtr (const HDPA hdpa, INT32 i, LPVOID p)
1095 LPVOID *lpTemp;
1097 TRACE (commctrl, "(%p %d %p)\n", hdpa, i, p);
1099 if ((!hdpa) || i < 0)
1100 return FALSE;
1102 if (hdpa->nItemCount <= i) {
1103 /* within the old array */
1104 if (hdpa->nMaxCount > i) {
1105 /* within the allocated space, set a new boundary */
1106 hdpa->nItemCount = i;
1108 else {
1109 /* resize the block of memory */
1110 INT32 nNewItems =
1111 hdpa->nGrow * ((INT32)((i - 1) / hdpa->nGrow) + 1);
1112 INT32 nSize = nNewItems * sizeof(LPVOID);
1114 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1115 hdpa->ptrs, nSize);
1116 if (!lpTemp)
1117 return FALSE;
1119 hdpa->nItemCount = nNewItems;
1120 hdpa->ptrs = lpTemp;
1124 /* put the new entry in */
1125 hdpa->ptrs[i] = p;
1127 return TRUE;
1131 /**************************************************************************
1132 * DPA_DeletePtr [COMCTL32.336]
1134 * Removes a pointer from the pointer array.
1136 * PARAMS
1137 * hdpa [I] handle (pointer) to the pointer array
1138 * i [I] index of the pointer that will be deleted
1140 * RETURNS
1141 * Success: deleted pointer
1142 * Failure: NULL
1145 LPVOID WINAPI
1146 DPA_DeletePtr (const HDPA hdpa, INT32 i)
1148 LPVOID lpDest, lpSrc, lpTemp = NULL;
1149 INT32 nSize;
1151 TRACE (commctrl, "(%p %d)\n", hdpa, i);
1153 if ((!hdpa) || i < 0 || i >= hdpa->nItemCount)
1154 return NULL;
1156 lpTemp = hdpa->ptrs[i];
1158 /* do we need to move ?*/
1159 if (i < hdpa->nItemCount - 1) {
1160 lpDest = hdpa->ptrs + (i * sizeof (LPVOID));
1161 lpSrc = lpDest + sizeof(LPVOID);
1162 nSize = (hdpa->nItemCount - i - 1) * sizeof(LPVOID);
1163 TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",
1164 lpDest, lpSrc, nSize);
1165 memmove (lpDest, lpSrc, nSize);
1168 hdpa->nItemCount --;
1170 /* free memory ?*/
1171 if ((hdpa->nMaxCount - hdpa->nItemCount) >= hdpa->nGrow) {
1172 INT32 nNewItems = MIN(hdpa->nGrow * 2, hdpa->nItemCount);
1173 nSize = nNewItems * sizeof(LPVOID);
1174 lpDest = (LPVOID)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1175 hdpa->ptrs, nSize);
1176 if (!lpDest)
1177 return NULL;
1179 hdpa->nMaxCount = nNewItems;
1180 hdpa->ptrs = (LPVOID*)lpDest;
1183 return lpTemp;
1187 /**************************************************************************
1188 * DPA_DeleteAllPtrs [COMCTL32.337]
1190 * Removes all pointers and reinitializes the array.
1192 * PARAMS
1193 * hdpa [I] handle (pointer) to the pointer array
1195 * RETURNS
1196 * Success: TRUE
1197 * Failure: FALSE
1200 BOOL32 WINAPI
1201 DPA_DeleteAllPtrs (const HDPA hdpa)
1203 TRACE (commctrl, "(%p)\n", hdpa);
1205 if (!hdpa)
1206 return FALSE;
1208 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
1209 return FALSE;
1211 hdpa->nItemCount = 0;
1212 hdpa->nMaxCount = hdpa->nGrow * 2;
1213 hdpa->ptrs = (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1214 hdpa->nMaxCount * sizeof(LPVOID));
1216 return TRUE;
1220 /**************************************************************************
1221 * DPA_QuickSort [Internal]
1223 * Ordinary quicksort (used by DPA_Sort).
1225 * PARAMS
1226 * lpPtrs [I] pointer to the pointer array
1227 * l [I] index of the "left border" of the partition
1228 * r [I] index of the "right border" of the partition
1229 * pfnCompare [I] pointer to the compare function
1230 * lParam [I] user defined value (3rd parameter in compare function)
1232 * RETURNS
1233 * NONE
1236 static VOID
1237 DPA_QuickSort (LPVOID *lpPtrs, INT32 l, INT32 r,
1238 PFNDPACOMPARE pfnCompare, LPARAM lParam)
1240 LPVOID t, v;
1241 INT32 i, j;
1243 TRACE (commctrl, "l=%i r=%i\n", l, r);
1245 i = l;
1246 j = r;
1247 v = lpPtrs[(int)(l+r)/2];
1248 do {
1249 while ((pfnCompare)(lpPtrs[i], v, lParam) < 0) i++;
1250 while ((pfnCompare)(lpPtrs[j], v, lParam) > 0) j--;
1251 if (i <= j)
1253 t = lpPtrs[i];
1254 lpPtrs[i++] = lpPtrs[j];
1255 lpPtrs[j--] = t;
1257 } while (i <= j);
1258 if (l < j) DPA_QuickSort (lpPtrs, l, j, pfnCompare, lParam);
1259 if (i < r) DPA_QuickSort (lpPtrs, i, r, pfnCompare, lParam);
1263 /**************************************************************************
1264 * DPA_Sort [COMCTL32.338]
1266 * Sorts a pointer array using a user defined compare function
1268 * PARAMS
1269 * hdpa [I] handle (pointer) to the pointer array
1270 * pfnCompare [I] pointer to the compare function
1271 * lParam [I] user defined value (3rd parameter of compare function)
1273 * RETURNS
1274 * Success: TRUE
1275 * Failure: FALSE
1278 BOOL32 WINAPI
1279 DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
1281 if (!hdpa || !pfnCompare)
1282 return FALSE;
1284 TRACE (commctrl, "(%p %p 0x%lx)\n", hdpa, pfnCompare, lParam);
1286 if ((hdpa->nItemCount > 1) && (hdpa->ptrs))
1287 DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1,
1288 pfnCompare, lParam);
1290 return TRUE;
1294 /**************************************************************************
1295 * DPA_Search [COMCTL32.339]
1297 * Searches a pointer array for a specified pointer
1299 * PARAMS
1300 * hdpa [I] handle (pointer) to the pointer array
1301 * pFind [I] pointer to search for
1302 * nStart [I] start index
1303 * pfnCompare [I] pointer to the compare function
1304 * lParam [I] user defined value (3rd parameter of compare function)
1305 * uOptions [I] search options
1307 * RETURNS
1308 * Success: index of the pointer in the array.
1309 * Failure: -1
1311 * NOTES
1312 * Binary search taken from R.Sedgewick "Algorithms in C"!
1313 * Function is NOT tested!
1314 * If something goes wrong, blame HIM not ME! (Eric Kohl)
1317 INT32 WINAPI
1318 DPA_Search (const HDPA hdpa, LPVOID pFind, INT32 nStart,
1319 PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT32 uOptions)
1321 if (!hdpa || !pfnCompare || !pFind)
1322 return -1;
1324 TRACE (commctrl, "(%p %p %d %p 0x%08lx 0x%08x)\n",
1325 hdpa, pFind, nStart, pfnCompare, lParam, uOptions);
1327 if (uOptions & DPAS_SORTED) {
1328 /* array is sorted --> use binary search */
1329 INT32 l, r, x, n;
1330 LPVOID *lpPtr;
1332 TRACE (commctrl, "binary search\n");
1334 l = (nStart == -1) ? 0 : nStart;
1335 r = hdpa->nItemCount - 1;
1336 lpPtr = hdpa->ptrs;
1337 while (r >= l) {
1338 x = (l + r) / 2;
1339 n = (pfnCompare)(pFind, lpPtr[x], lParam);
1340 if (n < 0)
1341 r = x - 1;
1342 else
1343 l = x + 1;
1344 if (n == 0) {
1345 TRACE (commctrl, "-- ret=%d\n", n);
1346 return n;
1350 if (uOptions & DPAS_INSERTBEFORE) {
1351 TRACE (commctrl, "-- ret=%d\n", r);
1352 return r;
1355 if (uOptions & DPAS_INSERTAFTER) {
1356 TRACE (commctrl, "-- ret=%d\n", r);
1357 return l;
1360 else {
1361 /* array is not sorted --> use linear search */
1362 LPVOID *lpPtr;
1363 INT32 nIndex;
1365 TRACE (commctrl, "linear search\n");
1367 nIndex = (nStart == -1)? 0 : nStart;
1368 lpPtr = hdpa->ptrs;
1369 for (; nIndex < hdpa->nItemCount; nIndex++) {
1370 if ((pfnCompare)(pFind, lpPtr[nIndex], lParam) == 0) {
1371 TRACE (commctrl, "-- ret=%d\n", nIndex);
1372 return nIndex;
1377 TRACE (commctrl, "-- not found: ret=-1\n");
1378 return -1;
1382 /**************************************************************************
1383 * DPA_CreateEx [COMCTL32.340]
1385 * Creates a dynamic pointer array using the specified size and heap.
1387 * PARAMS
1388 * nGrow [I] number of items by which the array grows when it is filled
1389 * hHeap [I] handle to the heap where the array is stored
1391 * RETURNS
1392 * Success: handle (pointer) to the pointer array.
1393 * Failure: NULL
1396 HDPA WINAPI
1397 DPA_CreateEx (INT32 nGrow, HANDLE32 hHeap)
1399 HDPA hdpa;
1401 TRACE (commctrl, "(%d 0x%x)\n", nGrow, hHeap);
1403 if (hHeap)
1404 hdpa = (HDPA)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, sizeof(DPA));
1405 else
1406 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
1408 if (hdpa) {
1409 hdpa->nGrow = MIN(8, nGrow);
1410 hdpa->hHeap = hHeap ? hHeap : COMCTL32_hHeap;
1411 hdpa->nMaxCount = hdpa->nGrow * 2;
1412 hdpa->ptrs =
1413 (LPVOID*)HeapAlloc (hHeap, HEAP_ZERO_MEMORY,
1414 hdpa->nMaxCount * sizeof(LPVOID));
1417 TRACE (commctrl, "-- %p\n", hdpa);
1419 return hdpa;
1423 /**************************************************************************
1424 * Notification functions
1427 typedef struct tagNOTIFYDATA
1429 HWND32 hwndFrom;
1430 HWND32 hwndTo;
1431 DWORD dwParam3;
1432 DWORD dwParam4;
1433 DWORD dwParam5;
1434 DWORD dwParam6;
1435 } NOTIFYDATA, *LPNOTIFYDATA;
1438 /**************************************************************************
1439 * DoNotify [Internal]
1442 static LRESULT
1443 DoNotify (LPNOTIFYDATA lpNotify, UINT32 uCode, LPNMHDR lpHdr)
1445 NMHDR nmhdr;
1446 LPNMHDR lpNmh = NULL;
1447 UINT32 idFrom = 0;
1449 TRACE (commctrl, "(0x%04x 0x%04x %d %p 0x%08lx)\n",
1450 lpNotify->hwndFrom, lpNotify->hwndTo, uCode, lpHdr,
1451 lpNotify->dwParam5);
1453 if (!lpNotify->hwndTo)
1454 return 0;
1456 if (lpNotify->hwndFrom == -1) {
1457 lpNmh = lpHdr;
1458 idFrom = lpHdr->idFrom;
1460 else {
1461 if (lpNotify->hwndFrom) {
1462 HWND32 hwndParent = GetParent32 (lpNotify->hwndFrom);
1463 if (hwndParent) {
1464 hwndParent = GetWindow32 (lpNotify->hwndFrom, GW_OWNER);
1465 if (hwndParent)
1466 idFrom = GetDlgCtrlID32 (lpNotify->hwndFrom);
1470 lpNmh = (lpHdr) ? lpHdr : &nmhdr;
1472 lpNmh->hwndFrom = lpNotify->hwndFrom;
1473 lpNmh->idFrom = idFrom;
1474 lpNmh->code = uCode;
1477 return SendMessage32A (lpNotify->hwndTo, WM_NOTIFY, idFrom, (LPARAM)lpNmh);
1481 /**************************************************************************
1482 * SendNotify [COMCTL32.341]
1484 * PARAMS
1485 * hwndFrom [I]
1486 * hwndTo [I]
1487 * uCode [I]
1488 * lpHdr [I]
1490 * RETURNS
1491 * Success: return value from notification
1492 * Failure: 0
1495 LRESULT WINAPI
1496 COMCTL32_SendNotify (HWND32 hwndFrom, HWND32 hwndTo,
1497 UINT32 uCode, LPNMHDR lpHdr)
1499 NOTIFYDATA notify;
1501 TRACE (commctrl, "(0x%04x 0x%04x %d %p)\n",
1502 hwndFrom, hwndTo, uCode, lpHdr);
1504 notify.hwndFrom = hwndFrom;
1505 notify.hwndTo = hwndTo;
1506 notify.dwParam5 = 0;
1507 notify.dwParam6 = 0;
1509 return DoNotify (&notify, uCode, lpHdr);
1513 /**************************************************************************
1514 * SendNotifyEx [COMCTL32.342]
1516 * PARAMS
1517 * hwndFrom [I]
1518 * hwndTo [I]
1519 * uCode [I]
1520 * lpHdr [I]
1521 * dwParam5 [I]
1523 * RETURNS
1524 * Success: return value from notification
1525 * Failure: 0
1528 LRESULT WINAPI
1529 COMCTL32_SendNotifyEx (HWND32 hwndTo, HWND32 hwndFrom, UINT32 uCode,
1530 LPNMHDR lpHdr, DWORD dwParam5)
1532 NOTIFYDATA notify;
1533 HWND32 hwndNotify;
1535 TRACE (commctrl, "(0x%04x 0x%04x %d %p 0x%08lx)\n",
1536 hwndFrom, hwndTo, uCode, lpHdr, dwParam5);
1538 hwndNotify = hwndTo;
1539 if (!hwndTo) {
1540 if (IsWindow32 (hwndFrom)) {
1541 hwndNotify = GetParent32 (hwndFrom);
1542 if (!hwndNotify)
1543 return 0;
1547 notify.hwndFrom = hwndFrom;
1548 notify.hwndTo = hwndNotify;
1549 notify.dwParam5 = dwParam5;
1550 notify.dwParam6 = 0;
1552 return DoNotify (&notify, uCode, lpHdr);
1556 /**************************************************************************
1557 * StrChrA [COMCTL32.350]
1561 LPSTR WINAPI
1562 COMCTL32_StrChrA (LPCSTR lpString, CHAR cChar)
1564 return strchr (lpString, cChar);
1568 /**************************************************************************
1569 * StrStrIA [COMCTL32.355]
1572 LPSTR WINAPI
1573 COMCTL32_StrStrIA (LPCSTR lpStr1, LPCSTR lpStr2)
1575 INT32 len1, len2, i;
1576 CHAR first;
1578 if (*lpStr2 == 0)
1579 return ((LPSTR)lpStr1);
1580 len1 = 0;
1581 while (lpStr1[len1] != 0) ++len1;
1582 len2 = 0;
1583 while (lpStr2[len2] != 0) ++len2;
1584 if (len2 == 0)
1585 return ((LPSTR)(lpStr1 + len1));
1586 first = tolower (*lpStr2);
1587 while (len1 >= len2) {
1588 if (tolower(*lpStr1) == first) {
1589 for (i = 1; i < len2; ++i)
1590 if (tolower (lpStr1[i]) != tolower(lpStr2[i]))
1591 break;
1592 if (i >= len2)
1593 return ((LPSTR)lpStr1);
1595 ++lpStr1; --len1;
1597 return (NULL);
1601 /**************************************************************************
1602 * StrToIntA [COMCTL32.357] Converts a string to a signed integer.
1605 INT32 WINAPI
1606 COMCTL32_StrToIntA (LPSTR lpString)
1608 return atoi(lpString);
1612 /**************************************************************************
1613 * COMCTL32_385 [COMCTL32.385]
1615 * Enumerates all items in a dynamic pointer array.
1617 * PARAMS
1618 * hdpa [I] handle to the dynamic pointer array
1619 * enumProc [I]
1620 * dwParam3 [I]
1622 * RETURNS
1623 * none
1625 * NOTES
1626 * Original function name unknown!
1629 typedef DWORD (CALLBACK *DPAENUMPROC)(LPVOID, DWORD);
1631 VOID WINAPI
1632 COMCTL32_385 (HDPA hdpa, DPAENUMPROC enumProc, DWORD dwParam3)
1634 INT32 i;
1636 TRACE (commctrl, "(%p %p %08lx)\n", hdpa, enumProc, dwParam3);
1638 if (!hdpa)
1639 return;
1640 if (hdpa->nItemCount <= 0)
1641 return;
1643 for (i = 0; i < hdpa->nItemCount; i++) {
1644 if ((enumProc)(hdpa->ptrs[i], dwParam3) == 0)
1645 return;
1648 return;
1652 /**************************************************************************
1653 * COMCTL32_386 [COMCTL32.386]
1655 * Enumerates all items in a dynamic pointer array and destroys it.
1657 * PARAMS
1658 * hdpa [I] handle to the dynamic pointer array
1659 * enumProc [I]
1660 * dwParam3 [I]
1662 * RETURNS
1663 * Success: TRUE
1664 * Failure: FALSE
1666 * NOTES
1667 * Original function name unknown!
1670 BOOL32 WINAPI
1671 COMCTL32_386 (HDPA hdpa, DPAENUMPROC enumProc, DWORD dwParam3)
1673 TRACE (commctrl, "(%p %p %08lx)\n", hdpa, enumProc, dwParam3);
1675 COMCTL32_385 (hdpa, enumProc, dwParam3);
1677 return DPA_Destroy (hdpa);
1681 /**************************************************************************
1682 * COMCTL32_387 [COMCTL32.387]
1684 * Enumerates all items in a dynamic storage array.
1686 * PARAMS
1687 * hdsa [I] handle to the dynamic storage array
1688 * enumProc [I]
1689 * dwParam3 [I]
1691 * RETURNS
1692 * none
1694 * NOTES
1695 * Original function name unknown!
1698 typedef DWORD (CALLBACK *DSAENUMPROC)(LPVOID, DWORD);
1700 VOID WINAPI
1701 COMCTL32_387 (HDSA hdsa, DSAENUMPROC enumProc, DWORD dwParam3)
1703 INT32 i;
1705 TRACE (commctrl, "(%p %p %08lx)\n", hdsa, enumProc, dwParam3);
1707 if (!hdsa)
1708 return;
1709 if (hdsa->nItemCount <= 0)
1710 return;
1712 for (i = 0; i < hdsa->nItemCount; i++) {
1713 LPVOID lpItem = DSA_GetItemPtr (hdsa, i);
1714 if ((enumProc)(lpItem, dwParam3) == 0)
1715 return;
1718 return;
1722 /**************************************************************************
1723 * COMCTL32_388 [COMCTL32.388]
1725 * Enumerates all items in a dynamic storage array and destroys it.
1727 * PARAMS
1728 * hdsa [I] handle to the dynamic storage array
1729 * enumProc [I]
1730 * dwParam3 [I]
1732 * RETURNS
1733 * Success: TRUE
1734 * Failure: FALSE
1736 * NOTES
1737 * Original function name unknown!
1740 BOOL32 WINAPI
1741 COMCTL32_388 (HDSA hdsa, DSAENUMPROC enumProc, DWORD dwParam3)
1743 TRACE (commctrl, "(%p %p %08lx)\n", hdsa, enumProc, dwParam3);
1745 COMCTL32_387 (hdsa, enumProc, dwParam3);
1747 return DSA_Destroy (hdsa);