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

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

wine-990731 update

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