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

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

wine-990704 updates, TBCUSTOMIZE implemented

File size: 43.7 KB
Line 
1/* $Id: comctl32undoc.c,v 1.8 1999-07-12 15:58:46 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 = 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 = MIN(hdpa->nGrow * 2, hdpa->nItemCount);
1253 nSize = nNewItems * sizeof(LPVOID);
1254 lpDest = (LPVOID)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1255 hdpa->ptrs, nSize);
1256 if (!lpDest)
1257 return NULL;
1258
1259 hdpa->nMaxCount = nNewItems;
1260 hdpa->ptrs = (LPVOID*)lpDest;
1261 }
1262
1263 return lpTemp;
1264}
1265
1266
1267/**************************************************************************
1268 * DPA_DeleteAllPtrs [COMCTL32.337]
1269 *
1270 * Removes all pointers and reinitializes the array.
1271 *
1272 * PARAMS
1273 * hdpa [I] handle (pointer) to the pointer array
1274 *
1275 * RETURNS
1276 * Success: TRUE
1277 * Failure: FALSE
1278 */
1279
1280BOOL WINAPI
1281DPA_DeleteAllPtrs (const HDPA hdpa)
1282{
1283// TRACE (commctrl, "(%p)\n", hdpa);
1284
1285 if (!hdpa)
1286 return FALSE;
1287
1288 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
1289 return FALSE;
1290
1291 hdpa->nItemCount = 0;
1292 hdpa->nMaxCount = hdpa->nGrow * 2;
1293 hdpa->ptrs = (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1294 hdpa->nMaxCount * sizeof(LPVOID));
1295
1296 return TRUE;
1297}
1298
1299
1300/**************************************************************************
1301 * DPA_QuickSort [Internal]
1302 *
1303 * Ordinary quicksort (used by DPA_Sort).
1304 *
1305 * PARAMS
1306 * lpPtrs [I] pointer to the pointer array
1307 * l [I] index of the "left border" of the partition
1308 * r [I] index of the "right border" of the partition
1309 * pfnCompare [I] pointer to the compare function
1310 * lParam [I] user defined value (3rd parameter in compare function)
1311 *
1312 * RETURNS
1313 * NONE
1314 */
1315
1316static VOID
1317DPA_QuickSort (LPVOID *lpPtrs, INT l, INT r,
1318 PFNDPACOMPARE pfnCompare, LPARAM lParam)
1319{
1320 LPVOID t, v;
1321 INT i, j;
1322
1323// TRACE (commctrl, "l=%i r=%i\n", l, r);
1324
1325 i = l;
1326 j = r;
1327 v = lpPtrs[(int)(l+r)/2];
1328 do {
1329 while ((pfnCompare)(lpPtrs[i], v, lParam) > 0) i++;
1330 while ((pfnCompare)(lpPtrs[j], v, lParam) < 0) j--;
1331 if (i <= j)
1332 {
1333 t = lpPtrs[i];
1334 lpPtrs[i++] = lpPtrs[j];
1335 lpPtrs[j--] = t;
1336 }
1337 } while (i <= j);
1338 if (l < j) DPA_QuickSort (lpPtrs, l, j, pfnCompare, lParam);
1339 if (i < r) DPA_QuickSort (lpPtrs, i, r, pfnCompare, lParam);
1340}
1341
1342
1343/**************************************************************************
1344 * DPA_Sort [COMCTL32.338]
1345 *
1346 * Sorts a pointer array using a user defined compare function
1347 *
1348 * PARAMS
1349 * hdpa [I] handle (pointer) to the pointer array
1350 * pfnCompare [I] pointer to the compare function
1351 * lParam [I] user defined value (3rd parameter of compare function)
1352 *
1353 * RETURNS
1354 * Success: TRUE
1355 * Failure: FALSE
1356 */
1357
1358BOOL WINAPI
1359DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
1360{
1361 if (!hdpa || !pfnCompare)
1362 return FALSE;
1363
1364// TRACE (commctrl, "(%p %p 0x%lx)\n", hdpa, pfnCompare, lParam);
1365
1366 if ((hdpa->nItemCount > 1) && (hdpa->ptrs))
1367 DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1,
1368 pfnCompare, lParam);
1369
1370 return TRUE;
1371}
1372
1373
1374/**************************************************************************
1375 * DPA_Search [COMCTL32.339]
1376 *
1377 * Searches a pointer array for a specified pointer
1378 *
1379 * PARAMS
1380 * hdpa [I] handle (pointer) to the pointer array
1381 * pFind [I] pointer to search for
1382 * nStart [I] start index
1383 * pfnCompare [I] pointer to the compare function
1384 * lParam [I] user defined value (3rd parameter of compare function)
1385 * uOptions [I] search options
1386 *
1387 * RETURNS
1388 * Success: index of the pointer in the array.
1389 * Failure: -1
1390 *
1391 * NOTES
1392 * Binary search taken from R.Sedgewick "Algorithms in C"!
1393 * Function is NOT tested!
1394 * If something goes wrong, blame HIM not ME! (Eric Kohl)
1395 */
1396
1397INT WINAPI
1398DPA_Search (const HDPA hdpa, LPVOID pFind, INT nStart,
1399 PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT uOptions)
1400{
1401 if (!hdpa || !pfnCompare || !pFind)
1402 return -1;
1403
1404// TRACE (commctrl, "(%p %p %d %p 0x%08lx 0x%08x)\n",
1405// hdpa, pFind, nStart, pfnCompare, lParam, uOptions);
1406
1407 if (uOptions & DPAS_SORTED) {
1408 /* array is sorted --> use binary search */
1409 INT l, r, x, n;
1410 LPVOID *lpPtr;
1411
1412// TRACE (commctrl, "binary search\n");
1413
1414 l = (nStart == -1) ? 0 : nStart;
1415 r = hdpa->nItemCount - 1;
1416 lpPtr = hdpa->ptrs;
1417 while (r >= l) {
1418 x = (l + r) / 2;
1419 n = (pfnCompare)(pFind, lpPtr[x], lParam);
1420 if (n < 0)
1421 r = x - 1;
1422 else
1423 l = x + 1;
1424 if (n == 0) {
1425// TRACE (commctrl, "-- ret=%d\n", n);
1426 return n;
1427 }
1428 }
1429
1430 if (uOptions & DPAS_INSERTBEFORE) {
1431// TRACE (commctrl, "-- ret=%d\n", r);
1432 return r;
1433 }
1434
1435 if (uOptions & DPAS_INSERTAFTER) {
1436// TRACE (commctrl, "-- ret=%d\n", l);
1437 return l;
1438 }
1439 }
1440 else {
1441 /* array is not sorted --> use linear search */
1442 LPVOID *lpPtr;
1443 INT nIndex;
1444
1445// TRACE (commctrl, "linear search\n");
1446
1447 nIndex = (nStart == -1)? 0 : nStart;
1448 lpPtr = hdpa->ptrs;
1449 for (; nIndex < hdpa->nItemCount; nIndex++) {
1450 if ((pfnCompare)(pFind, lpPtr[nIndex], lParam) == 0) {
1451// TRACE (commctrl, "-- ret=%d\n", nIndex);
1452 return nIndex;
1453 }
1454 }
1455 }
1456
1457// TRACE (commctrl, "-- not found: ret=-1\n");
1458 return -1;
1459}
1460
1461
1462/**************************************************************************
1463 * DPA_CreateEx [COMCTL32.340]
1464 *
1465 * Creates a dynamic pointer array using the specified size and heap.
1466 *
1467 * PARAMS
1468 * nGrow [I] number of items by which the array grows when it is filled
1469 * hHeap [I] handle to the heap where the array is stored
1470 *
1471 * RETURNS
1472 * Success: handle (pointer) to the pointer array.
1473 * Failure: NULL
1474 */
1475
1476HDPA WINAPI
1477DPA_CreateEx (INT nGrow, HANDLE hHeap)
1478{
1479 HDPA hdpa;
1480
1481// TRACE (commctrl, "(%d 0x%x)\n", nGrow, hHeap);
1482
1483 if (hHeap)
1484 hdpa = (HDPA)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, sizeof(DPA));
1485 else
1486 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
1487
1488 if (hdpa) {
1489 hdpa->nGrow = MIN(8, nGrow);
1490 hdpa->hHeap = hHeap ? hHeap : COMCTL32_hHeap;
1491 hdpa->nMaxCount = hdpa->nGrow * 2;
1492 hdpa->ptrs =
1493 (LPVOID*)HeapAlloc (hHeap, HEAP_ZERO_MEMORY,
1494 hdpa->nMaxCount * sizeof(LPVOID));
1495 }
1496
1497// TRACE (commctrl, "-- %p\n", hdpa);
1498
1499 return hdpa;
1500}
1501
1502/**************************************************************************
1503 * Notification functions
1504 */
1505
1506typedef struct tagNOTIFYDATA
1507{
1508 HWND hwndFrom;
1509 HWND hwndTo;
1510 DWORD dwParam3;
1511 DWORD dwParam4;
1512 DWORD dwParam5;
1513 DWORD dwParam6;
1514} NOTIFYDATA, *LPNOTIFYDATA;
1515
1516
1517/**************************************************************************
1518 * DoNotify [Internal]
1519 */
1520
1521static LRESULT
1522DoNotify (LPNOTIFYDATA lpNotify, UINT uCode, LPNMHDR lpHdr)
1523{
1524 NMHDR nmhdr;
1525 LPNMHDR lpNmh = NULL;
1526 UINT idFrom = 0;
1527
1528// TRACE (commctrl, "(0x%04x 0x%04x %d %p 0x%08lx)\n",
1529// lpNotify->hwndFrom, lpNotify->hwndTo, uCode, lpHdr,
1530// lpNotify->dwParam5);
1531
1532 if (!lpNotify->hwndTo)
1533 return 0;
1534
1535 if (lpNotify->hwndFrom == -1) {
1536 lpNmh = lpHdr;
1537 idFrom = lpHdr->idFrom;
1538 }
1539 else {
1540 if (lpNotify->hwndFrom) {
1541 HWND hwndParent = GetParent (lpNotify->hwndFrom);
1542 if (hwndParent) {
1543 hwndParent = GetWindow (lpNotify->hwndFrom, GW_OWNER);
1544 if (hwndParent)
1545 idFrom = GetDlgCtrlID (lpNotify->hwndFrom);
1546 }
1547 }
1548
1549 lpNmh = (lpHdr) ? lpHdr : &nmhdr;
1550
1551 lpNmh->hwndFrom = lpNotify->hwndFrom;
1552 lpNmh->idFrom = idFrom;
1553 lpNmh->code = uCode;
1554 }
1555
1556 return SendMessageA (lpNotify->hwndTo, WM_NOTIFY, idFrom, (LPARAM)lpNmh);
1557}
1558
1559
1560/**************************************************************************
1561 * SendNotify [COMCTL32.341]
1562 *
1563 * PARAMS
1564 * hwndFrom [I]
1565 * hwndTo [I]
1566 * uCode [I]
1567 * lpHdr [I]
1568 *
1569 * RETURNS
1570 * Success: return value from notification
1571 * Failure: 0
1572 */
1573
1574LRESULT WINAPI
1575COMCTL32_SendNotify (HWND hwndFrom, HWND hwndTo,
1576 UINT uCode, LPNMHDR lpHdr)
1577{
1578 NOTIFYDATA notify;
1579
1580// TRACE (commctrl, "(0x%04x 0x%04x %d %p)\n",
1581// hwndFrom, hwndTo, uCode, lpHdr);
1582
1583 notify.hwndFrom = hwndFrom;
1584 notify.hwndTo = hwndTo;
1585 notify.dwParam5 = 0;
1586 notify.dwParam6 = 0;
1587
1588 return DoNotify (&notify, uCode, lpHdr);
1589}
1590
1591
1592/**************************************************************************
1593 * SendNotifyEx [COMCTL32.342]
1594 *
1595 * PARAMS
1596 * hwndFrom [I]
1597 * hwndTo [I]
1598 * uCode [I]
1599 * lpHdr [I]
1600 * dwParam5 [I]
1601 *
1602 * RETURNS
1603 * Success: return value from notification
1604 * Failure: 0
1605 */
1606
1607LRESULT WINAPI
1608COMCTL32_SendNotifyEx (HWND hwndTo, HWND hwndFrom, UINT uCode,
1609 LPNMHDR lpHdr, DWORD dwParam5)
1610{
1611 NOTIFYDATA notify;
1612 HWND hwndNotify;
1613
1614// TRACE (commctrl, "(0x%04x 0x%04x %d %p 0x%08lx)\n",
1615// hwndFrom, hwndTo, uCode, lpHdr, dwParam5);
1616
1617 hwndNotify = hwndTo;
1618 if (!hwndTo) {
1619 if (IsWindow (hwndFrom)) {
1620 hwndNotify = GetParent (hwndFrom);
1621 if (!hwndNotify)
1622 return 0;
1623 }
1624 }
1625
1626 notify.hwndFrom = hwndFrom;
1627 notify.hwndTo = hwndNotify;
1628 notify.dwParam5 = dwParam5;
1629 notify.dwParam6 = 0;
1630
1631 return DoNotify (&notify, uCode, lpHdr);
1632}
1633
1634
1635/**************************************************************************
1636 * StrChrA [COMCTL32.350]
1637 *
1638 */
1639
1640LPSTR WINAPI
1641COMCTL32_StrChrA (LPCSTR lpString, CHAR cChar)
1642{
1643 return strchr (lpString, cChar);
1644}
1645
1646
1647/**************************************************************************
1648 * StrStrIA [COMCTL32.355]
1649 */
1650
1651LPSTR WINAPI
1652COMCTL32_StrStrIA (LPCSTR lpStr1, LPCSTR lpStr2)
1653{
1654 INT len1, len2, i;
1655 CHAR first;
1656
1657 if (*lpStr2 == 0)
1658 return ((LPSTR)lpStr1);
1659 len1 = 0;
1660 while (lpStr1[len1] != 0) ++len1;
1661 len2 = 0;
1662 while (lpStr2[len2] != 0) ++len2;
1663 if (len2 == 0)
1664 return ((LPSTR)(lpStr1 + len1));
1665 first = tolower (*lpStr2);
1666 while (len1 >= len2) {
1667 if (tolower(*lpStr1) == first) {
1668 for (i = 1; i < len2; ++i)
1669 if (tolower (lpStr1[i]) != tolower(lpStr2[i]))
1670 break;
1671 if (i >= len2)
1672 return ((LPSTR)lpStr1);
1673 }
1674 ++lpStr1; --len1;
1675 }
1676 return (NULL);
1677}
1678
1679
1680/**************************************************************************
1681 * StrToIntA [COMCTL32.357] Converts a string to a signed integer.
1682 */
1683
1684INT WINAPI
1685COMCTL32_StrToIntA (LPSTR lpString)
1686{
1687 return atoi(lpString);
1688}
1689
1690/**************************************************************************
1691 * DPA_EnumCallback [COMCTL32.385]
1692 *
1693 * Enumerates all items in a dynamic pointer array.
1694 *
1695 * PARAMS
1696 * hdpa [I] handle to the dynamic pointer array
1697 * enumProc [I]
1698 * lParam [I]
1699 *
1700 * RETURNS
1701 * none
1702 */
1703
1704
1705VOID WINAPI
1706DPA_EnumCallback (const HDPA hdpa, DPAENUMPROC enumProc, LPARAM lParam)
1707{
1708 INT i;
1709
1710// TRACE (commctrl, "(%p %p %08lx)\n", hdpa, enumProc, lParam);
1711
1712 if (!hdpa)
1713 return;
1714 if (hdpa->nItemCount <= 0)
1715 return;
1716
1717 for (i = 0; i < hdpa->nItemCount; i++) {
1718 if ((enumProc)(hdpa->ptrs[i], lParam) == 0)
1719 return;
1720 }
1721
1722 return;
1723}
1724
1725
1726/**************************************************************************
1727 * DPA_DestroyCallback [COMCTL32.386]
1728 *
1729 * Enumerates all items in a dynamic pointer array and destroys it.
1730 *
1731 * PARAMS
1732 * hdpa [I] handle to the dynamic pointer array
1733 * enumProc [I]
1734 * lParam [I]
1735 *
1736 * RETURNS
1737 * Success: TRUE
1738 * Failure: FALSE
1739 */
1740
1741BOOL WINAPI
1742DPA_DestroyCallback (const HDPA hdpa, DPAENUMPROC enumProc, LPARAM lParam)
1743{
1744// TRACE (commctrl, "(%p %p %08lx)\n", hdpa, enumProc, lParam);
1745
1746 DPA_EnumCallback (hdpa, enumProc, lParam);
1747
1748 return DPA_Destroy (hdpa);
1749}
1750
1751
1752/**************************************************************************
1753 * DSA_EnumCallback [COMCTL32.387]
1754 *
1755 * Enumerates all items in a dynamic storage array.
1756 *
1757 * PARAMS
1758 * hdsa [I] handle to the dynamic storage array
1759 * enumProc [I]
1760 * lParam [I]
1761 *
1762 * RETURNS
1763 * none
1764 */
1765
1766VOID WINAPI
1767DSA_EnumCallback (const HDSA hdsa, DSAENUMPROC enumProc, LPARAM lParam)
1768{
1769 INT i;
1770
1771// TRACE (commctrl, "(%p %p %08lx)\n", hdsa, enumProc, lParam);
1772
1773 if (!hdsa)
1774 return;
1775 if (hdsa->nItemCount <= 0)
1776 return;
1777
1778 for (i = 0; i < hdsa->nItemCount; i++) {
1779 LPVOID lpItem = DSA_GetItemPtr (hdsa, i);
1780 if ((enumProc)(lpItem, lParam) == 0)
1781 return;
1782 }
1783
1784 return;
1785}
1786
1787
1788/**************************************************************************
1789 * DSA_DestroyCallback [COMCTL32.388]
1790 *
1791 * Enumerates all items in a dynamic storage array and destroys it.
1792 *
1793 * PARAMS
1794 * hdsa [I] handle to the dynamic storage array
1795 * enumProc [I]
1796 * lParam [I]
1797 *
1798 * RETURNS
1799 * Success: TRUE
1800 * Failure: FALSE
1801 */
1802
1803BOOL WINAPI
1804DSA_DestroyCallback (const HDSA hdsa, DSAENUMPROC enumProc, LPARAM lParam)
1805{
1806// TRACE (commctrl, "(%p %p %08lx)\n", hdsa, enumProc, lParam);
1807
1808 DSA_EnumCallback (hdsa, enumProc, lParam);
1809
1810 return DSA_Destroy (hdsa);
1811}
1812
1813/**************************************************************************
1814 * StrCSpnA [COMCTL32.356]
1815 *
1816 */
1817INT WINAPI COMCTL32_StrCSpnA( LPCSTR lpStr, LPCSTR lpSet) {
1818 return strcspn(lpStr, lpSet);
1819}
1820
1821/**************************************************************************
1822 * StrChrW [COMCTL32.358]
1823 *
1824 */
1825LPWSTR WINAPI COMCTL32_StrChrW( LPCWSTR lpStart, WORD wMatch) {
1826// return CRTDLL_wcschr(lpStart, wMatch);
1827}
1828
1829/**************************************************************************
1830 * StrCmpNA [COMCTL32.352]
1831 *
1832 */
1833INT WINAPI COMCTL32_StrCmpNA( LPCSTR lpStr1, LPCSTR lpStr2, int nChar) {
1834// return lstrncmpA(lpStr1, lpStr2, nChar);
1835}
1836
1837/**************************************************************************
1838 * StrCmpNW [COMCTL32.360]
1839 *
1840 */
1841INT WINAPI COMCTL32_StrCmpNW( LPCWSTR lpStr1, LPCWSTR lpStr2, int nChar) {
1842// return lstrncmpW(lpStr1, lpStr2, nChar);
1843}
1844
1845/**************************************************************************
1846 * StrRChrA [COMCTL32.351]
1847 *
1848 */
1849LPSTR WINAPI COMCTL32_StrRChrA( LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch) {
1850// return lstrrchr(lpStart, lpEnd, wMatch);
1851}
1852
1853/**************************************************************************
1854 * StrRChrW [COMCTL32.359]
1855 *
1856 */
1857LPWSTR WINAPI COMCTL32_StrRChrW( LPCWSTR lpStart, LPCWSTR lpEnd, WORD wMatch) {
1858// return lstrrchrw(lpStart, lpEnd, wMatch);
1859}
1860
1861/**************************************************************************
1862 * StrStrA [COMCTL32.354]
1863 *
1864 */
1865LPSTR WINAPI COMCTL32_StrStrA( LPCSTR lpFirst, LPCSTR lpSrch) {
1866 return strstr(lpFirst, lpSrch);
1867}
1868
1869/**************************************************************************
1870 * StrStrW [COMCTL32.362]
1871 *
1872 */
1873LPWSTR WINAPI COMCTL32_StrStrW( LPCWSTR lpFirst, LPCWSTR lpSrch) {
1874// return strstrw(lpFirst, lpSrch);
1875}
1876
1877/**************************************************************************
1878 * StrSpnW [COMCTL32.364]
1879 *
1880 */
1881INT WINAPI COMCTL32_StrSpnW( LPWSTR lpStr, LPWSTR lpSet) {
1882 LPWSTR lpLoop = lpStr;
1883
1884 /* validate ptr */
1885 if ((lpStr == 0) || (lpSet == 0)) return 0;
1886
1887/* while(*lpLoop) { if lpLoop++; } */
1888
1889// for(; (*lpLoop != 0); lpLoop++)
1890// if( CRTDLL_wcschr(lpSet, *(WORD*)lpLoop))
1891// return (INT)(lpLoop-lpStr);
1892
1893// return (INT)(lpLoop-lpStr);
1894}
Note: See TracBrowser for help on using the repository browser.