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

Last change on this file since 2820 was 2820, checked in by cbratschi, 26 years ago

* empty log message *

File size: 52.5 KB
Line 
1/* $Id: comctl32undoc.c,v 1.18 2000-02-18 17:13:37 cbratschi Exp $ */
2/*
3 * Undocumented functions from COMCTL32.DLL
4 *
5 * Copyright (C) 1999 Achim Hasenmueller
6 *
7 * Based on the work of the WINE group (www.winehq.com)
8 *
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13
14/* WINE 20000130 level */
15
16/* CB: todo
17 - porting/implementing string functions
18 - DPA_LoadStream
19 - DPA_SaveStream
20*/
21
22#include "comctl32.h"
23#include <memory.h>
24#include <string.h>
25#include <stdlib.h>
26#include <ctype.h>
27#include <wchar.h>
28#include <wcstr.h>
29#include <wctype.h>
30
31extern HANDLE COMCTL32_hHeap; /* handle to the private heap */
32
33/**************************************************************************
34 * DPA_Merge [COMCTL32.11]
35 *
36 * PARAMS
37 * hdpa1 [I] handle to a dynamic pointer array
38 * hdpa2 [I] handle to a dynamic pointer array
39 * dwFlags [I] flags
40 * pfnSort [I] pointer to sort function
41 * pfnMerge [I] pointer to merge function
42 * lParam [I] application specific value
43 *
44 * NOTES
45 * No more information available yet!
46 */
47
48BOOL WINAPI
49DPA_Merge (const HDPA hdpa1, const HDPA hdpa2, DWORD dwFlags,
50 PFNDPACOMPARE pfnCompare, PFNDPAMERGE pfnMerge, LPARAM lParam)
51{
52 INT nCount;
53
54#if 0 /* these go with the "incomplete implementation" below */
55 LPVOID pWork1, pWork2;
56 INT nResult;
57 INT nIndex;
58 INT nNewItems;
59#endif
60
61
62 dprintf(("COMCTL32: DPA_Merge"));
63
64 if (IsBadWritePtr (hdpa1, sizeof(DPA)))
65 return FALSE;
66
67 if (IsBadWritePtr (hdpa2, sizeof(DPA)))
68 return FALSE;
69
70 if (IsBadCodePtr ((FARPROC)pfnCompare))
71 return FALSE;
72
73 if (IsBadCodePtr ((FARPROC)pfnMerge))
74 return FALSE;
75
76 if (dwFlags & DPAM_SORT) {
77// TRACE("sorting dpa's!\n");
78 if (hdpa1->nItemCount > 0)
79 DPA_Sort (hdpa1, pfnCompare, lParam);
80// TRACE ("dpa 1 sorted!\n");
81 if (hdpa2->nItemCount > 0)
82 DPA_Sort (hdpa2, pfnCompare, lParam);
83// TRACE ("dpa 2 sorted!\n");
84 }
85
86 if (hdpa2->nItemCount < 1)
87 return TRUE;
88
89// TRACE("hdpa1->nItemCount=%d hdpa2->nItemCount=%d\n",
90// hdpa1->nItemCount, hdpa2->nItemCount);
91
92
93 /* preliminary hack - simply append the pointer list hdpa2 to hdpa1*/
94 for (nCount = 0; nCount < hdpa2->nItemCount; nCount++)
95 DPA_InsertPtr (hdpa1, hdpa1->nItemCount + 1, hdpa2->ptrs[nCount]);
96
97#if 0
98 /* incomplete implementation */
99
100 pWork1 = &(hdpa1->ptrs[hdpa1->nItemCount - 1]);
101 pWork2 = &(hdpa2->ptrs[hdpa2->nItemCount - 1]);
102
103 nIndex = hdpa1->nItemCount - 1;
104 nCount = hdpa2->nItemCount - 1;
105
106 do
107 {
108 nResult = (pfnCompare)(pWork1, pWork2, lParam);
109
110 if (nResult == 0)
111 {
112 PVOID ptr;
113
114 ptr = (pfnMerge)(1, pWork1, pWork2, lParam);
115 if (!ptr)
116 return FALSE;
117
118 nCount--;
119 pWork2--;
120 pWork1 = ptr;
121 }
122 else if (nResult < 0)
123 {
124 if (!dwFlags & 8)
125 {
126 PVOID ptr;
127
128 ptr = DPA_DeletePtr (hdpa1, hdpa1->nItemCount - 1);
129
130 (pfnMerge)(2, ptr, NULL, lParam);
131 }
132 }
133 else
134 {
135 if (!dwFlags & 4)
136 {
137 PVOID ptr;
138
139 ptr = (pfnMerge)(3, pWork2, NULL, lParam);
140 if (!ptr)
141 return FALSE;
142 DPA_InsertPtr (hdpa1, nIndex, ptr);
143 }
144 nCount--;
145 pWork2--;
146 }
147
148 nIndex--;
149 pWork1--;
150
151 }
152 while (nCount >= 0);
153#endif
154
155 return TRUE;
156}
157
158
159/**************************************************************************
160 * Alloc [COMCTL32.71]
161 *
162 * Allocates memory block from the dll's private heap
163 *
164 * PARAMS
165 * dwSize [I] size of the allocated memory block
166 *
167 * RETURNS
168 * Success: pointer to allocated memory block
169 * Failure: NULL
170 */
171
172
173LPVOID WINAPI COMCTL32_Alloc (DWORD dwSize)
174{
175 LPVOID lpPtr;
176
177 dprintf2(("COMCTL32: COMCTL32_Alloc"));
178
179 lpPtr = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
180
181 return lpPtr;
182}
183
184
185/**************************************************************************
186 * ReAlloc [COMCTL32.72]
187 *
188 * Changes the size of an allocated memory block or allocates a memory
189 * block using the dll's private heap.
190 *
191 * PARAMS
192 * lpSrc [I] pointer to memory block which will be resized
193 * dwSize [I] new size of the memory block.
194 *
195 * RETURNS
196 * Success: pointer to the resized memory block
197 * Failure: NULL
198 *
199 * NOTES
200 * If lpSrc is a NULL-pointer, then COMCTL32_ReAlloc allocates a memory
201 * block like COMCTL32_Alloc.
202 */
203
204LPVOID WINAPI COMCTL32_ReAlloc (LPVOID lpSrc, DWORD dwSize)
205{
206 LPVOID lpDest;
207
208 dprintf2(("COMCTL32: COMCTL32_ReAlloc"));
209
210 if (lpSrc)
211 lpDest = HeapReAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, lpSrc, dwSize);
212 else
213 lpDest = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
214
215 return lpDest;
216}
217
218
219/**************************************************************************
220 * Free [COMCTL32.73]
221 *
222 * Frees an allocated memory block from the dll's private heap.
223 *
224 * PARAMS
225 * lpMem [I] pointer to memory block which will be freed
226 *
227 * RETURNS
228 * Success: TRUE
229 * Failure: FALSE
230 */
231
232BOOL WINAPI COMCTL32_Free (LPVOID lpMem)
233{
234 dprintf2(("COMCTL32: COMCTL32_Free"));
235
236 return HeapFree (COMCTL32_hHeap, 0, lpMem);
237}
238
239
240/**************************************************************************
241 * GetSize [COMCTL32.74]
242 *
243 * Retrieves the size of the specified memory block from the dll's
244 * private heap.
245 *
246 * PARAMS
247 * lpMem [I] pointer to an allocated memory block
248 *
249 * RETURNS
250 * Success: size of the specified memory block
251 * Failure: 0
252 */
253
254DWORD WINAPI COMCTL32_GetSize (LPVOID lpMem)
255{
256 dprintf2(("COMCTL32: COMCTL32_GetSize"));
257
258 return HeapSize (COMCTL32_hHeap, 0, lpMem);
259}
260
261
262/**************************************************************************
263 * The MRU-API is a set of functions to manipulate MRU(Most Recently Used)
264 * lists.
265 *
266 * Stored in the reg. as a set of values under a single key. Each item in the
267 * list has a value name that is a single char. 'a' - 'z', '{', '|' or '}'.
268 * The order of the list is stored with value name 'MRUList' which is a string
269 * containing the value names (i.e. 'a', 'b', etc.) in the relevant order.
270 */
271
272typedef struct tagCREATEMRULIST
273{
274 DWORD cbSize; /* size of struct */
275 DWORD nMaxItems; /* max no. of items in list */
276 DWORD dwFlags; /* see below */
277 HKEY hKey; /* root reg. key under which list is saved */
278 LPCSTR lpszSubKey; /* reg. subkey */
279 PROC lpfnCompare; /* item compare proc */
280} CREATEMRULIST, *LPCREATEMRULIST;
281
282/* dwFlags */
283#define MRUF_STRING_LIST 0 /* list will contain strings */
284#define MRUF_BINARY_LIST 1 /* list will contain binary data */
285#define MRUF_DELAYED_SAVE 2 /* only save list order to reg. is FreeMRUList */
286
287/* If list is a string list lpfnCompare has the following prototype
288 * int CALLBACK MRUCompareString(LPCSTR s1, LPCSTR s2)
289 * for binary lists the prototype is
290 * int CALLBACK MRUCompareBinary(LPCVOID data1, LPCVOID data2, DWORD cbData)
291 * where cbData is the no. of bytes to compare.
292 * Need to check what return value means identical - 0?
293 */
294
295typedef struct tagMRU
296{
297 DWORD dwParam1; /* some kind of flag */
298 DWORD dwParam2;
299 DWORD dwParam3;
300 HKEY hkeyMRU;
301 LPCSTR lpszSubKey;
302 DWORD dwParam6;
303} MRU, *HMRU;
304
305HANDLE WINAPI
306CreateMRUListLazyA (LPCREATEMRULIST lpcml, DWORD dwParam2,
307 DWORD dwParam3, DWORD dwParam4);
308
309
310/**************************************************************************
311 * CreateMRUListA [COMCTL32.151]
312 *
313 * PARAMS
314 * lpcml [I] ptr to CREATEMRULIST structure.
315 *
316 * RETURNS
317 * Handle to MRU list.
318 */
319HANDLE WINAPI
320CreateMRUListA (LPCREATEMRULIST lpcml)
321{
322 dprintf(("COMCTL32: CreateMRUListA"));
323
324 return CreateMRUListLazyA (lpcml, 0, 0, 0);
325}
326
327/**************************************************************************
328 * FreeMRUListA [COMCTL32.152]
329 *
330 * PARAMS
331 * hMRUList [I] Handle to list.
332 *
333 */
334DWORD WINAPI
335FreeMRUListA (HANDLE hMRUList)
336{
337 dprintf(("COMCTL32: FreeMRUListA"));
338 //FIXME("(%08x) empty stub!\n", hMRUList);
339
340#if 0
341 if (!(hmru->dwParam1 & 1001)) {
342 RegSetValueExA (hmru->hKeyMRU, "MRUList", 0, REG_SZ,
343 hmru->lpszMRUString,
344 lstrlenA (hmru->lpszMRUString));
345 }
346
347
348 RegClosKey (hmru->hkeyMRU
349 COMCTL32_Free32 (hmru->lpszMRUString);
350#endif
351
352 return COMCTL32_Free ((LPVOID)hMRUList);
353}
354
355
356/**************************************************************************
357 * AddMRUData [COMCTL32.167]
358 *
359 * Add item to MRU binary list. If item already exists in list them it is
360 * simply moved up to the top of the list and not added again. If list is
361 * full then the least recently used item is removed to make room.
362 *
363 * PARAMS
364 * hList [I] Handle to list.
365 * lpData [I] ptr to data to add.
366 * cbData [I] no. of bytes of data.
367 *
368 * RETURNS
369 * No. corresponding to registry name where value is stored 'a' -> 0 etc.
370 * -1 on error.
371 */
372INT WINAPI
373AddMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData)
374{
375 dprintf(("COMCTL32: AddMRUData - empty stub!"));
376
377 return 0;
378}
379
380/**************************************************************************
381 * AddMRUStringA [COMCTL32.153]
382 *
383 * Add item to MRU string list. If item already exists in list them it is
384 * simply moved up to the top of the list and not added again. If list is
385 * full then the least recently used item is removed to make room.
386 *
387 * PARAMS
388 * hList [I] Handle to list.
389 * lpszString [I] ptr to string to add.
390 *
391 * RETURNS
392 * No. corresponding to registry name where value is stored 'a' -> 0 etc.
393 * -1 on error.
394 */
395INT WINAPI
396AddMRUStringA(HANDLE hList, LPCSTR lpszString)
397{
398 dprintf(("COMCTL32: AddMRUStringA - empty stub!"));
399
400 return 0;
401}
402
403/**************************************************************************
404 * DelMRUString [COMCTL32.156]
405 *
406 * Removes item from either string or binary list (despite its name)
407 *
408 * PARAMS
409 * hList [I] list handle
410 * nItemPos [I] item position to remove 0 -> MRU
411 *
412 * RETURNS
413 * TRUE is successful, FALSE if nItemPos is out of range.
414 */
415BOOL WINAPI
416DelMRUString(HANDLE hList, INT nItemPos)
417{
418 dprintf(("COMCTL32: DelMRUString - empty stub!"));
419
420 return TRUE;
421}
422
423/**************************************************************************
424 * FindMRUData [COMCTL32.169]
425 *
426 * Searches binary list for item that matches lpData of length cbData.
427 * Returns position in list order 0 -> MRU and if lpRegNum != NULL then value
428 * corresponding to item's reg. name will be stored in it ('a' -> 0).
429 *
430 * PARAMS
431 * hList [I] list handle
432 * lpData [I] data to find
433 * cbData [I] length of data
434 * lpRegNum [O] position in registry (maybe NULL)
435 *
436 * RETURNS
437 * Position in list 0 -> MRU. -1 if item not found.
438 */
439INT WINAPI
440FindMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum)
441{
442 dprintf(("COMCTL32: FindMRUData - empty stub!"));
443
444 return 0;
445}
446
447/**************************************************************************
448 * FindMRUStringA [COMCTL32.155]
449 *
450 * Searches string list for item that matches lpszString.
451 * Returns position in list order 0 -> MRU and if lpRegNum != NULL then value
452 * corresponding to item's reg. name will be stored in it ('a' -> 0).
453 *
454 * PARAMS
455 * hList [I] list handle
456 * lpszString [I] string to find
457 * lpRegNum [O] position in registry (maybe NULL)
458 *
459 * RETURNS
460 * Position in list 0 -> MRU. -1 if item not found.
461 */
462INT WINAPI
463FindMRUStringA (HANDLE hList, LPCSTR lpszString, LPINT lpRegNum)
464{
465 dprintf(("COMCTL32: FindMRUStringA - empty stub!"));
466
467 return 0;
468}
469
470HANDLE WINAPI
471CreateMRUListLazyA (LPCREATEMRULIST lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
472{
473 /* DWORD dwLocal1; *
474 * HKEY hkeyResult; *
475 * DWORD dwLocal3; *
476 * LPVOID lMRU; *
477 * DWORD dwLocal5; *
478 * DWORD dwLocal6; *
479 * DWORD dwLocal7; *
480 * DWORD dwDisposition; */
481
482 /* internal variables */
483 LPVOID ptr;
484
485 dprintf(("COMCTL32: CreateMRUListLazyA - empty stub!"));
486
487 if (lpcml == NULL)
488 return 0;
489
490 if (lpcml->cbSize < sizeof(CREATEMRULIST))
491 return 0;
492
493 //FIXME("(%lu %lu %lx %lx \"%s\" %p)\n",
494 // lpcml->cbSize, lpcml->nMaxItems, lpcml->dwFlags,
495 // (DWORD)lpcml->hKey, lpcml->lpszSubKey, lpcml->lpfnCompare);
496
497 /* dummy pointer creation */
498 ptr = COMCTL32_Alloc (32);
499
500 //FIXME("-- ret = %p\n", ptr);
501
502 return (HANDLE)ptr;
503}
504
505/**************************************************************************
506 * EnumMRUListA [COMCTL32.154]
507 *
508 * Enumerate item in a list
509 *
510 * PARAMS
511 * hList [I] list handle
512 * nItemPos [I] item position to enumerate
513 * lpBuffer [O] buffer to receive item
514 * nBufferSize [I] size of buffer
515 *
516 * RETURNS
517 * For binary lists specifies how many bytes were copied to buffer, for
518 * string lists specifies full length of string. Enumerating past the end
519 * of list returns -1.
520 * If lpBuffer == NULL or nItemPos is -ve return value is no. of items in
521 * the list.
522 */
523INT WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer,
524DWORD nBufferSize)
525{
526 dprintf(("COMCTL32: EnumMRUListA - empty stub!"));
527
528 return 0;
529}
530
531
532
533/**************************************************************************
534 * Str_GetPtrA [COMCTL32.233]
535 *
536 * PARAMS
537 * lpSrc [I]
538 * lpDest [O]
539 * nMaxLen [I]
540 *
541 * RETURNS
542 */
543
544INT WINAPI
545Str_GetPtrA (LPCSTR lpSrc, LPSTR lpDest, INT nMaxLen)
546{
547 INT len;
548
549 dprintf(("COMCTL32: Str_GetPtrA"));
550
551 if (!lpDest && lpSrc)
552 return lstrlenA (lpSrc);
553
554 if (nMaxLen == 0)
555 return 0;
556
557 if (lpSrc == NULL) {
558 lpDest[0] = '\0';
559 return 0;
560 }
561
562 len = lstrlenA (lpSrc);
563 if (len >= nMaxLen)
564 len = nMaxLen - 1;
565
566 RtlMoveMemory (lpDest, lpSrc, len);
567 lpDest[len] = '\0';
568
569 return len;
570}
571
572
573/**************************************************************************
574 * Str_SetPtrA [COMCTL32.234]
575 *
576 * PARAMS
577 * lppDest [O]
578 * lpSrc [I]
579 *
580 * RETURNS
581 */
582
583BOOL WINAPI
584Str_SetPtrA (LPSTR *lppDest, LPCSTR lpSrc)
585{
586 dprintf(("COMCTL32: Str_SetPtrA"));
587
588 if (lpSrc) {
589 LPSTR ptr = COMCTL32_ReAlloc (*lppDest, lstrlenA (lpSrc) + 1);
590 if (!ptr)
591 return FALSE;
592 lstrcpyA (ptr, lpSrc);
593 *lppDest = ptr;
594 }
595 else {
596 if (*lppDest) {
597 COMCTL32_Free (*lppDest);
598 *lppDest = NULL;
599 }
600 }
601
602 return TRUE;
603}
604
605
606/**************************************************************************
607 * Str_GetPtrW [COMCTL32.235]
608 *
609 * PARAMS
610 * lpSrc [I]
611 * lpDest [O]
612 * nMaxLen [I]
613 *
614 * RETURNS
615 */
616
617INT WINAPI
618Str_GetPtrW (LPCWSTR lpSrc, LPWSTR lpDest, INT nMaxLen)
619{
620 INT len;
621
622 dprintf(("COMCTL32: Str_GetPtrW"));
623
624 if (!lpDest && lpSrc)
625 return lstrlenW (lpSrc);
626
627 if (nMaxLen == 0)
628 return 0;
629
630 if (lpSrc == NULL) {
631 lpDest[0] = L'\0';
632 return 0;
633 }
634
635 len = lstrlenW (lpSrc);
636 if (len >= nMaxLen)
637 len = nMaxLen - 1;
638
639 RtlMoveMemory (lpDest, lpSrc, len*sizeof(WCHAR));
640 lpDest[len] = L'\0';
641
642 return len;
643}
644
645
646/**************************************************************************
647 * Str_SetPtrW [COMCTL32.236]
648 *
649 * PARAMS
650 * lpDest [O]
651 * lpSrc [I]
652 *
653 * RETURNS
654 */
655
656BOOL WINAPI
657Str_SetPtrW (LPWSTR *lppDest, LPCWSTR lpSrc)
658{
659 dprintf(("COMCTL32: Str_SetPtrW"));
660
661 if (lpSrc) {
662 INT len = lstrlenW (lpSrc) + 1;
663 LPWSTR ptr = COMCTL32_ReAlloc (*lppDest, len * sizeof(WCHAR));
664 if (!ptr)
665 return FALSE;
666 lstrcpyW (ptr, lpSrc);
667 *lppDest = ptr;
668 }
669 else {
670 if (*lppDest) {
671 COMCTL32_Free (*lppDest);
672 *lppDest = NULL;
673 }
674 }
675
676 return TRUE;
677}
678
679
680/**************************************************************************
681 * The DSA-API is a set of functions to create and manipulate arrays of
682 * fix sized memory blocks. These arrays can store any kind of data
683 * (strings, icons...).
684 */
685
686/**************************************************************************
687 * DSA_Create [COMCTL32.320] Creates a dynamic storage array
688 *
689 * PARAMS
690 * nSize [I] size of the array elements
691 * nGrow [I] number of elements by which the array grows when it is filled
692 *
693 * RETURNS
694 * Success: pointer to a array control structure. use this like a handle.
695 * Failure: NULL
696 */
697
698HDSA WINAPI
699DSA_Create (INT nSize, INT nGrow)
700{
701 HDSA hdsa;
702
703 dprintf(("COMCTL32: DSA_Create"));
704
705 hdsa = (HDSA)COMCTL32_Alloc (sizeof(DSA));
706 if (hdsa)
707 {
708 hdsa->nItemCount = 0;
709 hdsa->pData = NULL;
710 hdsa->nMaxCount = 0;
711 hdsa->nItemSize = nSize;
712 hdsa->nGrow = MAX(1, nGrow);
713 }
714
715 return hdsa;
716}
717
718
719/**************************************************************************
720 * DSA_Destroy [COMCTL32.321] Destroys a dynamic storage array
721 *
722 * PARAMS
723 * hdsa [I] pointer to the array control structure
724 *
725 * RETURNS
726 * Success: TRUE
727 * Failure: FALSE
728 */
729
730BOOL WINAPI
731DSA_Destroy (const HDSA hdsa)
732{
733 dprintf(("COMCTL32: DSA_Destroy"));
734
735 if (!hdsa)
736 return FALSE;
737
738 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
739 return FALSE;
740
741 return COMCTL32_Free (hdsa);
742}
743
744
745/**************************************************************************
746 * DSA_GetItem [COMCTL32.322]
747 *
748 * PARAMS
749 * hdsa [I] pointer to the array control structure
750 * nIndex [I] number of the Item to get
751 * pDest [O] destination buffer. Has to be >= dwElementSize.
752 *
753 * RETURNS
754 * Success: TRUE
755 * Failure: FALSE
756 */
757
758BOOL WINAPI
759DSA_GetItem (const HDSA hdsa, INT nIndex, LPVOID pDest)
760{
761 LPVOID pSrc;
762
763 dprintf(("COMCTL32: DSA_GetItem"));
764
765 if (!hdsa)
766 return FALSE;
767 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
768 return FALSE;
769
770 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
771 memmove (pDest, pSrc, hdsa->nItemSize);
772
773 return TRUE;
774}
775
776
777/**************************************************************************
778 * DSA_GetItemPtr [COMCTL32.323]
779 *
780 * Retrieves a pointer to the specified item.
781 *
782 * PARAMS
783 * hdsa [I] pointer to the array control structure
784 * nIndex [I] index of the desired item
785 *
786 * RETURNS
787 * Success: pointer to an item
788 * Failure: NULL
789 */
790
791LPVOID WINAPI
792DSA_GetItemPtr (const HDSA hdsa, INT nIndex)
793{
794 LPVOID pSrc;
795
796 dprintf(("COMCTL32: DSA_GetItemPtr"));
797
798 if (!hdsa)
799 return NULL;
800 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
801 return NULL;
802
803 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
804
805// TRACE (commctrl, "-- ret=%p\n", pSrc);
806
807 return pSrc;
808}
809
810
811/**************************************************************************
812 * DSA_SetItem [COMCTL32.325]
813 *
814 * Sets the contents of an item in the array.
815 *
816 * PARAMS
817 * hdsa [I] pointer to the array control structure
818 * nIndex [I] index for the item
819 * pSrc [I] pointer to the new item data
820 *
821 * RETURNS
822 * Success: TRUE
823 * Failure: FALSE
824 */
825
826BOOL WINAPI
827DSA_SetItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
828{
829 INT nSize, nNewItems;
830 LPVOID pDest, lpTemp;
831
832 dprintf(("COMCTL32: DSA_SetItem"));
833
834 if ((!hdsa) || nIndex < 0)
835 return FALSE;
836
837 if (hdsa->nItemCount <= nIndex) {
838 /* within the old array */
839 if (hdsa->nMaxCount > nIndex) {
840 /* within the allocated space, set a new boundary */
841 hdsa->nItemCount = nIndex + 1;
842 }
843 else {
844 /* resize the block of memory */
845 nNewItems =
846 hdsa->nGrow * ((INT)(((nIndex + 1) - 1) / hdsa->nGrow) + 1);
847 nSize = hdsa->nItemSize * nNewItems;
848
849 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
850 if (!lpTemp)
851 return FALSE;
852
853 hdsa->nMaxCount = nNewItems;
854 hdsa->nItemCount = nIndex + 1;
855 hdsa->pData = lpTemp;
856 }
857 }
858
859 /* put the new entry in */
860 pDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
861// TRACE("-- move dest=%p src=%p size=%d\n",
862// pDest, pSrc, hdsa->nItemSize);
863 memmove (pDest, pSrc, hdsa->nItemSize);
864
865 return TRUE;
866}
867
868
869/**************************************************************************
870 * DSA_InsertItem [COMCTL32.325]
871 *
872 * PARAMS
873 * hdsa [I] pointer to the array control structure
874 * nIndex [I] index for the new item
875 * pSrc [I] pointer to the element
876 *
877 * RETURNS
878 * Success: position of the new item
879 * Failure: -1
880 */
881
882INT WINAPI
883DSA_InsertItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
884{
885 INT nNewItems, nSize, i;
886 LPVOID lpTemp, lpDest;
887 LPDWORD p;
888
889 dprintf(("COMCTL32: DSA_InsertItem"));
890
891 if ((!hdsa) || nIndex < 0)
892 return -1;
893
894 for (i = 0; i < hdsa->nItemSize; i += 4) {
895 p = *(DWORD**)((char *) pSrc + i);
896// if (IsBadStringPtrA ((char*)p, 256))
897// TRACE("-- %d=%p\n", i, (DWORD*)p);
898// else
899// TRACE("-- %d=%p [%s]\n", i, p, debugstr_a((char*)p));
900 }
901
902 /* when nIndex > nItemCount then append */
903 if (nIndex >= hdsa->nItemCount)
904 nIndex = hdsa->nItemCount;
905
906 /* do we need to resize ? */
907 if (hdsa->nItemCount >= hdsa->nMaxCount) {
908 nNewItems = hdsa->nMaxCount + hdsa->nGrow;
909 nSize = hdsa->nItemSize * nNewItems;
910
911 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
912 if (!lpTemp)
913 return -1;
914
915 hdsa->nMaxCount = nNewItems;
916 hdsa->pData = lpTemp;
917 }
918
919 /* do we need to move elements ? */
920 if (nIndex < hdsa->nItemCount) {
921 lpTemp = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
922 lpDest = (char *) lpTemp + hdsa->nItemSize;
923 nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize;
924// TRACE("-- move dest=%p src=%p size=%d\n",
925// lpDest, lpTemp, nSize);
926 memmove (lpDest, lpTemp, nSize);
927 }
928
929 /* ok, we can put the new Item in */
930 hdsa->nItemCount++;
931 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
932// TRACE("-- move dest=%p src=%p size=%d\n",
933// lpDest, pSrc, hdsa->nItemSize);
934 memmove (lpDest, pSrc, hdsa->nItemSize);
935
936 return hdsa->nItemCount;
937}
938
939
940/**************************************************************************
941 * DSA_DeleteItem [COMCTL32.326]
942 *
943 * PARAMS
944 * hdsa [I] pointer to the array control structure
945 * nIndex [I] index for the element to delete
946 *
947 * RETURNS
948 * Success: number of the deleted element
949 * Failure: -1
950 */
951
952INT WINAPI
953DSA_DeleteItem (const HDSA hdsa, INT nIndex)
954{
955 LPVOID lpDest,lpSrc;
956 INT nSize;
957
958 dprintf(("COMCTL32: DSA_DeleteItem"));
959
960 if (!hdsa)
961 return -1;
962 if (nIndex < 0 || nIndex >= hdsa->nItemCount)
963 return -1;
964
965 /* do we need to move ? */
966 if (nIndex < hdsa->nItemCount - 1) {
967 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
968 lpSrc = (char *) lpDest + hdsa->nItemSize;
969 nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1);
970// TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
971// lpDest, lpSrc, nSize);
972 memmove (lpDest, lpSrc, nSize);
973 }
974
975 hdsa->nItemCount--;
976
977 /* free memory ? */
978 if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) {
979 nSize = MAX(2*hdsa->nGrow,hdsa->nItemSize)*hdsa->nItemCount;
980
981 lpDest = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
982 if (!lpDest)
983 return -1;
984
985 hdsa->nMaxCount = hdsa->nItemCount;
986 hdsa->pData = lpDest;
987 }
988
989 return nIndex;
990}
991
992
993/**************************************************************************
994 * DSA_DeleteAllItems [COMCTL32.326]
995 *
996 * Removes all items and reinitializes the array.
997 *
998 * PARAMS
999 * hdsa [I] pointer to the array control structure
1000 *
1001 * RETURNS
1002 * Success: TRUE
1003 * Failure: FALSE
1004 */
1005
1006BOOL WINAPI
1007DSA_DeleteAllItems (const HDSA hdsa)
1008{
1009 dprintf(("COMCTL32: DSA_DeleteAllItems"));
1010
1011 if (!hdsa)
1012 return FALSE;
1013 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
1014 return FALSE;
1015
1016 hdsa->nItemCount = 0;
1017 hdsa->pData = NULL;
1018 hdsa->nMaxCount = 0;
1019
1020 return TRUE;
1021}
1022
1023
1024/**************************************************************************
1025 * The DPA-API is a set of functions to create and manipulate arrays of
1026 * pointers.
1027 */
1028
1029/**************************************************************************
1030 * DPA_Create [COMCTL32.328] Creates a dynamic pointer array
1031 *
1032 * PARAMS
1033 * nGrow [I] number of items by which the array grows when it is filled
1034 *
1035 * RETURNS
1036 * Success: handle (pointer) to the pointer array.
1037 * Failure: NULL
1038 */
1039
1040HDPA WINAPI
1041DPA_Create (INT nGrow)
1042{
1043 HDPA hdpa;
1044
1045 dprintf(("COMCTL32: DPA_Create"));
1046
1047 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
1048 if (hdpa) {
1049 hdpa->nGrow = MAX(8, nGrow);
1050 hdpa->hHeap = COMCTL32_hHeap;
1051 hdpa->nMaxCount = hdpa->nGrow * 2;
1052 hdpa->ptrs =
1053 (LPVOID*)COMCTL32_Alloc (hdpa->nMaxCount * sizeof(LPVOID));
1054 }
1055
1056// TRACE (commctrl, "-- %p\n", hdpa);
1057
1058 return hdpa;
1059}
1060
1061
1062/**************************************************************************
1063 * DPA_Destroy [COMCTL32.329] Destroys a dynamic pointer array
1064 *
1065 * PARAMS
1066 * hdpa [I] handle (pointer) to the pointer array
1067 *
1068 * RETURNS
1069 * Success: TRUE
1070 * Failure: FALSE
1071 */
1072
1073BOOL WINAPI
1074DPA_Destroy (const HDPA hdpa)
1075{
1076 dprintf(("COMCTL32: DPA_Destroy"));
1077
1078 if (!hdpa)
1079 return FALSE;
1080
1081 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
1082 return FALSE;
1083
1084 return HeapFree (hdpa->hHeap, 0, hdpa);
1085}
1086
1087
1088/**************************************************************************
1089 * DPA_Grow [COMCTL32.330]
1090 *
1091 * Sets the growth amount.
1092 *
1093 * PARAMS
1094 * hdpa [I] handle (pointer) to the existing (source) pointer array
1095 * nGrow [I] number of items, the array grows, when it's too small
1096 *
1097 * RETURNS
1098 * Success: TRUE
1099 * Failure: FALSE
1100 */
1101
1102BOOL WINAPI
1103DPA_Grow (const HDPA hdpa, INT nGrow)
1104{
1105 dprintf(("COMCTL32: DPA_Grow"));
1106
1107 if (!hdpa)
1108 return FALSE;
1109
1110 hdpa->nGrow = MAX(8, nGrow);
1111
1112 return TRUE;
1113}
1114
1115
1116/**************************************************************************
1117 * DPA_Clone [COMCTL32.331]
1118 *
1119 * Copies a pointer array to an other one or creates a copy
1120 *
1121 * PARAMS
1122 * hdpa [I] handle (pointer) to the existing (source) pointer array
1123 * hdpaNew [O] handle (pointer) to the destination pointer array
1124 *
1125 * RETURNS
1126 * Success: pointer to the destination pointer array.
1127 * Failure: NULL
1128 *
1129 * NOTES
1130 * - If the 'hdpaNew' is a NULL-Pointer, a copy of the source pointer
1131 * array will be created and it's handle (pointer) is returned.
1132 * - If 'hdpa' is a NULL-Pointer, the original implementation crashes,
1133 * this implementation just returns NULL.
1134 */
1135
1136HDPA WINAPI
1137DPA_Clone (const HDPA hdpa, const HDPA hdpaNew)
1138{
1139 INT nNewItems, nSize;
1140 HDPA hdpaTemp;
1141
1142 dprintf(("COMCTL32: DPA_Clone"));
1143
1144 if (!hdpa)
1145 return NULL;
1146
1147 if (!hdpaNew) {
1148 /* create a new DPA */
1149 hdpaTemp = (HDPA)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1150 sizeof(DPA));
1151 hdpaTemp->hHeap = hdpa->hHeap;
1152 hdpaTemp->nGrow = hdpa->nGrow;
1153 }
1154 else
1155 hdpaTemp = hdpaNew;
1156
1157 if (hdpaTemp->ptrs) {
1158 /* remove old pointer array */
1159 HeapFree (hdpaTemp->hHeap, 0, hdpaTemp->ptrs);
1160 hdpaTemp->ptrs = NULL;
1161 hdpaTemp->nItemCount = 0;
1162 hdpaTemp->nMaxCount = 0;
1163 }
1164
1165 /* create a new pointer array */
1166 nNewItems = hdpaTemp->nGrow *
1167 ((INT)((hdpa->nItemCount - 1) / hdpaTemp->nGrow) + 1);
1168 nSize = nNewItems * sizeof(LPVOID);
1169 hdpaTemp->ptrs =
1170 (LPVOID*)HeapAlloc (hdpaTemp->hHeap, HEAP_ZERO_MEMORY, nSize);
1171 hdpaTemp->nMaxCount = nNewItems;
1172
1173 /* clone the pointer array */
1174 hdpaTemp->nItemCount = hdpa->nItemCount;
1175 memmove (hdpaTemp->ptrs, hdpa->ptrs,
1176 hdpaTemp->nItemCount * sizeof(LPVOID));
1177
1178 return hdpaTemp;
1179}
1180
1181
1182/**************************************************************************
1183 * DPA_GetPtr [COMCTL32.332]
1184 *
1185 * Retrieves a pointer from a dynamic pointer array
1186 *
1187 * PARAMS
1188 * hdpa [I] handle (pointer) to the pointer array
1189 * nIndex [I] array index of the desired pointer
1190 *
1191 * RETURNS
1192 * Success: pointer
1193 * Failure: NULL
1194 */
1195
1196LPVOID WINAPI
1197DPA_GetPtr (const HDPA hdpa, INT i)
1198{
1199 dprintf(("COMCTL32: DPA_GetPtr"));
1200
1201 if (!hdpa)
1202 return NULL;
1203 if (!hdpa->ptrs)
1204 return NULL;
1205 if ((i < 0) || (i >= hdpa->nItemCount))
1206 return NULL;
1207
1208// TRACE (commctrl, "-- %p\n", hdpa->ptrs[i]);
1209
1210 return hdpa->ptrs[i];
1211}
1212
1213
1214/**************************************************************************
1215 * DPA_GetPtrIndex [COMCTL32.333]
1216 *
1217 * Retrieves the index of the specified pointer
1218 *
1219 * PARAMS
1220 * hdpa [I] handle (pointer) to the pointer array
1221 * p [I] pointer
1222 *
1223 * RETURNS
1224 * Success: index of the specified pointer
1225 * Failure: -1
1226 */
1227
1228INT WINAPI
1229DPA_GetPtrIndex (const HDPA hdpa, LPVOID p)
1230{
1231 INT i;
1232
1233 dprintf(("COMCTL32: DPA_GetPtrIndex"));
1234
1235 if (!hdpa->ptrs)
1236 return -1;
1237
1238 for (i = 0; i < hdpa->nItemCount; i++) {
1239 if (hdpa->ptrs[i] == p)
1240 return i;
1241 }
1242
1243 return -1;
1244}
1245
1246
1247/**************************************************************************
1248 * DPA_InsertPtr [COMCTL32.334]
1249 *
1250 * Inserts a pointer into a dynamic pointer array
1251 *
1252 * PARAMS
1253 * hdpa [I] handle (pointer) to the array
1254 * i [I] array index
1255 * p [I] pointer to insert
1256 *
1257 * RETURNS
1258 * Success: index of the inserted pointer
1259 * Failure: -1
1260 */
1261
1262INT WINAPI
1263DPA_InsertPtr (const HDPA hdpa, INT i, LPVOID p)
1264{
1265 INT nNewItems, nSize, nIndex = 0;
1266 LPVOID *lpTemp, *lpDest;
1267
1268 dprintf(("COMCTL32: DPA_InsertPtr"));
1269
1270 if ((!hdpa) || (i < 0))
1271 return -1;
1272
1273 if (!hdpa->ptrs) {
1274 hdpa->ptrs =
1275 (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1276 2 * hdpa->nGrow * sizeof(LPVOID));
1277 if (!hdpa->ptrs)
1278 return -1;
1279 hdpa->nMaxCount = hdpa->nGrow * 2;
1280 nIndex = 0;
1281 }
1282 else {
1283 if (hdpa->nItemCount >= hdpa->nMaxCount) {
1284// TRACE (commctrl, "-- resizing\n");
1285 nNewItems = hdpa->nMaxCount + hdpa->nGrow;
1286 nSize = nNewItems * sizeof(LPVOID);
1287
1288 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1289 hdpa->ptrs, nSize);
1290 if (!lpTemp)
1291 return -1;
1292 hdpa->nMaxCount = nNewItems;
1293 hdpa->ptrs = lpTemp;
1294 }
1295
1296 if (i >= hdpa->nItemCount) {
1297 nIndex = hdpa->nItemCount;
1298// TRACE (commctrl, "-- appending at %d\n", nIndex);
1299 }
1300 else {
1301// TRACE (commctrl, "-- inserting at %d\n", i);
1302 lpTemp = hdpa->ptrs + i;
1303 lpDest = lpTemp + 1;
1304 nSize = (hdpa->nItemCount - i) * sizeof(LPVOID);
1305// TRACE (commctrl, "-- move dest=%p src=%p size=%x\n",
1306// lpDest, lpTemp, nSize);
1307 memmove (lpDest, lpTemp, nSize);
1308 nIndex = i;
1309 }
1310 }
1311
1312 /* insert item */
1313 hdpa->nItemCount++;
1314 hdpa->ptrs[nIndex] = p;
1315
1316 return nIndex;
1317}
1318
1319
1320/**************************************************************************
1321 * DPA_SetPtr [COMCTL32.335]
1322 *
1323 * Sets a pointer in the pointer array
1324 *
1325 * PARAMS
1326 * hdpa [I] handle (pointer) to the pointer array
1327 * i [I] index of the pointer that will be set
1328 * p [I] pointer to be set
1329 *
1330 * RETURNS
1331 * Success: TRUE
1332 * Failure: FALSE
1333 */
1334
1335BOOL WINAPI
1336DPA_SetPtr (const HDPA hdpa, INT i, LPVOID p)
1337{
1338 LPVOID *lpTemp;
1339
1340 dprintf(("COMCTL32: DPA_SetPtr"));
1341
1342 if ((!hdpa) || i < 0)
1343 return FALSE;
1344
1345 if (hdpa->nItemCount <= i) {
1346 /* within the old array */
1347 if (hdpa->nMaxCount > i) {
1348 /* within the allocated space, set a new boundary */
1349 hdpa->nItemCount = i;
1350 }
1351 else {
1352 /* resize the block of memory */
1353 INT nNewItems =
1354 hdpa->nGrow * ((INT)(((i+1) - 1) / hdpa->nGrow) + 1);
1355 INT nSize = nNewItems * sizeof(LPVOID);
1356
1357 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1358 hdpa->ptrs, nSize);
1359 if (!lpTemp)
1360 return FALSE;
1361
1362 hdpa->nItemCount = nNewItems;
1363 hdpa->ptrs = lpTemp;
1364 }
1365 }
1366
1367 /* put the new entry in */
1368 hdpa->ptrs[i] = p;
1369
1370 return TRUE;
1371}
1372
1373
1374/**************************************************************************
1375 * DPA_DeletePtr [COMCTL32.336]
1376 *
1377 * Removes a pointer from the pointer array.
1378 *
1379 * PARAMS
1380 * hdpa [I] handle (pointer) to the pointer array
1381 * i [I] index of the pointer that will be deleted
1382 *
1383 * RETURNS
1384 * Success: deleted pointer
1385 * Failure: NULL
1386 */
1387
1388LPVOID WINAPI
1389DPA_DeletePtr (const HDPA hdpa, INT i)
1390{
1391 LPVOID *lpDest, *lpSrc, lpTemp = NULL;
1392 INT nSize;
1393
1394 dprintf(("COMCTL32: DPA_DeletePtr"));
1395
1396 if ((!hdpa) || i < 0 || i >= hdpa->nItemCount)
1397 return NULL;
1398
1399 lpTemp = hdpa->ptrs[i];
1400
1401 /* do we need to move ?*/
1402 if (i < hdpa->nItemCount - 1) {
1403 lpDest = hdpa->ptrs + i;
1404 lpSrc = lpDest + 1;
1405 nSize = (hdpa->nItemCount - i - 1) * sizeof(LPVOID);
1406// TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",
1407// lpDest, lpSrc, nSize);
1408 memmove (lpDest, lpSrc, nSize);
1409 }
1410
1411 hdpa->nItemCount --;
1412
1413 /* free memory ?*/
1414 if ((hdpa->nMaxCount - hdpa->nItemCount) >= hdpa->nGrow) {
1415 INT nNewItems = MAX(hdpa->nGrow*2,hdpa->nItemCount);
1416
1417 nSize = nNewItems * sizeof(LPVOID);
1418 lpDest = (LPVOID)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1419 hdpa->ptrs, nSize);
1420 if (!lpDest)
1421 return NULL;
1422
1423 hdpa->nMaxCount = nNewItems;
1424 hdpa->ptrs = (LPVOID*)lpDest;
1425 }
1426
1427 return lpTemp;
1428}
1429
1430
1431/**************************************************************************
1432 * DPA_DeleteAllPtrs [COMCTL32.337]
1433 *
1434 * Removes all pointers and reinitializes the array.
1435 *
1436 * PARAMS
1437 * hdpa [I] handle (pointer) to the pointer array
1438 *
1439 * RETURNS
1440 * Success: TRUE
1441 * Failure: FALSE
1442 */
1443
1444BOOL WINAPI
1445DPA_DeleteAllPtrs (const HDPA hdpa)
1446{
1447 dprintf(("COMCTL32: DPA_DeleteAllPtrs"));
1448
1449 if (!hdpa)
1450 return FALSE;
1451
1452 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
1453 return FALSE;
1454
1455 hdpa->nItemCount = 0;
1456 hdpa->nMaxCount = hdpa->nGrow * 2;
1457 hdpa->ptrs = (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1458 hdpa->nMaxCount * sizeof(LPVOID));
1459
1460 return TRUE;
1461}
1462
1463
1464/**************************************************************************
1465 * DPA_QuickSort [Internal]
1466 *
1467 * Ordinary quicksort (used by DPA_Sort).
1468 *
1469 * PARAMS
1470 * lpPtrs [I] pointer to the pointer array
1471 * l [I] index of the "left border" of the partition
1472 * r [I] index of the "right border" of the partition
1473 * pfnCompare [I] pointer to the compare function
1474 * lParam [I] user defined value (3rd parameter in compare function)
1475 *
1476 * RETURNS
1477 * NONE
1478 */
1479
1480static VOID
1481DPA_QuickSort (LPVOID *lpPtrs, INT l, INT r,
1482 PFNDPACOMPARE pfnCompare, LPARAM lParam)
1483{
1484 LPVOID t, v;
1485 INT i, j;
1486
1487// TRACE (commctrl, "l=%i r=%i\n", l, r);
1488
1489 i = l;
1490 j = r;
1491 v = lpPtrs[(int)(l+r)/2];
1492 do {
1493 while ((pfnCompare)(lpPtrs[i], v, lParam) < 0) i++;
1494 while ((pfnCompare)(lpPtrs[j], v, lParam) > 0) j--;
1495 if (i <= j)
1496 {
1497 t = lpPtrs[i];
1498 lpPtrs[i++] = lpPtrs[j];
1499 lpPtrs[j--] = t;
1500 }
1501 } while (i <= j);
1502 if (l < j) DPA_QuickSort (lpPtrs, l, j, pfnCompare, lParam);
1503 if (i < r) DPA_QuickSort (lpPtrs, i, r, pfnCompare, lParam);
1504}
1505
1506
1507/**************************************************************************
1508 * DPA_Sort [COMCTL32.338]
1509 *
1510 * Sorts a pointer array using a user defined compare function
1511 *
1512 * PARAMS
1513 * hdpa [I] handle (pointer) to the pointer array
1514 * pfnCompare [I] pointer to the compare function
1515 * lParam [I] user defined value (3rd parameter of compare function)
1516 *
1517 * RETURNS
1518 * Success: TRUE
1519 * Failure: FALSE
1520 */
1521
1522BOOL WINAPI
1523DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
1524{
1525 dprintf(("COMCTL32: DPA_Sort"));
1526
1527 if (!hdpa || !pfnCompare)
1528 return FALSE;
1529
1530 if ((hdpa->nItemCount > 1) && (hdpa->ptrs))
1531 DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1,
1532 pfnCompare, lParam);
1533
1534 return TRUE;
1535}
1536
1537
1538/**************************************************************************
1539 * DPA_Search [COMCTL32.339]
1540 *
1541 * Searches a pointer array for a specified pointer
1542 *
1543 * PARAMS
1544 * hdpa [I] handle (pointer) to the pointer array
1545 * pFind [I] pointer to search for
1546 * nStart [I] start index
1547 * pfnCompare [I] pointer to the compare function
1548 * lParam [I] user defined value (3rd parameter of compare function)
1549 * uOptions [I] search options
1550 *
1551 * RETURNS
1552 * Success: index of the pointer in the array.
1553 * Failure: -1
1554 *
1555 * NOTES
1556 * Binary search taken from R.Sedgewick "Algorithms in C"!
1557 * Function is NOT tested!
1558 * If something goes wrong, blame HIM not ME! (Eric Kohl)
1559 */
1560
1561INT WINAPI
1562DPA_Search (const HDPA hdpa, LPVOID pFind, INT nStart,
1563 PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT uOptions)
1564{
1565 dprintf(("COMCTL32: DPA_Search"));
1566
1567 if (!hdpa || !pfnCompare || !pFind)
1568 return -1;
1569
1570 if (uOptions & DPAS_SORTED) {
1571 /* array is sorted --> use binary search */
1572 INT l, r, x, n;
1573 LPVOID *lpPtr;
1574
1575// TRACE (commctrl, "binary search\n");
1576
1577 l = (nStart == -1) ? 0 : nStart;
1578 r = hdpa->nItemCount - 1;
1579 lpPtr = hdpa->ptrs;
1580 while (r >= l) {
1581 x = (l + r) / 2;
1582 n = (pfnCompare)(pFind, lpPtr[x], lParam);
1583 if (n < 0)
1584 r = x - 1;
1585 else
1586 l = x + 1;
1587 if (n == 0) {
1588// TRACE (commctrl, "-- ret=%d\n", n);
1589 return n;
1590 }
1591 }
1592
1593 if (uOptions & DPAS_INSERTBEFORE) {
1594// TRACE (commctrl, "-- ret=%d\n", r);
1595 return r;
1596 }
1597
1598 if (uOptions & DPAS_INSERTAFTER) {
1599// TRACE (commctrl, "-- ret=%d\n", l);
1600 return l;
1601 }
1602 }
1603 else {
1604 /* array is not sorted --> use linear search */
1605 LPVOID *lpPtr;
1606 INT nIndex;
1607
1608// TRACE (commctrl, "linear search\n");
1609
1610 nIndex = (nStart == -1)? 0 : nStart;
1611 lpPtr = hdpa->ptrs;
1612 for (; nIndex < hdpa->nItemCount; nIndex++) {
1613 if ((pfnCompare)(pFind, lpPtr[nIndex], lParam) == 0) {
1614// TRACE (commctrl, "-- ret=%d\n", nIndex);
1615 return nIndex;
1616 }
1617 }
1618 }
1619
1620// TRACE (commctrl, "-- not found: ret=-1\n");
1621 return -1;
1622}
1623
1624
1625/**************************************************************************
1626 * DPA_CreateEx [COMCTL32.340]
1627 *
1628 * Creates a dynamic pointer array using the specified size and heap.
1629 *
1630 * PARAMS
1631 * nGrow [I] number of items by which the array grows when it is filled
1632 * hHeap [I] handle to the heap where the array is stored
1633 *
1634 * RETURNS
1635 * Success: handle (pointer) to the pointer array.
1636 * Failure: NULL
1637 */
1638
1639HDPA WINAPI
1640DPA_CreateEx (INT nGrow, HANDLE hHeap)
1641{
1642 HDPA hdpa;
1643
1644 dprintf(("COMCTL32: DPA_CreateEx"));
1645
1646 if (hHeap)
1647 hdpa = (HDPA)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, sizeof(DPA));
1648 else
1649 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
1650
1651 if (hdpa) {
1652 hdpa->nGrow = MIN(8, nGrow);
1653 hdpa->hHeap = hHeap ? hHeap : COMCTL32_hHeap;
1654 hdpa->nMaxCount = hdpa->nGrow * 2;
1655 hdpa->ptrs =
1656 (LPVOID*)HeapAlloc (hHeap, HEAP_ZERO_MEMORY,
1657 hdpa->nMaxCount * sizeof(LPVOID));
1658 }
1659
1660// TRACE (commctrl, "-- %p\n", hdpa);
1661
1662 return hdpa;
1663}
1664
1665/**************************************************************************
1666 * Notification functions
1667 */
1668
1669typedef struct tagNOTIFYDATA
1670{
1671 HWND hwndFrom;
1672 HWND hwndTo;
1673 DWORD dwParam3;
1674 DWORD dwParam4;
1675 DWORD dwParam5;
1676 DWORD dwParam6;
1677} NOTIFYDATA, *LPNOTIFYDATA;
1678
1679
1680/**************************************************************************
1681 * DoNotify [Internal]
1682 */
1683
1684static LRESULT
1685DoNotify (LPNOTIFYDATA lpNotify, UINT uCode, LPNMHDR lpHdr)
1686{
1687 NMHDR nmhdr;
1688 LPNMHDR lpNmh = NULL;
1689 UINT idFrom = 0;
1690
1691// TRACE (commctrl, "(0x%04x 0x%04x %d %p 0x%08lx)\n",
1692// lpNotify->hwndFrom, lpNotify->hwndTo, uCode, lpHdr,
1693// lpNotify->dwParam5);
1694
1695 if (!lpNotify->hwndTo)
1696 return 0;
1697
1698 if (lpNotify->hwndFrom == -1) {
1699 lpNmh = lpHdr;
1700 idFrom = lpHdr->idFrom;
1701 }
1702 else {
1703 if (lpNotify->hwndFrom) {
1704 HWND hwndParent = GetParent (lpNotify->hwndFrom);
1705 if (hwndParent) {
1706 hwndParent = GetWindow (lpNotify->hwndFrom, GW_OWNER);
1707 if (hwndParent)
1708 idFrom = GetDlgCtrlID (lpNotify->hwndFrom);
1709 }
1710 }
1711
1712 lpNmh = (lpHdr) ? lpHdr : &nmhdr;
1713
1714 lpNmh->hwndFrom = lpNotify->hwndFrom;
1715 lpNmh->idFrom = idFrom;
1716 lpNmh->code = uCode;
1717 }
1718
1719 return SendMessageA (lpNotify->hwndTo, WM_NOTIFY, idFrom, (LPARAM)lpNmh);
1720}
1721
1722
1723/**************************************************************************
1724 * SendNotify [COMCTL32.341]
1725 *
1726 * PARAMS
1727 * hwndFrom [I]
1728 * hwndTo [I]
1729 * uCode [I]
1730 * lpHdr [I]
1731 *
1732 * RETURNS
1733 * Success: return value from notification
1734 * Failure: 0
1735 */
1736
1737LRESULT WINAPI
1738COMCTL32_SendNotify (HWND hwndFrom, HWND hwndTo,
1739 UINT uCode, LPNMHDR lpHdr)
1740{
1741 NOTIFYDATA notify;
1742
1743 dprintf(("COMCTL32: SendNotify"));
1744
1745 notify.hwndFrom = hwndFrom;
1746 notify.hwndTo = hwndTo;
1747 notify.dwParam5 = 0;
1748 notify.dwParam6 = 0;
1749
1750 return DoNotify (&notify, uCode, lpHdr);
1751}
1752
1753
1754/**************************************************************************
1755 * SendNotifyEx [COMCTL32.342]
1756 *
1757 * PARAMS
1758 * hwndFrom [I]
1759 * hwndTo [I]
1760 * uCode [I]
1761 * lpHdr [I]
1762 * dwParam5 [I]
1763 *
1764 * RETURNS
1765 * Success: return value from notification
1766 * Failure: 0
1767 */
1768
1769LRESULT WINAPI
1770COMCTL32_SendNotifyEx (HWND hwndTo, HWND hwndFrom, UINT uCode,
1771 LPNMHDR lpHdr, DWORD dwParam5)
1772{
1773 NOTIFYDATA notify;
1774 HWND hwndNotify;
1775
1776 dprintf(("COMCTL32: SendNotifyEx"));
1777
1778 hwndNotify = hwndTo;
1779 if (!hwndTo) {
1780 if (IsWindow (hwndFrom)) {
1781 hwndNotify = GetParent (hwndFrom);
1782 if (!hwndNotify)
1783 return 0;
1784 }
1785 }
1786
1787 notify.hwndFrom = hwndFrom;
1788 notify.hwndTo = hwndNotify;
1789 notify.dwParam5 = dwParam5;
1790 notify.dwParam6 = 0;
1791
1792 return DoNotify (&notify, uCode, lpHdr);
1793}
1794
1795
1796/**************************************************************************
1797 * StrChrA [COMCTL32.350]
1798 *
1799 */
1800
1801LPSTR WINAPI
1802COMCTL32_StrChrA (LPCSTR lpString, CHAR cChar)
1803{
1804 dprintf(("COMCTL32: StrChrA"));
1805
1806 return strchr (lpString, cChar);
1807}
1808
1809
1810/**************************************************************************
1811 * StrStrIA [COMCTL32.355]
1812 */
1813
1814LPSTR WINAPI
1815COMCTL32_StrStrIA (LPCSTR lpStr1, LPCSTR lpStr2)
1816{
1817 INT len1, len2, i;
1818 CHAR first;
1819
1820 dprintf(("COMCTL32: StrStrIA"));
1821
1822 if (*lpStr2 == 0)
1823 return ((LPSTR)lpStr1);
1824 len1 = 0;
1825 while (lpStr1[len1] != 0) ++len1;
1826 len2 = 0;
1827 while (lpStr2[len2] != 0) ++len2;
1828 if (len2 == 0)
1829 return ((LPSTR)(lpStr1 + len1));
1830 first = tolower (*lpStr2);
1831 while (len1 >= len2) {
1832 if (tolower(*lpStr1) == first) {
1833 for (i = 1; i < len2; ++i)
1834 if (tolower (lpStr1[i]) != tolower(lpStr2[i]))
1835 break;
1836 if (i >= len2)
1837 return ((LPSTR)lpStr1);
1838 }
1839 ++lpStr1; --len1;
1840 }
1841 return (NULL);
1842}
1843
1844
1845/**************************************************************************
1846 * StrToIntA [COMCTL32.357] Converts a string to a signed integer.
1847 */
1848
1849INT WINAPI
1850COMCTL32_StrToIntA (LPSTR lpString)
1851{
1852 dprintf(("COMCTL32: StrToIntA"));
1853
1854 return atoi(lpString);
1855}
1856
1857/**************************************************************************
1858 * DPA_EnumCallback [COMCTL32.385]
1859 *
1860 * Enumerates all items in a dynamic pointer array.
1861 *
1862 * PARAMS
1863 * hdpa [I] handle to the dynamic pointer array
1864 * enumProc [I]
1865 * lParam [I]
1866 *
1867 * RETURNS
1868 * none
1869 */
1870
1871
1872VOID WINAPI
1873DPA_EnumCallback (const HDPA hdpa, DPAENUMPROC enumProc, LPARAM lParam)
1874{
1875 INT i;
1876
1877 dprintf(("COMCTL32: DPA_EnumCallback"));
1878
1879 if (!hdpa)
1880 return;
1881 if (hdpa->nItemCount <= 0)
1882 return;
1883
1884 for (i = 0; i < hdpa->nItemCount; i++) {
1885 if ((enumProc)(hdpa->ptrs[i], lParam) == 0)
1886 return;
1887 }
1888
1889 return;
1890}
1891
1892
1893/**************************************************************************
1894 * DPA_DestroyCallback [COMCTL32.386]
1895 *
1896 * Enumerates all items in a dynamic pointer array and destroys it.
1897 *
1898 * PARAMS
1899 * hdpa [I] handle to the dynamic pointer array
1900 * enumProc [I]
1901 * lParam [I]
1902 *
1903 * RETURNS
1904 * Success: TRUE
1905 * Failure: FALSE
1906 */
1907
1908BOOL WINAPI
1909DPA_DestroyCallback (const HDPA hdpa, DPAENUMPROC enumProc, LPARAM lParam)
1910{
1911 dprintf(("COMCTL32: DPA_DestroyCallback"));
1912
1913 DPA_EnumCallback (hdpa, enumProc, lParam);
1914
1915 return DPA_Destroy (hdpa);
1916}
1917
1918
1919/**************************************************************************
1920 * DSA_EnumCallback [COMCTL32.387]
1921 *
1922 * Enumerates all items in a dynamic storage array.
1923 *
1924 * PARAMS
1925 * hdsa [I] handle to the dynamic storage array
1926 * enumProc [I]
1927 * lParam [I]
1928 *
1929 * RETURNS
1930 * none
1931 */
1932
1933VOID WINAPI
1934DSA_EnumCallback (const HDSA hdsa, DSAENUMPROC enumProc, LPARAM lParam)
1935{
1936 INT i;
1937
1938 dprintf(("COMCTL32: DSA_EnumCallback"));
1939
1940 if (!hdsa)
1941 return;
1942 if (hdsa->nItemCount <= 0)
1943 return;
1944
1945 for (i = 0; i < hdsa->nItemCount; i++) {
1946 LPVOID lpItem = DSA_GetItemPtr (hdsa, i);
1947 if ((enumProc)(lpItem, lParam) == 0)
1948 return;
1949 }
1950
1951 return;
1952}
1953
1954
1955/**************************************************************************
1956 * DSA_DestroyCallback [COMCTL32.388]
1957 *
1958 * Enumerates all items in a dynamic storage array and destroys it.
1959 *
1960 * PARAMS
1961 * hdsa [I] handle to the dynamic storage array
1962 * enumProc [I]
1963 * lParam [I]
1964 *
1965 * RETURNS
1966 * Success: TRUE
1967 * Failure: FALSE
1968 */
1969
1970BOOL WINAPI
1971DSA_DestroyCallback (const HDSA hdsa, DSAENUMPROC enumProc, LPARAM lParam)
1972{
1973 dprintf(("COMCTL32: DSA_DestroyCallback"));
1974
1975 DSA_EnumCallback (hdsa, enumProc, lParam);
1976
1977 return DSA_Destroy (hdsa);
1978}
1979
1980/**************************************************************************
1981 * StrCSpnA [COMCTL32.356]
1982 *
1983 */
1984INT WINAPI COMCTL32_StrCSpnA( LPCSTR lpStr, LPCSTR lpSet)
1985{
1986 dprintf(("COMCTL32: StrCSpnA"));
1987
1988 return strcspn(lpStr, lpSet);
1989}
1990
1991/**************************************************************************
1992 * StrChrW [COMCTL32.358]
1993 *
1994 */
1995LPWSTR WINAPI COMCTL32_StrChrW( LPCWSTR lpStart, WORD wMatch)
1996{
1997 dprintf(("COMCTL32: StrChrW"));
1998
1999 return (unsigned short*)wcschr(lpStart, wMatch);
2000}
2001
2002/**************************************************************************
2003 * StrCmpNA [COMCTL32.352]
2004 *
2005 */
2006INT WINAPI COMCTL32_StrCmpNA( LPCSTR lpStr1, LPCSTR lpStr2, int nChar)
2007{
2008 dprintf(("COMCTL32: StrCmpNA"));
2009
2010 return strncmp(lpStr1, lpStr2, nChar);
2011}
2012
2013/**************************************************************************
2014 * StrCmpNIA [COMCTL32.353]
2015 *
2016 */
2017INT WINAPI COMCTL32_StrCmpNIA( LPCSTR lpStr1, LPCSTR lpStr2, int nChar)
2018{
2019 //AH: Inline helper function from WINE
2020 int res;
2021
2022 dprintf(("COMCTL32: StrCmpNIA"));
2023
2024 if (!nChar) return 0;
2025 while ((--nChar > 0) && *lpStr1)
2026 if ((res = toupper(*lpStr1++) - toupper(*lpStr2++))) return res;
2027 return toupper(*lpStr1) - toupper(*lpStr2);
2028}
2029
2030/**************************************************************************
2031 * StrCmpNW [COMCTL32.360]
2032 *
2033 */
2034INT WINAPI COMCTL32_StrCmpNW( LPCWSTR lpStr1, LPCWSTR lpStr2, int nChar)
2035{
2036 dprintf(("COMCTL32: StrCmpNW"));
2037
2038 return wcsncmp(lpStr1, lpStr2, nChar);
2039}
2040
2041/**************************************************************************
2042 * StrCmpNIW [COMCTL32.361]
2043 *
2044 */
2045INT WINAPI COMCTL32_StrCmpNIW( LPCWSTR lpStr1, LPCWSTR lpStr2, int nChar)
2046{
2047 dprintf(("COMCTL32: StrCmpNIW - unimplemented stub\n"));
2048
2049 return 0;
2050}
2051
2052/***********************************************************************
2053 * ChrCmpA
2054 * This fuction returns FALSE if both words match, TRUE otherwise...
2055 */
2056static BOOL ChrCmpA( WORD word1, WORD word2) {
2057 if (LOBYTE(word1) == LOBYTE(word2)) {
2058 if (IsDBCSLeadByte(LOBYTE(word1))) {
2059 return (word1 != word2);
2060 }
2061 return FALSE;
2062 }
2063 return TRUE;
2064}
2065
2066/**************************************************************************
2067 * StrRChrA [COMCTL32.351]
2068 *
2069 */
2070LPSTR WINAPI COMCTL32_StrRChrA( LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch)
2071{
2072 LPCSTR lpGotIt = NULL;
2073
2074 dprintf(("COMCTL32: StrRChrA"));
2075
2076 if (!lpEnd) lpEnd = lpStart + strlen(lpStart);
2077
2078 for(; lpStart < lpEnd; lpStart = CharNextA(lpStart))
2079 if (!ChrCmpA( GET_WORD(lpStart), wMatch))
2080 lpGotIt = lpStart;
2081
2082 return ((LPSTR)lpGotIt);
2083
2084 return 0;
2085}
2086
2087/***********************************************************************
2088 * ChrCmpW
2089 * This fuction returns FALSE if both words match, TRUE otherwise...
2090 */
2091static BOOL ChrCmpW( WORD word1, WORD word2) {
2092 return (word1 != word2);
2093}
2094
2095/**************************************************************************
2096 * StrRChrW [COMCTL32.359]
2097 *
2098 */
2099LPWSTR WINAPI COMCTL32_StrRChrW( LPCWSTR lpStart, LPCWSTR lpEnd, WORD wMatch)
2100{
2101 //AH: Inline Wine helper function
2102 LPCWSTR lpGotIt = NULL;
2103
2104 dprintf(("COMCTL32: StrRChrW"));
2105
2106 if (!lpEnd) lpEnd = lpStart + lstrlenW(lpStart);
2107
2108 for(; lpStart < lpEnd; lpStart = CharNextW(lpStart))
2109 if (!ChrCmpW( GET_WORD(lpStart), wMatch))
2110 lpGotIt = lpStart;
2111
2112 return (LPWSTR)lpGotIt;
2113}
2114
2115
2116/**************************************************************************
2117 * StrStrA [COMCTL32.354]
2118 *
2119 */
2120LPSTR WINAPI COMCTL32_StrStrA( LPCSTR lpFirst, LPCSTR lpSrch)
2121{
2122 dprintf(("COMCTL32: StrStrA"));
2123
2124 return strstr(lpFirst, lpSrch);
2125}
2126
2127/**************************************************************************
2128 * StrStrW [COMCTL32.362]
2129 *
2130 */
2131LPWSTR WINAPI COMCTL32_StrStrW( LPCWSTR lpFirst, LPCWSTR lpSrch)
2132{
2133 dprintf(("COMCTL32: StrStrW"));
2134
2135 return (unsigned short*)wcsstr(lpFirst, lpSrch);
2136}
2137
2138/**************************************************************************
2139 * StrSpnW [COMCTL32.364]
2140 *
2141 */
2142INT WINAPI COMCTL32_StrSpnW( LPWSTR lpStr, LPWSTR lpSet)
2143{
2144 LPWSTR lpLoop = lpStr;
2145
2146 dprintf(("COMCTL32: StrSpnW"));
2147
2148 /* validate ptr */
2149 if ((lpStr == 0) || (lpSet == 0)) return 0;
2150
2151/* while(*lpLoop) { if lpLoop++; } */
2152
2153 for(; (*lpLoop != 0); lpLoop++)
2154 if (wcschr(lpSet, *(WORD*)lpLoop))
2155 return (INT)(lpLoop-lpStr);
2156
2157 return (INT)(lpLoop-lpStr);
2158}
2159
2160/**************************************************************************
2161 * comctl32_410 [COMCTL32.410]
2162 *
2163 * FIXME: What's this supposed to do?
2164 * Parameter 1 is an HWND, you're on your own for the rest.
2165 */
2166
2167BOOL WINAPI comctl32_410( HWND hw, DWORD b, DWORD c, DWORD d)
2168{
2169 dprintf(("COMCTL32: comctl32_410 - empty stub!"));
2170
2171 return TRUE;
2172}
2173
2174/**************************************************************************
2175 * comctl32_411 [COMCTL32.411]
2176 *
2177 * FIXME: What's this supposed to do?
2178 * Parameter 1 is an HWND, you're on your own for the rest.
2179 */
2180
2181BOOL WINAPI comctl32_411( HWND hw, DWORD b, DWORD c)
2182{
2183 dprintf(("COMCTL32: comctl32_411 - empty stub!"));
2184
2185 return TRUE;
2186}
2187
2188/**************************************************************************
2189 * comctl32_412 [COMCTL32.412]
2190 *
2191 * FIXME: What's this supposed to do?
2192 * Parameter 1 is an HWND, you're on your own for the rest.
2193 */
2194
2195BOOL WINAPI comctl32_412( HWND hwnd, DWORD b, DWORD c)
2196{
2197 dprintf(("COMCTL32: comctl32_412 - empty stub!"));
2198
2199 if (IsWindow (hwnd) == FALSE)
2200 return FALSE;
2201
2202 if (b == 0)
2203 return FALSE;
2204
2205
2206 return TRUE;
2207}
2208
2209/**************************************************************************
2210 * comctl32_413 [COMCTL32.413]
2211 *
2212 * FIXME: What's this supposed to do?
2213 * Parameter 1 is an HWND, you're on your own for the rest.
2214 */
2215
2216BOOL WINAPI comctl32_413( HWND hw, DWORD b, DWORD c, DWORD d)
2217{
2218 dprintf(("COMCTL32: comctl32_413 - empty stub!"));
2219
2220 return TRUE;
2221}
2222
2223/*************************************************************************
2224 * InitMUILanguage [COMCTL32.70]
2225 *
2226 * FIXME: What's this supposed to do? Apparently some i18n thing.
2227 *
2228 */
2229
2230BOOL WINAPI InitMUILanguage( LANGID uiLang)
2231{
2232 dprintf(("COMCTL32: InitMUILanguage - empty stub!"));
2233
2234 return TRUE;
2235}
Note: See TracBrowser for help on using the repository browser.