Release 980822
[wine/multimedia.git] / controls / comctl32undoc.c
blobaa5c83dc97b625e62cbad9270af0843c3ac91986
1 /*
2 * Undocumented functions from COMCTL32.DLL
4 * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
5 * 1998 Juergen Schmied <j.schmied@metronet.de>
6 * NOTES
7 * All of these functions are UNDOCUMENTED!! And I mean UNDOCUMENTED!!!!
8 * Do NOT rely on names or contents of undocumented structures and types!!!
9 * These functions are used by EXPLORER.EXE, IEXPLORE.EXE and
10 * COMCTL32.DLL (internally).
12 * TODO
13 * - Fix DSA_InsertItem.
14 * - Fix DSA_GetItem.
15 * - Write documentation.
18 #include <string.h>
19 #include <stdlib.h>
20 #include <ctype.h>
21 #include "windows.h"
22 #include "heap.h"
23 #include "debug.h"
25 typedef struct _DPA_DATA
27 DWORD dwEntryCount;
28 DWORD dwMaxCount;
29 DWORD dwGrow;
30 LPDWORD ptrs;
31 } DPA_DATA, *LPDPA_DATA;
34 DWORD WINAPI DPA_Create (DWORD);
35 DWORD WINAPI DPA_GetPtr (DWORD, DWORD);
36 DWORD WINAPI DPA_InsertPtr (DWORD, DWORD, DWORD);
39 CRITICAL_SECTION cs_comctl_alloc;
40 HANDLE32 hComctl32Heap=0;
41 /**************************************************************************
42 * Alloc [COMCTL32.71]
46 LPVOID WINAPI COMCTL32_Alloc (DWORD dwParam)
47 { LPVOID lpPtr;
49 TRACE (commctrl, "(0x%08lx)\n", dwParam);
51 if (hComctl32Heap==0)
52 { EnterCriticalSection((void*)&cs_comctl_alloc);
53 hComctl32Heap=HeapCreate(0,1,0x4000000);
54 LeaveCriticalSection((void*)&cs_comctl_alloc);
55 TRACE (commctrl, "Heap created: 0x%08x\n", hComctl32Heap);
56 if (! hComctl32Heap)
57 return FALSE;
60 // lpPtr = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, dwParam);
61 lpPtr = HeapAlloc (hComctl32Heap, HEAP_ZERO_MEMORY, dwParam);
62 TRACE (commctrl, "-- ret=%p\n", lpPtr);
63 return lpPtr;
67 /**************************************************************************
68 * ReAlloc [COMCTL32.72]
72 LPVOID WINAPI
73 COMCTL32_ReAlloc (LPVOID dwParam1, DWORD dwParam2)
75 LPVOID dwPtr;
76 TRACE (commctrl, "(0x%08lx 0x%08lx)\n",(DWORD)dwParam1, dwParam2);
78 if (dwParam1 == 0)
79 dwPtr = HeapAlloc (hComctl32Heap, HEAP_ZERO_MEMORY,
80 dwParam2);
81 else
82 dwPtr = HeapReAlloc (hComctl32Heap, HEAP_ZERO_MEMORY,
83 dwParam1, dwParam2);
85 TRACE (commctrl, "-- ret=0x%08lx\n", (DWORD)dwPtr);
87 return dwPtr;
91 /**************************************************************************
92 * Free [COMCTL32.73]
96 DWORD WINAPI
97 COMCTL32_Free (LPVOID dwParam)
99 TRACE (commctrl, "(0x%08lx)\n", (DWORD)dwParam);
100 HeapFree (hComctl32Heap, 0, dwParam);
102 return 0;
106 /**************************************************************************
107 * GetSize [COMCTL32.74]
111 DWORD WINAPI
112 COMCTL32_GetSize (LPVOID dwParam)
114 TRACE (commctrl, "(0x%08lx)\n", (DWORD)dwParam);
115 return (HeapSize (hComctl32Heap, 0, dwParam));
120 /**************************************************************************
121 * Str_SetPtrA [COMCTL32.234]
123 * PARAMS
124 * dwParam1 [I]
125 * dwParam2 [I]
128 BOOL32 WINAPI
129 COMCTL32_Str_SetPtrA (LPSTR lpStr, LPVOID *lpPtr)
131 INT32 len;
132 LPSTR ptr;
134 FIXME (commctrl, "(0x%08lx 0x%08lx)\n", (DWORD)lpStr, (DWORD)lpPtr);
135 FIXME (commctrl, "(\"%s\" \"%s\")\n", lpStr, (LPSTR)*lpPtr);
137 if (lpStr) {
138 len = lstrlen32A (lpStr);
139 ptr = COMCTL32_ReAlloc (lpPtr, len + 1);
140 if (!(ptr))
141 return FALSE;
142 lstrcpy32A (ptr, lpStr);
143 *lpPtr = ptr;
144 return TRUE;
147 if (*lpPtr) {
148 COMCTL32_Free (*lpPtr);
149 return TRUE;
152 return FALSE;
155 /*************************************************************************
156 * The DSA-API is a set of functions to create and manipulate arrays of
157 * fix sized memory blocks. This arrays can store any kind of data (strings,
158 * icons...) so the name "dynamic string array" is a bit misleading.
160 * STATUS
161 * complete
163 typedef struct _DSA_DATA
164 { DWORD dwEntryCount;
165 BYTE * pData;
166 DWORD dwMaxCount;
167 DWORD dwElementSize;
168 DWORD dwGrow;
169 } DSA_DATA, *LPDSA_DATA;
171 /**************************************************************************
172 * DSA_Create [COMCTL32.320] Creates a dynamic string array
174 * PARAMS
175 * dwSize [I] size of the array elements
176 * dwGrow [I]
177 * RETURNS
178 * pointer to a array control structure. use this like a handle.
181 LPDSA_DATA WINAPI DSA_Create (DWORD dwSize, DWORD dwGrow)
182 { LPDSA_DATA dsaPtr;
184 TRACE (commctrl, "(size=0x%08lx grow=0x%08lx)\n", dwSize, dwGrow);
186 if ((dsaPtr=(LPDSA_DATA)COMCTL32_Alloc(sizeof(DSA_DATA))));
187 { dsaPtr->dwEntryCount=0x00;
188 dsaPtr->pData=NULL;
189 dsaPtr->dwMaxCount=0x00;
190 dsaPtr->dwElementSize=dwSize;
191 if ( dwGrow == 0 )
192 dsaPtr->dwGrow=1;
193 else
194 dsaPtr->dwGrow=dwGrow;
195 return dsaPtr;
197 return FALSE;
200 /**************************************************************************
201 * DSA_Destroy [COMCTL32.321] Destroys a dynamic string array
203 * PARAMS
204 * dsaPtr [I] pointer to the array control structure
205 * RETURNS
206 * TRUE if dsaPtr = NULL or success
207 * FALSE if failure
210 BOOL32 WINAPI DSA_Destroy (const LPDSA_DATA dsaPtr )
211 { TRACE (commctrl, "(%p)\n", dsaPtr);
213 if (! dsaPtr)
214 return FALSE;
216 if (dsaPtr->pData && (! COMCTL32_Free(dsaPtr->pData)))
217 { return FALSE;
219 return COMCTL32_Free (dsaPtr);
222 /**************************************************************************
223 * DSA_GetItem [COMCTL32.322]
225 * PARAMS
226 * dsaPtr [I] pointer to the array control structure
227 * dwItem [I] number of the Item to get
228 + * pDest [O] destination buffer. Has to be >= dwElementSize.
231 BOOL32 WINAPI DSA_GetItem (const LPDSA_DATA dsaPtr, DWORD dwItem, LPBYTE pDest)
232 { BYTE * pSrc;
234 TRACE (commctrl, "(%p 0x%08lx %p)\n", dsaPtr, dwItem, pDest);
236 if ( (!dsaPtr) || (dwItem < 0) || (dwItem >= dsaPtr->dwEntryCount))
237 return FALSE;
239 pSrc = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem);
240 memmove(pDest,pSrc,dsaPtr->dwElementSize);
241 return TRUE;
244 /**************************************************************************
245 * DSA_GetItemPtr [COMCTL32.323]
247 * PARAMS
248 * dsaPtr [I] pointer to the array control structure
249 * dwItem [I] number of the Item to get
250 * RETURNS
251 * pointer ti a item
253 LPBYTE WINAPI DSA_GetItemPtr (const LPDSA_DATA dsaPtr, DWORD dwItem)
254 { BYTE * pSrc;
256 TRACE (commctrl, "(%p 0x%08lx)\n", dsaPtr, dwItem);
258 if ((!dsaPtr) || (dwItem < 0) || (dwItem >= dsaPtr->dwEntryCount))
259 return FALSE;
260 pSrc = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem);
262 TRACE (commctrl, "-- ret=%p\n", pSrc);
264 return pSrc;
267 /**************************************************************************
268 * DSA_SetItem [COMCTL32.325]
270 * PARAMS
271 * dsaPtr [I] pointer to the array control structure
272 * dwItem [I] index for the new element
273 * pSrc [I] the element
275 BOOL32 WINAPI DSA_SetItem (const LPDSA_DATA dsaPtr, DWORD dwItem, LPBYTE pSrc)
276 { LPBYTE pDest;
277 DWORD dwSize, dwNewItems;
278 LPBYTE lpTemp;
280 TRACE (commctrl, "(%p 0x%08lx %p)\n", dsaPtr, dwItem, pSrc);
282 if ((!dsaPtr) || dwItem<0 )
283 return FALSE;
285 if (dsaPtr->dwEntryCount <= dwItem) /* within the old array */
286 { if ( dsaPtr->dwMaxCount > dwItem)
287 { dsaPtr->dwEntryCount = dwItem; /* within the allocated space, set a new boundary */
289 else
290 { /* resize the block of memory*/
291 dwNewItems = dsaPtr->dwGrow * ( (WORD)((dwItem-1)/dsaPtr->dwGrow) +1);
292 dwSize = dsaPtr->dwElementSize * dwNewItems;
293 lpTemp = (LPBYTE) COMCTL32_ReAlloc(dsaPtr->pData,dwSize);
294 if (! lpTemp )
295 { return FALSE;
297 dsaPtr->dwMaxCount = dwNewItems;
298 dsaPtr->pData = lpTemp;
301 /* put the new entry in */
302 pDest = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem);
303 TRACE (commctrl,"move dest=%p src=%p size=%x",pDest,pSrc,dsaPtr->dwElementSize);
304 memmove(pDest,pSrc,dsaPtr->dwElementSize);
305 return TRUE;
308 /**************************************************************************
309 * DSA_InsertItem [COMCTL32.325]
311 * PARAMS
312 * dsaPtr [I] pointer to the array control structure
313 * dwItem [I] index for the new element
314 * pSrc [I] the element
316 * RETURNS
317 * the position of the new element
319 DWORD WINAPI DSA_InsertItem (const LPDSA_DATA dsaPtr, DWORD dwItem, LPBYTE pSrc)
320 { DWORD dwNewItems, dwSize,i;
321 LPBYTE lpTemp, lpDest;
322 LPDWORD p;
324 TRACE(commctrl, "(%p 0x%08lx %p)\n", dsaPtr, dwItem, pSrc);
326 if ( (!dsaPtr) || dwItem<0 )
327 return -1;
329 for (i=0; i<dsaPtr->dwElementSize;i+=4)
330 { p = *(DWORD**)(pSrc+i);
331 if ( IsBadStringPtr32A ((char*)p,256))
332 { TRACE(commctrl,"-- 0x%04lx=%p\n",i,(DWORD*)p);
334 else
335 { TRACE(commctrl,"-- 0x%04lx=%p [%s]\n",i,p,debugstr_a((char*)p));
339 if (dwItem > dsaPtr->dwEntryCount) /* when dwItem > dwEntryCount then append*/
340 dwItem = dsaPtr->dwEntryCount+1;
342 if (dwItem >= dsaPtr->dwMaxCount) /* do we need to resize ? */
343 { dwNewItems = dsaPtr->dwMaxCount + dsaPtr->dwGrow;
344 dwSize = dsaPtr->dwElementSize * dwNewItems;
345 lpTemp = (LPBYTE)COMCTL32_ReAlloc(dsaPtr->pData,dwSize);
346 if (!lpTemp)
347 { return -1;
349 dsaPtr->dwMaxCount = dwNewItems;
350 dsaPtr->pData = lpTemp;
353 if (dwItem < dsaPtr->dwEntryCount) /* do we need to move elements ?*/
354 { lpTemp = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem);
355 lpDest = lpTemp + dsaPtr->dwElementSize;
356 TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",lpDest,lpTemp,dsaPtr->dwElementSize);
357 memmove (lpDest,lpTemp,dsaPtr->dwElementSize);
359 /* ok, we can put the new Item in*/
360 dsaPtr->dwEntryCount++;
361 lpDest = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem);
362 TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",lpDest,pSrc,dsaPtr->dwElementSize);
363 memmove (lpDest,pSrc,dsaPtr->dwElementSize);
364 return dsaPtr->dwEntryCount;
366 /**************************************************************************
367 * DSA_DeleteItem [COMCTL32.326]
369 * PARAMS
370 * dsaPtr [I] pointer to the array control structure
371 * dwItem [I] index for the element to delete
372 * RETURNS
373 * number of the element deleted
375 DWORD WINAPI DSA_DeleteItem (const LPDSA_DATA dsaPtr, DWORD dwItem)
376 { LPBYTE lpDest,lpSrc;
377 DWORD dwSize;
379 TRACE (commctrl, "(%p 0x%08lx)\n", dsaPtr, dwItem);
381 if ( (! dsaPtr) || dwItem<0 || dwItem>=dsaPtr->dwEntryCount)
382 return FALSE;
384 if ( dwItem < dsaPtr->dwEntryCount-1 ) /* do we need to move ?*/
385 { lpDest = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem);
386 lpSrc = lpDest + dsaPtr->dwElementSize;
387 dwSize = dsaPtr->dwElementSize * (dsaPtr->dwEntryCount-dwItem-1);
388 TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",lpDest,lpSrc,dwSize);
389 memmove (lpDest,lpSrc,dwSize);
392 dsaPtr->dwEntryCount--;
394 if ( (dsaPtr->dwMaxCount-dsaPtr->dwEntryCount) >= dsaPtr->dwGrow) /* free memory ?*/
395 { dwSize = dsaPtr->dwElementSize * dsaPtr->dwEntryCount;
396 lpDest = (LPBYTE) COMCTL32_ReAlloc(dsaPtr->pData,dwSize);
397 if (!lpDest)
398 { return FALSE;
400 dsaPtr->dwMaxCount = dsaPtr->dwEntryCount;
401 dsaPtr->pData = lpDest;
404 return dwItem;
407 /**************************************************************************
408 * DSA_DeleteAllItems [COMCTL32.326]
409 * deletes all elements and initializes array
411 * PARAMS
412 * dsaPtr [I] pointer to the array control structure
414 * RETURNS
415 * TRUE/FALSE
417 BOOL32 WINAPI DSA_DeleteAllItems (const LPDSA_DATA dsaPtr)
418 { TRACE (commctrl, "(%p)\n", dsaPtr);
420 if (! dsaPtr)
421 return FALSE;
423 if (dsaPtr->pData && (! COMCTL32_Free(dsaPtr->pData)))
424 { return FALSE;
426 dsaPtr->dwEntryCount=0x00;
427 dsaPtr->pData=NULL;
428 dsaPtr->dwMaxCount=0x00;
429 return TRUE;
431 /**************************************************************************/
434 DWORD WINAPI
435 DPA_Create (DWORD dwParam1)
437 LPDPA_DATA dpaPtr;
439 TRACE (commctrl, "(0x%08lx)\n", dwParam1);
441 dpaPtr = (LPDPA_DATA)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, sizeof(DPA_DATA));
442 dpaPtr->dwGrow = dwParam1;
444 TRACE (commctrl, "ret=0x%08lx\n", (DWORD)dpaPtr);
446 return (DWORD)dpaPtr;
451 DWORD WINAPI
452 DPA_GetPtr (DWORD dwParam1, DWORD dwParam2)
454 LPDPA_DATA dpaPtr = (LPDPA_DATA)dwParam1;
456 TRACE (commctrl, "(0x%08lx 0x%08lx)\n", dwParam1, dwParam2);
458 if (dpaPtr == NULL)
459 return 0;
460 if (dpaPtr->ptrs == NULL)
461 return 0;
462 if ((dwParam2 < 0) || (dwParam2 >= dpaPtr->dwEntryCount))
463 return 0;
465 TRACE (commctrl, "ret=0x%08lx\n", (DWORD)dpaPtr->ptrs[dwParam2]);
467 return (DWORD)dpaPtr->ptrs[dwParam2];
472 DWORD WINAPI
473 DPA_InsertPtr (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
475 LPDPA_DATA dpaPtr = (LPDPA_DATA)dwParam1;
476 DWORD dwIndex;
478 TRACE (commctrl, "(0x%08lx 0x%08lx 0x%lx)\n",
479 dwParam1, dwParam2, dwParam3);
481 if (dpaPtr->ptrs == NULL) {
482 dpaPtr->ptrs = (LPDWORD)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
483 dpaPtr->dwGrow * sizeof(LPVOID));
484 dpaPtr->dwMaxCount = dpaPtr->dwGrow;
485 dwIndex = 0;
486 dpaPtr->ptrs[dwIndex] = dwParam3;
488 else {
489 FIXME (commctrl, "adding to existing array! stub!\n");
492 dwIndex = dwParam2;
495 dpaPtr->dwEntryCount++;
497 return (dwIndex);
501 /**************************************************************************
502 * DPA_CreateEx [COMCTL32.340]
506 DWORD WINAPI
507 DPA_CreateEx (DWORD dwParam1, DWORD dwParam2)
509 FIXME (commctrl, "(0x%08lx 0x%08lx)\n",
510 dwParam1, dwParam2);
512 return 0;
516 /**************************************************************************
517 * SendNotify [COMCTL32.341]
521 DWORD WINAPI
522 COMCTL32_SendNotify (DWORD dw1, DWORD dw2, DWORD dw3, DWORD dw4)
524 FIXME (commctrl, "(0x%08lx 0x%08lx 0x%08lx 0x%08lx)\n",
525 dw1, dw2, dw3, dw4);
527 return 0;
532 /**************************************************************************
533 * StrChrA [COMCTL32.350]
537 LPSTR WINAPI
538 COMCTL32_StrChrA (LPCSTR lpString, CHAR cChar)
540 return strchr (lpString, cChar);
544 /**************************************************************************
545 * StrStrIA [COMCTL32.355]
548 LPSTR WINAPI
549 COMCTL32_StrStrIA (LPCSTR lpStr1, LPCSTR lpStr2)
551 INT32 len1, len2, i;
552 CHAR first;
554 if (*lpStr2 == 0)
555 return ((LPSTR)lpStr1);
556 len1 = 0;
557 while (lpStr1[len1] != 0) ++len1;
558 len2 = 0;
559 while (lpStr2[len2] != 0) ++len2;
560 if (len2 == 0)
561 return ((LPSTR)(lpStr1 + len1));
562 first = tolower (*lpStr2);
563 while (len1 >= len2) {
564 if (tolower(*lpStr1) == first) {
565 for (i = 1; i < len2; ++i)
566 if (tolower (lpStr1[i]) != tolower(lpStr2[i]))
567 break;
568 if (i >= len2)
569 return ((LPSTR)lpStr1);
571 ++lpStr1; --len1;
573 return (NULL);
577 /**************************************************************************
578 * StrToIntA [COMCTL32.357] Converts a string to a signed integer.
581 INT32 WINAPI
582 COMCTL32_StrToIntA (LPSTR lpString)
584 return atoi(lpString);