2 * Undocumented functions from COMCTL32.DLL
4 * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
5 * 1998 Juergen Schmied <j.schmied@metronet.de>
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).
13 * - Add more functions.
14 * - Write some documentation.
26 extern HANDLE32 COMCTL32_hHeap
; /* handle to the private heap */
29 /**************************************************************************
30 * COMCTL32_11 [COMCTL32.11]
33 * hdpa1 [I] handle to a dynamic pointer array
34 * hdpa2 [I] handle to a dynamic pointer array
41 * No more information available yet!
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
);
56 /**************************************************************************
59 * Allocates memory block from the dll's private heap
62 * dwSize [I] size of the allocated memory block
65 * Success: pointer to allocated memory block
70 COMCTL32_Alloc (DWORD dwSize
)
74 TRACE (commctrl
, "(0x%lx)\n", dwSize
);
76 lpPtr
= HeapAlloc (COMCTL32_hHeap
, HEAP_ZERO_MEMORY
, dwSize
);
78 TRACE (commctrl
, "-- ret=%p\n", 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.
91 * lpSrc [I] pointer to memory block which will be resized
92 * dwSize [I] new size of the memory block.
95 * Success: pointer to the resized memory block
99 * If lpSrc is a NULL-pointer, then COMCTL32_ReAlloc allocates a memory
100 * block like COMCTL32_Alloc.
104 COMCTL32_ReAlloc (LPVOID lpSrc
, DWORD dwSize
)
108 TRACE (commctrl
, "(%p 0x%08lx)\n", lpSrc
, dwSize
);
111 lpDest
= HeapReAlloc (COMCTL32_hHeap
, HEAP_ZERO_MEMORY
, lpSrc
, dwSize
);
113 lpDest
= HeapAlloc (COMCTL32_hHeap
, HEAP_ZERO_MEMORY
, dwSize
);
115 TRACE (commctrl
, "-- ret=%p\n", lpDest
);
121 /**************************************************************************
124 * Frees an allocated memory block from the dll's private heap.
127 * lpMem [I] pointer to memory block which will be freed
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
150 * lpMem [I] pointer to an allocated memory block
153 * Success: size of the specified memory block
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)
173 typedef struct tagMRUINFO
181 } MRUINFO
, *LPMRUINFO
;
184 typedef struct tagMRU
186 DWORD dwParam1
; /* some kind of flag */
195 CreateMRUListEx32A (LPMRUINFO lpmi
, DWORD dwParam2
,
196 DWORD dwParam3
, DWORD dwParam4
);
199 /**************************************************************************
200 * CreateMRUListA [COMCTL32.151]
209 CreateMRUList32A (LPMRUINFO lpmi
)
211 return CreateMRUListEx32A (lpmi
, 0, 0, 0);
216 FreeMRUList32A (HMRU hmru
)
218 FIXME (commctrl
, "(%p) empty stub!\n", hmru
);
221 if (!(hmru
->dwParam1
& 1001)) {
222 RegSetValueEx32A (hmru
->hKeyMRU
, "MRUList", 0, REG_SZ
,
224 lstrlen32A (hmru
->lpszMRUString
));
228 RegClosKey32 (hmru
->hkeyMRU
229 COMCTL32_Free32 (hmru
->lpszMRUString
);
232 return COMCTL32_Free (hmru
);
238 AddMRUData (DWORD dwParam1
, DWORD dwParam2
, DWORD dwParam3
)
241 FIXME (commctrl
, "(%lx %lx %lx) empty stub!\n",
242 dwParam1
, dwParam2
, dwParam3
);
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
);
260 CreateMRUListEx32A (LPMRUINFO lpmi
, DWORD dwParam2
, DWORD dwParam3
, DWORD dwParam4
)
271 /* internal variables */
274 FIXME (commctrl
, "(%p) empty stub!\n", 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
);
293 /**************************************************************************
294 * Str_GetPtrA [COMCTL32.233]
305 Str_GetPtr32A (LPCSTR lpSrc
, LPSTR lpDest
, INT32 nMaxLen
)
309 TRACE (commctrl
, "(%p %p %d)\n", lpSrc
, lpDest
, nMaxLen
);
311 if (!lpDest
&& lpSrc
)
312 return lstrlen32A (lpSrc
);
322 len
= lstrlen32A (lpSrc
);
326 RtlMoveMemory (lpDest
, lpSrc
, len
);
333 /**************************************************************************
334 * Str_SetPtrA [COMCTL32.234]
344 Str_SetPtr32A (LPSTR
*lppDest
, LPCSTR lpSrc
)
346 TRACE (commctrl
, "(%p %p)\n", lppDest
, lpSrc
);
349 LPSTR ptr
= COMCTL32_ReAlloc (lppDest
, lstrlen32A (lpSrc
) + 1);
352 lstrcpy32A (ptr
, lpSrc
);
357 COMCTL32_Free (*lppDest
);
366 /**************************************************************************
367 * Str_GetPtrW [COMCTL32.235]
378 Str_GetPtr32W (LPCWSTR lpSrc
, LPWSTR lpDest
, INT32 nMaxLen
)
382 TRACE (commctrl
, "(%p %p %d)\n", lpSrc
, lpDest
, nMaxLen
);
384 if (!lpDest
&& lpSrc
)
385 return lstrlen32W (lpSrc
);
395 len
= lstrlen32W (lpSrc
);
399 RtlMoveMemory (lpDest
, lpSrc
, len
*sizeof(WCHAR
));
406 /**************************************************************************
407 * Str_SetPtrW [COMCTL32.236]
417 Str_SetPtr32W (LPWSTR
*lppDest
, LPCWSTR lpSrc
)
419 TRACE (commctrl
, "(%p %p)\n", lppDest
, lpSrc
);
422 INT32 len
= lstrlen32W (lpSrc
) + 1;
423 LPWSTR ptr
= COMCTL32_ReAlloc (lppDest
, len
* sizeof(WCHAR
));
426 lstrcpy32W (ptr
, lpSrc
);
431 COMCTL32_Free (*lppDest
);
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
450 * nSize [I] size of the array elements
451 * nGrow [I] number of elements by which the array grows when it is filled
454 * Success: pointer to a array control structure. use this like a handle.
459 DSA_Create (INT32 nSize
, INT32 nGrow
)
463 TRACE (commctrl
, "(size=%d grow=%d)\n", nSize
, nGrow
);
465 hdsa
= (HDSA
)COMCTL32_Alloc (sizeof(DSA
));
468 hdsa
->nItemCount
= 0;
471 hdsa
->nItemSize
= nSize
;
472 hdsa
->nGrow
= MAX(1, nGrow
);
479 /**************************************************************************
480 * DSA_Destroy [COMCTL32.321] Destroys a dynamic storage array
483 * hdsa [I] pointer to the array control structure
491 DSA_Destroy (const HDSA hdsa
)
493 TRACE (commctrl
, "(%p)\n", hdsa
);
498 if (hdsa
->pData
&& (!COMCTL32_Free (hdsa
->pData
)))
501 return COMCTL32_Free (hdsa
);
505 /**************************************************************************
506 * DSA_GetItem [COMCTL32.322]
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.
519 DSA_GetItem (const HDSA hdsa
, INT32 nIndex
, LPVOID pDest
)
523 TRACE (commctrl
, "(%p %d %p)\n", hdsa
, nIndex
, pDest
);
527 if ((nIndex
< 0) || (nIndex
>= hdsa
->nItemCount
))
530 pSrc
= hdsa
->pData
+ (hdsa
->nItemSize
* nIndex
);
531 memmove (pDest
, pSrc
, hdsa
->nItemSize
);
537 /**************************************************************************
538 * DSA_GetItemPtr [COMCTL32.323]
540 * Retrieves a pointer to the specified item.
543 * hdsa [I] pointer to the array control structure
544 * nIndex [I] index of the desired item
547 * Success: pointer to an item
552 DSA_GetItemPtr (const HDSA hdsa
, INT32 nIndex
)
556 TRACE (commctrl
, "(%p %d)\n", hdsa
, nIndex
);
560 if ((nIndex
< 0) || (nIndex
>= hdsa
->nItemCount
))
563 pSrc
= hdsa
->pData
+ (hdsa
->nItemSize
* nIndex
);
565 TRACE (commctrl
, "-- ret=%p\n", pSrc
);
571 /**************************************************************************
572 * DSA_SetItem [COMCTL32.325]
574 * Sets the contents of an item in the array.
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
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)
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
;
604 /* resize the block of memory */
606 hdsa
->nGrow
* ((INT32
)((nIndex
- 1) / hdsa
->nGrow
) + 1);
607 nSize
= hdsa
->nItemSize
* nNewItems
;
609 lpTemp
= (LPVOID
)COMCTL32_ReAlloc (hdsa
->pData
, nSize
);
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
);
628 /**************************************************************************
629 * DSA_InsertItem [COMCTL32.325]
632 * hdsa [I] pointer to the array control structure
633 * nIndex [I] index for the new item
634 * pSrc [I] pointer to the element
637 * Success: position of the new item
642 DSA_InsertItem (const HDSA hdsa
, INT32 nIndex
, LPVOID pSrc
)
644 INT32 nNewItems
, nSize
, i
;
645 LPVOID lpTemp
, lpDest
;
648 TRACE(commctrl
, "(%p %d %p)\n", hdsa
, nIndex
, pSrc
);
650 if ((!hdsa
) || nIndex
< 0)
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
);
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
);
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 */
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]
703 * hdsa [I] pointer to the array control structure
704 * nIndex [I] index for the element to delete
707 * Success: number of the deleted element
712 DSA_DeleteItem (const HDSA hdsa
, INT32 nIndex
)
717 TRACE (commctrl
, "(%p %d)\n", hdsa
, nIndex
);
721 if (nIndex
< 0 || nIndex
>= hdsa
->nItemCount
)
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
);
737 if ((hdsa
->nMaxCount
- hdsa
->nItemCount
) >= hdsa
->nGrow
) {
738 nSize
= hdsa
->nItemSize
* hdsa
->nItemCount
;
740 lpDest
= (LPVOID
)COMCTL32_ReAlloc (hdsa
->pData
, nSize
);
744 hdsa
->nMaxCount
= hdsa
->nItemCount
;
745 hdsa
->pData
= lpDest
;
752 /**************************************************************************
753 * DSA_DeleteAllItems [COMCTL32.326]
755 * Removes all items and reinitializes the array.
758 * hdsa [I] pointer to the array control structure
766 DSA_DeleteAllItems (const HDSA hdsa
)
768 TRACE (commctrl
, "(%p)\n", hdsa
);
772 if (hdsa
->pData
&& (!COMCTL32_Free (hdsa
->pData
)))
775 hdsa
->nItemCount
= 0;
783 /**************************************************************************
784 * The DPA-API is a set of functions to create and manipulate arrays of
788 /**************************************************************************
789 * DPA_Create [COMCTL32.328] Creates a dynamic pointer array
792 * nGrow [I] number of items by which the array grows when it is filled
795 * Success: handle (pointer) to the pointer array.
800 DPA_Create (INT32 nGrow
)
804 TRACE (commctrl
, "(%d)\n", nGrow
);
806 hdpa
= (HDPA
)COMCTL32_Alloc (sizeof(DPA
));
808 hdpa
->nGrow
= MAX(8, nGrow
);
809 hdpa
->hHeap
= COMCTL32_hHeap
;
810 hdpa
->nMaxCount
= hdpa
->nGrow
* 2;
812 (LPVOID
*)COMCTL32_Alloc (hdpa
->nMaxCount
* sizeof(LPVOID
));
815 TRACE (commctrl
, "-- %p\n", hdpa
);
821 /**************************************************************************
822 * DPA_Destroy [COMCTL32.329] Destroys a dynamic pointer array
825 * hdpa [I] handle (pointer) to the pointer array
833 DPA_Destroy (const HDPA hdpa
)
835 TRACE (commctrl
, "(%p)\n", hdpa
);
840 if (hdpa
->ptrs
&& (!HeapFree (hdpa
->hHeap
, 0, hdpa
->ptrs
)))
843 return HeapFree (hdpa
->hHeap
, 0, hdpa
);
847 /**************************************************************************
848 * DPA_Grow [COMCTL32.330]
850 * Sets the growth amount.
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
862 DPA_Grow (const HDPA hdpa
, INT32 nGrow
)
864 TRACE (commctrl
, "(%p %d)\n", hdpa
, nGrow
);
869 hdpa
->nGrow
= MAX(8, nGrow
);
875 /**************************************************************************
876 * DPA_Clone [COMCTL32.331]
878 * Copies a pointer array to an other one or creates a copy
881 * hdpa [I] handle (pointer) to the existing (source) pointer array
882 * hdpaNew [O] handle (pointer) to the destination pointer array
885 * Success: pointer to the destination pointer array.
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.
896 DPA_Clone (const HDPA hdpa
, const HDPA hdpaNew
)
898 INT32 nNewItems
, nSize
;
904 TRACE (commctrl
, "(%p %p)\n", hdpa
, hdpaNew
);
907 /* create a new DPA */
908 hdpaTemp
= (HDPA
)HeapAlloc (hdpa
->hHeap
, HEAP_ZERO_MEMORY
,
910 hdpaTemp
->hHeap
= hdpa
->hHeap
;
911 hdpaTemp
->nGrow
= hdpa
->nGrow
;
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
);
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
));
941 /**************************************************************************
942 * DPA_GetPtr [COMCTL32.332]
944 * Retrieves a pointer from a dynamic pointer array
947 * hdpa [I] handle (pointer) to the pointer array
948 * nIndex [I] array index of the desired pointer
956 DPA_GetPtr (const HDPA hdpa
, INT32 i
)
958 TRACE (commctrl
, "(%p %d)\n", hdpa
, i
);
964 if ((i
< 0) || (i
>= hdpa
->nItemCount
))
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
979 * hdpa [I] handle (pointer) to the pointer array
983 * Success: index of the specified pointer
988 DPA_GetPtrIndex (const HDPA hdpa
, LPVOID p
)
995 for (i
= 0; i
< hdpa
->nItemCount
; i
++) {
996 if (hdpa
->ptrs
[i
] == p
)
1004 /**************************************************************************
1005 * DPA_InsertPtr [COMCTL32.334]
1007 * Inserts a pointer into a dynamic pointer array
1010 * hdpa [I] handle (pointer) to the array
1012 * p [I] pointer to insert
1015 * Success: index of the inserted pointer
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))
1032 (LPVOID
*)HeapAlloc (hdpa
->hHeap
, HEAP_ZERO_MEMORY
,
1033 2 * hdpa
->nGrow
* sizeof(LPVOID
));
1036 hdpa
->nMaxCount
= hdpa
->nGrow
* 2;
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
,
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
);
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
);
1071 hdpa
->ptrs
[nIndex
] = p
;
1077 /**************************************************************************
1078 * DPA_SetPtr [COMCTL32.335]
1080 * Sets a pointer in the pointer array
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
1093 DPA_SetPtr (const HDPA hdpa
, INT32 i
, LPVOID p
)
1097 TRACE (commctrl
, "(%p %d %p)\n", hdpa
, i
, p
);
1099 if ((!hdpa
) || i
< 0)
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
;
1109 /* resize the block of memory */
1111 hdpa
->nGrow
* ((INT32
)((i
- 1) / hdpa
->nGrow
) + 1);
1112 INT32 nSize
= nNewItems
* sizeof(LPVOID
);
1114 lpTemp
= (LPVOID
*)HeapReAlloc (hdpa
->hHeap
, HEAP_ZERO_MEMORY
,
1119 hdpa
->nItemCount
= nNewItems
;
1120 hdpa
->ptrs
= lpTemp
;
1124 /* put the new entry in */
1131 /**************************************************************************
1132 * DPA_DeletePtr [COMCTL32.336]
1134 * Removes a pointer from the pointer array.
1137 * hdpa [I] handle (pointer) to the pointer array
1138 * i [I] index of the pointer that will be deleted
1141 * Success: deleted pointer
1146 DPA_DeletePtr (const HDPA hdpa
, INT32 i
)
1148 LPVOID lpDest
, lpSrc
, lpTemp
= NULL
;
1151 TRACE (commctrl
, "(%p %d)\n", hdpa
, i
);
1153 if ((!hdpa
) || i
< 0 || i
>= hdpa
->nItemCount
)
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
--;
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
,
1179 hdpa
->nMaxCount
= nNewItems
;
1180 hdpa
->ptrs
= (LPVOID
*)lpDest
;
1187 /**************************************************************************
1188 * DPA_DeleteAllPtrs [COMCTL32.337]
1190 * Removes all pointers and reinitializes the array.
1193 * hdpa [I] handle (pointer) to the pointer array
1201 DPA_DeleteAllPtrs (const HDPA hdpa
)
1203 TRACE (commctrl
, "(%p)\n", hdpa
);
1208 if (hdpa
->ptrs
&& (!HeapFree (hdpa
->hHeap
, 0, hdpa
->ptrs
)))
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
));
1220 /**************************************************************************
1221 * DPA_QuickSort [Internal]
1223 * Ordinary quicksort (used by DPA_Sort).
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)
1237 DPA_QuickSort (LPVOID
*lpPtrs
, INT32 l
, INT32 r
,
1238 PFNDPACOMPARE pfnCompare
, LPARAM lParam
)
1243 TRACE (commctrl
, "l=%i r=%i\n", l
, r
);
1247 v
= lpPtrs
[(int)(l
+r
)/2];
1249 while ((pfnCompare
)(lpPtrs
[i
], v
, lParam
) < 0) i
++;
1250 while ((pfnCompare
)(lpPtrs
[j
], v
, lParam
) > 0) j
--;
1254 lpPtrs
[i
++] = lpPtrs
[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
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)
1279 DPA_Sort (const HDPA hdpa
, PFNDPACOMPARE pfnCompare
, LPARAM lParam
)
1281 if (!hdpa
|| !pfnCompare
)
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
);
1294 /**************************************************************************
1295 * DPA_Search [COMCTL32.339]
1297 * Searches a pointer array for a specified pointer
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
1308 * Success: index of the pointer in the array.
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)
1318 DPA_Search (const HDPA hdpa
, LPVOID pFind
, INT32 nStart
,
1319 PFNDPACOMPARE pfnCompare
, LPARAM lParam
, UINT32 uOptions
)
1321 if (!hdpa
|| !pfnCompare
|| !pFind
)
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 */
1332 TRACE (commctrl
, "binary search\n");
1334 l
= (nStart
== -1) ? 0 : nStart
;
1335 r
= hdpa
->nItemCount
- 1;
1339 n
= (pfnCompare
)(pFind
, lpPtr
[x
], lParam
);
1345 TRACE (commctrl
, "-- ret=%d\n", n
);
1350 if (uOptions
& DPAS_INSERTBEFORE
) {
1351 TRACE (commctrl
, "-- ret=%d\n", r
);
1355 if (uOptions
& DPAS_INSERTAFTER
) {
1356 TRACE (commctrl
, "-- ret=%d\n", r
);
1361 /* array is not sorted --> use linear search */
1365 TRACE (commctrl
, "linear search\n");
1367 nIndex
= (nStart
== -1)? 0 : nStart
;
1369 for (; nIndex
< hdpa
->nItemCount
; nIndex
++) {
1370 if ((pfnCompare
)(pFind
, lpPtr
[nIndex
], lParam
) == 0) {
1371 TRACE (commctrl
, "-- ret=%d\n", nIndex
);
1377 TRACE (commctrl
, "-- not found: ret=-1\n");
1382 /**************************************************************************
1383 * DPA_CreateEx [COMCTL32.340]
1385 * Creates a dynamic pointer array using the specified size and heap.
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
1392 * Success: handle (pointer) to the pointer array.
1397 DPA_CreateEx (INT32 nGrow
, HANDLE32 hHeap
)
1401 TRACE (commctrl
, "(%d 0x%x)\n", nGrow
, hHeap
);
1404 hdpa
= (HDPA
)HeapAlloc (hHeap
, HEAP_ZERO_MEMORY
, sizeof(DPA
));
1406 hdpa
= (HDPA
)COMCTL32_Alloc (sizeof(DPA
));
1409 hdpa
->nGrow
= MIN(8, nGrow
);
1410 hdpa
->hHeap
= hHeap
? hHeap
: COMCTL32_hHeap
;
1411 hdpa
->nMaxCount
= hdpa
->nGrow
* 2;
1413 (LPVOID
*)HeapAlloc (hHeap
, HEAP_ZERO_MEMORY
,
1414 hdpa
->nMaxCount
* sizeof(LPVOID
));
1417 TRACE (commctrl
, "-- %p\n", hdpa
);
1423 /**************************************************************************
1424 * Notification functions
1427 typedef struct tagNOTIFYDATA
1435 } NOTIFYDATA
, *LPNOTIFYDATA
;
1438 /**************************************************************************
1439 * DoNotify [Internal]
1443 DoNotify (LPNOTIFYDATA lpNotify
, UINT32 uCode
, LPNMHDR lpHdr
)
1446 LPNMHDR lpNmh
= NULL
;
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
)
1456 if (lpNotify
->hwndFrom
== -1) {
1458 idFrom
= lpHdr
->idFrom
;
1461 if (lpNotify
->hwndFrom
) {
1462 HWND32 hwndParent
= GetParent32 (lpNotify
->hwndFrom
);
1464 hwndParent
= GetWindow32 (lpNotify
->hwndFrom
, GW_OWNER
);
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]
1491 * Success: return value from notification
1496 COMCTL32_SendNotify (HWND32 hwndFrom
, HWND32 hwndTo
,
1497 UINT32 uCode
, LPNMHDR lpHdr
)
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 (¬ify
, uCode
, lpHdr
);
1513 /**************************************************************************
1514 * SendNotifyEx [COMCTL32.342]
1524 * Success: return value from notification
1529 COMCTL32_SendNotifyEx (HWND32 hwndTo
, HWND32 hwndFrom
, UINT32 uCode
,
1530 LPNMHDR lpHdr
, DWORD dwParam5
)
1535 TRACE (commctrl
, "(0x%04x 0x%04x %d %p 0x%08lx)\n",
1536 hwndFrom
, hwndTo
, uCode
, lpHdr
, dwParam5
);
1538 hwndNotify
= hwndTo
;
1540 if (IsWindow32 (hwndFrom
)) {
1541 hwndNotify
= GetParent32 (hwndFrom
);
1547 notify
.hwndFrom
= hwndFrom
;
1548 notify
.hwndTo
= hwndNotify
;
1549 notify
.dwParam5
= dwParam5
;
1550 notify
.dwParam6
= 0;
1552 return DoNotify (¬ify
, uCode
, lpHdr
);
1556 /**************************************************************************
1557 * StrChrA [COMCTL32.350]
1562 COMCTL32_StrChrA (LPCSTR lpString
, CHAR cChar
)
1564 return strchr (lpString
, cChar
);
1568 /**************************************************************************
1569 * StrStrIA [COMCTL32.355]
1573 COMCTL32_StrStrIA (LPCSTR lpStr1
, LPCSTR lpStr2
)
1575 INT32 len1
, len2
, i
;
1579 return ((LPSTR
)lpStr1
);
1581 while (lpStr1
[len1
] != 0) ++len1
;
1583 while (lpStr2
[len2
] != 0) ++len2
;
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
]))
1593 return ((LPSTR
)lpStr1
);
1601 /**************************************************************************
1602 * StrToIntA [COMCTL32.357] Converts a string to a signed integer.
1606 COMCTL32_StrToIntA (LPSTR lpString
)
1608 return atoi(lpString
);
1612 /**************************************************************************
1613 * COMCTL32_385 [COMCTL32.385]
1615 * Enumerates all items in a dynamic pointer array.
1618 * hdpa [I] handle to the dynamic pointer array
1626 * Original function name unknown!
1629 typedef DWORD (CALLBACK
*DPAENUMPROC
)(LPVOID
, DWORD
);
1632 COMCTL32_385 (HDPA hdpa
, DPAENUMPROC enumProc
, DWORD dwParam3
)
1636 TRACE (commctrl
, "(%p %p %08lx)\n", hdpa
, enumProc
, dwParam3
);
1640 if (hdpa
->nItemCount
<= 0)
1643 for (i
= 0; i
< hdpa
->nItemCount
; i
++) {
1644 if ((enumProc
)(hdpa
->ptrs
[i
], dwParam3
) == 0)
1652 /**************************************************************************
1653 * COMCTL32_386 [COMCTL32.386]
1655 * Enumerates all items in a dynamic pointer array and destroys it.
1658 * hdpa [I] handle to the dynamic pointer array
1667 * Original function name unknown!
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.
1687 * hdsa [I] handle to the dynamic storage array
1695 * Original function name unknown!
1698 typedef DWORD (CALLBACK
*DSAENUMPROC
)(LPVOID
, DWORD
);
1701 COMCTL32_387 (HDSA hdsa
, DSAENUMPROC enumProc
, DWORD dwParam3
)
1705 TRACE (commctrl
, "(%p %p %08lx)\n", hdsa
, enumProc
, dwParam3
);
1709 if (hdsa
->nItemCount
<= 0)
1712 for (i
= 0; i
< hdsa
->nItemCount
; i
++) {
1713 LPVOID lpItem
= DSA_GetItemPtr (hdsa
, i
);
1714 if ((enumProc
)(lpItem
, dwParam3
) == 0)
1722 /**************************************************************************
1723 * COMCTL32_388 [COMCTL32.388]
1725 * Enumerates all items in a dynamic storage array and destroys it.
1728 * hdsa [I] handle to the dynamic storage array
1737 * Original function name unknown!
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
);