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

Last change on this file since 6502 was 6380, checked in by sandervl, 24 years ago

wine resync

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