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

Last change on this file since 6644 was 6644, checked in by bird, 24 years ago

Added $Id:$ keyword.

File size: 56.7 KB
Line 
1/* $Id: comctl32undoc.c,v 1.22 2001-09-05 12:04:57 bird Exp $ */
2/*
3 * Undocumented functions from COMCTL32.DLL
4 *
5 * Copyright 1998 Eric Kohl
6 * 1998 Juergen Schmied <j.schmied@metronet.de>
7 * 2000 Eric Kohl for CodeWeavers
8 *
9 * NOTES
10 * All of these functions are UNDOCUMENTED!! And I mean UNDOCUMENTED!!!!
11 * Do NOT rely on names or contents of undocumented structures and types!!!
12 * These functions are used by EXPLORER.EXE, IEXPLORE.EXE and
13 * COMCTL32.DLL (internally).
14 *
15 * TODO
16 * - Add more functions.
17 * - Write some documentation.
18 */
19#ifdef __WIN32OS2__
20#define WINE_LARGE_INTEGER
21#endif
22#include <string.h>
23#include <stdlib.h> /* atoi */
24#include <ctype.h>
25
26#include "commctrl.h"
27#include "objbase.h"
28#include "winbase.h"
29#include "winerror.h"
30
31#include "wine/unicode.h"
32#include "comctl32.h"
33
34#include "debugtools.h"
35
36DEFAULT_DEBUG_CHANNEL(commctrl);
37
38
39#ifdef __WIN32OS2__
40#undef FIXME
41//#undef TRACE
42#ifdef DEBUG
43#define FIXME WriteLog("FIXME COMCTL32: %s", __FUNCTION__); WriteLog
44#else
45#define FIXME 1 ? (void)0 : (void)((int (*)(char *, ...)) NULL)
46#endif
47#endif
48
49extern HANDLE COMCTL32_hHeap; /* handle to the private heap */
50
51
52typedef struct _STREAMDATA
53{
54 DWORD dwSize;
55 DWORD dwData2;
56 DWORD dwItems;
57} STREAMDATA, *PSTREAMDATA;
58
59typedef struct _LOADDATA
60{
61 INT nCount;
62 PVOID ptr;
63} LOADDATA, *LPLOADDATA;
64
65#ifdef __WIN32OS2__
66typedef HRESULT (* CALLBACK DPALOADPROC)(LPLOADDATA,IStream*,LPARAM);
67#else
68typedef HRESULT CALLBACK (*DPALOADPROC)(LPLOADDATA,IStream*,LPARAM);
69#endif
70
71INT __cdecl _wtoi(LPWSTR string);
72
73/**************************************************************************
74 * DPA_LoadStream [COMCTL32.9]
75 *
76 * Loads a dynamic pointer array from a stream
77 *
78 * PARAMS
79 * phDpa [O] pointer to a handle to a dynamic pointer array
80 * loadProc [I] pointer to a callback function
81 * pStream [I] pointer to a stream
82 * lParam [I] application specific value
83 *
84 * NOTES
85 * No more information available yet!
86 */
87
88HRESULT WINAPI
89DPA_LoadStream (HDPA *phDpa, DPALOADPROC loadProc, IStream *pStream, LPARAM lParam)
90{
91 HRESULT errCode;
92 LARGE_INTEGER position;
93 ULARGE_INTEGER newPosition;
94 STREAMDATA streamData;
95 LOADDATA loadData;
96 ULONG ulRead;
97 HDPA hDpa;
98 PVOID *ptr;
99
100 FIXME ("phDpa=%p loadProc=%p pStream=%p lParam=%lx\n",
101 phDpa, loadProc, pStream, lParam);
102
103 if (!phDpa || !loadProc || !pStream)
104 return E_INVALIDARG;
105
106 *phDpa = (HDPA)NULL;
107
108 position.s.LowPart = 0;
109 position.s.HighPart = 0;
110
111 errCode = IStream_Seek (pStream, position, STREAM_SEEK_CUR, &newPosition);
112 if (errCode != S_OK)
113 return errCode;
114
115 errCode = IStream_Read (pStream, &streamData, sizeof(STREAMDATA), &ulRead);
116 if (errCode != S_OK)
117 return errCode;
118
119 FIXME ("dwSize=%lu dwData2=%lu dwItems=%lu\n",
120 streamData.dwSize, streamData.dwData2, streamData.dwItems);
121
122 if (lParam < sizeof(STREAMDATA) ||
123 streamData.dwSize < sizeof(STREAMDATA) ||
124 streamData.dwData2 < 1) {
125 errCode = E_FAIL;
126 }
127
128 /* create the dpa */
129 hDpa = DPA_Create (streamData.dwItems);
130 if (!hDpa)
131 return E_OUTOFMEMORY;
132
133 if (!DPA_Grow (hDpa, streamData.dwItems))
134 return E_OUTOFMEMORY;
135
136 /* load data from the stream into the dpa */
137 ptr = hDpa->ptrs;
138 for (loadData.nCount = 0; loadData.nCount < streamData.dwItems; loadData.nCount++) {
139 errCode = (loadProc)(&loadData, pStream, lParam);
140 if (errCode != S_OK) {
141 errCode = S_FALSE;
142 break;
143 }
144
145 *ptr = loadData.ptr;
146 ptr++;
147 }
148
149 /* set the number of items */
150 hDpa->nItemCount = loadData.nCount;
151
152 /* store the handle to the dpa */
153 *phDpa = hDpa;
154 FIXME ("new hDpa=%p\n", hDpa);
155
156 return errCode;
157}
158
159
160/**************************************************************************
161 * DPA_SaveStream [COMCTL32.10]
162 *
163 * Saves a dynamic pointer array to a stream
164 *
165 * PARAMS
166 * hDpa [I] handle to a dynamic pointer array
167 * loadProc [I] pointer to a callback function
168 * pStream [I] pointer to a stream
169 * lParam [I] application specific value
170 *
171 * NOTES
172 * No more information available yet!
173 */
174
175HRESULT WINAPI
176DPA_SaveStream (const HDPA hDpa, DPALOADPROC loadProc, IStream *pStream, LPARAM lParam)
177{
178
179 FIXME ("hDpa=%p loadProc=%p pStream=%p lParam=%lx\n",
180 hDpa, loadProc, pStream, lParam);
181
182 return E_FAIL;
183}
184
185
186/**************************************************************************
187 * DPA_Merge [COMCTL32.11]
188 *
189 * PARAMS
190 * hdpa1 [I] handle to a dynamic pointer array
191 * hdpa2 [I] handle to a dynamic pointer array
192 * dwFlags [I] flags
193 * pfnCompare [I] pointer to sort function
194 * pfnMerge [I] pointer to merge function
195 * lParam [I] application specific value
196 *
197 * NOTES
198 * No more information available yet!
199 */
200
201BOOL WINAPI
202DPA_Merge (const HDPA hdpa1, const HDPA hdpa2, DWORD dwFlags,
203 PFNDPACOMPARE pfnCompare, PFNDPAMERGE pfnMerge, LPARAM lParam)
204{
205 INT nCount;
206 LPVOID *pWork1, *pWork2;
207 INT nResult;
208 INT nIndex;
209
210 TRACE("%p %p %08lx %p %p %08lx)\n",
211 hdpa1, hdpa2, dwFlags, pfnCompare, pfnMerge, lParam);
212
213 if (IsBadWritePtr (hdpa1, sizeof(DPA)))
214 return FALSE;
215
216 if (IsBadWritePtr (hdpa2, sizeof(DPA)))
217 return FALSE;
218
219 if (IsBadCodePtr ((FARPROC)pfnCompare))
220 return FALSE;
221
222 if (IsBadCodePtr ((FARPROC)pfnMerge))
223 return FALSE;
224
225 if (dwFlags & DPAM_SORT) {
226 TRACE("sorting dpa's!\n");
227 if (hdpa1->nItemCount > 0)
228 DPA_Sort (hdpa1, pfnCompare, lParam);
229 TRACE ("dpa 1 sorted!\n");
230 if (hdpa2->nItemCount > 0)
231 DPA_Sort (hdpa2, pfnCompare, lParam);
232 TRACE ("dpa 2 sorted!\n");
233 }
234
235 if (hdpa2->nItemCount < 1)
236 return TRUE;
237
238 TRACE("hdpa1->nItemCount=%d hdpa2->nItemCount=%d\n",
239 hdpa1->nItemCount, hdpa2->nItemCount);
240
241
242 /* working but untrusted implementation */
243
244 pWork1 = &(hdpa1->ptrs[hdpa1->nItemCount - 1]);
245 pWork2 = &(hdpa2->ptrs[hdpa2->nItemCount - 1]);
246
247 nIndex = hdpa1->nItemCount - 1;
248 nCount = hdpa2->nItemCount - 1;
249
250 do
251 {
252 if (nIndex < 0) break;
253 nResult = (pfnCompare)(*pWork1, *pWork2, lParam);
254 TRACE("compare result=%d, dpa1.cnt=%d, dpa2.cnt=%d\n",
255 nResult, nIndex, nCount);
256
257 if (nResult == 0)
258 {
259 PVOID ptr;
260
261 ptr = (pfnMerge)(1, *pWork1, *pWork2, lParam);
262 if (!ptr)
263 return FALSE;
264
265 nCount--;
266 pWork2--;
267 *pWork1 = ptr;
268 nIndex--;
269 pWork1--;
270 }
271 else if (nResult < 0)
272 {
273 if (!dwFlags & 8)
274 {
275 PVOID ptr;
276
277 ptr = DPA_DeletePtr (hdpa1, hdpa1->nItemCount - 1);
278
279 (pfnMerge)(2, ptr, NULL, lParam);
280 }
281 nIndex--;
282 pWork1--;
283 }
284 else
285 {
286 if (!dwFlags & 4)
287 {
288 PVOID ptr;
289
290 ptr = (pfnMerge)(3, *pWork2, NULL, lParam);
291 if (!ptr)
292 return FALSE;
293 DPA_InsertPtr (hdpa1, nIndex, ptr);
294 }
295 nCount--;
296 pWork2--;
297 }
298
299 }
300 while (nCount >= 0);
301
302 return TRUE;
303}
304
305
306/**************************************************************************
307 * Alloc [COMCTL32.71]
308 *
309 * Allocates memory block from the dll's private heap
310 *
311 * PARAMS
312 * dwSize [I] size of the allocated memory block
313 *
314 * RETURNS
315 * Success: pointer to allocated memory block
316 * Failure: NULL
317 */
318
319LPVOID WINAPI
320COMCTL32_Alloc (DWORD dwSize)
321{
322 LPVOID lpPtr;
323
324 TRACE("(0x%lx)\n", dwSize);
325
326 lpPtr = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
327
328 TRACE("-- ret=%p\n", lpPtr);
329
330 return lpPtr;
331}
332
333
334/**************************************************************************
335 * ReAlloc [COMCTL32.72]
336 *
337 * Changes the size of an allocated memory block or allocates a memory
338 * block using the dll's private heap.
339 *
340 * PARAMS
341 * lpSrc [I] pointer to memory block which will be resized
342 * dwSize [I] new size of the memory block.
343 *
344 * RETURNS
345 * Success: pointer to the resized memory block
346 * Failure: NULL
347 *
348 * NOTES
349 * If lpSrc is a NULL-pointer, then COMCTL32_ReAlloc allocates a memory
350 * block like COMCTL32_Alloc.
351 */
352
353LPVOID WINAPI
354COMCTL32_ReAlloc (LPVOID lpSrc, DWORD dwSize)
355{
356 LPVOID lpDest;
357
358 TRACE("(%p 0x%08lx)\n", lpSrc, dwSize);
359
360 if (lpSrc)
361 lpDest = HeapReAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, lpSrc, dwSize);
362 else
363 lpDest = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
364
365 TRACE("-- ret=%p\n", lpDest);
366
367 return lpDest;
368}
369
370
371/**************************************************************************
372 * Free [COMCTL32.73]
373 *
374 * Frees an allocated memory block from the dll's private heap.
375 *
376 * PARAMS
377 * lpMem [I] pointer to memory block which will be freed
378 *
379 * RETURNS
380 * Success: TRUE
381 * Failure: FALSE
382 */
383
384BOOL WINAPI
385COMCTL32_Free (LPVOID lpMem)
386{
387 TRACE("(%p)\n", lpMem);
388
389 return HeapFree (COMCTL32_hHeap, 0, lpMem);
390}
391
392
393/**************************************************************************
394 * GetSize [COMCTL32.74]
395 *
396 * Retrieves the size of the specified memory block from the dll's
397 * private heap.
398 *
399 * PARAMS
400 * lpMem [I] pointer to an allocated memory block
401 *
402 * RETURNS
403 * Success: size of the specified memory block
404 * Failure: 0
405 */
406
407DWORD WINAPI
408COMCTL32_GetSize (LPVOID lpMem)
409{
410 TRACE("(%p)\n", lpMem);
411
412 return HeapSize (COMCTL32_hHeap, 0, lpMem);
413}
414
415
416/**************************************************************************
417 * The MRU-API is a set of functions to manipulate MRU(Most Recently Used)
418 * lists.
419 *
420 * Stored in the reg. as a set of values under a single key. Each item in the
421 * list has a value name that is a single char. 'a' - 'z', '{', '|' or '}'.
422 * The order of the list is stored with value name 'MRUList' which is a string
423 * containing the value names (i.e. 'a', 'b', etc.) in the relevant order.
424 */
425
426typedef struct tagCREATEMRULIST
427{
428 DWORD cbSize; /* size of struct */
429 DWORD nMaxItems; /* max no. of items in list */
430 DWORD dwFlags; /* see below */
431 HKEY hKey; /* root reg. key under which list is saved */
432 LPCSTR lpszSubKey; /* reg. subkey */
433 PROC lpfnCompare; /* item compare proc */
434} CREATEMRULIST, *LPCREATEMRULIST;
435
436/* dwFlags */
437#define MRUF_STRING_LIST 0 /* list will contain strings */
438#define MRUF_BINARY_LIST 1 /* list will contain binary data */
439#define MRUF_DELAYED_SAVE 2 /* only save list order to reg. is FreeMRUList */
440
441/* If list is a string list lpfnCompare has the following prototype
442 * int CALLBACK MRUCompareString(LPCSTR s1, LPCSTR s2)
443 * for binary lists the prototype is
444 * int CALLBACK MRUCompareBinary(LPCVOID data1, LPCVOID data2, DWORD cbData)
445 * where cbData is the no. of bytes to compare.
446 * Need to check what return value means identical - 0?
447 */
448
449typedef struct tagMRU
450{
451 DWORD dwParam1; /* some kind of flag */
452 DWORD dwParam2;
453 DWORD dwParam3;
454 HKEY hkeyMRU;
455 LPCSTR lpszSubKey;
456 DWORD dwParam6;
457} MRU, *HMRU;
458
459HANDLE WINAPI
460CreateMRUListLazyA (LPCREATEMRULIST lpcml, DWORD dwParam2,
461 DWORD dwParam3, DWORD dwParam4);
462
463
464/**************************************************************************
465 * CreateMRUListA [COMCTL32.151]
466 *
467 * PARAMS
468 * lpcml [I] ptr to CREATEMRULIST structure.
469 *
470 * RETURNS
471 * Handle to MRU list.
472 */
473HANDLE WINAPI
474CreateMRUListA (LPCREATEMRULIST lpcml)
475{
476 return CreateMRUListLazyA (lpcml, 0, 0, 0);
477}
478
479/**************************************************************************
480 * FreeMRUList [COMCTL32.152]
481 *
482 * PARAMS
483 * hMRUList [I] Handle to list.
484 *
485 */
486DWORD WINAPI
487FreeMRUListA (HANDLE hMRUList)
488{
489 FIXME("(%08x) empty stub!\n", hMRUList);
490
491#if 0
492 if (!(hmru->dwParam1 & 1001)) {
493 RegSetValueExA (hmru->hKeyMRU, "MRUList", 0, REG_SZ,
494 hmru->lpszMRUString,
495 strlen (hmru->lpszMRUString));
496 }
497
498
499 RegClosKey (hmru->hkeyMRU
500 COMCTL32_Free32 (hmru->lpszMRUString);
501#endif
502
503 return COMCTL32_Free ((LPVOID)hMRUList);
504}
505
506
507/**************************************************************************
508 * AddMRUData [COMCTL32.167]
509 *
510 * Add item to MRU binary list. If item already exists in list then it is
511 * simply moved up to the top of the list and not added again. If list is
512 * full then the least recently used item is removed to make room.
513 *
514 * PARAMS
515 * hList [I] Handle to list.
516 * lpData [I] ptr to data to add.
517 * cbData [I] no. of bytes of data.
518 *
519 * RETURNS
520 * No. corresponding to registry name where value is stored 'a' -> 0 etc.
521 * -1 on error.
522 */
523INT WINAPI
524AddMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData)
525{
526 FIXME("(%08x, %p, %ld) empty stub!\n", hList, lpData, cbData);
527
528 return 0;
529}
530
531/**************************************************************************
532 * AddMRUStringA [COMCTL32.153]
533 *
534 * Add item to MRU string list. If item already exists in list them it is
535 * simply moved up to the top of the list and not added again. If list is
536 * full then the least recently used item is removed to make room.
537 *
538 * PARAMS
539 * hList [I] Handle to list.
540 * lpszString [I] ptr to string to add.
541 *
542 * RETURNS
543 * No. corresponding to registry name where value is stored 'a' -> 0 etc.
544 * -1 on error.
545 */
546INT WINAPI
547AddMRUStringA(HANDLE hList, LPCSTR lpszString)
548{
549 FIXME("(%08x, %s) empty stub!\n", hList, debugstr_a(lpszString));
550
551 return 0;
552}
553
554/**************************************************************************
555 * DelMRUString [COMCTL32.156]
556 *
557 * Removes item from either string or binary list (despite its name)
558 *
559 * PARAMS
560 * hList [I] list handle
561 * nItemPos [I] item position to remove 0 -> MRU
562 *
563 * RETURNS
564 * TRUE if successful, FALSE if nItemPos is out of range.
565 */
566BOOL WINAPI
567DelMRUString(HANDLE hList, INT nItemPos)
568{
569 FIXME("(%08x, %d): stub\n", hList, nItemPos);
570 return TRUE;
571}
572
573/**************************************************************************
574 * FindMRUData [COMCTL32.169]
575 *
576 * Searches binary list for item that matches lpData of length cbData.
577 * Returns position in list order 0 -> MRU and if lpRegNum != NULL then value
578 * corresponding to item's reg. name will be stored in it ('a' -> 0).
579 *
580 * PARAMS
581 * hList [I] list handle
582 * lpData [I] data to find
583 * cbData [I] length of data
584 * lpRegNum [O] position in registry (maybe NULL)
585 *
586 * RETURNS
587 * Position in list 0 -> MRU. -1 if item not found.
588 */
589INT WINAPI
590FindMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum)
591{
592 FIXME("(%08x, %p, %ld, %p) empty stub!\n",
593 hList, lpData, cbData, lpRegNum);
594
595 return 0;
596}
597
598/**************************************************************************
599 * FindMRUStringA [COMCTL32.155]
600 *
601 * Searches string list for item that matches lpszString.
602 * Returns position in list order 0 -> MRU and if lpRegNum != NULL then value
603 * corresponding to item's reg. name will be stored in it ('a' -> 0).
604 *
605 * PARAMS
606 * hList [I] list handle
607 * lpszString [I] string to find
608 * lpRegNum [O] position in registry (maybe NULL)
609 *
610 * RETURNS
611 * Position in list 0 -> MRU. -1 if item not found.
612 */
613INT WINAPI
614FindMRUStringA (HANDLE hList, LPCSTR lpszString, LPINT lpRegNum)
615{
616 FIXME("(%08x, %s, %p) empty stub!\n", hList, debugstr_a(lpszString),
617 lpRegNum);
618
619 return 0;
620}
621
622/**************************************************************************
623 * CreateMRUListLazyA [COMCTL32.157]
624 */
625HANDLE WINAPI
626CreateMRUListLazyA (LPCREATEMRULIST lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
627{
628 /* DWORD dwLocal1; *
629 * HKEY hkeyResult; *
630 * DWORD dwLocal3; *
631 * LPVOID lMRU; *
632 * DWORD dwLocal5; *
633 * DWORD dwLocal6; *
634 * DWORD dwLocal7; *
635 * DWORD dwDisposition; */
636
637 /* internal variables */
638 LPVOID ptr;
639
640 FIXME("(%p) empty stub!\n", lpcml);
641
642 if (lpcml == NULL)
643 return 0;
644
645 if (lpcml->cbSize < sizeof(CREATEMRULIST))
646 return 0;
647
648 FIXME("(%lu %lu %lx %lx \"%s\" %p)\n",
649 lpcml->cbSize, lpcml->nMaxItems, lpcml->dwFlags,
650 (DWORD)lpcml->hKey, lpcml->lpszSubKey, lpcml->lpfnCompare);
651
652 /* dummy pointer creation */
653 ptr = COMCTL32_Alloc (32);
654
655 FIXME("-- ret = %p\n", ptr);
656
657 return (HANDLE)ptr;
658}
659
660/**************************************************************************
661 * EnumMRUListA [COMCTL32.154]
662 *
663 * Enumerate item in a list
664 *
665 * PARAMS
666 * hList [I] list handle
667 * nItemPos [I] item position to enumerate
668 * lpBuffer [O] buffer to receive item
669 * nBufferSize [I] size of buffer
670 *
671 * RETURNS
672 * For binary lists specifies how many bytes were copied to buffer, for
673 * string lists specifies full length of string. Enumerating past the end
674 * of list returns -1.
675 * If lpBuffer == NULL or nItemPos is -ve return value is no. of items in
676 * the list.
677 */
678INT WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer,
679DWORD nBufferSize)
680{
681 FIXME("(%08x, %d, %p, %ld): stub\n", hList, nItemPos, lpBuffer,
682 nBufferSize);
683 return 0;
684}
685
686/**************************************************************************
687 * Str_GetPtrA [COMCTL32.233]
688 *
689 * PARAMS
690 * lpSrc [I]
691 * lpDest [O]
692 * nMaxLen [I]
693 *
694 * RETURNS
695 */
696
697INT WINAPI
698Str_GetPtrA (LPCSTR lpSrc, LPSTR lpDest, INT nMaxLen)
699{
700 INT len;
701
702 TRACE("(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
703
704 if (!lpDest && lpSrc)
705 return strlen (lpSrc);
706
707 if (nMaxLen == 0)
708 return 0;
709
710 if (lpSrc == NULL) {
711 lpDest[0] = '\0';
712 return 0;
713 }
714
715 len = strlen (lpSrc);
716 if (len >= nMaxLen)
717 len = nMaxLen - 1;
718
719 RtlMoveMemory (lpDest, lpSrc, len);
720 lpDest[len] = '\0';
721
722 return len;
723}
724
725
726/**************************************************************************
727 * Str_SetPtrA [COMCTL32.234]
728 *
729 * PARAMS
730 * lppDest [O]
731 * lpSrc [I]
732 *
733 * RETURNS
734 */
735
736BOOL WINAPI
737Str_SetPtrA (LPSTR *lppDest, LPCSTR lpSrc)
738{
739 TRACE("(%p %p)\n", lppDest, lpSrc);
740
741 if (lpSrc) {
742 LPSTR ptr = COMCTL32_ReAlloc (*lppDest, strlen (lpSrc) + 1);
743 if (!ptr)
744 return FALSE;
745 strcpy (ptr, lpSrc);
746 *lppDest = ptr;
747 }
748 else {
749 if (*lppDest) {
750 COMCTL32_Free (*lppDest);
751 *lppDest = NULL;
752 }
753 }
754
755 return TRUE;
756}
757
758
759/**************************************************************************
760 * Str_GetPtrW [COMCTL32.235]
761 *
762 * PARAMS
763 * lpSrc [I]
764 * lpDest [O]
765 * nMaxLen [I]
766 *
767 * RETURNS
768 */
769
770INT WINAPI
771Str_GetPtrW (LPCWSTR lpSrc, LPWSTR lpDest, INT nMaxLen)
772{
773 INT len;
774
775 TRACE("(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
776
777 if (!lpDest && lpSrc)
778 return strlenW (lpSrc);
779
780 if (nMaxLen == 0)
781 return 0;
782
783 if (lpSrc == NULL) {
784 lpDest[0] = L'\0';
785 return 0;
786 }
787
788 len = strlenW (lpSrc);
789 if (len >= nMaxLen)
790 len = nMaxLen - 1;
791
792 RtlMoveMemory (lpDest, lpSrc, len*sizeof(WCHAR));
793 lpDest[len] = L'\0';
794
795 return len;
796}
797
798
799/**************************************************************************
800 * Str_SetPtrW [COMCTL32.236]
801 *
802 * PARAMS
803 * lpDest [O]
804 * lpSrc [I]
805 *
806 * RETURNS
807 */
808
809BOOL WINAPI
810Str_SetPtrW (LPWSTR *lppDest, LPCWSTR lpSrc)
811{
812 TRACE("(%p %p)\n", lppDest, lpSrc);
813
814 if (lpSrc) {
815 INT len = strlenW (lpSrc) + 1;
816 LPWSTR ptr = COMCTL32_ReAlloc (*lppDest, len * sizeof(WCHAR));
817 if (!ptr)
818 return FALSE;
819 strcpyW (ptr, lpSrc);
820 *lppDest = ptr;
821 }
822 else {
823 if (*lppDest) {
824 COMCTL32_Free (*lppDest);
825 *lppDest = NULL;
826 }
827 }
828
829 return TRUE;
830}
831
832
833/**************************************************************************
834 * Str_GetPtrWtoA [internal]
835 *
836 * Converts a unicode string into a multi byte string
837 *
838 * PARAMS
839 * lpSrc [I] Pointer to the unicode source string
840 * lpDest [O] Pointer to caller supplied storage for the multi byte string
841 * nMaxLen [I] Size, in bytes, of the destination buffer
842 *
843 * RETURNS
844 * Length, in bytes, of the converted string.
845 */
846
847INT
848Str_GetPtrWtoA (LPCWSTR lpSrc, LPSTR lpDest, INT nMaxLen)
849{
850 INT len;
851
852 TRACE("(%s %p %d)\n", debugstr_w(lpSrc), lpDest, nMaxLen);
853
854 if (!lpDest && lpSrc)
855 return WideCharToMultiByte(CP_ACP, 0, lpSrc, -1, 0, 0, NULL, NULL);
856
857 if (nMaxLen == 0)
858 return 0;
859
860 if (lpSrc == NULL) {
861 lpDest[0] = '\0';
862 return 0;
863 }
864
865 len = WideCharToMultiByte(CP_ACP, 0, lpSrc, -1, 0, 0, NULL, NULL);
866 if (len >= nMaxLen)
867 len = nMaxLen - 1;
868
869 WideCharToMultiByte(CP_ACP, 0, lpSrc, -1, lpDest, len, NULL, NULL);
870 lpDest[len] = '\0';
871
872 return len;
873}
874
875
876/**************************************************************************
877 * Str_SetPtrAtoW [internal]
878 *
879 * Converts a multi byte string to a unicode string.
880 * If the pointer to the destination buffer is NULL a buffer is allocated.
881 * If the destination buffer is too small to keep the converted multi byte
882 * string the destination buffer is reallocated. If the source pointer is
883 * NULL, the destination buffer is freed.
884 *
885 * PARAMS
886 * lppDest [I/O] pointer to a pointer to the destination buffer
887 * lpSrc [I] pointer to a multi byte string
888 *
889 * RETURNS
890 * TRUE: conversion successful
891 * FALSE: error
892 */
893
894BOOL
895Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc)
896{
897 TRACE("(%p %s)\n", lppDest, lpSrc);
898
899 if (lpSrc) {
900 INT len = MultiByteToWideChar(CP_ACP,0,lpSrc,-1,NULL,0);
901 LPWSTR ptr = COMCTL32_ReAlloc (*lppDest, len*sizeof(WCHAR));
902
903 if (!ptr)
904 return FALSE;
905 MultiByteToWideChar(CP_ACP,0,lpSrc,-1,ptr,len);
906 *lppDest = ptr;
907 }
908 else {
909 if (*lppDest) {
910 COMCTL32_Free (*lppDest);
911 *lppDest = NULL;
912 }
913 }
914
915 return TRUE;
916}
917
918
919/**************************************************************************
920 * The DSA-API is a set of functions to create and manipulate arrays of
921 * fixed-size memory blocks. These arrays can store any kind of data
922 * (strings, icons...).
923 */
924
925/**************************************************************************
926 * DSA_Create [COMCTL32.320] Creates a dynamic storage array
927 *
928 * PARAMS
929 * nSize [I] size of the array elements
930 * nGrow [I] number of elements by which the array grows when it is filled
931 *
932 * RETURNS
933 * Success: pointer to an array control structure. Use this like a handle.
934 * Failure: NULL
935 */
936
937HDSA WINAPI
938DSA_Create (INT nSize, INT nGrow)
939{
940 HDSA hdsa;
941
942 TRACE("(size=%d grow=%d)\n", nSize, nGrow);
943
944 hdsa = (HDSA)COMCTL32_Alloc (sizeof(DSA));
945 if (hdsa)
946 {
947 hdsa->nItemCount = 0;
948 hdsa->pData = NULL;
949 hdsa->nMaxCount = 0;
950 hdsa->nItemSize = nSize;
951 hdsa->nGrow = max(1, nGrow);
952 }
953
954 return hdsa;
955}
956
957
958/**************************************************************************
959 * DSA_Destroy [COMCTL32.321] Destroys a dynamic storage array
960 *
961 * PARAMS
962 * hdsa [I] pointer to the array control structure
963 *
964 * RETURNS
965 * Success: TRUE
966 * Failure: FALSE
967 */
968
969BOOL WINAPI
970DSA_Destroy (const HDSA hdsa)
971{
972 TRACE("(%p)\n", hdsa);
973
974 if (!hdsa)
975 return FALSE;
976
977 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
978 return FALSE;
979
980 return COMCTL32_Free (hdsa);
981}
982
983
984/**************************************************************************
985 * DSA_GetItem [COMCTL32.322]
986 *
987 * PARAMS
988 * hdsa [I] pointer to the array control structure
989 * nIndex [I] number of the Item to get
990 * pDest [O] destination buffer. Has to be >= dwElementSize.
991 *
992 * RETURNS
993 * Success: TRUE
994 * Failure: FALSE
995 */
996
997BOOL WINAPI
998DSA_GetItem (const HDSA hdsa, INT nIndex, LPVOID pDest)
999{
1000 LPVOID pSrc;
1001
1002 TRACE("(%p %d %p)\n", hdsa, nIndex, pDest);
1003
1004 if (!hdsa)
1005 return FALSE;
1006 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
1007 return FALSE;
1008
1009 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
1010 memmove (pDest, pSrc, hdsa->nItemSize);
1011
1012 return TRUE;
1013}
1014
1015
1016/**************************************************************************
1017 * DSA_GetItemPtr [COMCTL32.323]
1018 *
1019 * Retrieves a pointer to the specified item.
1020 *
1021 * PARAMS
1022 * hdsa [I] pointer to the array control structure
1023 * nIndex [I] index of the desired item
1024 *
1025 * RETURNS
1026 * Success: pointer to an item
1027 * Failure: NULL
1028 */
1029
1030LPVOID WINAPI
1031DSA_GetItemPtr (const HDSA hdsa, INT nIndex)
1032{
1033 LPVOID pSrc;
1034
1035 TRACE("(%p %d)\n", hdsa, nIndex);
1036
1037 if (!hdsa)
1038 return NULL;
1039 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
1040 return NULL;
1041
1042 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
1043
1044 TRACE("-- ret=%p\n", pSrc);
1045
1046 return pSrc;
1047}
1048
1049
1050/**************************************************************************
1051 * DSA_SetItem [COMCTL32.325]
1052 *
1053 * Sets the contents of an item in the array.
1054 *
1055 * PARAMS
1056 * hdsa [I] pointer to the array control structure
1057 * nIndex [I] index for the item
1058 * pSrc [I] pointer to the new item data
1059 *
1060 * RETURNS
1061 * Success: TRUE
1062 * Failure: FALSE
1063 */
1064
1065BOOL WINAPI
1066DSA_SetItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
1067{
1068 INT nSize, nNewItems;
1069 LPVOID pDest, lpTemp;
1070
1071 TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc);
1072
1073 if ((!hdsa) || nIndex < 0)
1074 return FALSE;
1075
1076 if (hdsa->nItemCount <= nIndex) {
1077 /* within the old array */
1078 if (hdsa->nMaxCount > nIndex) {
1079 /* within the allocated space, set a new boundary */
1080 hdsa->nItemCount = nIndex + 1;
1081 }
1082 else {
1083 /* resize the block of memory */
1084 nNewItems =
1085 hdsa->nGrow * ((INT)(((nIndex + 1) - 1) / hdsa->nGrow) + 1);
1086 nSize = hdsa->nItemSize * nNewItems;
1087
1088 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
1089 if (!lpTemp)
1090 return FALSE;
1091
1092 hdsa->nMaxCount = nNewItems;
1093 hdsa->nItemCount = nIndex + 1;
1094 hdsa->pData = lpTemp;
1095 }
1096 }
1097
1098 /* put the new entry in */
1099 pDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
1100 TRACE("-- move dest=%p src=%p size=%d\n",
1101 pDest, pSrc, hdsa->nItemSize);
1102 memmove (pDest, pSrc, hdsa->nItemSize);
1103
1104 return TRUE;
1105}
1106
1107
1108/**************************************************************************
1109 * DSA_InsertItem [COMCTL32.324]
1110 *
1111 * PARAMS
1112 * hdsa [I] pointer to the array control structure
1113 * nIndex [I] index for the new item
1114 * pSrc [I] pointer to the element
1115 *
1116 * RETURNS
1117 * Success: position of the new item
1118 * Failure: -1
1119 */
1120
1121INT WINAPI
1122DSA_InsertItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
1123{
1124 INT nNewItems, nSize, i;
1125 LPVOID lpTemp, lpDest;
1126 LPDWORD p;
1127
1128 TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc);
1129
1130 if ((!hdsa) || nIndex < 0)
1131 return -1;
1132
1133 for (i = 0; i < hdsa->nItemSize; i += 4) {
1134 p = *(DWORD**)((char *) pSrc + i);
1135 if (IsBadStringPtrA ((char*)p, 256))
1136 TRACE("-- %d=%p\n", i, (DWORD*)p);
1137 else
1138 TRACE("-- %d=%p [%s]\n", i, p, debugstr_a((char*)p));
1139 }
1140
1141 /* when nIndex >= nItemCount then append */
1142 if (nIndex >= hdsa->nItemCount)
1143 nIndex = hdsa->nItemCount;
1144
1145 /* do we need to resize ? */
1146 if (hdsa->nItemCount >= hdsa->nMaxCount) {
1147 nNewItems = hdsa->nMaxCount + hdsa->nGrow;
1148 nSize = hdsa->nItemSize * nNewItems;
1149
1150 lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
1151 if (!lpTemp)
1152 return -1;
1153
1154 hdsa->nMaxCount = nNewItems;
1155 hdsa->pData = lpTemp;
1156 }
1157
1158 /* do we need to move elements ? */
1159 if (nIndex < hdsa->nItemCount) {
1160 lpTemp = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
1161 lpDest = (char *) lpTemp + hdsa->nItemSize;
1162 nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize;
1163 TRACE("-- move dest=%p src=%p size=%d\n",
1164 lpDest, lpTemp, nSize);
1165 memmove (lpDest, lpTemp, nSize);
1166 }
1167
1168 /* ok, we can put the new Item in */
1169 hdsa->nItemCount++;
1170 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
1171 TRACE("-- move dest=%p src=%p size=%d\n",
1172 lpDest, pSrc, hdsa->nItemSize);
1173 memmove (lpDest, pSrc, hdsa->nItemSize);
1174
1175 return nIndex;
1176}
1177
1178
1179/**************************************************************************
1180 * DSA_DeleteItem [COMCTL32.326]
1181 *
1182 * PARAMS
1183 * hdsa [I] pointer to the array control structure
1184 * nIndex [I] index for the element to delete
1185 *
1186 * RETURNS
1187 * Success: number of the deleted element
1188 * Failure: -1
1189 */
1190
1191INT WINAPI
1192DSA_DeleteItem (const HDSA hdsa, INT nIndex)
1193{
1194 LPVOID lpDest,lpSrc;
1195 INT nSize;
1196
1197 TRACE("(%p %d)\n", hdsa, nIndex);
1198
1199 if (!hdsa)
1200 return -1;
1201 if (nIndex < 0 || nIndex >= hdsa->nItemCount)
1202 return -1;
1203
1204 /* do we need to move ? */
1205 if (nIndex < hdsa->nItemCount - 1) {
1206 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
1207 lpSrc = (char *) lpDest + hdsa->nItemSize;
1208 nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1);
1209 TRACE("-- move dest=%p src=%p size=%d\n",
1210 lpDest, lpSrc, nSize);
1211 memmove (lpDest, lpSrc, nSize);
1212 }
1213
1214 hdsa->nItemCount--;
1215
1216 /* free memory ? */
1217 if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) {
1218 nSize = hdsa->nItemSize * hdsa->nItemCount;
1219
1220 lpDest = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
1221 if (!lpDest)
1222 return -1;
1223
1224 hdsa->nMaxCount = hdsa->nItemCount;
1225 hdsa->pData = lpDest;
1226 }
1227
1228 return nIndex;
1229}
1230
1231
1232/**************************************************************************
1233 * DSA_DeleteAllItems [COMCTL32.327]
1234 *
1235 * Removes all items and reinitializes the array.
1236 *
1237 * PARAMS
1238 * hdsa [I] pointer to the array control structure
1239 *
1240 * RETURNS
1241 * Success: TRUE
1242 * Failure: FALSE
1243 */
1244
1245BOOL WINAPI
1246DSA_DeleteAllItems (const HDSA hdsa)
1247{
1248 TRACE("(%p)\n", hdsa);
1249
1250 if (!hdsa)
1251 return FALSE;
1252 if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
1253 return FALSE;
1254
1255 hdsa->nItemCount = 0;
1256 hdsa->pData = NULL;
1257 hdsa->nMaxCount = 0;
1258
1259 return TRUE;
1260}
1261
1262
1263/**************************************************************************
1264 * The DPA-API is a set of functions to create and manipulate arrays of
1265 * pointers.
1266 */
1267
1268/**************************************************************************
1269 * DPA_Create [COMCTL32.328] Creates a dynamic pointer array
1270 *
1271 * PARAMS
1272 * nGrow [I] number of items by which the array grows when it is filled
1273 *
1274 * RETURNS
1275 * Success: handle (pointer) to the pointer array.
1276 * Failure: NULL
1277 */
1278
1279HDPA WINAPI
1280DPA_Create (INT nGrow)
1281{
1282 HDPA hdpa;
1283
1284 TRACE("(%d)\n", nGrow);
1285
1286 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
1287 if (hdpa) {
1288 hdpa->nGrow = max(8, nGrow);
1289 hdpa->hHeap = COMCTL32_hHeap;
1290 hdpa->nMaxCount = hdpa->nGrow * 2;
1291 hdpa->ptrs =
1292 (LPVOID*)COMCTL32_Alloc (hdpa->nMaxCount * sizeof(LPVOID));
1293 }
1294
1295 TRACE("-- %p\n", hdpa);
1296
1297 return hdpa;
1298}
1299
1300
1301/**************************************************************************
1302 * DPA_Destroy [COMCTL32.329] Destroys a dynamic pointer array
1303 *
1304 * PARAMS
1305 * hdpa [I] handle (pointer) to the pointer array
1306 *
1307 * RETURNS
1308 * Success: TRUE
1309 * Failure: FALSE
1310 */
1311
1312BOOL WINAPI
1313DPA_Destroy (const HDPA hdpa)
1314{
1315 TRACE("(%p)\n", hdpa);
1316
1317 if (!hdpa)
1318 return FALSE;
1319
1320 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
1321 return FALSE;
1322
1323 return HeapFree (hdpa->hHeap, 0, hdpa);
1324}
1325
1326
1327/**************************************************************************
1328 * DPA_Grow [COMCTL32.330]
1329 *
1330 * Sets the growth amount.
1331 *
1332 * PARAMS
1333 * hdpa [I] handle (pointer) to the existing (source) pointer array
1334 * nGrow [I] number of items by which the array grows when it's too small
1335 *
1336 * RETURNS
1337 * Success: TRUE
1338 * Failure: FALSE
1339 */
1340
1341BOOL WINAPI
1342DPA_Grow (const HDPA hdpa, INT nGrow)
1343{
1344 TRACE("(%p %d)\n", hdpa, nGrow);
1345
1346 if (!hdpa)
1347 return FALSE;
1348
1349 hdpa->nGrow = max(8, nGrow);
1350
1351 return TRUE;
1352}
1353
1354
1355/**************************************************************************
1356 * DPA_Clone [COMCTL32.331]
1357 *
1358 * Copies a pointer array to an other one or creates a copy
1359 *
1360 * PARAMS
1361 * hdpa [I] handle (pointer) to the existing (source) pointer array
1362 * hdpaNew [O] handle (pointer) to the destination pointer array
1363 *
1364 * RETURNS
1365 * Success: pointer to the destination pointer array.
1366 * Failure: NULL
1367 *
1368 * NOTES
1369 * - If the 'hdpaNew' is a NULL-Pointer, a copy of the source pointer
1370 * array will be created and it's handle (pointer) is returned.
1371 * - If 'hdpa' is a NULL-Pointer, the original implementation crashes,
1372 * this implementation just returns NULL.
1373 */
1374
1375HDPA WINAPI
1376DPA_Clone (const HDPA hdpa, const HDPA hdpaNew)
1377{
1378 INT nNewItems, nSize;
1379 HDPA hdpaTemp;
1380
1381 if (!hdpa)
1382 return NULL;
1383
1384 TRACE("(%p %p)\n", hdpa, hdpaNew);
1385
1386 if (!hdpaNew) {
1387 /* create a new DPA */
1388 hdpaTemp = (HDPA)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1389 sizeof(DPA));
1390 hdpaTemp->hHeap = hdpa->hHeap;
1391 hdpaTemp->nGrow = hdpa->nGrow;
1392 }
1393 else
1394 hdpaTemp = hdpaNew;
1395
1396 if (hdpaTemp->ptrs) {
1397 /* remove old pointer array */
1398 HeapFree (hdpaTemp->hHeap, 0, hdpaTemp->ptrs);
1399 hdpaTemp->ptrs = NULL;
1400 hdpaTemp->nItemCount = 0;
1401 hdpaTemp->nMaxCount = 0;
1402 }
1403
1404 /* create a new pointer array */
1405 nNewItems = hdpaTemp->nGrow *
1406 ((INT)((hdpa->nItemCount - 1) / hdpaTemp->nGrow) + 1);
1407 nSize = nNewItems * sizeof(LPVOID);
1408 hdpaTemp->ptrs =
1409 (LPVOID*)HeapAlloc (hdpaTemp->hHeap, HEAP_ZERO_MEMORY, nSize);
1410 hdpaTemp->nMaxCount = nNewItems;
1411
1412 /* clone the pointer array */
1413 hdpaTemp->nItemCount = hdpa->nItemCount;
1414 memmove (hdpaTemp->ptrs, hdpa->ptrs,
1415 hdpaTemp->nItemCount * sizeof(LPVOID));
1416
1417 return hdpaTemp;
1418}
1419
1420
1421/**************************************************************************
1422 * DPA_GetPtr [COMCTL32.332]
1423 *
1424 * Retrieves a pointer from a dynamic pointer array
1425 *
1426 * PARAMS
1427 * hdpa [I] handle (pointer) to the pointer array
1428 * nIndex [I] array index of the desired pointer
1429 *
1430 * RETURNS
1431 * Success: pointer
1432 * Failure: NULL
1433 */
1434
1435LPVOID WINAPI
1436DPA_GetPtr (const HDPA hdpa, INT i)
1437{
1438 TRACE("(%p %d)\n", hdpa, i);
1439
1440 if (!hdpa)
1441 return NULL;
1442 if (!hdpa->ptrs) {
1443 WARN("no pointer array.\n");
1444 return NULL;
1445 }
1446 if ((i < 0) || (i >= hdpa->nItemCount)) {
1447 WARN("not enough pointers in array (%d vs %d).\n",i,hdpa->nItemCount);
1448 return NULL;
1449 }
1450
1451 TRACE("-- %p\n", hdpa->ptrs[i]);
1452
1453 return hdpa->ptrs[i];
1454}
1455
1456
1457/**************************************************************************
1458 * DPA_GetPtrIndex [COMCTL32.333]
1459 *
1460 * Retrieves the index of the specified pointer
1461 *
1462 * PARAMS
1463 * hdpa [I] handle (pointer) to the pointer array
1464 * p [I] pointer
1465 *
1466 * RETURNS
1467 * Success: index of the specified pointer
1468 * Failure: -1
1469 */
1470
1471INT WINAPI
1472DPA_GetPtrIndex (const HDPA hdpa, LPVOID p)
1473{
1474 INT i;
1475
1476 if (!hdpa->ptrs)
1477 return -1;
1478
1479 for (i = 0; i < hdpa->nItemCount; i++) {
1480 if (hdpa->ptrs[i] == p)
1481 return i;
1482 }
1483
1484 return -1;
1485}
1486
1487
1488/**************************************************************************
1489 * DPA_InsertPtr [COMCTL32.334]
1490 *
1491 * Inserts a pointer into a dynamic pointer array
1492 *
1493 * PARAMS
1494 * hdpa [I] handle (pointer) to the array
1495 * i [I] array index
1496 * p [I] pointer to insert
1497 *
1498 * RETURNS
1499 * Success: index of the inserted pointer
1500 * Failure: -1
1501 */
1502
1503INT WINAPI
1504DPA_InsertPtr (const HDPA hdpa, INT i, LPVOID p)
1505{
1506 INT nNewItems, nSize, nIndex = 0;
1507 LPVOID *lpTemp, *lpDest;
1508
1509 TRACE("(%p %d %p)\n", hdpa, i, p);
1510
1511 if ((!hdpa) || (i < 0))
1512 return -1;
1513
1514 if (!hdpa->ptrs) {
1515 hdpa->ptrs =
1516 (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1517 2 * hdpa->nGrow * sizeof(LPVOID));
1518 if (!hdpa->ptrs)
1519 return -1;
1520 hdpa->nMaxCount = hdpa->nGrow * 2;
1521 nIndex = 0;
1522 }
1523 else {
1524 if (hdpa->nItemCount >= hdpa->nMaxCount) {
1525 TRACE("-- resizing\n");
1526 nNewItems = hdpa->nMaxCount + hdpa->nGrow;
1527 nSize = nNewItems * sizeof(LPVOID);
1528
1529 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1530 hdpa->ptrs, nSize);
1531 if (!lpTemp)
1532 return -1;
1533 hdpa->nMaxCount = nNewItems;
1534 hdpa->ptrs = lpTemp;
1535 }
1536
1537 if (i >= hdpa->nItemCount) {
1538 nIndex = hdpa->nItemCount;
1539 TRACE("-- appending at %d\n", nIndex);
1540 }
1541 else {
1542 TRACE("-- inserting at %d\n", i);
1543 lpTemp = hdpa->ptrs + i;
1544 lpDest = lpTemp + 1;
1545 nSize = (hdpa->nItemCount - i) * sizeof(LPVOID);
1546 TRACE("-- move dest=%p src=%p size=%x\n",
1547 lpDest, lpTemp, nSize);
1548 memmove (lpDest, lpTemp, nSize);
1549 nIndex = i;
1550 }
1551 }
1552
1553 /* insert item */
1554 hdpa->nItemCount++;
1555 hdpa->ptrs[nIndex] = p;
1556
1557 return nIndex;
1558}
1559
1560
1561/**************************************************************************
1562 * DPA_SetPtr [COMCTL32.335]
1563 *
1564 * Sets a pointer in the pointer array
1565 *
1566 * PARAMS
1567 * hdpa [I] handle (pointer) to the pointer array
1568 * i [I] index of the pointer that will be set
1569 * p [I] pointer to be set
1570 *
1571 * RETURNS
1572 * Success: TRUE
1573 * Failure: FALSE
1574 */
1575
1576BOOL WINAPI
1577DPA_SetPtr (const HDPA hdpa, INT i, LPVOID p)
1578{
1579 LPVOID *lpTemp;
1580
1581 TRACE("(%p %d %p)\n", hdpa, i, p);
1582
1583 if ((!hdpa) || i < 0)
1584 return FALSE;
1585
1586 if (hdpa->nItemCount <= i) {
1587 /* within the old array */
1588 if (hdpa->nMaxCount > i) {
1589 /* within the allocated space, set a new boundary */
1590 hdpa->nItemCount = i+1;
1591 }
1592 else {
1593 /* resize the block of memory */
1594 INT nNewItems =
1595 hdpa->nGrow * ((INT)(((i+1) - 1) / hdpa->nGrow) + 1);
1596 INT nSize = nNewItems * sizeof(LPVOID);
1597
1598 lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1599 hdpa->ptrs, nSize);
1600 if (!lpTemp)
1601 return FALSE;
1602
1603 hdpa->nItemCount = nNewItems;
1604 hdpa->ptrs = lpTemp;
1605 }
1606 }
1607
1608 /* put the new entry in */
1609 hdpa->ptrs[i] = p;
1610
1611 return TRUE;
1612}
1613
1614
1615/**************************************************************************
1616 * DPA_DeletePtr [COMCTL32.336]
1617 *
1618 * Removes a pointer from the pointer array.
1619 *
1620 * PARAMS
1621 * hdpa [I] handle (pointer) to the pointer array
1622 * i [I] index of the pointer that will be deleted
1623 *
1624 * RETURNS
1625 * Success: deleted pointer
1626 * Failure: NULL
1627 */
1628
1629LPVOID WINAPI
1630DPA_DeletePtr (const HDPA hdpa, INT i)
1631{
1632 LPVOID *lpDest, *lpSrc, lpTemp = NULL;
1633 INT nSize;
1634
1635 TRACE("(%p %d)\n", hdpa, i);
1636
1637 if ((!hdpa) || i < 0 || i >= hdpa->nItemCount)
1638 return NULL;
1639
1640 lpTemp = hdpa->ptrs[i];
1641
1642 /* do we need to move ?*/
1643 if (i < hdpa->nItemCount - 1) {
1644 lpDest = hdpa->ptrs + i;
1645 lpSrc = lpDest + 1;
1646 nSize = (hdpa->nItemCount - i - 1) * sizeof(LPVOID);
1647 TRACE("-- move dest=%p src=%p size=%x\n",
1648 lpDest, lpSrc, nSize);
1649 memmove (lpDest, lpSrc, nSize);
1650 }
1651
1652 hdpa->nItemCount --;
1653
1654 /* free memory ?*/
1655 if ((hdpa->nMaxCount - hdpa->nItemCount) >= hdpa->nGrow) {
1656 INT nNewItems = max(hdpa->nGrow * 2, hdpa->nItemCount);
1657 nSize = nNewItems * sizeof(LPVOID);
1658 lpDest = (LPVOID)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1659 hdpa->ptrs, nSize);
1660 if (!lpDest)
1661 return NULL;
1662
1663 hdpa->nMaxCount = nNewItems;
1664 hdpa->ptrs = (LPVOID*)lpDest;
1665 }
1666
1667 return lpTemp;
1668}
1669
1670
1671/**************************************************************************
1672 * DPA_DeleteAllPtrs [COMCTL32.337]
1673 *
1674 * Removes all pointers and reinitializes the array.
1675 *
1676 * PARAMS
1677 * hdpa [I] handle (pointer) to the pointer array
1678 *
1679 * RETURNS
1680 * Success: TRUE
1681 * Failure: FALSE
1682 */
1683
1684BOOL WINAPI
1685DPA_DeleteAllPtrs (const HDPA hdpa)
1686{
1687 TRACE("(%p)\n", hdpa);
1688
1689 if (!hdpa)
1690 return FALSE;
1691
1692 if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
1693 return FALSE;
1694
1695 hdpa->nItemCount = 0;
1696 hdpa->nMaxCount = hdpa->nGrow * 2;
1697 hdpa->ptrs = (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
1698 hdpa->nMaxCount * sizeof(LPVOID));
1699
1700 return TRUE;
1701}
1702
1703
1704/**************************************************************************
1705 * DPA_QuickSort [Internal]
1706 *
1707 * Ordinary quicksort (used by DPA_Sort).
1708 *
1709 * PARAMS
1710 * lpPtrs [I] pointer to the pointer array
1711 * l [I] index of the "left border" of the partition
1712 * r [I] index of the "right border" of the partition
1713 * pfnCompare [I] pointer to the compare function
1714 * lParam [I] user defined value (3rd parameter in compare function)
1715 *
1716 * RETURNS
1717 * NONE
1718 */
1719
1720static VOID
1721DPA_QuickSort (LPVOID *lpPtrs, INT l, INT r,
1722 PFNDPACOMPARE pfnCompare, LPARAM lParam)
1723{
1724 INT m;
1725 LPVOID t;
1726
1727 TRACE("l=%i r=%i\n", l, r);
1728
1729 if (l==r) /* one element is always sorted */
1730 return;
1731 if (r<l) /* oops, got it in the wrong order */
1732 {
1733 DPA_QuickSort(lpPtrs, r, l, pfnCompare, lParam);
1734 return;
1735 }
1736 m = (l+r)/2; /* divide by two */
1737 DPA_QuickSort(lpPtrs, l, m, pfnCompare, lParam);
1738 DPA_QuickSort(lpPtrs, m+1, r, pfnCompare, lParam);
1739
1740 /* join the two sides */
1741 while( (l<=m) && (m<r) )
1742 {
1743 if(pfnCompare(lpPtrs[l],lpPtrs[m+1],lParam)>0)
1744 {
1745 t = lpPtrs[m+1];
1746 memmove(&lpPtrs[l+1],&lpPtrs[l],(m-l+1)*sizeof lpPtrs[l]);
1747 lpPtrs[l] = t;
1748
1749 m++;
1750 }
1751 l++;
1752 }
1753}
1754
1755
1756/**************************************************************************
1757 * DPA_Sort [COMCTL32.338]
1758 *
1759 * Sorts a pointer array using a user defined compare function
1760 *
1761 * PARAMS
1762 * hdpa [I] handle (pointer) to the pointer array
1763 * pfnCompare [I] pointer to the compare function
1764 * lParam [I] user defined value (3rd parameter of compare function)
1765 *
1766 * RETURNS
1767 * Success: TRUE
1768 * Failure: FALSE
1769 */
1770
1771BOOL WINAPI
1772DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
1773{
1774 if (!hdpa || !pfnCompare)
1775 return FALSE;
1776
1777 TRACE("(%p %p 0x%lx)\n", hdpa, pfnCompare, lParam);
1778
1779 if ((hdpa->nItemCount > 1) && (hdpa->ptrs))
1780 DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1,
1781 pfnCompare, lParam);
1782
1783 return TRUE;
1784}
1785
1786
1787/**************************************************************************
1788 * DPA_Search [COMCTL32.339]
1789 *
1790 * Searches a pointer array for a specified pointer
1791 *
1792 * PARAMS
1793 * hdpa [I] handle (pointer) to the pointer array
1794 * pFind [I] pointer to search for
1795 * nStart [I] start index
1796 * pfnCompare [I] pointer to the compare function
1797 * lParam [I] user defined value (3rd parameter of compare function)
1798 * uOptions [I] search options
1799 *
1800 * RETURNS
1801 * Success: index of the pointer in the array.
1802 * Failure: -1
1803 *
1804 * NOTES
1805 * Binary search taken from R.Sedgewick "Algorithms in C"!
1806 * Function is NOT tested!
1807 * If something goes wrong, blame HIM not ME! (Eric Kohl)
1808 */
1809
1810INT WINAPI
1811DPA_Search (const HDPA hdpa, LPVOID pFind, INT nStart,
1812 PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT uOptions)
1813{
1814 if (!hdpa || !pfnCompare || !pFind)
1815 return -1;
1816
1817 TRACE("(%p %p %d %p 0x%08lx 0x%08x)\n",
1818 hdpa, pFind, nStart, pfnCompare, lParam, uOptions);
1819
1820 if (uOptions & DPAS_SORTED) {
1821 /* array is sorted --> use binary search */
1822 INT l, r, x, n;
1823 LPVOID *lpPtr;
1824
1825 TRACE("binary search\n");
1826
1827 l = (nStart == -1) ? 0 : nStart;
1828 r = hdpa->nItemCount - 1;
1829 lpPtr = hdpa->ptrs;
1830 while (r >= l) {
1831 x = (l + r) / 2;
1832 n = (pfnCompare)(pFind, lpPtr[x], lParam);
1833 if (n < 0)
1834 r = x - 1;
1835 else
1836 l = x + 1;
1837 if (n == 0) {
1838 TRACE("-- ret=%d\n", n);
1839 return n;
1840 }
1841 }
1842
1843 if (uOptions & DPAS_INSERTBEFORE) {
1844 TRACE("-- ret=%d\n", r);
1845 return r;
1846 }
1847
1848 if (uOptions & DPAS_INSERTAFTER) {
1849 TRACE("-- ret=%d\n", l);
1850 return l;
1851 }
1852 }
1853 else {
1854 /* array is not sorted --> use linear search */
1855 LPVOID *lpPtr;
1856 INT nIndex;
1857
1858 TRACE("linear search\n");
1859
1860 nIndex = (nStart == -1)? 0 : nStart;
1861 lpPtr = hdpa->ptrs;
1862 for (; nIndex < hdpa->nItemCount; nIndex++) {
1863 if ((pfnCompare)(pFind, lpPtr[nIndex], lParam) == 0) {
1864 TRACE("-- ret=%d\n", nIndex);
1865 return nIndex;
1866 }
1867 }
1868 }
1869
1870 TRACE("-- not found: ret=-1\n");
1871 return -1;
1872}
1873
1874
1875/**************************************************************************
1876 * DPA_CreateEx [COMCTL32.340]
1877 *
1878 * Creates a dynamic pointer array using the specified size and heap.
1879 *
1880 * PARAMS
1881 * nGrow [I] number of items by which the array grows when it is filled
1882 * hHeap [I] handle to the heap where the array is stored
1883 *
1884 * RETURNS
1885 * Success: handle (pointer) to the pointer array.
1886 * Failure: NULL
1887 */
1888
1889HDPA WINAPI
1890DPA_CreateEx (INT nGrow, HANDLE hHeap)
1891{
1892 HDPA hdpa;
1893
1894 TRACE("(%d 0x%x)\n", nGrow, hHeap);
1895
1896 if (hHeap)
1897 hdpa = (HDPA)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, sizeof(DPA));
1898 else
1899 hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
1900
1901 if (hdpa) {
1902 hdpa->nGrow = min(8, nGrow);
1903 hdpa->hHeap = hHeap ? hHeap : COMCTL32_hHeap;
1904 hdpa->nMaxCount = hdpa->nGrow * 2;
1905 hdpa->ptrs =
1906 (LPVOID*)HeapAlloc (hHeap, HEAP_ZERO_MEMORY,
1907 hdpa->nMaxCount * sizeof(LPVOID));
1908 }
1909
1910 TRACE("-- %p\n", hdpa);
1911
1912 return hdpa;
1913}
1914
1915
1916/**************************************************************************
1917 * Notification functions
1918 */
1919
1920typedef struct tagNOTIFYDATA
1921{
1922 HWND hwndFrom;
1923 HWND hwndTo;
1924 DWORD dwParam3;
1925 DWORD dwParam4;
1926 DWORD dwParam5;
1927 DWORD dwParam6;
1928} NOTIFYDATA, *LPNOTIFYDATA;
1929
1930
1931/**************************************************************************
1932 * DoNotify [Internal]
1933 */
1934
1935static LRESULT
1936DoNotify (LPNOTIFYDATA lpNotify, UINT uCode, LPNMHDR lpHdr)
1937{
1938 NMHDR nmhdr;
1939 LPNMHDR lpNmh = NULL;
1940 UINT idFrom = 0;
1941
1942 TRACE("(0x%04x 0x%04x %d %p 0x%08lx)\n",
1943 lpNotify->hwndFrom, lpNotify->hwndTo, uCode, lpHdr,
1944 lpNotify->dwParam5);
1945
1946 if (!lpNotify->hwndTo)
1947 return 0;
1948
1949 if (lpNotify->hwndFrom == -1) {
1950 lpNmh = lpHdr;
1951 idFrom = lpHdr->idFrom;
1952 }
1953 else {
1954 if (lpNotify->hwndFrom) {
1955 HWND hwndParent = GetParent (lpNotify->hwndFrom);
1956 if (hwndParent) {
1957 hwndParent = GetWindow (lpNotify->hwndFrom, GW_OWNER);
1958 if (hwndParent)
1959 idFrom = GetDlgCtrlID (lpNotify->hwndFrom);
1960 }
1961 }
1962
1963 lpNmh = (lpHdr) ? lpHdr : &nmhdr;
1964
1965 lpNmh->hwndFrom = lpNotify->hwndFrom;
1966 lpNmh->idFrom = idFrom;
1967 lpNmh->code = uCode;
1968 }
1969
1970 return SendMessageA (lpNotify->hwndTo, WM_NOTIFY, idFrom, (LPARAM)lpNmh);
1971}
1972
1973
1974/**************************************************************************
1975 * SendNotify [COMCTL32.341]
1976 *
1977 * PARAMS
1978 * hwndFrom [I]
1979 * hwndTo [I]
1980 * uCode [I]
1981 * lpHdr [I]
1982 *
1983 * RETURNS
1984 * Success: return value from notification
1985 * Failure: 0
1986 */
1987
1988LRESULT WINAPI
1989COMCTL32_SendNotify (HWND hwndFrom, HWND hwndTo,
1990 UINT uCode, LPNMHDR lpHdr)
1991{
1992 NOTIFYDATA notify;
1993
1994 TRACE("(0x%04x 0x%04x %d %p)\n",
1995 hwndFrom, hwndTo, uCode, lpHdr);
1996
1997 notify.hwndFrom = hwndFrom;
1998 notify.hwndTo = hwndTo;
1999 notify.dwParam5 = 0;
2000 notify.dwParam6 = 0;
2001
2002 return DoNotify (&notify, uCode, lpHdr);
2003}
2004
2005
2006/**************************************************************************
2007 * SendNotifyEx [COMCTL32.342]
2008 *
2009 * PARAMS
2010 * hwndFrom [I]
2011 * hwndTo [I]
2012 * uCode [I]
2013 * lpHdr [I]
2014 * dwParam5 [I]
2015 *
2016 * RETURNS
2017 * Success: return value from notification
2018 * Failure: 0
2019 */
2020
2021LRESULT WINAPI
2022COMCTL32_SendNotifyEx (HWND hwndTo, HWND hwndFrom, UINT uCode,
2023 LPNMHDR lpHdr, DWORD dwParam5)
2024{
2025 NOTIFYDATA notify;
2026 HWND hwndNotify;
2027
2028 TRACE("(0x%04x 0x%04x %d %p 0x%08lx)\n",
2029 hwndFrom, hwndTo, uCode, lpHdr, dwParam5);
2030
2031 hwndNotify = hwndTo;
2032 if (!hwndTo) {
2033 if (IsWindow (hwndFrom)) {
2034 hwndNotify = GetParent (hwndFrom);
2035 if (!hwndNotify)
2036 return 0;
2037 }
2038 }
2039
2040 notify.hwndFrom = hwndFrom;
2041 notify.hwndTo = hwndNotify;
2042 notify.dwParam5 = dwParam5;
2043 notify.dwParam6 = 0;
2044
2045 return DoNotify (&notify, uCode, lpHdr);
2046}
2047
2048
2049/**************************************************************************
2050 * StrChrA [COMCTL32.350]
2051 *
2052 */
2053
2054LPSTR WINAPI
2055COMCTL32_StrChrA (LPCSTR lpString, CHAR cChar)
2056{
2057 return strchr (lpString, cChar);
2058}
2059
2060
2061/**************************************************************************
2062 * StrStrIA [COMCTL32.355]
2063 */
2064
2065LPSTR WINAPI
2066COMCTL32_StrStrIA (LPCSTR lpStr1, LPCSTR lpStr2)
2067{
2068 INT len1, len2, i;
2069 CHAR first;
2070
2071 if (*lpStr2 == 0)
2072 return ((LPSTR)lpStr1);
2073 len1 = 0;
2074 while (lpStr1[len1] != 0) ++len1;
2075 len2 = 0;
2076 while (lpStr2[len2] != 0) ++len2;
2077 if (len2 == 0)
2078 return ((LPSTR)(lpStr1 + len1));
2079 first = tolower (*lpStr2);
2080 while (len1 >= len2) {
2081 if (tolower(*lpStr1) == first) {
2082 for (i = 1; i < len2; ++i)
2083 if (tolower (lpStr1[i]) != tolower(lpStr2[i]))
2084 break;
2085 if (i >= len2)
2086 return ((LPSTR)lpStr1);
2087 }
2088 ++lpStr1; --len1;
2089 }
2090 return (NULL);
2091}
2092
2093
2094/**************************************************************************
2095 * StrToIntA [COMCTL32.357] Converts a string to a signed integer.
2096 */
2097
2098INT WINAPI
2099COMCTL32_StrToIntA (LPSTR lpString)
2100{
2101 return atoi(lpString);
2102}
2103
2104/**************************************************************************
2105 * StrToIntW [COMCTL32.365] Converts a wide char string to a signed integer.
2106 */
2107
2108INT WINAPI
2109COMCTL32_StrToIntW (LPWSTR lpString)
2110{
2111 return _wtoi(lpString);
2112}
2113
2114
2115/**************************************************************************
2116 * DPA_EnumCallback [COMCTL32.385]
2117 *
2118 * Enumerates all items in a dynamic pointer array.
2119 *
2120 * PARAMS
2121 * hdpa [I] handle to the dynamic pointer array
2122 * enumProc [I]
2123 * lParam [I]
2124 *
2125 * RETURNS
2126 * none
2127 */
2128
2129VOID WINAPI
2130DPA_EnumCallback (const HDPA hdpa, DPAENUMPROC enumProc, LPARAM lParam)
2131{
2132 INT i;
2133
2134 TRACE("(%p %p %08lx)\n", hdpa, enumProc, lParam);
2135
2136 if (!hdpa)
2137 return;
2138 if (hdpa->nItemCount <= 0)
2139 return;
2140
2141 for (i = 0; i < hdpa->nItemCount; i++) {
2142 if ((enumProc)(hdpa->ptrs[i], lParam) == 0)
2143 return;
2144 }
2145
2146 return;
2147}
2148
2149
2150/**************************************************************************
2151 * DPA_DestroyCallback [COMCTL32.386]
2152 *
2153 * Enumerates all items in a dynamic pointer array and destroys it.
2154 *
2155 * PARAMS
2156 * hdpa [I] handle to the dynamic pointer array
2157 * enumProc [I]
2158 * lParam [I]
2159 *
2160 * RETURNS
2161 * Success: TRUE
2162 * Failure: FALSE
2163 */
2164
2165BOOL WINAPI
2166DPA_DestroyCallback (const HDPA hdpa, DPAENUMPROC enumProc, LPARAM lParam)
2167{
2168 TRACE("(%p %p %08lx)\n", hdpa, enumProc, lParam);
2169
2170 DPA_EnumCallback (hdpa, enumProc, lParam);
2171
2172 return DPA_Destroy (hdpa);
2173}
2174
2175
2176/**************************************************************************
2177 * DSA_EnumCallback [COMCTL32.387]
2178 *
2179 * Enumerates all items in a dynamic storage array.
2180 *
2181 * PARAMS
2182 * hdsa [I] handle to the dynamic storage array
2183 * enumProc [I]
2184 * lParam [I]
2185 *
2186 * RETURNS
2187 * none
2188 */
2189
2190VOID WINAPI
2191DSA_EnumCallback (const HDSA hdsa, DSAENUMPROC enumProc, LPARAM lParam)
2192{
2193 INT i;
2194
2195 TRACE("(%p %p %08lx)\n", hdsa, enumProc, lParam);
2196
2197 if (!hdsa)
2198 return;
2199 if (hdsa->nItemCount <= 0)
2200 return;
2201
2202 for (i = 0; i < hdsa->nItemCount; i++) {
2203 LPVOID lpItem = DSA_GetItemPtr (hdsa, i);
2204 if ((enumProc)(lpItem, lParam) == 0)
2205 return;
2206 }
2207
2208 return;
2209}
2210
2211
2212/**************************************************************************
2213 * DSA_DestroyCallback [COMCTL32.388]
2214 *
2215 * Enumerates all items in a dynamic storage array and destroys it.
2216 *
2217 * PARAMS
2218 * hdsa [I] handle to the dynamic storage array
2219 * enumProc [I]
2220 * lParam [I]
2221 *
2222 * RETURNS
2223 * Success: TRUE
2224 * Failure: FALSE
2225 */
2226
2227BOOL WINAPI
2228DSA_DestroyCallback (const HDSA hdsa, DSAENUMPROC enumProc, LPARAM lParam)
2229{
2230 TRACE("(%p %p %08lx)\n", hdsa, enumProc, lParam);
2231
2232 DSA_EnumCallback (hdsa, enumProc, lParam);
2233
2234 return DSA_Destroy (hdsa);
2235}
2236
2237/**************************************************************************
2238 * StrCSpnA [COMCTL32.356]
2239 *
2240 */
2241INT WINAPI COMCTL32_StrCSpnA( LPCSTR lpStr, LPCSTR lpSet) {
2242 return strcspn(lpStr, lpSet);
2243}
2244
2245/**************************************************************************
2246 * StrChrW [COMCTL32.358]
2247 *
2248 */
2249LPWSTR WINAPI COMCTL32_StrChrW( LPCWSTR lpStart, WORD wMatch) {
2250 return strchrW(lpStart, wMatch);
2251}
2252
2253/**************************************************************************
2254 * StrCmpNA [COMCTL32.352]
2255 *
2256 */
2257INT WINAPI COMCTL32_StrCmpNA( LPCSTR lpStr1, LPCSTR lpStr2, int nChar) {
2258 return strncmp(lpStr1, lpStr2, nChar);
2259}
2260
2261/**************************************************************************
2262 * StrCmpNIA [COMCTL32.353]
2263 *
2264 */
2265INT WINAPI COMCTL32_StrCmpNIA( LPCSTR lpStr1, LPCSTR lpStr2, int nChar) {
2266 return strncasecmp(lpStr1, lpStr2, nChar);
2267}
2268
2269/**************************************************************************
2270 * StrCmpNW [COMCTL32.360]
2271 *
2272 */
2273INT WINAPI COMCTL32_StrCmpNW( LPCWSTR lpStr1, LPCWSTR lpStr2, int nChar) {
2274 return strncmpW(lpStr1, lpStr2, nChar);
2275}
2276
2277/**************************************************************************
2278 * StrCmpNIW [COMCTL32.361]
2279 *
2280 */
2281INT WINAPI COMCTL32_StrCmpNIW( LPCWSTR lpStr1, LPCWSTR lpStr2, int nChar) {
2282 FIXME("(%s, %s, %i): stub\n", debugstr_w(lpStr1), debugstr_w(lpStr2), nChar);
2283 return 0;
2284}
2285
2286/**************************************************************************
2287 * StrRChrA [COMCTL32.351]
2288 *
2289 */
2290LPSTR WINAPI COMCTL32_StrRChrA( LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch )
2291{
2292 LPCSTR lpGotIt = NULL;
2293 BOOL dbcs = IsDBCSLeadByte( LOBYTE(wMatch) );
2294
2295 TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
2296
2297 if (!lpEnd) lpEnd = lpStart + strlen(lpStart);
2298
2299 for(; lpStart < lpEnd; lpStart = CharNextA(lpStart))
2300 {
2301 if (*lpStart != LOBYTE(wMatch)) continue;
2302 if (dbcs && lpStart[1] != HIBYTE(wMatch)) continue;
2303 lpGotIt = lpStart;
2304 }
2305 return (LPSTR)lpGotIt;
2306}
2307
2308
2309/**************************************************************************
2310 * StrRChrW [COMCTL32.359]
2311 *
2312 */
2313LPWSTR WINAPI COMCTL32_StrRChrW( LPCWSTR lpStart, LPCWSTR lpEnd, WORD wMatch)
2314{
2315 LPCWSTR lpGotIt = NULL;
2316
2317 TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
2318 if (!lpEnd) lpEnd = lpStart + strlenW(lpStart);
2319
2320 for(; lpStart < lpEnd; lpStart = CharNextW(lpStart))
2321 if (*lpStart == wMatch) lpGotIt = lpStart;
2322
2323 return (LPWSTR)lpGotIt;
2324}
2325
2326
2327/**************************************************************************
2328 * StrStrA [COMCTL32.354]
2329 *
2330 */
2331LPSTR WINAPI COMCTL32_StrStrA( LPCSTR lpFirst, LPCSTR lpSrch) {
2332 return strstr(lpFirst, lpSrch);
2333}
2334
2335/**************************************************************************
2336 * StrStrW [COMCTL32.362]
2337 *
2338 */
2339LPWSTR WINAPI COMCTL32_StrStrW( LPCWSTR lpFirst, LPCWSTR lpSrch) {
2340 return strstrW(lpFirst, lpSrch);
2341}
2342
2343/**************************************************************************
2344 * StrSpnW [COMCTL32.364]
2345 *
2346 */
2347INT WINAPI COMCTL32_StrSpnW( LPWSTR lpStr, LPWSTR lpSet) {
2348 LPWSTR lpLoop = lpStr;
2349
2350 /* validate ptr */
2351 if ((lpStr == 0) || (lpSet == 0)) return 0;
2352
2353/* while(*lpLoop) { if lpLoop++; } */
2354
2355 for(; (*lpLoop != 0); lpLoop++)
2356 if( strchrW(lpSet, *(WORD*)lpLoop))
2357 return (INT)(lpLoop-lpStr);
2358
2359 return (INT)(lpLoop-lpStr);
2360}
2361
2362/**************************************************************************
2363 * @ [COMCTL32.410]
2364 *
2365 * FIXME: What's this supposed to do?
2366 * Parameter 1 is an HWND, you're on your own for the rest.
2367 */
2368
2369BOOL WINAPI COMCTL32_410( HWND hw, DWORD b, DWORD c, DWORD d) {
2370
2371 FIXME("(%x, %lx, %lx, %lx): stub!\n", hw, b, c, d);
2372
2373 return TRUE;
2374}
2375
2376/**************************************************************************
2377 * @ [COMCTL32.411]
2378 *
2379 * FIXME: What's this supposed to do?
2380 * Parameter 1 is an HWND, you're on your own for the rest.
2381 */
2382
2383BOOL WINAPI COMCTL32_411( HWND hw, DWORD b, DWORD c) {
2384
2385 FIXME("(%x, %lx, %lx): stub!\n", hw, b, c);
2386
2387 return TRUE;
2388}
2389
2390/**************************************************************************
2391 * @ [COMCTL32.412]
2392 *
2393 * FIXME: What's this supposed to do?
2394 * Parameter 1 is an HWND, you're on your own for the rest.
2395 */
2396
2397BOOL WINAPI COMCTL32_412( HWND hwnd, DWORD b, DWORD c)
2398{
2399 FIXME("(%x, %lx, %lx): stub!\n", hwnd, b, c);
2400
2401 if (IsWindow (hwnd) == FALSE)
2402 return FALSE;
2403
2404 if (b == 0)
2405 return FALSE;
2406
2407
2408 return TRUE;
2409}
2410
2411/**************************************************************************
2412 * @ [COMCTL32.413]
2413 *
2414 * FIXME: What's this supposed to do?
2415 * Parameter 1 is an HWND, you're on your own for the rest.
2416 */
2417
2418BOOL WINAPI COMCTL32_413( HWND hw, DWORD b, DWORD c, DWORD d) {
2419
2420 FIXME("(%x, %lx, %lx, %lx): stub!\n", hw, b, c, d);
2421
2422 return TRUE;
2423}
2424
2425
2426/**************************************************************************
2427 * @ [COMCTL32.415]
2428 *
2429 * FIXME: What's this supposed to do?
2430 * Parameter 1 is an HWND, you're on your own for the rest.
2431 */
2432
2433BOOL WINAPI COMCTL32_415( HWND hwnd, DWORD b, DWORD c, DWORD d, DWORD e)
2434{
2435
2436 FIXME("(%x, %lx, %lx, %lx, %lx): stub!\n", hwnd, b, c, d, e);
2437
2438 return TRUE;
2439}
2440
2441#ifdef __WIN32OS2__
2442DWORD WINAPI COMCTL32_389(DWORD x1, DWORD x2)
2443{
2444 dprintf(("comctl32_389: %x %X not implemented!!", x1, x2));
2445 return 0; //NT 4 comctl32 returns 0
2446}
2447
2448DWORD WINAPI COMCTL32_390(DWORD x1, DWORD x2, DWORD x3, DWORD x4)
2449{
2450 dprintf(("comctl32_390: %x %x %x %x not implemented!!", x1, x2, x3, x4));
2451
2452 /* Pseudo Assembler
2453 push [esp+arg_C]
2454 mov eax, [esp+4+arg_0]
2455 push [esp+4+arg_8]
2456 mov dword ptr [eax+1A8h], 1
2457 push [esp+8+arg_4]
2458 push dword ptr [eax + 38h]
2459 call ds:SetDIBColorTable
2460 retn 10h
2461 */
2462
2463 return 0;
2464}
2465#endif
Note: See TracBrowser for help on using the repository browser.