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

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

DPA_Delete* fix

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