00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#include "precomp.h"
00014
#pragma hdrstop
00015
00016
INT xxxLBBinarySearchString(
PLBIV plb,LPWSTR lpstr);
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 int xxxSetLBScrollParms(
PLBIV plb,
int nCtl)
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
00069 iPage =
max(
min((
int)iPage, cItems + 1), 0);
00070
00071
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
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
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 }
00118
00119
00120
00121
00122
00123
00124
00125 void xxxLBShowHideScrollBars(
00126
PLBIV plb)
00127 {
00128
BOOL fVertDone =
FALSE;
00129
BOOL fHorzDone =
FALSE;
00130
00131
00132
00133
if ((!plb->
fHorzBar && !plb->
fVertBar) || !plb->
fRedraw)
00134
return;
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
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 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 LONG_PTR
LBGetItemData(
00177
PLBIV plb,
00178 INT sItem)
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
00189
00190
if (!plb->
fHasData) {
00191
return 0
L;
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 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 INT LBGetText(
00215
PLBIV plb,
00216 BOOL fLengthOnly,
00217 BOOL fAnsi,
00218 INT index,
00219 LPWSTR lpbuffer)
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
00233
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
00248
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
00261
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 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 BOOL GrowMem(
00286
PLBIV plb,
00287 INT numItems)
00288
00289 {
00290 LONG cb;
00291 HANDLE hMem;
00292
00293
00294
00295
00296 cb = (plb->
cMax + numItems) *
00297 (plb->
fHasStrings ?
sizeof(
LBItem)
00298 : (plb->
fHasData ?
sizeof(
LBODItem)
00299 : 0));
00300
00301
00302
00303
00304
00305
if (plb->
wMultiple !=
SINGLESEL) {
00306 cb += (plb->
cMax + numItems);
00307 }
00308
00309
00310
00311
00312
if (plb->
OwnerDraw ==
OWNERDRAWVAR) {
00313 cb += (plb->
cMax + numItems);
00314 }
00315
00316
00317
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 }
00335
00336
00337
00338
00339
00340
00341
00342 LONG
xxxLBInitStorage(
PLBIV plb, BOOL fAnsi, INT cItems, INT cb)
00343 {
00344 HANDLE hMem;
00345
INT cbChunk;
00346
00347
00348
00349
00350
00351
if (fAnsi) {
00352 cb *=
sizeof(WCHAR) ;
00353 }
00354
00355
00356
00357
00358
if ((cItems < 0) || (cb < 0)) {
00359
xxxNotifyOwner(plb, LBN_ERRSPACE);
00360
return LB_ERRSPACE;
00361 }
00362
00363
00364
00365
00366
00367 cItems -= plb->
cMax - plb->
cMac ;
00368
if ((cItems > 0) && !
GrowMem(plb, cItems)) {
00369
xxxNotifyOwner(plb, LBN_ERRSPACE);
00370
return LB_ERRSPACE;
00371 }
00372
00373
00374
00375
00376
if (plb->
fHasStrings) {
00377
if ((cbChunk = (plb->
ichAlloc + cb)) > plb->
cchStrings) {
00378
00379
00380
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 }
00390 }
00391
00392
00393
00394
00395
return plb->
cMax ;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 INT xxxLBInsertItem(
00408
PLBIV plb,
00409
00410
00411
00412
00413
00414 LPWSTR lpsz,
00415 INT index,
00416 UINT wFlags)
00417 {
00418 MEASUREITEMSTRUCT measureItemStruct;
00419
INT cbString;
00420
INT cbChunk;
00421
PBYTE lp;
00422
PBYTE lpT;
00423
PBYTE lpHeightStart;
00424 LONG cbItem;
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, 0
L);
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
00462
00463 cbString = (wcslen(lpsz) + 1)*
sizeof(WCHAR);
00464
00465
if ((cbChunk = (plb->
ichAlloc + cbString)) > plb->
cchStrings) {
00466
00467
00468
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
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
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
00507
00508
00509
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
00519
00520 cbChunk += plb->
cMac;
00521 }
00522
00523
if (plb->
OwnerDraw ==
OWNERDRAWVAR) {
00524
00525
00526
00527
00528 cbChunk += plb->
cMac;
00529 }
00530
00531
00532
00533
00534
00535 lpT += (index * cbItem);
00536 RtlMoveMemory(lpT + cbItem, lpT, cbChunk);
00537
if (!plb->
fHasStrings && plb->
OwnerDraw) {
00538
if (plb->
fHasData) {
00539
00540
00541
00542
lpLBODItem p = (
lpLBODItem)lpT;
00543 p->
itemData = (ULONG_PTR)lpsz;
00544 }
00545 }
else {
00546
lpLBItem p = ((
lpLBItem)lpT);
00547
00548
00549
00550
00551 p->
offsz = (LONG)(plb->
ichAlloc);
00552 p->
itemData = 0;
00553 plb->
ichAlloc += cbString;
00554 }
00555
00556
00557
00558
00559
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;
00566 }
00567
00568
00569
00570
00571
00572 plb->
cMac++;
00573
00574
00575
00576
00577
00578
if (plb->
OwnerDraw ==
OWNERDRAWVAR) {
00579
00580
00581
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
00590
00591 measureItemStruct.CtlType = ODT_LISTBOX;
00592 measureItemStruct.CtlID = PtrToUlong(plb->
spwnd->
spmenu);
00593 measureItemStruct.itemID = index;
00594
00595
00596
00597
00598 measureItemStruct.itemHeight = (
UINT)
gpsi->cySysFontChar;
00599 measureItemStruct.itemData = (ULONG_PTR)lpsz;
00600
00601
00602
00603
00604
00605
00606
00607
00608
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
00626
00627
00628
if ((plb->
wMultiple ==
SINGLESEL) && (plb->
iSel >= index))
00629 plb->
iSel++;
00630
00631
if (plb->
OwnerDraw ==
OWNERDRAWVAR)
00632
LBSetCItemFullMax(plb);
00633
00634
00635
00636
00637 plb->
fFromInsert =
TRUE;
00638
xxxLBShowHideScrollBars(plb);
00639
if (plb->
fHorzBar && plb->
fRightAlign && !(plb->
fMultiColumn || plb->
OwnerDraw)) {
00640
00641
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 }
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 INT LBlstrcmpi(
00672 LPWSTR lpStr1,
00673 LPWSTR lpStr2,
00674 DWORD dwLocaleId)
00675 {
00676
00677
00678
00679
00680
00681
00682
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
00702
00703
return (*pfnWowIlstrcmp)(lpStr1, lpStr2);
00704 }
00705
return (
INT)CompareStringW((LCID)dwLocaleId, NORM_IGNORECASE,
00706 lpStr1, -1, lpStr2, -1 ) - 2;
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 INT xxxLBBinarySearchString(
00723
PLBIV plb,
00724 LPWSTR lpstr)
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
00754
00755 pszLB = (LPWSTR)((LPSTR)pszLBBase + ((
lpLBItem)lprgpch)[itemnew].offsz);
00756 sortResult =
LBlstrcmpi(pszLB, lpstr, plb->
dwLocaleId);
00757 }
else {
00758
00759
00760
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 }
00790
00791
00792
00793
00794
00795
00796
00797 BOOL xxxLBResetContent(
00798
PLBIV plb)
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 }
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842 INT xxxLBoxCtlDelete(
00843
PLBIV plb,
00844 INT sItem)
00845 {
00846 LONG cb;
00847 LPBYTE lp;
00848 LPBYTE lpT;
00849 RECT rc;
00850
int cbItem;
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
00873
00874
00875
SendMessageWorker(plb->
spwnd, LB_RESETCONTENT, 0, 0,
FALSE);
00876
goto FinishUpDelete;
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
if (
LBGetItemRect(plb, (
INT)(plb->
cMac - 1), &rc)) {
00886
xxxLBInvalidateRect(plb, &rc,
TRUE);
00887 }
00888
00889
00890
00891
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
00904
00905
if (plb->
wMultiple !=
SINGLESEL) {
00906 cb += (plb->
cMac + 1);
00907 }
00908
00909
if (plb->
OwnerDraw ==
OWNERDRAWVAR) {
00910
00911
00912
00913
00914 cb += (plb->
cMac + 1);
00915 }
00916
00917
00918
00919
00920
00921
if ((cb != 0) || plb->
fHasStrings) {
00922 lp = plb->
rgpch;
00923
00924 lpT = (lp + (sItem * cbItem));
00925
00926
if (plb->
fHasStrings) {
00927
00928
00929
00930
00931
00932
00933
00934
00935 pbStrings = (
PBYTE)(plb->
hStrings);
00936 lpString = (LPTSTR)(pbStrings + ((
lpLBItem)lpT)->offsz);
00937 cbStringLen = (wcslen(lpString) + 1) *
sizeof(WCHAR);
00938
00939
00940
00941
00942 plb->
ichAlloc = plb->
ichAlloc - cbStringLen;
00943
00944 RtlMoveMemory(lpString, (
PBYTE)lpString + cbStringLen,
00945 plb->
ichAlloc + (pbStrings - (LPBYTE)lpString));
00946
00947
00948
00949
00950
00951
00952
00953
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
00968
00969
00970 RtlMoveMemory(lpT, lpT + cbItem, cb);
00971
00972
00973
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
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
01025
01026
01027
01028
xxxInsureVisible(plb, plb->
iTop,
FALSE);
01029
01030 FinishUpDelete:
01031
01032
01033
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 }
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053 void xxxLBoxDeleteItem(
01054
PLBIV plb,
01055 INT sItem)
01056 {
01057 DELETEITEMSTRUCT dis;
01058
TL tlpwndParent;
01059
01060
CheckLock(plb->
spwnd);
01061
if (plb->
spwnd ==
NULL)
01062
return;
01063
01064
01065
01066
01067
01068
if (!plb->
fHasData) {
01069
return;
01070 }
01071
01072
01073
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
01082
01083
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 }
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 INT xxxLBSetCount(
01108
PLBIV plb,
01109 INT cItems)
01110 {
01111
UINT cbRequired;
01112
BOOL fRedraw;
01113
01114
CheckLock(plb->
spwnd);
01115
01116
01117
01118
01119
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
01132
if (fRedraw = plb->
fRedraw)
01133
xxxLBSetRedraw(plb,
FALSE);
01134
01135 cbRequired =
LBCalcAllocNeeded(plb, cItems);
01136
01137
01138
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) {
01148
01149
01150
01151
01152
01153
if (plb->
rgpch ==
NULL) {
01154 plb->
rgpch =
UserLocalAlloc(HEAP_ZERO_MEMORY, 0
L);
01155 plb->
cMax = 0;
01156
01157
if (plb->
rgpch ==
NULL) {
01158
xxxNotifyOwner(plb, LBN_ERRSPACE);
01159
return LB_ERRSPACE;
01160 }
01161 }
01162
01163
01164
01165
01166
01167
if (cItems >= plb->
cMax) {
01168
INT cMaxNew;
01169
UINT cbNew;
01170 HANDLE hmemNew;
01171
01172
01173
01174
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
01191
01192 RtlZeroMemory(plb->
rgpch, cbRequired);
01193 }
01194
01195 plb->
cMac = cItems;
01196
01197
01198
if (fRedraw)
01199
xxxLBSetRedraw(plb,
TRUE);
01200
01201
xxxLBInvalidateRect(plb,
NULL,
TRUE);
01202
01203
01204
01205
xxxLBShowHideScrollBars(plb);
01206
01207
return 0;
01208 }
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220 UINT LBCalcAllocNeeded(
01221
PLBIV plb,
01222 INT cItems)
01223 {
01224
UINT cb;
01225
01226
01227
01228
01229 cb = cItems * (plb->
fHasStrings ?
sizeof(
LBItem)
01230 : (plb->
fHasData ?
sizeof(
LBODItem)
01231 : 0));
01232
01233
01234
01235
01236
01237
if (plb->
wMultiple !=
SINGLESEL) {
01238 cb += cItems;
01239 }
01240
01241
01242
01243
01244
if (plb->
OwnerDraw ==
OWNERDRAWVAR) {
01245 cb += cItems;
01246 }
01247
01248
return cb;
01249 }