source: trunk/src/comctl32/comctl32undoc.c@ 44

Last change on this file since 44 was 44, checked in by achimha, 26 years ago

* empty log message *

File size: 27.3 KB
Line 
1/*
2 * Undocumented functions from COMCTL32.DLL
3 *
4 * Copyright (C) 1999 Achim Hasenmueller
5 *
6 * Based on the work of the WINE group (www.winehq.com)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12
13#include "comctl32.h"
14#include <memory.h>
15
16extern HANDLE COMCTL32_hHeap; /* handle to the private heap */
17
18
19/**************************************************************************
20 * Alloc [COMCTL32.71]
21 *
22 * Allocates memory block from the dll's private heap
23 *
24 * PARAMS
25 * dwSize [I] size of the allocated memory block
26 *
27 * RETURNS
28 * Success: pointer to allocated memory block
29 * Failure: NULL
30 */
31
32
33LPVOID WINAPI COMCTL32_Alloc (DWORD dwSize)
34{
35 LPVOID lpPtr;
36
37 lpPtr = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
38
39 return lpPtr;
40}
41
42
43/**************************************************************************
44 * ReAlloc [COMCTL32.72]
45 *
46 * Changes the size of an allocated memory block or allocates a memory
47 * block using the dll's private heap.
48 *
49 * PARAMS
50 * lpSrc [I] pointer to memory block which will be resized
51 * dwSize [I] new size of the memory block.
52 *
53 * RETURNS
54 * Success: pointer to the resized memory block
55 * Failure: NULL
56 *
57 * NOTES
58 * If lpSrc is a NULL-pointer, then COMCTL32_ReAlloc allocates a memory
59 * block like COMCTL32_Alloc.
60 */
61
62LPVOID WINAPI COMCTL32_ReAlloc (LPVOID lpSrc, DWORD dwSize)
63{
64 LPVOID lpDest;
65
66 if (lpSrc)
67 lpDest = HeapReAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, lpSrc, dwSize);
68 else
69 lpDest = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
70
71 return lpDest;
72}
73
74
75/**************************************************************************
76 * Free [COMCTL32.73]
77 *
78 * Frees an allocated memory block from the dll's private heap.
79 *
80 * PARAMS
81 * lpMem [I] pointer to memory block which will be freed
82 *
83 * RETURNS
84 * Success: TRUE
85 * Failure: FALSE
86 */
87
88BOOL WINAPI COMCTL32_Free (LPVOID lpMem)
89{
90 return HeapFree (COMCTL32_hHeap, 0, lpMem);
91}
92
93
94/**************************************************************************
95 * GetSize [COMCTL32.74]
96 *
97 * Retrieves the size of the specified memory block from the dll's
98 * private heap.
99 *
100 * PARAMS
101 * lpMem [I] pointer to an allocated memory block
102 *
103 * RETURNS
104 * Success: size of the specified memory block
105 * Failure: 0
106 */
107
108DWORD WINAPI COMCTL32_GetSize (LPVOID lpMem)
109{
110
111 return HeapSize (COMCTL32_hHeap, 0, lpMem);
112}
113
114
115/**************************************************************************
116 * Str_GetPtrA [COMCTL32.233]
117 *
118 * PARAMS
119 * lpSrc [I]
120 * lpDest [O]
121 * nMaxLen [I]
122 *
123 * RETURNS
124 */
125
126INT WINAPI
127Str_GetPtrA (LPCSTR lpSrc, LPSTR lpDest, INT nMaxLen)
128{
129 INT len;
130
131// TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
132
133 if (!lpDest && lpSrc)
134 return lstrlenA (lpSrc);
135
136 if (nMaxLen == 0)
137 return 0;
138
139 if (lpSrc == NULL) {
140 lpDest[0] = '\0';
141 return 0;
142 }
143
144 len = lstrlenA (lpSrc);
145 if (len >= nMaxLen)
146 len = nMaxLen - 1;
147
148 RtlMoveMemory (lpDest, lpSrc, len);
149 lpDest[len] = '\0';
150
151 return len;
152}
153
154
155/**************************************************************************
156 * Str_SetPtrA [COMCTL32.234]
157 *
158 * PARAMS
159 * lppDest [O]
160 * lpSrc [I]
161 *
162 * RETURNS
163 */
164
165BOOL WINAPI
166Str_SetPtrA (LPSTR *lppDest, LPCSTR lpSrc)
167{
168// TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc);
169
170 if (lpSrc) {
171 LPSTR ptr = COMCTL32_ReAlloc (*lppDest, lstrlenA (lpSrc) + 1);
172 if (!ptr)
173 return FALSE;
174 lstrcpyA (ptr, lpSrc);
175 *lppDest = ptr;
176 }
177 else {
178 if (*lppDest) {
179 COMCTL32_Free (*lppDest);
180 *lppDest = NULL;
181 }
182 }
183
184 return TRUE;
185}
186
187
188/**************************************************************************
189 * Str_GetPtrW [COMCTL32.235]
190 *
191 * PARAMS
192 * lpSrc [I]
193 * lpDest [O]
194 * nMaxLen [I]
195 *
196 * RETURNS
197 */
198
199INT WINAPI
200Str_GetPtrW (LPCWSTR lpSrc, LPWSTR lpDest, INT nMaxLen)
201{
202 INT len;
203
204// TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
205
206 if (!lpDest && lpSrc)
207 return lstrlenW (lpSrc);
208
209 if (nMaxLen == 0)
210 return 0;
211
212 if (lpSrc == NULL) {
213 lpDest[0] = L'\0';
214 return 0;
215 }
216
217 len = lstrlenW (lpSrc);
218 if (len >= nMaxLen)
219 len = nMaxLen - 1;
220
221 RtlMoveMemory (lpDest, lpSrc, len*sizeof(WCHAR));
222 lpDest[len] = L'\0';
223
224 return len;
225}
226
227
228/**************************************************************************
229 * Str_SetPtrW [COMCTL32.236]
230 *
231 * PARAMS
232 * lpDest [O]
233 * lpSrc [I]
234 *
235 * RETURNS
236 */
237
238BOOL WINAPI
239Str_SetPtrW (LPWSTR *lppDest, LPCWSTR lpSrc)
240{
241// TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc);
242
243 if (lpSrc) {
244 INT len = lstrlenW (lpSrc) + 1;
245 LPWSTR ptr = COMCTL32_ReAlloc (*lppDest, len * sizeof(WCHAR));
246 if (!ptr)
247 return FALSE;
248 lstrcpyW (ptr, lpSrc);
249 *lppDest = ptr;
250 }
251 else {
252 if (*lppDest) {
253 COMCTL32_Free (*lppDest);
254 *lppDest = NULL;
255 }
256 }
257
258 return TRUE;
259}
260
261
262/**************************************************************************
263 * The DSA-API is a set of functions to create and manipulate arrays of
264 * fix sized memory blocks. These arrays can store any kind of data
265 * (strings, icons...).
266 */
267
268/**************************************************************************
269 * DSA_Create [COMCTL32.320] Creates a dynamic storage array
270 *
271 * PARAMS
272 * nSize [I] size of the array elements
273 * nGrow [I] number of elements by which the array grows when it is filled
274 *
275 * RETURNS
276 * Success: pointer to a array control structure. use this like a handle.
277 * Failure: NULL
278 */
279
280HDSA WINAPI
281DSA_Create (INT nSize, INT nGrow)
282{
283 HDSA hdsa;
284
285// TRACE (commctrl, "(size=%d grow=%d)\n", nSize, nGrow);
286
287 hdsa = (HDSA)COMCTL32_Alloc (sizeof(DSA));
288 if (hdsa)
289 {
290 hdsa->nItemCount = 0;
291 hdsa->pData = NULL;
292 hdsa->nMaxCount = 0;
293 hdsa->nItemSize = nSize;
294 hdsa->nGrow = MAX(1, nGrow);
295 }
296
297 return hdsa;
298}
299
300
301/**************************************************************************
302 * DSA_Destroy [COMCTL32.321] Destroys a dynamic storage array
303 *
304 * PARAMS
305 * hdsa [I] pointer to the array control structure
306 *
307 * RETURNS
308 * Success: TRUE
309 * Failure: FALSE
310 */
311
312BOOL WINAPI
313DSA_Destroy (const HDSA hdsa)
314{
315// TRACE (commctrl, "(%p)\n", hdsa);
316
317 if (!hdsa)
318 return FALSE;
319
320 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
321 return FALSE;
322
323 return COMCTL32_Free (hdsa);
324}
325
326
327/**************************************************************************
328 * DSA_GetItem [COMCTL32.322]
329 *
330 * PARAMS
331 * hdsa [I] pointer to the array control structure
332 * nIndex [I] number of the Item to get
333 * pDest [O] destination buffer. Has to be >= dwElementSize.
334 *
335 * RETURNS
336 * Success: TRUE
337 * Failure: FALSE
338 */
339
340BOOL WINAPI
341DSA_GetItem (const HDSA hdsa, INT nIndex, LPVOID pDest)
342{
343 LPVOID pSrc;
344
345// TRACE (commctrl, "(%p %d %p)\n", hdsa, nIndex, pDest);
346
347 if (!hdsa)
348 return FALSE;
349 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
350 return FALSE;
351
352 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
353 memmove (pDest, pSrc, hdsa->nItemSize);
354
355 return TRUE;
356}
357
358
359/**************************************************************************
360 * DSA_GetItemPtr [COMCTL32.323]
361 *
362 * Retrieves a pointer to the specified item.
363 *
364 * PARAMS
365 * hdsa [I] pointer to the array control structure
366 * nIndex [I] index of the desired item
367 *
368 * RETURNS
369 * Success: pointer to an item
370 * Failure: NULL
371 */
372
373LPVOID WINAPI
374DSA_GetItemPtr (const HDSA hdsa, INT nIndex)
375{
376 LPVOID pSrc;
377
378// TRACE (commctrl, "(%p %d)\n", hdsa, nIndex);
379
380 if (!hdsa)
381 return NULL;
382 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
383 return NULL;
384
385 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
386
387// TRACE (commctrl, "-- ret=%p\n", pSrc);
388
389 return pSrc;
390}
391
392
393/**************************************************************************
394 * DSA_SetItem [COMCTL32.325]
395 *
396 * Sets the contents of an item in the array.
397 *
398 * PARAMS
399 * hdsa [I] pointer to the array control structure
400 * nIndex [I] index for the item
401 * pSrc [I] pointer to the new item data
402 *
403 * RETURNS
404 * Success: TRUE
405 * Failure: FALSE
406 */
407
408BOOL WINAPI
409DSA_SetItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
410{
411 INT nSize, nNewItems;
412 LPVOID pDest, lpTemp;
413
414// TRACE (commctrl, "(%p %d %p)\n", hdsa, nIndex, pSrc);
415
416 if ((!hdsa) || nIndex < 0)
417 return FALSE;
418
419 if (hdsa->nItemCount <= nIndex) {
420 /* within the old array */
421 if (hdsa->nMaxCount > nIndex) {
422 /* within the allocated space, set a new boundary */
423 hdsa->nItemCount = nIndex;
424 }
425 else {
426 /* resize the block of memory */
427 nNewItems =
428 hdsa->nGrow * ((INT)((nIndex - 1) / hdsa->nGrow) + 1);
429 nSize = hdsa->nItemSize * nNewItems;
430
431 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
432 if (!lpTemp)
433 return FALSE;
434
435 hdsa->nMaxCount = nNewItems;
436 hdsa->pData = lpTemp;
437 }
438 }
439
440 /* put the new entry in */
441 pDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
442// TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
443// pDest, pSrc, hdsa->nItemSize);
444 memmove (pDest, pSrc, hdsa->nItemSize);
445
446 return TRUE;
447}
448
449
450/**************************************************************************
451 * DSA_InsertItem [COMCTL32.325]
452 *
453 * PARAMS
454 * hdsa [I] pointer to the array control structure
455 * nIndex [I] index for the new item
456 * pSrc [I] pointer to the element
457 *
458 * RETURNS
459 * Success: position of the new item
460 * Failure: -1
461 */
462
463INT WINAPI
464DSA_InsertItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
465{
466 INT nNewItems, nSize, i;
467 LPVOID lpTemp, lpDest;
468 LPDWORD p;
469
470// TRACE(commctrl, "(%p %d %p)\n", hdsa, nIndex, pSrc);
471
472 if ((!hdsa) || nIndex < 0)
473 return -1;
474
475 for (i = 0; i < hdsa->nItemSize; i += 4) {
476 p = *(DWORD**)((char *) pSrc + i);
477// if (IsBadStringPtrA ((char*)p, 256))
478// TRACE (commctrl, "-- %d=%p\n", i, (DWORD*)p);
479// else
480// TRACE (commctrl, "-- %d=%p [%s]\n", i, p, debugstr_a((char*)p));
481 }
482
483 /* when nIndex > nItemCount then append */
484 if (nIndex >= hdsa->nItemCount)
485 nIndex = hdsa->nItemCount;
486
487 /* do we need to resize ? */
488 if (hdsa->nItemCount >= hdsa->nMaxCount) {
489 nNewItems = hdsa->nMaxCount + hdsa->nGrow;
490 nSize = hdsa->nItemSize * nNewItems;
491
492 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
493 if (!lpTemp)
494 return -1;
495
496 hdsa->nMaxCount = nNewItems;
497 hdsa->pData = lpTemp;
498 }
499
500 /* do we need to move elements ? */
501 if (nIndex < hdsa->nItemCount) {
502 lpTemp = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
503 lpDest = (char *) lpTemp + hdsa->nItemSize;
504 nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize;
505// TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
506// lpDest, lpTemp, nSize);
507 memmove (lpDest, lpTemp, nSize);
508 }
509
510 /* ok, we can put the new Item in */
511 hdsa->nItemCount++;
512 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
513// TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
514// lpDest, pSrc, hdsa->nItemSize);
515 memmove (lpDest, pSrc, hdsa->nItemSize);
516
517 return hdsa->nItemCount;
518}
519
520
521/**************************************************************************
522 * DSA_DeleteItem [COMCTL32.326]
523 *
524 * PARAMS
525 * hdsa [I] pointer to the array control structure
526 * nIndex [I] index for the element to delete
527 *
528 * RETURNS
529 * Success: number of the deleted element
530 * Failure: -1
531 */
532
533INT WINAPI
534DSA_DeleteItem (const HDSA hdsa, INT nIndex)
535{
536 LPVOID lpDest,lpSrc;
537 INT nSize;
538
539// TRACE (commctrl, "(%p %d)\n", hdsa, nIndex);
540
541 if (!hdsa)
542 return -1;
543 if (nIndex < 0 || nIndex >= hdsa->nItemCount)
544 return -1;
545
546 /* do we need to move ? */
547 if (nIndex < hdsa->nItemCount - 1) {
548 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
549 lpSrc = (char *) lpDest + hdsa->nItemSize;
550 nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1);
551// TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
552// lpDest, lpSrc, nSize);
553 memmove (lpDest, lpSrc, nSize);
554 }
555
556 hdsa->nItemCount--;
557
558 /* free memory ? */
559 if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) {
560 nSize = hdsa->nItemSize * hdsa->nItemCount;
561
562 lpDest = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
563 if (!lpDest)
564 return -1;
565
566 hdsa->nMaxCount = hdsa->nItemCount;
567 hdsa->pData = lpDest;
568 }
569
570 return nIndex;
571}
572
573
574/**************************************************************************
575 * DSA_DeleteAllItems [COMCTL32.326]
576 *
577 * Removes all items and reinitializes the array.
578 *
579 * PARAMS
580 * hdsa [I] pointer to the array control structure
581 *
582 * RETURNS
583 * Success: TRUE
584 * Failure: FALSE
585 */
586
587BOOL WINAPI
588DSA_DeleteAllItems (const HDSA hdsa)
589{
590// TRACE (commctrl, "(%p)\n", hdsa);
591
592 if (!hdsa)
593 return FALSE;
594 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
595 return FALSE;
596
597 hdsa->nItemCount = 0;
598 hdsa->pData = NULL;
599 hdsa->nMaxCount = 0;
600
601 return TRUE;
602}
603
604
605/**************************************************************************
606 * The DPA-API is a set of functions to create and manipulate arrays of
607 * pointers.
608 */
609
610/**************************************************************************
611 * DPA_Create [COMCTL32.328] Creates a dynamic pointer array
612 *
613 * PARAMS
614 * nGrow [I] number of items by which the array grows when it is filled
615 *
616 * RETURNS
617 * Success: handle (pointer) to the pointer array.
618 * Failure: NULL
619 */
620
621HDPA WINAPI
622DPA_Create (INT nGrow)
623{
624 HDPA hdpa;
625
626// TRACE (commctrl, "(%d)\n", nGrow);
627
628 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
629 if (hdpa) {
630 hdpa->nGrow = MAX(8, nGrow);
631 hdpa->hHeap = COMCTL32_hHeap;
632 hdpa->nMaxCount = hdpa->nGrow * 2;
633 hdpa->ptrs =
634 (LPVOID*)COMCTL32_Alloc (hdpa->nMaxCount * sizeof(LPVOID));
635 }
636
637// TRACE (commctrl, "-- %p\n", hdpa);
638
639 return hdpa;
640}
641
642
643/**************************************************************************
644 * DPA_Destroy [COMCTL32.329] Destroys a dynamic pointer array
645 *
646 * PARAMS
647 * hdpa [I] handle (pointer) to the pointer array
648 *
649 * RETURNS
650 * Success: TRUE
651 * Failure: FALSE
652 */
653
654BOOL WINAPI
655DPA_Destroy (const HDPA hdpa)
656{
657// TRACE (commctrl, "(%p)\n", hdpa);
658
659 if (!hdpa)
660 return FALSE;
661
662 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
663 return FALSE;
664
665 return HeapFree (hdpa->hHeap, 0, hdpa);
666}
667
668
669/**************************************************************************
670 * DPA_Grow [COMCTL32.330]
671 *
672 * Sets the growth amount.
673 *
674 * PARAMS
675 * hdpa [I] handle (pointer) to the existing (source) pointer array
676 * nGrow [I] number of items, the array grows, when it's too small
677 *
678 * RETURNS
679 * Success: TRUE
680 * Failure: FALSE
681 */
682
683BOOL WINAPI
684DPA_Grow (const HDPA hdpa, INT nGrow)
685{
686// TRACE (commctrl, "(%p %d)\n", hdpa, nGrow);
687
688 if (!hdpa)
689 return FALSE;
690
691 hdpa->nGrow = MAX(8, nGrow);
692
693 return TRUE;
694}
695
696
697/**************************************************************************
698 * DPA_Clone [COMCTL32.331]
699 *
700 * Copies a pointer array to an other one or creates a copy
701 *
702 * PARAMS
703 * hdpa [I] handle (pointer) to the existing (source) pointer array
704 * hdpaNew [O] handle (pointer) to the destination pointer array
705 *
706 * RETURNS
707 * Success: pointer to the destination pointer array.
708 * Failure: NULL
709 *
710 * NOTES
711 * - If the 'hdpaNew' is a NULL-Pointer, a copy of the source pointer
712 * array will be created and it's handle (pointer) is returned.
713 * - If 'hdpa' is a NULL-Pointer, the original implementation crashes,
714 * this implementation just returns NULL.
715 */
716
717HDPA WINAPI
718DPA_Clone (const HDPA hdpa, const HDPA hdpaNew)
719{
720 INT nNewItems, nSize;
721 HDPA hdpaTemp;
722
723 if (!hdpa)
724 return NULL;
725
726// TRACE (commctrl, "(%p %p)\n", hdpa, hdpaNew);
727
728 if (!hdpaNew) {
729 /* create a new DPA */
730 hdpaTemp = (HDPA)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
731 sizeof(DPA));
732 hdpaTemp->hHeap = hdpa->hHeap;
733 hdpaTemp->nGrow = hdpa->nGrow;
734 }
735 else
736 hdpaTemp = hdpaNew;
737
738 if (hdpaTemp->ptrs) {
739 /* remove old pointer array */
740 HeapFree (hdpaTemp->hHeap, 0, hdpaTemp->ptrs);
741 hdpaTemp->ptrs = NULL;
742 hdpaTemp->nItemCount = 0;
743 hdpaTemp->nMaxCount = 0;
744 }
745
746 /* create a new pointer array */
747 nNewItems = hdpaTemp->nGrow *
748 ((INT)((hdpa->nItemCount - 1) / hdpaTemp->nGrow) + 1);
749 nSize = nNewItems * sizeof(LPVOID);
750 hdpaTemp->ptrs =
751 (LPVOID*)HeapAlloc (hdpaTemp->hHeap, HEAP_ZERO_MEMORY, nSize);
752 hdpaTemp->nMaxCount = nNewItems;
753
754 /* clone the pointer array */
755 hdpaTemp->nItemCount = hdpa->nItemCount;
756 memmove (hdpaTemp->ptrs, hdpa->ptrs,
757 hdpaTemp->nItemCount * sizeof(LPVOID));
758
759 return hdpaTemp;
760}
761
762
763/**************************************************************************
764 * DPA_GetPtr [COMCTL32.332]
765 *
766 * Retrieves a pointer from a dynamic pointer array
767 *
768 * PARAMS
769 * hdpa [I] handle (pointer) to the pointer array
770 * nIndex [I] array index of the desired pointer
771 *
772 * RETURNS
773 * Success: pointer
774 * Failure: NULL
775 */
776
777LPVOID WINAPI
778DPA_GetPtr (const HDPA hdpa, INT i)
779{
780// TRACE (commctrl, "(%p %d)\n", hdpa, i);
781
782 if (!hdpa)
783 return NULL;
784 if (!hdpa->ptrs)
785 return NULL;
786 if ((i < 0) || (i >= hdpa->nItemCount))
787 return NULL;
788
789// TRACE (commctrl, "-- %p\n", hdpa->ptrs[i]);
790
791 return hdpa->ptrs[i];
792}
793
794
795/**************************************************************************
796 * DPA_GetPtrIndex [COMCTL32.333]
797 *
798 * Retrieves the index of the specified pointer
799 *
800 * PARAMS
801 * hdpa [I] handle (pointer) to the pointer array
802 * p [I] pointer
803 *
804 * RETURNS
805 * Success: index of the specified pointer
806 * Failure: -1
807 */
808
809INT WINAPI
810DPA_GetPtrIndex (const HDPA hdpa, LPVOID p)
811{
812 INT i;
813
814 if (!hdpa->ptrs)
815 return -1;
816
817 for (i = 0; i < hdpa->nItemCount; i++) {
818 if (hdpa->ptrs[i] == p)
819 return i;
820 }
821
822 return -1;
823}
824
825
826/**************************************************************************
827 * DPA_InsertPtr [COMCTL32.334]
828 *
829 * Inserts a pointer into a dynamic pointer array
830 *
831 * PARAMS
832 * hdpa [I] handle (pointer) to the array
833 * i [I] array index
834 * p [I] pointer to insert
835 *
836 * RETURNS
837 * Success: index of the inserted pointer
838 * Failure: -1
839 */
840
841INT WINAPI
842DPA_InsertPtr (const HDPA hdpa, INT i, LPVOID p)
843{
844 INT nNewItems, nSize, nIndex = 0;
845 LPVOID *lpTemp, *lpDest;
846
847// TRACE (commctrl, "(%p %d %p)\n", hdpa, i, p);
848
849 if ((!hdpa) || (i < 0))
850 return -1;
851
852 if (!hdpa->ptrs) {
853 hdpa->ptrs =
854 (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
855 2 * hdpa->nGrow * sizeof(LPVOID));
856 if (!hdpa->ptrs)
857 return -1;
858 hdpa->nMaxCount = hdpa->nGrow * 2;
859 nIndex = 0;
860 }
861 else {
862 if (hdpa->nItemCount >= hdpa->nMaxCount) {
863// TRACE (commctrl, "-- resizing\n");
864 nNewItems = hdpa->nMaxCount + hdpa->nGrow;
865 nSize = nNewItems * sizeof(LPVOID);
866
867 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
868 hdpa->ptrs, nSize);
869 if (!lpTemp)
870 return -1;
871 hdpa->nMaxCount = nNewItems;
872 hdpa->ptrs = lpTemp;
873 }
874
875 if (i >= hdpa->nItemCount) {
876 nIndex = hdpa->nItemCount;
877// TRACE (commctrl, "-- appending at %d\n", nIndex);
878 }
879 else {
880// TRACE (commctrl, "-- inserting at %d\n", i);
881 lpTemp = hdpa->ptrs + i;
882 lpDest = lpTemp + 1;
883 nSize = (hdpa->nItemCount - i) * sizeof(LPVOID);
884// TRACE (commctrl, "-- move dest=%p src=%p size=%x\n",
885// lpDest, lpTemp, nSize);
886 memmove (lpDest, lpTemp, nSize);
887 nIndex = i;
888 }
889 }
890
891 /* insert item */
892 hdpa->nItemCount++;
893 hdpa->ptrs[nIndex] = p;
894
895 return nIndex;
896}
897
898
899/**************************************************************************
900 * DPA_SetPtr [COMCTL32.335]
901 *
902 * Sets a pointer in the pointer array
903 *
904 * PARAMS
905 * hdpa [I] handle (pointer) to the pointer array
906 * i [I] index of the pointer that will be set
907 * p [I] pointer to be set
908 *
909 * RETURNS
910 * Success: TRUE
911 * Failure: FALSE
912 */
913
914BOOL WINAPI
915DPA_SetPtr (const HDPA hdpa, INT i, LPVOID p)
916{
917 LPVOID *lpTemp;
918
919// TRACE (commctrl, "(%p %d %p)\n", hdpa, i, p);
920
921 if ((!hdpa) || i < 0)
922 return FALSE;
923
924 if (hdpa->nItemCount <= i) {
925 /* within the old array */
926 if (hdpa->nMaxCount > i) {
927 /* within the allocated space, set a new boundary */
928 hdpa->nItemCount = i;
929 }
930 else {
931 /* resize the block of memory */
932 INT nNewItems =
933 hdpa->nGrow * ((INT)((i - 1) / hdpa->nGrow) + 1);
934 INT nSize = nNewItems * sizeof(LPVOID);
935
936 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
937 hdpa->ptrs, nSize);
938 if (!lpTemp)
939 return FALSE;
940
941 hdpa->nItemCount = nNewItems;
942 hdpa->ptrs = lpTemp;
943 }
944 }
945
946 /* put the new entry in */
947 hdpa->ptrs[i] = p;
948
949 return TRUE;
950}
951
952
953/**************************************************************************
954 * DPA_DeletePtr [COMCTL32.336]
955 *
956 * Removes a pointer from the pointer array.
957 *
958 * PARAMS
959 * hdpa [I] handle (pointer) to the pointer array
960 * i [I] index of the pointer that will be deleted
961 *
962 * RETURNS
963 * Success: deleted pointer
964 * Failure: NULL
965 */
966
967LPVOID WINAPI
968DPA_DeletePtr (const HDPA hdpa, INT i)
969{
970 LPVOID *lpDest, *lpSrc, lpTemp = NULL;
971 INT nSize;
972
973// TRACE (commctrl, "(%p %d)\n", hdpa, i);
974
975 if ((!hdpa) || i < 0 || i >= hdpa->nItemCount)
976 return NULL;
977
978 lpTemp = hdpa->ptrs[i];
979
980 /* do we need to move ?*/
981 if (i < hdpa->nItemCount - 1) {
982 lpDest = hdpa->ptrs + i;
983 lpSrc = lpDest + 1;
984 nSize = (hdpa->nItemCount - i - 1) * sizeof(LPVOID);
985// TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",
986// lpDest, lpSrc, nSize);
987 memmove (lpDest, lpSrc, nSize);
988 }
989
990 hdpa->nItemCount --;
991
992 /* free memory ?*/
993 if ((hdpa->nMaxCount - hdpa->nItemCount) >= hdpa->nGrow) {
994 INT nNewItems = MIN(hdpa->nGrow * 2, hdpa->nItemCount);
995 nSize = nNewItems * sizeof(LPVOID);
996 lpDest = (LPVOID)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
997 hdpa->ptrs, nSize);
998 if (!lpDest)
999 return NULL;
1000
1001 hdpa->nMaxCount = nNewItems;
1002 hdpa->ptrs = (LPVOID*)lpDest;
1003 }
1004
1005 return lpTemp;
1006}
1007
1008
1009/**************************************************************************
1010 * DPA_DeleteAllPtrs [COMCTL32.337]
1011 *
1012 * Removes all pointers and reinitializes the array.
1013 *
1014 * PARAMS
1015 * hdpa [I] handle (pointer) to the pointer array
1016 *
1017 * RETURNS
1018 * Success: TRUE
1019 * Failure: FALSE
1020 */
1021
1022BOOL WINAPI
1023DPA_DeleteAllPtrs (const HDPA hdpa)
1024{
1025// TRACE (commctrl, "(%p)\n", hdpa);
1026
1027 if (!hdpa)
1028 return FALSE;
1029
1030 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
1031 return FALSE;
1032
1033 hdpa->nItemCount = 0;
1034 hdpa->nMaxCount = hdpa->nGrow * 2;
1035 hdpa->ptrs = (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1036 hdpa->nMaxCount * sizeof(LPVOID));
1037
1038 return TRUE;
1039}
1040
1041
1042/**************************************************************************
1043 * DPA_QuickSort [Internal]
1044 *
1045 * Ordinary quicksort (used by DPA_Sort).
1046 *
1047 * PARAMS
1048 * lpPtrs [I] pointer to the pointer array
1049 * l [I] index of the "left border" of the partition
1050 * r [I] index of the "right border" of the partition
1051 * pfnCompare [I] pointer to the compare function
1052 * lParam [I] user defined value (3rd parameter in compare function)
1053 *
1054 * RETURNS
1055 * NONE
1056 */
1057
1058static VOID
1059DPA_QuickSort (LPVOID *lpPtrs, INT l, INT r,
1060 PFNDPACOMPARE pfnCompare, LPARAM lParam)
1061{
1062 LPVOID t, v;
1063 INT i, j;
1064
1065// TRACE (commctrl, "l=%i r=%i\n", l, r);
1066
1067 i = l;
1068 j = r;
1069 v = lpPtrs[(int)(l+r)/2];
1070 do {
1071 while ((pfnCompare)(lpPtrs[i], v, lParam) > 0) i++;
1072 while ((pfnCompare)(lpPtrs[j], v, lParam) < 0) j--;
1073 if (i <= j)
1074 {
1075 t = lpPtrs[i];
1076 lpPtrs[i++] = lpPtrs[j];
1077 lpPtrs[j--] = t;
1078 }
1079 } while (i <= j);
1080 if (l < j) DPA_QuickSort (lpPtrs, l, j, pfnCompare, lParam);
1081 if (i < r) DPA_QuickSort (lpPtrs, i, r, pfnCompare, lParam);
1082}
1083
1084
1085/**************************************************************************
1086 * DPA_Sort [COMCTL32.338]
1087 *
1088 * Sorts a pointer array using a user defined compare function
1089 *
1090 * PARAMS
1091 * hdpa [I] handle (pointer) to the pointer array
1092 * pfnCompare [I] pointer to the compare function
1093 * lParam [I] user defined value (3rd parameter of compare function)
1094 *
1095 * RETURNS
1096 * Success: TRUE
1097 * Failure: FALSE
1098 */
1099
1100BOOL WINAPI
1101DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
1102{
1103 if (!hdpa || !pfnCompare)
1104 return FALSE;
1105
1106// TRACE (commctrl, "(%p %p 0x%lx)\n", hdpa, pfnCompare, lParam);
1107
1108 if ((hdpa->nItemCount > 1) && (hdpa->ptrs))
1109 DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1,
1110 pfnCompare, lParam);
1111
1112 return TRUE;
1113}
1114
1115
1116/**************************************************************************
1117 * DPA_Search [COMCTL32.339]
1118 *
1119 * Searches a pointer array for a specified pointer
1120 *
1121 * PARAMS
1122 * hdpa [I] handle (pointer) to the pointer array
1123 * pFind [I] pointer to search for
1124 * nStart [I] start index
1125 * pfnCompare [I] pointer to the compare function
1126 * lParam [I] user defined value (3rd parameter of compare function)
1127 * uOptions [I] search options
1128 *
1129 * RETURNS
1130 * Success: index of the pointer in the array.
1131 * Failure: -1
1132 *
1133 * NOTES
1134 * Binary search taken from R.Sedgewick "Algorithms in C"!
1135 * Function is NOT tested!
1136 * If something goes wrong, blame HIM not ME! (Eric Kohl)
1137 */
1138
1139INT WINAPI
1140DPA_Search (const HDPA hdpa, LPVOID pFind, INT nStart,
1141 PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT uOptions)
1142{
1143 if (!hdpa || !pfnCompare || !pFind)
1144 return -1;
1145
1146// TRACE (commctrl, "(%p %p %d %p 0x%08lx 0x%08x)\n",
1147// hdpa, pFind, nStart, pfnCompare, lParam, uOptions);
1148
1149 if (uOptions & DPAS_SORTED) {
1150 /* array is sorted --> use binary search */
1151 INT l, r, x, n;
1152 LPVOID *lpPtr;
1153
1154// TRACE (commctrl, "binary search\n");
1155
1156 l = (nStart == -1) ? 0 : nStart;
1157 r = hdpa->nItemCount - 1;
1158 lpPtr = hdpa->ptrs;
1159 while (r >= l) {
1160 x = (l + r) / 2;
1161 n = (pfnCompare)(pFind, lpPtr[x], lParam);
1162 if (n < 0)
1163 r = x - 1;
1164 else
1165 l = x + 1;
1166 if (n == 0) {
1167// TRACE (commctrl, "-- ret=%d\n", n);
1168 return n;
1169 }
1170 }
1171
1172 if (uOptions & DPAS_INSERTBEFORE) {
1173// TRACE (commctrl, "-- ret=%d\n", r);
1174 return r;
1175 }
1176
1177 if (uOptions & DPAS_INSERTAFTER) {
1178// TRACE (commctrl, "-- ret=%d\n", l);
1179 return l;
1180 }
1181 }
1182 else {
1183 /* array is not sorted --> use linear search */
1184 LPVOID *lpPtr;
1185 INT nIndex;
1186
1187// TRACE (commctrl, "linear search\n");
1188
1189 nIndex = (nStart == -1)? 0 : nStart;
1190 lpPtr = hdpa->ptrs;
1191 for (; nIndex < hdpa->nItemCount; nIndex++) {
1192 if ((pfnCompare)(pFind, lpPtr[nIndex], lParam) == 0) {
1193// TRACE (commctrl, "-- ret=%d\n", nIndex);
1194 return nIndex;
1195 }
1196 }
1197 }
1198
1199// TRACE (commctrl, "-- not found: ret=-1\n");
1200 return -1;
1201}
1202
1203
1204/**************************************************************************
1205 * DPA_CreateEx [COMCTL32.340]
1206 *
1207 * Creates a dynamic pointer array using the specified size and heap.
1208 *
1209 * PARAMS
1210 * nGrow [I] number of items by which the array grows when it is filled
1211 * hHeap [I] handle to the heap where the array is stored
1212 *
1213 * RETURNS
1214 * Success: handle (pointer) to the pointer array.
1215 * Failure: NULL
1216 */
1217
1218HDPA WINAPI
1219DPA_CreateEx (INT nGrow, HANDLE hHeap)
1220{
1221 HDPA hdpa;
1222
1223// TRACE (commctrl, "(%d 0x%x)\n", nGrow, hHeap);
1224
1225 if (hHeap)
1226 hdpa = (HDPA)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, sizeof(DPA));
1227 else
1228 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
1229
1230 if (hdpa) {
1231 hdpa->nGrow = MIN(8, nGrow);
1232 hdpa->hHeap = hHeap ? hHeap : COMCTL32_hHeap;
1233 hdpa->nMaxCount = hdpa->nGrow * 2;
1234 hdpa->ptrs =
1235 (LPVOID*)HeapAlloc (hHeap, HEAP_ZERO_MEMORY,
1236 hdpa->nMaxCount * sizeof(LPVOID));
1237 }
1238
1239// TRACE (commctrl, "-- %p\n", hdpa);
1240
1241 return hdpa;
1242}
Note: See TracBrowser for help on using the repository browser.