Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendsa.c
Go to the documentation of this file.
00001 /* 00002 * Dynamic structure array (DSA) implementation 00003 * 00004 * Copyright 1998 Eric Kohl 00005 * 1998 Juergen Schmied <j.schmied@metronet.de> 00006 * 2000 Eric Kohl for CodeWeavers 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00021 * 00022 * NOTES 00023 * These functions were involuntarily documented by Microsoft in 2002 as 00024 * the outcome of an anti-trust suit brought by various U.S. governments. 00025 * As a result the specifications on MSDN are inaccurate, incomplete 00026 * and misleading. A much more complete (unofficial) documentation is 00027 * available at: 00028 * 00029 * http://members.ozemail.com.au/~geoffch/samples/win32/shell/comctl32 00030 */ 00031 00032 #include <stdarg.h> 00033 00034 #include "windef.h" 00035 #include "winbase.h" 00036 #include "winuser.h" 00037 #include "commctrl.h" 00038 00039 #include "comctl32.h" 00040 #include "wine/debug.h" 00041 00042 WINE_DEFAULT_DEBUG_CHANNEL(dsa); 00043 00044 struct _DSA 00045 { 00046 INT nItemCount; 00047 LPVOID pData; 00048 INT nMaxCount; 00049 INT nItemSize; 00050 INT nGrow; 00051 }; 00052 00053 /************************************************************************** 00054 * DSA_Create [COMCTL32.320] 00055 * 00056 * Creates a dynamic storage array 00057 * 00058 * PARAMS 00059 * nSize [I] size of the array elements 00060 * nGrow [I] number of elements by which the array grows when it is filled 00061 * 00062 * RETURNS 00063 * Success: pointer to an array control structure. Use this like a handle. 00064 * Failure: NULL 00065 * 00066 * NOTES 00067 * The DSA_ functions can be used to create and manipulate arrays of 00068 * fixed-size memory blocks. These arrays can store any kind of data 00069 * (e.g. strings and icons). 00070 */ 00071 HDSA WINAPI DSA_Create (INT nSize, INT nGrow) 00072 { 00073 HDSA hdsa; 00074 00075 TRACE("(size=%d grow=%d)\n", nSize, nGrow); 00076 00077 hdsa = Alloc (sizeof(*hdsa)); 00078 if (hdsa) 00079 { 00080 hdsa->nItemCount = 0; 00081 hdsa->pData = NULL; 00082 hdsa->nMaxCount = 0; 00083 hdsa->nItemSize = nSize; 00084 hdsa->nGrow = max(1, nGrow); 00085 } 00086 00087 return hdsa; 00088 } 00089 00090 00091 /************************************************************************** 00092 * DSA_Destroy [COMCTL32.321] 00093 * 00094 * Destroys a dynamic storage array 00095 * 00096 * PARAMS 00097 * hdsa [I] pointer to the array control structure 00098 * 00099 * RETURNS 00100 * Success: TRUE 00101 * Failure: FALSE 00102 */ 00103 BOOL WINAPI DSA_Destroy (const HDSA hdsa) 00104 { 00105 TRACE("(%p)\n", hdsa); 00106 00107 if (!hdsa) 00108 return FALSE; 00109 00110 if (hdsa->pData && (!Free (hdsa->pData))) 00111 return FALSE; 00112 00113 return Free (hdsa); 00114 } 00115 00116 00117 /************************************************************************** 00118 * DSA_GetItem [COMCTL32.322] 00119 * 00120 * Copies the specified item into a caller-supplied buffer. 00121 * 00122 * PARAMS 00123 * hdsa [I] pointer to the array control structure 00124 * nIndex [I] number of the Item to get 00125 * pDest [O] destination buffer. Has to be >= dwElementSize. 00126 * 00127 * RETURNS 00128 * Success: TRUE 00129 * Failure: FALSE 00130 */ 00131 BOOL WINAPI DSA_GetItem (const HDSA hdsa, INT nIndex, LPVOID pDest) 00132 { 00133 LPVOID pSrc; 00134 00135 TRACE("(%p %d %p)\n", hdsa, nIndex, pDest); 00136 00137 if (!hdsa) 00138 return FALSE; 00139 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount)) 00140 return FALSE; 00141 00142 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); 00143 memmove (pDest, pSrc, hdsa->nItemSize); 00144 00145 return TRUE; 00146 } 00147 00148 00149 /************************************************************************** 00150 * DSA_GetItemPtr [COMCTL32.323] 00151 * 00152 * Retrieves a pointer to the specified item. 00153 * 00154 * PARAMS 00155 * hdsa [I] pointer to the array control structure 00156 * nIndex [I] index of the desired item 00157 * 00158 * RETURNS 00159 * Success: pointer to an item 00160 * Failure: NULL 00161 */ 00162 LPVOID WINAPI DSA_GetItemPtr (const HDSA hdsa, INT nIndex) 00163 { 00164 LPVOID pSrc; 00165 00166 TRACE("(%p %d)\n", hdsa, nIndex); 00167 00168 if (!hdsa) 00169 return NULL; 00170 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount)) 00171 return NULL; 00172 00173 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); 00174 00175 TRACE("-- ret=%p\n", pSrc); 00176 00177 return pSrc; 00178 } 00179 00180 00181 /************************************************************************** 00182 * DSA_SetItem [COMCTL32.325] 00183 * 00184 * Sets the contents of an item in the array. 00185 * 00186 * PARAMS 00187 * hdsa [I] pointer to the array control structure 00188 * nIndex [I] index for the item 00189 * pSrc [I] pointer to the new item data 00190 * 00191 * RETURNS 00192 * Success: TRUE 00193 * Failure: FALSE 00194 */ 00195 BOOL WINAPI DSA_SetItem (const HDSA hdsa, INT nIndex, LPVOID pSrc) 00196 { 00197 INT nSize, nNewItems; 00198 LPVOID pDest, lpTemp; 00199 00200 TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc); 00201 00202 if ((!hdsa) || nIndex < 0) 00203 return FALSE; 00204 00205 if (hdsa->nItemCount <= nIndex) { 00206 /* within the old array */ 00207 if (hdsa->nMaxCount > nIndex) { 00208 /* within the allocated space, set a new boundary */ 00209 hdsa->nItemCount = nIndex + 1; 00210 } 00211 else { 00212 /* resize the block of memory */ 00213 nNewItems = 00214 hdsa->nGrow * ((((nIndex + 1) - 1) / hdsa->nGrow) + 1); 00215 nSize = hdsa->nItemSize * nNewItems; 00216 00217 lpTemp = ReAlloc (hdsa->pData, nSize); 00218 if (!lpTemp) 00219 return FALSE; 00220 00221 hdsa->nMaxCount = nNewItems; 00222 hdsa->nItemCount = nIndex + 1; 00223 hdsa->pData = lpTemp; 00224 } 00225 } 00226 00227 /* put the new entry in */ 00228 pDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); 00229 TRACE("-- move dest=%p src=%p size=%d\n", 00230 pDest, pSrc, hdsa->nItemSize); 00231 memmove (pDest, pSrc, hdsa->nItemSize); 00232 00233 return TRUE; 00234 } 00235 00236 00237 /************************************************************************** 00238 * DSA_InsertItem [COMCTL32.324] 00239 * 00240 * Inserts an item into the array at the specified index. 00241 * 00242 * PARAMS 00243 * hdsa [I] pointer to the array control structure 00244 * nIndex [I] index for the new item 00245 * pSrc [I] pointer to the element 00246 * 00247 * RETURNS 00248 * Success: position of the new item 00249 * Failure: -1 00250 */ 00251 INT WINAPI DSA_InsertItem (const HDSA hdsa, INT nIndex, LPVOID pSrc) 00252 { 00253 INT nNewItems, nSize; 00254 LPVOID lpTemp, lpDest; 00255 00256 TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc); 00257 00258 if ((!hdsa) || nIndex < 0) 00259 return -1; 00260 00261 /* when nIndex >= nItemCount then append */ 00262 if (nIndex >= hdsa->nItemCount) 00263 nIndex = hdsa->nItemCount; 00264 00265 /* do we need to resize ? */ 00266 if (hdsa->nItemCount >= hdsa->nMaxCount) { 00267 nNewItems = hdsa->nMaxCount + hdsa->nGrow; 00268 nSize = hdsa->nItemSize * nNewItems; 00269 00270 lpTemp = ReAlloc (hdsa->pData, nSize); 00271 if (!lpTemp) 00272 return -1; 00273 00274 hdsa->nMaxCount = nNewItems; 00275 hdsa->pData = lpTemp; 00276 } 00277 00278 /* do we need to move elements ? */ 00279 if (nIndex < hdsa->nItemCount) { 00280 lpTemp = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); 00281 lpDest = (char *) lpTemp + hdsa->nItemSize; 00282 nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize; 00283 TRACE("-- move dest=%p src=%p size=%d\n", 00284 lpDest, lpTemp, nSize); 00285 memmove (lpDest, lpTemp, nSize); 00286 } 00287 00288 /* ok, we can put the new Item in */ 00289 hdsa->nItemCount++; 00290 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); 00291 TRACE("-- move dest=%p src=%p size=%d\n", 00292 lpDest, pSrc, hdsa->nItemSize); 00293 memmove (lpDest, pSrc, hdsa->nItemSize); 00294 00295 return nIndex; 00296 } 00297 00298 00299 /************************************************************************** 00300 * DSA_DeleteItem [COMCTL32.326] 00301 * 00302 * Deletes the specified item from the array. 00303 * 00304 * PARAMS 00305 * hdsa [I] pointer to the array control structure 00306 * nIndex [I] index for the element to delete 00307 * 00308 * RETURNS 00309 * Success: number of the deleted element 00310 * Failure: -1 00311 */ 00312 INT WINAPI DSA_DeleteItem (const HDSA hdsa, INT nIndex) 00313 { 00314 LPVOID lpDest,lpSrc; 00315 INT nSize; 00316 00317 TRACE("(%p %d)\n", hdsa, nIndex); 00318 00319 if (!hdsa) 00320 return -1; 00321 if (nIndex < 0 || nIndex >= hdsa->nItemCount) 00322 return -1; 00323 00324 /* do we need to move ? */ 00325 if (nIndex < hdsa->nItemCount - 1) { 00326 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex); 00327 lpSrc = (char *) lpDest + hdsa->nItemSize; 00328 nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1); 00329 TRACE("-- move dest=%p src=%p size=%d\n", 00330 lpDest, lpSrc, nSize); 00331 memmove (lpDest, lpSrc, nSize); 00332 } 00333 00334 hdsa->nItemCount--; 00335 00336 /* free memory ? */ 00337 if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) { 00338 nSize = hdsa->nItemSize * hdsa->nItemCount; 00339 00340 lpDest = ReAlloc (hdsa->pData, nSize); 00341 if (!lpDest) 00342 return -1; 00343 00344 hdsa->nMaxCount = hdsa->nItemCount; 00345 hdsa->pData = lpDest; 00346 } 00347 00348 return nIndex; 00349 } 00350 00351 00352 /************************************************************************** 00353 * DSA_DeleteAllItems [COMCTL32.327] 00354 * 00355 * Removes all items and reinitializes the array. 00356 * 00357 * PARAMS 00358 * hdsa [I] pointer to the array control structure 00359 * 00360 * RETURNS 00361 * Success: TRUE 00362 * Failure: FALSE 00363 */ 00364 BOOL WINAPI DSA_DeleteAllItems (const HDSA hdsa) 00365 { 00366 TRACE("(%p)\n", hdsa); 00367 00368 if (!hdsa) 00369 return FALSE; 00370 if (hdsa->pData && (!Free (hdsa->pData))) 00371 return FALSE; 00372 00373 hdsa->nItemCount = 0; 00374 hdsa->pData = NULL; 00375 hdsa->nMaxCount = 0; 00376 00377 return TRUE; 00378 } 00379 00380 00381 /************************************************************************** 00382 * DSA_EnumCallback [COMCTL32.387] 00383 * 00384 * Enumerates all items in a dynamic storage array. 00385 * 00386 * PARAMS 00387 * hdsa [I] handle to the dynamic storage array 00388 * enumProc [I] 00389 * lParam [I] 00390 * 00391 * RETURNS 00392 * none 00393 */ 00394 VOID WINAPI DSA_EnumCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc, 00395 LPVOID lParam) 00396 { 00397 INT i; 00398 00399 TRACE("(%p %p %p)\n", hdsa, enumProc, lParam); 00400 00401 if (!hdsa) 00402 return; 00403 if (hdsa->nItemCount <= 0) 00404 return; 00405 00406 for (i = 0; i < hdsa->nItemCount; i++) { 00407 LPVOID lpItem = DSA_GetItemPtr (hdsa, i); 00408 if ((enumProc)(lpItem, lParam) == 0) 00409 return; 00410 } 00411 00412 return; 00413 } 00414 00415 00416 /************************************************************************** 00417 * DSA_DestroyCallback [COMCTL32.388] 00418 * 00419 * Enumerates all items in a dynamic storage array and destroys it. 00420 * 00421 * PARAMS 00422 * hdsa [I] handle to the dynamic storage array 00423 * enumProc [I] 00424 * lParam [I] 00425 * 00426 * RETURNS 00427 * none 00428 */ 00429 void WINAPI DSA_DestroyCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc, 00430 LPVOID lParam) 00431 { 00432 TRACE("(%p %p %p)\n", hdsa, enumProc, lParam); 00433 00434 DSA_EnumCallback (hdsa, enumProc, lParam); 00435 DSA_Destroy (hdsa); 00436 } Generated on Fri May 25 2012 04:20:57 for ReactOS by
1.7.6.1
|