Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

lboxctl1.c File Reference

#include "precomp.h"

Go to the source code of this file.

Functions

INT xxxLBBinarySearchString (PLBIV plb, LPWSTR lpstr)
int xxxSetLBScrollParms (PLBIV plb, int nCtl)
void xxxLBShowHideScrollBars (PLBIV plb)
LONG_PTR LBGetItemData (PLBIV plb, INT sItem)
INT LBGetText (PLBIV plb, BOOL fLengthOnly, BOOL fAnsi, INT index, LPWSTR lpbuffer)
BOOL GrowMem (PLBIV plb, INT numItems)
LONG xxxLBInitStorage (PLBIV plb, BOOL fAnsi, INT cItems, INT cb)
INT xxxLBInsertItem (PLBIV plb, LPWSTR lpsz, INT index, UINT wFlags)
INT LBlstrcmpi (LPWSTR lpStr1, LPWSTR lpStr2, DWORD dwLocaleId)
BOOL xxxLBResetContent (PLBIV plb)
INT xxxLBoxCtlDelete (PLBIV plb, INT sItem)
void xxxLBoxDeleteItem (PLBIV plb, INT sItem)
INT xxxLBSetCount (PLBIV plb, INT cItems)
UINT LBCalcAllocNeeded (PLBIV plb, INT cItems)


Function Documentation

BOOL GrowMem PLBIV  plb,
INT  numItems
 

Definition at line 285 of file lboxctl1.c.

References BOOL, tagLBIV::cMax, FALSE, tagLBIV::fHasData, tagLBIV::fHasStrings, NULL, tagLBIV::OwnerDraw, OWNERDRAWVAR, tagLBIV::rgpch, SINGLESEL, TRUE, UserLocalAlloc, UserLocalReAlloc, and tagLBIV::wMultiple.

Referenced by xxxLBInitStorage(), and xxxLBInsertItem().

00289 { 00290 LONG cb; 00291 HANDLE hMem; 00292 00293 /* 00294 * Allocate memory for pointers to the strings. 00295 */ 00296 cb = (plb->cMax + numItems) * 00297 (plb->fHasStrings ? sizeof(LBItem) 00298 : (plb->fHasData ? sizeof(LBODItem) 00299 : 0)); 00300 00301 /* 00302 * If multiple selection list box (MULTIPLESEL or EXTENDEDSEL), then 00303 * allocate an extra byte per item to keep track of it's selection state. 00304 */ 00305 if (plb->wMultiple != SINGLESEL) { 00306 cb += (plb->cMax + numItems); 00307 } 00308 00309 /* 00310 * Extra bytes for each item so that we can store its height. 00311 */ 00312 if (plb->OwnerDraw == OWNERDRAWVAR) { 00313 cb += (plb->cMax + numItems); 00314 } 00315 00316 /* 00317 * Don't allocate more than 2G of memory 00318 */ 00319 if (cb > MAXLONG) 00320 return FALSE; 00321 00322 if (plb->rgpch == NULL) { 00323 if ((plb->rgpch = UserLocalAlloc(HEAP_ZERO_MEMORY, (LONG)cb)) == NULL) 00324 return FALSE; 00325 } else { 00326 if ((hMem = UserLocalReAlloc(plb->rgpch, (LONG)cb, HEAP_ZERO_MEMORY)) == NULL) 00327 return FALSE; 00328 plb->rgpch = hMem; 00329 } 00330 00331 plb->cMax += numItems; 00332 00333 return TRUE; 00334 }

UINT LBCalcAllocNeeded PLBIV  plb,
INT  cItems
 

Definition at line 1220 of file lboxctl1.c.

References tagLBIV::fHasData, tagLBIV::fHasStrings, tagLBIV::OwnerDraw, OWNERDRAWVAR, SINGLESEL, UINT, and tagLBIV::wMultiple.

Referenced by xxxLBSetCount().

01223 { 01224 UINT cb; 01225 01226 /* 01227 * Allocate memory for pointers to the strings. 01228 */ 01229 cb = cItems * (plb->fHasStrings ? sizeof(LBItem) 01230 : (plb->fHasData ? sizeof(LBODItem) 01231 : 0)); 01232 01233 /* 01234 * If multiple selection list box (MULTIPLESEL or EXTENDEDSEL), then 01235 * allocate an extra byte per item to keep track of it's selection state. 01236 */ 01237 if (plb->wMultiple != SINGLESEL) { 01238 cb += cItems; 01239 } 01240 01241 /* 01242 * Extra bytes for each item so that we can store its height. 01243 */ 01244 if (plb->OwnerDraw == OWNERDRAWVAR) { 01245 cb += cItems; 01246 } 01247 01248 return cb; 01249 }

LONG_PTR LBGetItemData PLBIV  plb,
INT  sItem
 

Definition at line 176 of file lboxctl1.c.

References tagLBIV::cMac, tagLBIV::fHasData, tagLBIV::fHasStrings, L, LBItem, LBODItem, lpLBODItem, and tagLBIV::rgpch.

Referenced by LBGetText(), ListBoxWndProcWorker(), xxxLBoxDeleteItem(), and xxxLBoxDrawItem().

00179 { 00180 LONG_PTR buffer; 00181 LPBYTE lpItem; 00182 00183 if (sItem < 0 || sItem >= plb->cMac) { 00184 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00185 return LB_ERR; 00186 } 00187 00188 // No-data listboxes always return 0L 00189 // 00190 if (!plb->fHasData) { 00191 return 0L; 00192 } 00193 00194 lpItem = (plb->rgpch + 00195 (sItem * (plb->fHasStrings ? sizeof(LBItem) : sizeof(LBODItem)))); 00196 buffer = (plb->fHasStrings ? ((lpLBItem)lpItem)->itemData : ((lpLBODItem)lpItem)->itemData); 00197 return buffer; 00198 }

INT LBGetText PLBIV  plb,
BOOL  fLengthOnly,
BOOL  fAnsi,
INT  index,
LPWSTR  lpbuffer
 

Definition at line 214 of file lboxctl1.c.

References tagLBIV::cMac, FALSE, tagLBIV::fHasStrings, GetLpszItem(), INT, LBGetItemData(), tagLBIV::OwnerDraw, and RtlUnicodeToMultiByteSize().

Referenced by ListBoxWndProcWorker().

00220 { 00221 LPWSTR lpItemText; 00222 INT cchText; 00223 00224 if (index < 0 || index >= plb->cMac) { 00225 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00226 return LB_ERR; 00227 } 00228 00229 if (!plb->fHasStrings && plb->OwnerDraw) { 00230 00231 /* 00232 * Owner draw without strings so we must copy the app supplied DWORD 00233 * value. 00234 */ 00235 cchText = sizeof(ULONG_PTR); 00236 00237 if (!fLengthOnly) { 00238 LONG_PTR UNALIGNED *p = (LONG_PTR UNALIGNED *)lpbuffer; 00239 *p = LBGetItemData(plb, index); 00240 } 00241 } else { 00242 lpItemText = GetLpszItem(plb, index); 00243 if (!lpItemText) 00244 return LB_ERR; 00245 00246 /* 00247 * These are strings so we are copying the text and we must include 00248 * the terminating 0 when doing the RtlMoveMemory. 00249 */ 00250 cchText = wcslen(lpItemText); 00251 00252 if (fLengthOnly) { 00253 if (fAnsi) 00254 RtlUnicodeToMultiByteSize(&cchText, lpItemText, cchText*sizeof(WCHAR)); 00255 } else { 00256 if (fAnsi) { 00257 #ifdef FE_SB // LBGetText() 00258 cchText = WCSToMB(lpItemText, cchText+1, &((LPSTR)lpbuffer), (cchText+1)*sizeof(WORD), FALSE); 00259 /* 00260 * Here.. cchText contains null-terminate char, subtract it... Because, we pass cchText+1 to 00261 * above Unicode->Ansi convertsion to make sure the string is terminated with null. 00262 */ 00263 cchText--; 00264 #else 00265 WCSToMB(lpItemText, cchText+1, &((LPSTR)lpbuffer), cchText+1, FALSE); 00266 #endif // FE_SB 00267 } else { 00268 RtlCopyMemory(lpbuffer, lpItemText, (cchText+1)*sizeof(WCHAR)); 00269 } 00270 } 00271 00272 } 00273 00274 return cchText; 00275 }

INT LBlstrcmpi LPWSTR  lpStr1,
LPWSTR  lpStr2,
DWORD  dwLocaleId
 

Definition at line 671 of file lboxctl1.c.

References GetClientInfo, INT, and TIF_16BIT.

Referenced by xxxLBBinarySearchString().

00675 { 00676 00677 /* 00678 * NOTE: This function is written so as to reduce the number of calls 00679 * made to the costly IsCharAlphaNumeric() function because that might 00680 * load a language module; It 'traps' the most frequently occurring cases 00681 * like both strings starting with '[' or both strings NOT starting with '[' 00682 * first and only in abosolutely necessary cases calls IsCharAlphaNumeric(); 00683 */ 00684 if (*lpStr1 == TEXT('[')) { 00685 if (*lpStr2 == TEXT('[')) { 00686 goto LBL_End; 00687 } 00688 if (IsCharAlphaNumeric(*lpStr2)) { 00689 return 1; 00690 } 00691 } 00692 00693 if ((*lpStr2 == TEXT('[')) && IsCharAlphaNumeric(*lpStr1)) { 00694 return -1; 00695 } 00696 00697 LBL_End: 00698 if ((GetClientInfo()->dwTIFlags & TIF_16BIT) && 00699 dwLocaleId == MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)) { 00700 /* 00701 * This is how Windows95 does, bug #4199 00702 */ 00703 return (*pfnWowIlstrcmp)(lpStr1, lpStr2); 00704 } 00705 return (INT)CompareStringW((LCID)dwLocaleId, NORM_IGNORECASE, 00706 lpStr1, -1, lpStr2, -1 ) - 2; 00707 }

INT xxxLBBinarySearchString PLBIV  plb,
LPWSTR  lpstr
 

Definition at line 722 of file lboxctl1.c.

References BYTE, CheckLock, tagLBIV::cMac, tagLBIV::dwLocaleId, FAR, tagLBIV::fHasStrings, tagLBIV::hStrings, HW, HWq, INT, LBlstrcmpi(), max, tagLBIV::rgpch, SendMessage(), tagWND::spmenu, tagLBIV::spwnd, tagLBIV::spwndParent, ThreadLock, ThreadUnlock, and UINT.

Referenced by xxxLBInsertItem().

00725 { 00726 BYTE *FAR *lprgpch; 00727 INT sortResult; 00728 COMPAREITEMSTRUCT cis; 00729 LPWSTR pszLBBase; 00730 LPWSTR pszLB; 00731 INT itemhigh; 00732 INT itemnew = 0; 00733 INT itemlow = 0; 00734 TL tlpwndParent; 00735 00736 CheckLock(plb->spwnd); 00737 00738 if (!plb->cMac) 00739 return 0; 00740 00741 lprgpch = (BYTE *FAR *)(plb->rgpch); 00742 if (plb->fHasStrings) { 00743 pszLBBase = plb->hStrings; 00744 } 00745 00746 itemhigh = plb->cMac - 1; 00747 while (itemlow <= itemhigh) { 00748 itemnew = (itemhigh + itemlow) / 2; 00749 00750 if (plb->fHasStrings) { 00751 00752 /* 00753 * Searching for string matches. 00754 */ 00755 pszLB = (LPWSTR)((LPSTR)pszLBBase + ((lpLBItem)lprgpch)[itemnew].offsz); 00756 sortResult = LBlstrcmpi(pszLB, lpstr, plb->dwLocaleId); 00757 } else { 00758 00759 /* 00760 * Send compare item messages to the parent for sorting 00761 */ 00762 cis.CtlType = ODT_LISTBOX; 00763 cis.CtlID = PtrToUlong(plb->spwnd->spmenu); 00764 cis.hwndItem = HWq(plb->spwnd); 00765 cis.itemID1 = itemnew; 00766 cis.itemData1 = ((lpLBODItem)lprgpch)[itemnew].itemData; 00767 cis.itemID2 = (UINT)-1; 00768 cis.itemData2 = (ULONG_PTR)lpstr; 00769 cis.dwLocaleId = plb->dwLocaleId; 00770 ThreadLock(plb->spwndParent, &tlpwndParent); 00771 sortResult = (INT)SendMessage(HW(plb->spwndParent), WM_COMPAREITEM, 00772 cis.CtlID, (LPARAM)&cis); 00773 ThreadUnlock(&tlpwndParent); 00774 } 00775 00776 if (sortResult < 0) { 00777 itemlow = itemnew + 1; 00778 } else if (sortResult > 0) { 00779 itemhigh = itemnew - 1; 00780 } else { 00781 itemlow = itemnew; 00782 goto FoundIt; 00783 } 00784 } 00785 00786 FoundIt: 00787 00788 return max(0, itemlow); 00789 }

LONG xxxLBInitStorage PLBIV  plb,
BOOL  fAnsi,
INT  cItems,
INT  cb
 

Definition at line 342 of file lboxctl1.c.

References tagLBIV::cchStrings, tagLBIV::cMac, tagLBIV::cMax, tagLBIV::fHasStrings, GrowMem(), tagLBIV::hStrings, tagLBIV::ichAlloc, INT, UserLocalReAlloc, and xxxNotifyOwner().

Referenced by ListBoxWndProcWorker().

00343 { 00344 HANDLE hMem; 00345 INT cbChunk; 00346 00347 /* 00348 * if the app is talking ANSI, then adjust for the worst case in unicode 00349 * where each single ansi byte translates to one 16 bit unicode value 00350 */ 00351 if (fAnsi) { 00352 cb *= sizeof(WCHAR) ; 00353 } /* if */ 00354 00355 /* 00356 * Fail if either of the parameters look bad. 00357 */ 00358 if ((cItems < 0) || (cb < 0)) { 00359 xxxNotifyOwner(plb, LBN_ERRSPACE); 00360 return LB_ERRSPACE; 00361 } /* if */ 00362 00363 /* 00364 * try to grow the pointer array (if necessary) accounting for the free space 00365 * already available. 00366 */ 00367 cItems -= plb->cMax - plb->cMac ; 00368 if ((cItems > 0) && !GrowMem(plb, cItems)) { 00369 xxxNotifyOwner(plb, LBN_ERRSPACE); 00370 return LB_ERRSPACE; 00371 } /* if */ 00372 00373 /* 00374 * now grow the string space if necessary 00375 */ 00376 if (plb->fHasStrings) { 00377 if ((cbChunk = (plb->ichAlloc + cb)) > plb->cchStrings) { 00378 00379 /* 00380 * Round up to the nearest 256 byte chunk. 00381 */ 00382 cbChunk = (cbChunk & ~0xff) + 0x100; 00383 if (!(hMem = UserLocalReAlloc(plb->hStrings, (LONG)cbChunk, 0))) { 00384 xxxNotifyOwner(plb, LBN_ERRSPACE); 00385 return LB_ERRSPACE; 00386 } 00387 plb->hStrings = hMem; 00388 plb->cchStrings = cbChunk; 00389 } /* if */ 00390 } /* if */ 00391 00392 /* 00393 * return the number of items that can be stored 00394 */ 00395 return plb->cMax ; 00396 }

INT xxxLBInsertItem PLBIV  plb,
LPWSTR  lpsz,
INT  index,
UINT  wFlags
 

Definition at line 407 of file lboxctl1.c.

References BYTE, tagLBIV::cchStrings, CharLowerBuffW(), CharUpperBuffW(), CheckLock, CITEMSALLOC, tagLBIV::cMac, tagLBIV::cMax, FALSE, tagLBIV::fFromInsert, tagLBIV::fHasData, tagLBIV::fHasStrings, tagLBIV::fHorzBar, tagLBIV::fMultiColumn, tagLBIV::fRightAlign, tagLBIV::fSort, FWINABLE, gpsi, GrowMem(), tagLBIV::hStrings, HW, tagLBIV::ichAlloc, INT, tagLBIV::iSel, tagLBIV::iSelBase, tagLBItem::itemData, tagLBODItem::itemData, tagLBIV::iTop, L, LBEvent(), LBI_ADD, LBSetCItemFullMax(), LOWERCASE, MSGFLAG_SPECIAL_THUNK, tagLBItem::offsz, tagLBIV::OwnerDraw, OWNERDRAWVAR, PBYTE, tagLBIV::rgpch, SendMessage(), SINGLESEL, tagWND::spmenu, tagLBIV::spwnd, tagLBIV::spwndParent, ThreadLock, ThreadUnlock, TRUE, UINT, UPPERCASE, UserLocalAlloc, UserLocalReAlloc, tagLBIV::wMultiple, xxxCheckRedraw(), xxxLBBinarySearchString(), xxxLBoxCtlHScroll(), xxxLBShowHideScrollBars(), and xxxNotifyOwner().

00417 { 00418 MEASUREITEMSTRUCT measureItemStruct; 00419 INT cbString; 00420 INT cbChunk; 00421 PBYTE lp; 00422 PBYTE lpT; 00423 PBYTE lpHeightStart; 00424 LONG cbItem; /* sizeof the Item in rgpch */ 00425 HANDLE hMem; 00426 TL tlpwndParent; 00427 00428 CheckLock(plb->spwnd); 00429 00430 if (wFlags & LBI_ADD) 00431 index = (plb->fSort) ? xxxLBBinarySearchString(plb, lpsz) : -1; 00432 00433 if (!plb->rgpch) { 00434 if (index != 0 && index != -1) { 00435 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00436 return LB_ERR; 00437 } 00438 00439 plb->iSel = -1; 00440 plb->iSelBase = 0; 00441 plb->cMax = 0; 00442 plb->cMac = 0; 00443 plb->iTop = 0; 00444 plb->rgpch = UserLocalAlloc(HEAP_ZERO_MEMORY, 0L); 00445 if (!plb->rgpch) 00446 return LB_ERR; 00447 } 00448 00449 if (index == -1) { 00450 index = plb->cMac; 00451 } 00452 00453 if (index > plb->cMac || plb->cMac >= MAXLONG) { 00454 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00455 return LB_ERR; 00456 } 00457 00458 if (plb->fHasStrings) { 00459 00460 /* 00461 * we must store the string in the hStrings memory block. 00462 */ 00463 cbString = (wcslen(lpsz) + 1)*sizeof(WCHAR); /* include 0 terminator */ 00464 00465 if ((cbChunk = (plb->ichAlloc + cbString)) > plb->cchStrings) { 00466 00467 /* 00468 * Round up to the nearest 256 byte chunk. 00469 */ 00470 cbChunk = (cbChunk & ~0xff) + 0x100; 00471 if (!(hMem = UserLocalReAlloc(plb->hStrings, (LONG)cbChunk, 00472 0))) { 00473 xxxNotifyOwner(plb, LBN_ERRSPACE); 00474 return LB_ERRSPACE; 00475 } 00476 plb->hStrings = hMem; 00477 00478 plb->cchStrings = cbChunk; 00479 } 00480 00481 /* 00482 * Note difference between Win 95 code with placement of new string 00483 */ 00484 if (wFlags & UPPERCASE) 00485 CharUpperBuffW((LPWSTR)lpsz, cbString / sizeof(WCHAR)); 00486 else if (wFlags & LOWERCASE) 00487 CharLowerBuffW((LPWSTR)lpsz, cbString / sizeof(WCHAR)); 00488 00489 lp = (PBYTE)(plb->hStrings); 00490 RtlMoveMemory(lp + plb->ichAlloc, lpsz, cbString); 00491 } 00492 00493 /* 00494 * Now expand the pointer array. 00495 */ 00496 if (plb->cMac >= plb->cMax) { 00497 if (!GrowMem(plb, CITEMSALLOC)) { 00498 xxxNotifyOwner(plb, LBN_ERRSPACE); 00499 return LB_ERRSPACE; 00500 } 00501 } 00502 00503 lpHeightStart = lpT = lp = plb->rgpch; 00504 00505 /* 00506 * Now calculate how much room we must make for the string pointer (lpsz). 00507 * If we are ownerdraw without LBS_HASSTRINGS, then a single DWORD 00508 * (LBODItem.itemData) stored for each item, but if we have strings with 00509 * each item then a LONG string offset (LBItem.offsz) is also stored. 00510 */ 00511 cbItem = (plb->fHasStrings ? sizeof(LBItem) 00512 : (plb->fHasData ? sizeof(LBODItem):0)); 00513 cbChunk = (plb->cMac - index) * cbItem; 00514 00515 if (plb->wMultiple != SINGLESEL) { 00516 00517 /* 00518 * Extra bytes were allocated for selection flag for each item 00519 */ 00520 cbChunk += plb->cMac; 00521 } 00522 00523 if (plb->OwnerDraw == OWNERDRAWVAR) { 00524 00525 /* 00526 * Extra bytes were allocated for each item's height 00527 */ 00528 cbChunk += plb->cMac; 00529 } 00530 00531 /* 00532 * First, make room for the 2 byte pointer to the string or the 4 byte app 00533 * supplied value. 00534 */ 00535 lpT += (index * cbItem); 00536 RtlMoveMemory(lpT + cbItem, lpT, cbChunk); 00537 if (!plb->fHasStrings && plb->OwnerDraw) { 00538 if (plb->fHasData) { 00539 /* 00540 * Ownerdraw so just save the DWORD value 00541 */ 00542 lpLBODItem p = (lpLBODItem)lpT; 00543 p->itemData = (ULONG_PTR)lpsz; 00544 } 00545 } else { 00546 lpLBItem p = ((lpLBItem)lpT); 00547 00548 /* 00549 * Save the start of the string. Let the item data field be 0 00550 */ 00551 p->offsz = (LONG)(plb->ichAlloc); 00552 p->itemData = 0; 00553 plb->ichAlloc += cbString; 00554 } 00555 00556 /* 00557 * Now if Multiple Selection lbox, we have to insert a selection status 00558 * byte. If var height ownerdraw, then we also have to move up the height 00559 * bytes. 00560 */ 00561 if (plb->wMultiple != SINGLESEL) { 00562 lpT = lp + ((plb->cMac + 1) * cbItem) + index; 00563 RtlMoveMemory(lpT + 1, lpT, plb->cMac - index + 00564 (plb->OwnerDraw == OWNERDRAWVAR ? plb->cMac : 0)); 00565 *lpT = 0; /* fSelected = FALSE */ 00566 } 00567 00568 /* 00569 * Increment count of items in the listbox now before we send a message to 00570 * the app. 00571 */ 00572 plb->cMac++; 00573 00574 /* 00575 * If varheight ownerdraw, we much insert an extra byte for the item's 00576 * height. 00577 */ 00578 if (plb->OwnerDraw == OWNERDRAWVAR) { 00579 00580 /* 00581 * Variable height owner draw so we need to get the height of each item. 00582 */ 00583 lpHeightStart += (plb->cMac * cbItem) + index + 00584 (plb->wMultiple ? plb->cMac : 0); 00585 00586 RtlMoveMemory(lpHeightStart + 1, lpHeightStart, plb->cMac - 1 - index); 00587 00588 /* 00589 * Query for item height only if we are var height owner draw. 00590 */ 00591 measureItemStruct.CtlType = ODT_LISTBOX; 00592 measureItemStruct.CtlID = PtrToUlong(plb->spwnd->spmenu); 00593 measureItemStruct.itemID = index; 00594 00595 /* 00596 * System font height is default height 00597 */ 00598 measureItemStruct.itemHeight = (UINT)gpsi->cySysFontChar; 00599 measureItemStruct.itemData = (ULONG_PTR)lpsz; 00600 00601 /* 00602 * If "has strings" then add the special thunk bit so the client data 00603 * will be thunked to a client side address. LB_DIR sends a string 00604 * even if the listbox is not HASSTRINGS so we need to special 00605 * thunk this case. HP Dashboard for windows send LB_DIR to a non 00606 * HASSTRINGS listbox needs the server string converted to client. 00607 * WOW needs to know about this situation as well so we mark the 00608 * previously uninitialized itemWidth as FLAT. 00609 */ 00610 if (plb->fHasStrings || (wFlags & MSGFLAG_SPECIAL_THUNK)) { 00611 measureItemStruct.itemWidth = MIFLAG_FLAT; 00612 } 00613 00614 ThreadLock(plb->spwndParent, &tlpwndParent); 00615 SendMessage(HW(plb->spwndParent), 00616 WM_MEASUREITEM, 00617 measureItemStruct.CtlID, 00618 (LPARAM)&measureItemStruct); 00619 ThreadUnlock(&tlpwndParent); 00620 *lpHeightStart = (BYTE)measureItemStruct.itemHeight; 00621 } 00622 00623 00624 /* 00625 * If the item was inserted above the current selection then move 00626 * the selection down one as well. 00627 */ 00628 if ((plb->wMultiple == SINGLESEL) && (plb->iSel >= index)) 00629 plb->iSel++; 00630 00631 if (plb->OwnerDraw == OWNERDRAWVAR) 00632 LBSetCItemFullMax(plb); 00633 00634 /* 00635 * Check if scroll bars need to be shown/hidden 00636 */ 00637 plb->fFromInsert = TRUE; 00638 xxxLBShowHideScrollBars(plb); 00639 if (plb->fHorzBar && plb->fRightAlign && !(plb->fMultiColumn || plb->OwnerDraw)) { 00640 /* 00641 * origin to right 00642 */ 00643 xxxLBoxCtlHScroll(plb, SB_BOTTOM, 0); 00644 } 00645 plb->fFromInsert = FALSE; 00646 00647 xxxCheckRedraw(plb, TRUE, index); 00648 00649 if (FWINABLE()) { 00650 LBEvent(plb, EVENT_OBJECT_CREATE, index); 00651 } 00652 00653 return index; 00654 }

INT xxxLBoxCtlDelete PLBIV  plb,
INT  sItem
 

Definition at line 842 of file lboxctl1.c.

References CheckLock, tagLBIV::cMac, EXTENDEDSEL, FALSE, tagLBIV::fFromInsert, tagLBIV::fHasData, tagLBIV::fHasStrings, FWINABLE, tagLBIV::hStrings, tagLBIV::ichAlloc, tagLBIV::iMouseDown, INT, tagLBIV::iSel, tagLBIV::iSelBase, tagLBIV::iTop, LBEvent(), LBGetItemRect(), LBSetCItemFullMax(), min, NULL, tagLBItem::offsz, tagLBIV::OwnerDraw, OWNERDRAWVAR, PBYTE, tagLBIV::pcbox, tagLBIV::rgpch, SendMessageWorker(), SINGLESEL, tagLBIV::spwnd, tagCBox::spwnd, TestWF, ThreadLock, ThreadUnlock, TRUE, WFWIN40COMPAT, tagLBIV::wMultiple, xxxCBInternalUpdateEditWindow(), xxxCheckRedraw(), xxxInsureVisible(), xxxLBInvalidateRect(), xxxLBoxDeleteItem(), and xxxLBShowHideScrollBars().

Referenced by ListBoxWndProcWorker().

00845 { 00846 LONG cb; 00847 LPBYTE lp; 00848 LPBYTE lpT; 00849 RECT rc; 00850 int cbItem; /* size of Item in rgpch */ 00851 LPWSTR lpString; 00852 PBYTE pbStrings; 00853 INT cbStringLen; 00854 LPBYTE itemNumbers; 00855 INT sTmp; 00856 TL tlpwnd; 00857 00858 CheckLock(plb->spwnd); 00859 00860 if (sItem < 0 || sItem >= plb->cMac) { 00861 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00862 return LB_ERR; 00863 } 00864 00865 if (FWINABLE()) { 00866 LBEvent(plb, EVENT_OBJECT_DESTROY, sItem); 00867 } 00868 00869 if (plb->cMac == 1) { 00870 00871 /* 00872 * When the item count is 0, we send a resetcontent message so that we 00873 * can reclaim our string space this way. 00874 */ 00875 SendMessageWorker(plb->spwnd, LB_RESETCONTENT, 0, 0, FALSE); 00876 goto FinishUpDelete; 00877 } 00878 00879 /* 00880 * Get the rectangle associated with the last item in the listbox. If it is 00881 * visible, we need to invalidate it. When we delete an item, everything 00882 * scrolls up to replace the item deleted so we must make sure we erase the 00883 * old image of the last item in the listbox. 00884 */ 00885 if (LBGetItemRect(plb, (INT)(plb->cMac - 1), &rc)) { 00886 xxxLBInvalidateRect(plb, &rc, TRUE); 00887 } 00888 00889 // 3.1 and earlier used to only send WM_DELETEITEMs if it was an ownerdraw 00890 // listbox. 4.0 and above will send WM_DELETEITEMs for every item that has 00891 // nonzero item data. 00892 if (TestWF(plb->spwnd, WFWIN40COMPAT) || (plb->OwnerDraw && plb->fHasData)) { 00893 xxxLBoxDeleteItem(plb, sItem); 00894 } 00895 00896 plb->cMac--; 00897 00898 cbItem = (plb->fHasStrings ? sizeof(LBItem) 00899 : (plb->fHasData ? sizeof(LBODItem): 0)); 00900 cb = ((plb->cMac - sItem) * cbItem); 00901 00902 /* 00903 * Byte for the selection status of the item. 00904 */ 00905 if (plb->wMultiple != SINGLESEL) { 00906 cb += (plb->cMac + 1); 00907 } 00908 00909 if (plb->OwnerDraw == OWNERDRAWVAR) { 00910 00911 /* 00912 * One byte for the height of the item. 00913 */ 00914 cb += (plb->cMac + 1); 00915 } 00916 00917 /* 00918 * Might be nodata and singlesel, for instance. 00919 * but what out for the case where cItem == cMac (and cb == 0). 00920 */ 00921 if ((cb != 0) || plb->fHasStrings) { 00922 lp = plb->rgpch; 00923 00924 lpT = (lp + (sItem * cbItem)); 00925 00926 if (plb->fHasStrings) { 00927 /* 00928 * If we has strings with each item, then we want to compact the string 00929 * heap so that we can recover the space occupied by the string of the 00930 * deleted item. 00931 */ 00932 /* 00933 * Get the string which we will be deleting 00934 */ 00935 pbStrings = (PBYTE)(plb->hStrings); 00936 lpString = (LPTSTR)(pbStrings + ((lpLBItem)lpT)->offsz); 00937 cbStringLen = (wcslen(lpString) + 1) * sizeof(WCHAR); /* include null terminator */ 00938 00939 /* 00940 * Now compact the string array 00941 */ 00942 plb->ichAlloc = plb->ichAlloc - cbStringLen; 00943 00944 RtlMoveMemory(lpString, (PBYTE)lpString + cbStringLen, 00945 plb->ichAlloc + (pbStrings - (LPBYTE)lpString)); 00946 00947 /* 00948 * We have to update the string pointers in plb->rgpch since all the 00949 * string after the deleted string have been moved down stringLength 00950 * bytes. Note that we have to explicitly check all items in the list 00951 * box if the string was allocated after the deleted item since the 00952 * LB_SORT style allows a lower item number to have a string allocated 00953 * at the end of the string heap for example. 00954 */ 00955 itemNumbers = lp; 00956 for (sTmp = 0; sTmp <= plb->cMac; sTmp++) { 00957 lpLBItem p =(lpLBItem)itemNumbers; 00958 if ( (LPTSTR)(p->offsz + pbStrings) > lpString ) { 00959 p->offsz -= cbStringLen; 00960 } 00961 p++; 00962 itemNumbers=(LPBYTE)p; 00963 } 00964 } 00965 00966 /* 00967 * Now compact the pointers to the strings (or the long app supplied values 00968 * if ownerdraw without strings). 00969 */ 00970 RtlMoveMemory(lpT, lpT + cbItem, cb); 00971 00972 /* 00973 * Compress the multiselection bytes 00974 */ 00975 if (plb->wMultiple != SINGLESEL) { 00976 lpT = (lp + (plb->cMac * cbItem) + sItem); 00977 RtlMoveMemory(lpT, lpT + 1, plb->cMac - sItem + 00978 (plb->OwnerDraw == OWNERDRAWVAR ? plb->cMac + 1 : 0)); 00979 } 00980 00981 if (plb->OwnerDraw == OWNERDRAWVAR) { 00982 /* 00983 * Compress the height bytes 00984 */ 00985 lpT = (lp + (plb->cMac * cbItem) + (plb->wMultiple ? plb->cMac : 0) 00986 + sItem); 00987 RtlMoveMemory(lpT, lpT + 1, plb->cMac - sItem); 00988 } 00989 00990 } 00991 00992 if (plb->wMultiple == SINGLESEL) { 00993 if (plb->iSel == sItem) { 00994 plb->iSel = -1; 00995 00996 if (plb->pcbox != NULL) { 00997 ThreadLock(plb->pcbox->spwnd, &tlpwnd); 00998 xxxCBInternalUpdateEditWindow(plb->pcbox, NULL); 00999 ThreadUnlock(&tlpwnd); 01000 } 01001 } else if (plb->iSel > sItem) 01002 plb->iSel--; 01003 } 01004 01005 if ((plb->iMouseDown != -1) && (sItem <= plb->iMouseDown)) 01006 plb->iMouseDown = -1; 01007 01008 if (plb->iSelBase && sItem == plb->iSelBase) 01009 plb->iSelBase--; 01010 01011 if (plb->cMac) { 01012 plb->iSelBase = min(plb->iSelBase, plb->cMac - 1); 01013 } else { 01014 plb->iSelBase = 0; 01015 } 01016 01017 if ((plb->wMultiple == EXTENDEDSEL) && (plb->iSel == -1)) 01018 plb->iSel = plb->iSelBase; 01019 01020 if (plb->OwnerDraw == OWNERDRAWVAR) 01021 LBSetCItemFullMax(plb); 01022 01023 /* 01024 * We always set a new iTop. The iTop won't change if it doesn't need to 01025 * but it will change if: 1. The iTop was deleted or 2. We need to change 01026 * the iTop so that we fill the listbox. 01027 */ 01028 xxxInsureVisible(plb, plb->iTop, FALSE); 01029 01030 FinishUpDelete: 01031 01032 /* 01033 * Check if scroll bars need to be shown/hidden 01034 */ 01035 plb->fFromInsert = TRUE; 01036 xxxLBShowHideScrollBars(plb); 01037 plb->fFromInsert = FALSE; 01038 01039 xxxCheckRedraw(plb, TRUE, sItem); 01040 xxxInsureVisible(plb, plb->iSelBase, FALSE); 01041 01042 return plb->cMac; 01043 }

void xxxLBoxDeleteItem PLBIV  plb,
INT  sItem
 

Definition at line 1053 of file lboxctl1.c.

References CheckLock, tagLBIV::fHasData, HWq, LBGetItemData(), NULL, SendMessage(), tagWND::spmenu, tagLBIV::spwnd, tagLBIV::spwndParent, ThreadLock, and ThreadUnlock.

Referenced by xxxLBoxCtlDelete(), and xxxLBoxDoDeleteItems().

01056 { 01057 DELETEITEMSTRUCT dis; 01058 TL tlpwndParent; 01059 01060 CheckLock(plb->spwnd); 01061 if (plb->spwnd == NULL) 01062 return; 01063 01064 /* 01065 * Bug 262122 - joejo 01066 * No need to send message if no data! 01067 */ 01068 if (!plb->fHasData) { 01069 return; 01070 } 01071 01072 /* 01073 * Fill the DELETEITEMSTRUCT 01074 */ 01075 dis.CtlType = ODT_LISTBOX; 01076 dis.CtlID = PtrToUlong(plb->spwnd->spmenu); 01077 dis.itemID = sItem; 01078 dis.hwndItem = HWq(plb->spwnd); 01079 01080 /* 01081 * Bug 262122 - joejo 01082 * Fixed in 93 so that ItemData was passed. For some reason, not 01083 * merged in. 01084 */ 01085 dis.itemData = LBGetItemData(plb, sItem); 01086 01087 if (plb->spwndParent != NULL) { 01088 ThreadLock(plb->spwndParent, &tlpwndParent); 01089 SendMessage(HWq(plb->spwndParent), WM_DELETEITEM, dis.CtlID, 01090 (LPARAM)&dis); 01091 ThreadUnlock(&tlpwndParent); 01092 } 01093 }

BOOL xxxLBResetContent PLBIV  plb  ) 
 

Definition at line 797 of file lboxctl1.c.

References BOOL, tagLBIV::cMac, tagLBIV::cMax, FALSE, tagLBIV::hStrings, HWq, tagLBIV::iLastSelection, InitHStrings(), tagLBIV::iSel, tagLBIV::iSelBase, IsVisible(), tagLBIV::iTop, NtUserInvalidateRect(), NULL, tagLBIV::rgpch, tagLBIV::spwnd, TestWF, TRUE, UserLocalFree, WFWIN31COMPAT, tagLBIV::xOrigin, xxxCheckRedraw(), xxxLBoxDoDeleteItems(), and xxxLBShowHideScrollBars().

Referenced by ListBoxWndProcWorker().

00799 { 00800 if (!plb->cMac) 00801 return TRUE; 00802 00803 xxxLBoxDoDeleteItems(plb); 00804 00805 if (plb->rgpch != NULL) { 00806 UserLocalFree(plb->rgpch); 00807 plb->rgpch = NULL; 00808 } 00809 00810 if (plb->hStrings != NULL) { 00811 UserLocalFree(plb->hStrings); 00812 plb->hStrings = NULL; 00813 } 00814 00815 InitHStrings(plb); 00816 00817 if (TestWF(plb->spwnd, WFWIN31COMPAT)) 00818 xxxCheckRedraw(plb, FALSE, 0); 00819 else if (IsVisible(plb->spwnd)) 00820 NtUserInvalidateRect(HWq(plb->spwnd), NULL, TRUE); 00821 00822 plb->iSelBase = 0; 00823 plb->iTop = 0; 00824 plb->cMac = 0; 00825 plb->cMax = 0; 00826 plb->xOrigin = 0; 00827 plb->iLastSelection = 0; 00828 plb->iSel = -1; 00829 00830 xxxLBShowHideScrollBars(plb); 00831 return TRUE; 00832 }

INT xxxLBSetCount PLBIV  plb,
INT  cItems
 

Definition at line 1107 of file lboxctl1.c.

References BOOL, CheckLock, CITEMSALLOC, tagLBIV::cMac, tagLBIV::cMax, FALSE, tagLBIV::fHasData, tagLBIV::fHasStrings, tagLBIV::fRedraw, tagLBIV::iLastSelection, INT, tagLBIV::iSel, tagLBIV::iSelBase, tagLBIV::iTop, L, LBCalcAllocNeeded(), NULL, tagLBIV::rgpch, SendMessageWorker(), tagLBIV::spwnd, TRUE, UINT, UserLocalAlloc, UserLocalReAlloc, tagLBIV::xOrigin, xxxLBInvalidateRect(), xxxLBSetRedraw(), xxxLBShowHideScrollBars(), and xxxNotifyOwner().

Referenced by ListBoxWndProcWorker().

01110 { 01111 UINT cbRequired; 01112 BOOL fRedraw; 01113 01114 CheckLock(plb->spwnd); 01115 01116 /* 01117 * SetCount is only valid on lazy-eval ("nodata") listboxes. 01118 * All other lboxen must add their items one at a time, although 01119 * they may SetCount(0) via RESETCONTENT. 01120 */ 01121 if (plb->fHasStrings || plb->fHasData) { 01122 RIPERR0(ERROR_SETCOUNT_ON_BAD_LB, RIP_VERBOSE, ""); 01123 return LB_ERR; 01124 } 01125 01126 if (cItems == 0) { 01127 SendMessageWorker(plb->spwnd, LB_RESETCONTENT, 0, 0, FALSE); 01128 return 0; 01129 } 01130 01131 // If redraw isn't turned off, turn it off now 01132 if (fRedraw = plb->fRedraw) 01133 xxxLBSetRedraw(plb, FALSE); 01134 01135 cbRequired = LBCalcAllocNeeded(plb, cItems); 01136 01137 /* 01138 * Reset selection and position 01139 */ 01140 plb->iSelBase = 0; 01141 plb->iTop = 0; 01142 plb->cMax = 0; 01143 plb->xOrigin = 0; 01144 plb->iLastSelection = 0; 01145 plb->iSel = -1; 01146 01147 if (cbRequired != 0) { // Only if record instance data required 01148 01149 /* 01150 * If listbox was previously empty, prepare for the 01151 * realloc-based alloc strategy ahead. 01152 */ 01153 if (plb->rgpch == NULL) { 01154 plb->rgpch = UserLocalAlloc(HEAP_ZERO_MEMORY, 0L); 01155 plb->cMax = 0; 01156 01157 if (plb->rgpch == NULL) { 01158 xxxNotifyOwner(plb, LBN_ERRSPACE); 01159 return LB_ERRSPACE; 01160 } 01161 } 01162 01163 /* 01164 * rgpch might not have enough room for the new record instance 01165 * data, so check and realloc as necessary. 01166 */ 01167 if (cItems >= plb->cMax) { 01168 INT cMaxNew; 01169 UINT cbNew; 01170 HANDLE hmemNew; 01171 01172 /* 01173 * Since GrowMem presumes a one-item-at-a-time add schema, 01174 * SetCount can't use it. Too bad. 01175 */ 01176 cMaxNew = cItems+CITEMSALLOC; 01177 cbNew = LBCalcAllocNeeded(plb, cMaxNew); 01178 hmemNew = UserLocalReAlloc(plb->rgpch, cbNew, HEAP_ZERO_MEMORY); 01179 01180 if (hmemNew == NULL) { 01181 xxxNotifyOwner(plb, LBN_ERRSPACE); 01182 return LB_ERRSPACE; 01183 } 01184 01185 plb->rgpch = hmemNew; 01186 plb->cMax = cMaxNew; 01187 } 01188 01189 /* 01190 * Reset the item instance data (multisel annotations) 01191 */ 01192 RtlZeroMemory(plb->rgpch, cbRequired); 01193 } 01194 01195 plb->cMac = cItems; 01196 01197 // Turn redraw back on 01198 if (fRedraw) 01199 xxxLBSetRedraw(plb, TRUE); 01200 01201 xxxLBInvalidateRect(plb, NULL, TRUE); 01202 // Not In Chicago -- FritzS 01203 // NtUserSetScrollPos(plb->spwnd, SB_HORZ, 0, plb->fRedraw); 01204 // NtUserSetScrollPos(plb->spwnd, SB_VERT, 0, plb->fRedraw); 01205 xxxLBShowHideScrollBars(plb); // takes care of fRedraw 01206 01207 return 0; 01208 }

void xxxLBShowHideScrollBars PLBIV  plb  ) 
 

Definition at line 125 of file lboxctl1.c.

References BOOL, FALSE, tagLBIV::fFromInsert, tagLBIV::fHorzBar, tagLBIV::fMultiColumn, tagLBIV::fRedraw, tagLBIV::fVertBar, tagLBIV::iTop, TRUE, tagLBIV::xOrigin, xxxLBoxCtlHScroll(), xxxNewITop(), and xxxSetLBScrollParms().

Referenced by ListBoxWndProcWorker(), xxxLbDir(), xxxLBInsertItem(), xxxLBoxCtlDelete(), xxxLBoxCtlHScroll(), xxxLBoxCtlHScrollMultiColumn(), xxxLBoxCtlKeyInput(), xxxLBoxCtlScroll(), xxxLBResetContent(), xxxLBSetCount(), xxxLBSetRedraw(), and xxxLBSize().

00127 { 00128 BOOL fVertDone = FALSE; 00129 BOOL fHorzDone = FALSE; 00130 00131 // Don't do anything if there are no scrollbars or if parents 00132 // are invisible. 00133 if ((!plb->fHorzBar && !plb->fVertBar) || !plb->fRedraw) 00134 return; 00135 00136 // 00137 // Adjust iTop if necessary but DO NOT REDRAW PERIOD. We never did 00138 // in 3.1. There's a potential bug: 00139 // If someone doesn't have redraw off and inserts an item in the 00140 // same position as the caret, we'll tell them to draw before they may 00141 // have called LB_SETITEMDATA for their item. This is because we turn 00142 // the caret off & on inside of NewITop(), even if the item isn't 00143 // changing. 00144 // So we just want to reflect the position/scroll changes. 00145 // CheckRedraw() will _really_ redraw the visual changes later if 00146 // redraw isn't off. 00147 // 00148 00149 if (!plb->fFromInsert) { 00150 xxxNewITop(plb, plb->iTop); 00151 fVertDone = TRUE; 00152 } 00153 00154 if (!plb->fMultiColumn) { 00155 if (!plb->fFromInsert) { 00156 fHorzDone = TRUE; 00157 xxxLBoxCtlHScroll(plb, SB_THUMBPOSITION, plb->xOrigin); 00158 } 00159 00160 if (!fVertDone) 00161 xxxSetLBScrollParms(plb, SB_VERT); 00162 } 00163 if (!fHorzDone) 00164 xxxSetLBScrollParms(plb, SB_HORZ); 00165 }

int xxxSetLBScrollParms PLBIV  plb,
int  nCtl
 

Definition at line 26 of file lboxctl1.c.

References BOOL, tagLBIV::cItemFullMax, _SCROLLPOS::cItems, tagLBIV::cMac, FALSE, tagLBIV::fDisableNoScroll, tagLBIV::fHorzBar, tagLBIV::fHorzInitialized, _SCROLLPOS::fMask, tagLBIV::fMultiColumn, tagLBIV::fRedraw, tagLBIV::fRightAlign, tagLBIV::fVertBar, tagLBIV::fVertInitialized, tagLBIV::HPos, HWq, _SCROLLPOS::iPage, _SCROLLPOS::iPos, _SCROLLPOS::iReturn, tagLBIV::itemsPerColumn, tagLBIV::iTop, max, tagLBIV::maxWidth, min, NtUserSetScrollInfo(), tagLBIV::numberOfColumns, PSCROLLPOS, tagWND::rcClient, tagLBIV::spwnd, TRUE, UINT, tagLBIV::VPos, and tagLBIV::xOrigin.

Referenced by xxxLBoxCtlHScroll(), xxxLBShowHideScrollBars(), and xxxNewITopEx().

00027 { 00028 int iPos; 00029 int cItems; 00030 UINT iPage; 00031 SCROLLINFO si; 00032 BOOL fNoScroll = FALSE; 00033 PSCROLLPOS psp; 00034 BOOL fCacheInitialized; 00035 int iReturn; 00036 00037 if (nCtl == SB_VERT) { 00038 iPos = plb->iTop; 00039 cItems = plb->cMac; 00040 iPage = plb->cItemFullMax; 00041 if (!plb->fVertBar) 00042 fNoScroll = TRUE; 00043 psp = &plb->VPos; 00044 fCacheInitialized = plb->fVertInitialized; 00045 } else { 00046 if (plb->fMultiColumn) { 00047 iPos = plb->iTop / plb->itemsPerColumn; 00048 cItems = plb->cMac ? ((plb->cMac - 1) / plb->itemsPerColumn) + 1 : 0; 00049 iPage = plb->numberOfColumns; 00050 if (plb->fRightAlign && cItems) 00051 iPos = cItems - iPos - 1; 00052 } else { 00053 iPos = plb->xOrigin; 00054 cItems = plb->maxWidth; 00055 iPage = plb->spwnd->rcClient.right - plb->spwnd->rcClient.left; 00056 } 00057 00058 if (!plb->fHorzBar) 00059 fNoScroll = TRUE; 00060 psp = &plb->HPos; 00061 fCacheInitialized = plb->fHorzInitialized; 00062 } 00063 00064 if (cItems) 00065 cItems--; 00066 00067 if (fNoScroll) { 00068 // Limit page to 0, posMax + 1 00069 iPage = max(min((int)iPage, cItems + 1), 0); 00070 00071 // Limit pos to 0, posMax - (page - 1). 00072 return(max(min(iPos, cItems - ((iPage) ? (int)(iPage - 1) : 0)), 0)); 00073 } else { 00074 si.fMask = SIF_ALL; 00075 if (plb->fDisableNoScroll) 00076 si.fMask |= SIF_DISABLENOSCROLL; 00077 00078 /* 00079 * If the scrollbar is already where we want it, do nothing. 00080 */ 00081 if (fCacheInitialized) { 00082 if (psp->fMask == si.fMask && 00083 psp->cItems == cItems && psp->iPage == iPage && 00084 psp->iPos == iPos) 00085 return psp->iReturn; 00086 } else if (nCtl == SB_VERT) { 00087 plb->fVertInitialized = TRUE; 00088 } else { 00089 plb->fHorzInitialized = TRUE; 00090 } 00091 00092 si.cbSize = sizeof(SCROLLINFO); 00093 si.nMin = 0; 00094 si.nMax = cItems; 00095 si.nPage = iPage; 00096 00097 if (plb->fMultiColumn && plb->fRightAlign) 00098 si.nPos = (iPos+1) > (int)iPage ? iPos - iPage + 1 : 0; 00099 else 00100 si.nPos = iPos; 00101 00102 iReturn = NtUserSetScrollInfo(HWq(plb->spwnd), nCtl, &si, plb->fRedraw); 00103 if (plb->fMultiColumn && plb->fRightAlign) 00104 iReturn = cItems - (iReturn + iPage - 1); 00105 00106 /* 00107 * Update the position cache 00108 */ 00109 psp->fMask = si.fMask; 00110 psp->cItems = cItems; 00111 psp->iPage = iPage; 00112 psp->iPos = iPos; 00113 psp->iReturn = iReturn; 00114 00115 return iReturn; 00116 } 00117 }


Generated on Sat May 15 19:44:30 2004 for test by doxygen 1.3.7