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

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

* empty log message *

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