2 * Undocumented functions from COMCTL32.DLL
4 * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
5 * 1998 Juergen Schmied <j.schmied@metronet.de>
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).
13 * - Fix DSA_InsertItem.
15 * - Write documentation.
25 typedef struct _DPA_DATA
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 /**************************************************************************
46 LPVOID WINAPI
COMCTL32_Alloc (DWORD dwParam
)
49 TRACE (commctrl
, "(0x%08lx)\n", dwParam
);
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
);
60 // lpPtr = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, dwParam);
61 lpPtr
= HeapAlloc (hComctl32Heap
, HEAP_ZERO_MEMORY
, dwParam
);
62 TRACE (commctrl
, "-- ret=%p\n", lpPtr
);
67 /**************************************************************************
68 * ReAlloc [COMCTL32.72]
73 COMCTL32_ReAlloc (LPVOID dwParam1
, DWORD dwParam2
)
76 TRACE (commctrl
, "(0x%08lx 0x%08lx)\n",(DWORD
)dwParam1
, dwParam2
);
79 dwPtr
= HeapAlloc (hComctl32Heap
, HEAP_ZERO_MEMORY
,
82 dwPtr
= HeapReAlloc (hComctl32Heap
, HEAP_ZERO_MEMORY
,
85 TRACE (commctrl
, "-- ret=0x%08lx\n", (DWORD
)dwPtr
);
91 /**************************************************************************
97 COMCTL32_Free (LPVOID dwParam
)
99 TRACE (commctrl
, "(0x%08lx)\n", (DWORD
)dwParam
);
100 HeapFree (hComctl32Heap
, 0, dwParam
);
106 /**************************************************************************
107 * GetSize [COMCTL32.74]
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]
129 COMCTL32_Str_SetPtrA (LPSTR lpStr
, LPVOID
*lpPtr
)
134 FIXME (commctrl
, "(0x%08lx 0x%08lx)\n", (DWORD
)lpStr
, (DWORD
)lpPtr
);
135 FIXME (commctrl
, "(\"%s\" \"%s\")\n", lpStr
, (LPSTR
)*lpPtr
);
138 len
= lstrlen32A (lpStr
);
139 ptr
= COMCTL32_ReAlloc (lpPtr
, len
+ 1);
142 lstrcpy32A (ptr
, lpStr
);
148 COMCTL32_Free (*lpPtr
);
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.
163 typedef struct _DSA_DATA
164 { DWORD dwEntryCount
;
169 } DSA_DATA
, *LPDSA_DATA
;
171 /**************************************************************************
172 * DSA_Create [COMCTL32.320] Creates a dynamic string array
175 * dwSize [I] size of the array elements
178 * pointer to a array control structure. use this like a handle.
181 LPDSA_DATA WINAPI
DSA_Create (DWORD dwSize
, DWORD dwGrow
)
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;
189 dsaPtr
->dwMaxCount
=0x00;
190 dsaPtr
->dwElementSize
=dwSize
;
194 dsaPtr
->dwGrow
=dwGrow
;
200 /**************************************************************************
201 * DSA_Destroy [COMCTL32.321] Destroys a dynamic string array
204 * dsaPtr [I] pointer to the array control structure
206 * TRUE if dsaPtr = NULL or success
210 BOOL32 WINAPI
DSA_Destroy (const LPDSA_DATA dsaPtr
)
211 { TRACE (commctrl
, "(%p)\n", dsaPtr
);
216 if (dsaPtr
->pData
&& (! COMCTL32_Free(dsaPtr
->pData
)))
219 return COMCTL32_Free (dsaPtr
);
222 /**************************************************************************
223 * DSA_GetItem [COMCTL32.322]
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
)
234 TRACE (commctrl
, "(%p 0x%08lx %p)\n", dsaPtr
, dwItem
, pDest
);
236 if ( (!dsaPtr
) || (dwItem
< 0) || (dwItem
>= dsaPtr
->dwEntryCount
))
239 pSrc
= dsaPtr
->pData
+ (dsaPtr
->dwElementSize
* dwItem
);
240 memmove(pDest
,pSrc
,dsaPtr
->dwElementSize
);
244 /**************************************************************************
245 * DSA_GetItemPtr [COMCTL32.323]
248 * dsaPtr [I] pointer to the array control structure
249 * dwItem [I] number of the Item to get
253 LPBYTE WINAPI
DSA_GetItemPtr (const LPDSA_DATA dsaPtr
, DWORD dwItem
)
256 TRACE (commctrl
, "(%p 0x%08lx)\n", dsaPtr
, dwItem
);
258 if ((!dsaPtr
) || (dwItem
< 0) || (dwItem
>= dsaPtr
->dwEntryCount
))
260 pSrc
= dsaPtr
->pData
+ (dsaPtr
->dwElementSize
* dwItem
);
262 TRACE (commctrl
, "-- ret=%p\n", pSrc
);
267 /**************************************************************************
268 * DSA_SetItem [COMCTL32.325]
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
)
277 DWORD dwSize
, dwNewItems
;
280 TRACE (commctrl
, "(%p 0x%08lx %p)\n", dsaPtr
, dwItem
, pSrc
);
282 if ((!dsaPtr
) || dwItem
<0 )
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 */
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
);
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
);
308 /**************************************************************************
309 * DSA_InsertItem [COMCTL32.325]
312 * dsaPtr [I] pointer to the array control structure
313 * dwItem [I] index for the new element
314 * pSrc [I] the element
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
;
324 TRACE(commctrl
, "(%p 0x%08lx %p)\n", dsaPtr
, dwItem
, pSrc
);
326 if ( (!dsaPtr
) || dwItem
<0 )
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
);
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
);
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]
370 * dsaPtr [I] pointer to the array control structure
371 * dwItem [I] index for the element to delete
373 * number of the element deleted
375 DWORD WINAPI
DSA_DeleteItem (const LPDSA_DATA dsaPtr
, DWORD dwItem
)
376 { LPBYTE lpDest
,lpSrc
;
379 TRACE (commctrl
, "(%p 0x%08lx)\n", dsaPtr
, dwItem
);
381 if ( (! dsaPtr
) || dwItem
<0 || dwItem
>=dsaPtr
->dwEntryCount
)
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
);
400 dsaPtr
->dwMaxCount
= dsaPtr
->dwEntryCount
;
401 dsaPtr
->pData
= lpDest
;
407 /**************************************************************************
408 * DSA_DeleteAllItems [COMCTL32.326]
409 * deletes all elements and initializes array
412 * dsaPtr [I] pointer to the array control structure
417 BOOL32 WINAPI
DSA_DeleteAllItems (const LPDSA_DATA dsaPtr
)
418 { TRACE (commctrl
, "(%p)\n", dsaPtr
);
423 if (dsaPtr
->pData
&& (! COMCTL32_Free(dsaPtr
->pData
)))
426 dsaPtr
->dwEntryCount
=0x00;
428 dsaPtr
->dwMaxCount
=0x00;
431 /**************************************************************************/
435 DPA_Create (DWORD dwParam1
)
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
;
452 DPA_GetPtr (DWORD dwParam1
, DWORD dwParam2
)
454 LPDPA_DATA dpaPtr
= (LPDPA_DATA
)dwParam1
;
456 TRACE (commctrl
, "(0x%08lx 0x%08lx)\n", dwParam1
, dwParam2
);
460 if (dpaPtr
->ptrs
== NULL
)
462 if ((dwParam2
< 0) || (dwParam2
>= dpaPtr
->dwEntryCount
))
465 TRACE (commctrl
, "ret=0x%08lx\n", (DWORD
)dpaPtr
->ptrs
[dwParam2
]);
467 return (DWORD
)dpaPtr
->ptrs
[dwParam2
];
473 DPA_InsertPtr (DWORD dwParam1
, DWORD dwParam2
, DWORD dwParam3
)
475 LPDPA_DATA dpaPtr
= (LPDPA_DATA
)dwParam1
;
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
;
486 dpaPtr
->ptrs
[dwIndex
] = dwParam3
;
489 FIXME (commctrl
, "adding to existing array! stub!\n");
495 dpaPtr
->dwEntryCount
++;
501 /**************************************************************************
502 * DPA_CreateEx [COMCTL32.340]
507 DPA_CreateEx (DWORD dwParam1
, DWORD dwParam2
)
509 FIXME (commctrl
, "(0x%08lx 0x%08lx)\n",
516 /**************************************************************************
517 * SendNotify [COMCTL32.341]
522 COMCTL32_SendNotify (DWORD dw1
, DWORD dw2
, DWORD dw3
, DWORD dw4
)
524 FIXME (commctrl
, "(0x%08lx 0x%08lx 0x%08lx 0x%08lx)\n",
532 /**************************************************************************
533 * StrChrA [COMCTL32.350]
538 COMCTL32_StrChrA (LPCSTR lpString
, CHAR cChar
)
540 return strchr (lpString
, cChar
);
544 /**************************************************************************
545 * StrStrIA [COMCTL32.355]
549 COMCTL32_StrStrIA (LPCSTR lpStr1
, LPCSTR lpStr2
)
555 return ((LPSTR
)lpStr1
);
557 while (lpStr1
[len1
] != 0) ++len1
;
559 while (lpStr2
[len2
] != 0) ++len2
;
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
]))
569 return ((LPSTR
)lpStr1
);
577 /**************************************************************************
578 * StrToIntA [COMCTL32.357] Converts a string to a signed integer.
582 COMCTL32_StrToIntA (LPSTR lpString
)
584 return atoi(lpString
);