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

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

merged with latest WINE changes

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