00038 {
00039 HWND hwnd =
HWq(pwnd);
00040 PAINTSTRUCT ps;
00041 HDC hdc;
00042 LPRECT lprc;
00043
PLBIV plb;
00044
INT iSel;
00045
DWORD dw;
00046
TL tlpwndParent;
00047
UINT wFlags;
00048 LPWSTR lpwsz =
NULL;
00049 LRESULT lReturn = 0;
00050
static BOOL fInit =
TRUE;
00051
00052
CheckLock(pwnd);
00053
00054
VALIDATECLASSANDSIZE(pwnd, FNID_LISTBOX);
00055
INITCONTROLLOOKASIDE(&ListboxLookaside,
LBIV, spwnd, 4);
00056
00057
00058
00059
00060
00061
00062 plb = ((
PLBWND)pwnd)->pLBIV;
00063
00064
00065
00066
00067
if (fAnsi) {
00068
switch (message) {
00069
case LB_ADDSTRING:
00070
case LB_ADDSTRINGUPPER:
00071
case LB_ADDSTRINGLOWER:
00072
case LB_FINDSTRING:
00073
case LB_FINDSTRINGEXACT:
00074
case LB_INSERTSTRING:
00075
case LB_INSERTSTRINGUPPER:
00076
case LB_INSERTSTRINGLOWER:
00077
case LB_SELECTSTRING:
00078
if (!plb->
fHasStrings) {
00079
break;
00080 }
00081
00082
case LB_ADDFILE:
00083
case LB_DIR:
00084
if (lParam) {
00085
if (!MBToWCS((LPSTR)lParam, -1, &lpwsz, -1, TRUE))
00086
return LB_ERR;
00087 }
00088
break;
00089
default:
00090
break;
00091 }
00092
if (lpwsz) {
00093 lParam = (LPARAM)lpwsz;
00094 }
00095 }
00096
00097
switch (message) {
00098
00099
case LB_GETTOPINDEX:
00100
return plb->
iTop;
00101
00102
case LB_SETTOPINDEX:
00103
if (wParam && ((
INT)wParam < 0 || (INT)wParam >= plb->
cMac)) {
00104 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,
"");
00105
return LB_ERR;
00106 }
00107
if (plb->
cMac) {
00108
xxxNewITop(plb, (INT)wParam);
00109 }
00110
break;
00111
00112
case WM_STYLECHANGED:
00113 plb->
fRtoLReading = (
TestWF(pwnd, WEFRTLREADING) != 0);
00114 plb->
fRightAlign = (
TestWF(pwnd, WEFRIGHT) != 0);
00115
xxxCheckRedraw(plb, FALSE, 0);
00116
break;
00117
00118
case WM_WINDOWPOSCHANGED:
00119
00120
00121
00122
00123
00124
00125
if (!plb->
fIgnoreSizeMsg)
00126
goto CallDWP;
00127
break;
00128
00129
case WM_SIZE:
00130
00131
00132
00133
00134
00135
if (!plb->
fIgnoreSizeMsg)
00136
xxxLBSize(plb,
GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam));
00137
break;
00138
00139
case WM_ERASEBKGND:
00140
ThreadLock(plb->
spwndParent, &tlpwndParent);
00141
FillWindow(
HW(plb->
spwndParent), hwnd, (HDC)wParam,
00142 (HBRUSH)CTLCOLOR_LISTBOX);
00143
ThreadUnlock(&tlpwndParent);
00144
return TRUE;
00145
00146
case LB_RESETCONTENT:
00147
xxxLBResetContent(plb);
00148
break;
00149
00150
case WM_TIMER:
00151
if (wParam ==
IDSYS_LBSEARCH) {
00152 plb->
iTypeSearch = 0;
00153
NtUserKillTimer(hwnd, IDSYS_LBSEARCH);
00154
xxxInvertLBItem(plb, plb->
iSel, TRUE);
00155
break;
00156 }
00157
00158 message = WM_MOUSEMOVE;
00159
xxxTrackMouse(plb, message, plb->
ptPrev);
00160
break;
00161
00162
00163
00164
00165
case WM_MOUSEMOVE:
00166
case WM_LBUTTONDOWN:
00167
case WM_LBUTTONUP:
00168
case WM_LBUTTONDBLCLK:
00169 {
00170 POINT pt;
00171
00172 POINTSTOPOINT(pt, lParam);
00173
xxxTrackMouse(plb, message, pt);
00174 }
00175
break;
00176
00177
case WM_MBUTTONDOWN:
00178
EnterReaderModeHelper(hwnd);
00179
break;
00180
00181
case WM_CAPTURECHANGED:
00182
00183
00184
00185
00186 UserAssert(
TestWF(pwnd, WFWIN40COMPAT));
00187
if (plb->
fCaptured)
00188
xxxLBButtonUp(plb, LBUP_NOTIFY);
00189
break;
00190
00191
case LBCB_STARTTRACK:
00192
00193
00194
00195
if (!plb->
pcbox)
00196
break;
00197
00198 plb->
fCaptured =
FALSE;
00199
if (wParam) {
00200 POINT pt;
00201
00202 POINTSTOPOINT(pt, lParam);
00203
00204
_ScreenToClient(pwnd, &pt);
00205
xxxTrackMouse(plb, WM_LBUTTONDOWN, pt);
00206 }
else {
00207
NtUserSetCapture(hwnd);
00208 plb->
fCaptured =
TRUE;
00209 plb->
iLastSelection = plb->
iSel;
00210 }
00211
break;
00212
00213
case LBCB_ENDTRACK:
00214
00215
if (plb->
fCaptured)
00216
xxxLBButtonUp(plb, LBUP_RELEASECAPTURE | (wParam ? LBUP_SELCHANGE :
00217 LBUP_RESETSELECTION));
00218
break;
00219
00220
case WM_PRINTCLIENT:
00221
xxxLBPaint(plb, (HDC) wParam, NULL);
00222
break;
00223
00224
case WM_PAINT:
00225
if (wParam) {
00226 hdc = (HDC) wParam;
00227 lprc =
NULL;
00228 }
else {
00229 hdc =
NtUserBeginPaint(hwnd, &ps);
00230 lprc = &(ps.rcPaint);
00231 }
00232
00233
if (
IsLBoxVisible(plb))
00234
xxxLBPaint(plb, hdc, lprc);
00235
00236
if (!wParam)
00237
NtUserEndPaint(hwnd, &ps);
00238
break;
00239
00240
case WM_NCDESTROY:
00241
case WM_FINALDESTROY:
00242
xxxDestroyLBox(plb, pwnd);
00243
break;
00244
00245
case WM_SETFOCUS:
00246
00247
CaretCreate(plb);
00248
xxxLBSetCaret(plb, TRUE);
00249
xxxNotifyOwner(plb, LBN_SETFOCUS);
00250
if (
FWINABLE()) {
00251
if (
_IsWindowVisible(pwnd)) {
00252
LBEvent(plb, EVENT_OBJECT_FOCUS, plb->
iSelBase);
00253 }
00254 }
00255
break;
00256
00257
case WM_KILLFOCUS:
00258
00259
00260
00261
gcWheelDelta = 0;
00262
00263
xxxLBSetCaret(plb, FALSE);
00264
xxxCaretDestroy(plb);
00265
xxxNotifyOwner(plb, LBN_KILLFOCUS);
00266
if (plb->
iTypeSearch) {
00267 plb->
iTypeSearch = 0;
00268
NtUserKillTimer(hwnd, IDSYS_LBSEARCH);
00269 }
00270
if (plb->
pszTypeSearch) {
00271
UserLocalFree(plb->
pszTypeSearch);
00272 plb->
pszTypeSearch =
NULL;
00273 }
00274
break;
00275
00276
case WM_MOUSEWHEEL:
00277 {
00278
int cDetants;
00279
int cPage;
00280
int cLines;
00281 RECT rc;
00282
int windowWidth;
00283
int cPos;
00284
00285
00286
00287
00288
if (wParam & (MK_SHIFT | MK_CONTROL)) {
00289
goto CallDWP;
00290 }
00291
00292 lReturn = 1;
00293
gcWheelDelta -= (
short) HIWORD(wParam);
00294 cDetants =
gcWheelDelta / WHEEL_DELTA;
00295
if ( cDetants != 0 &&
00296
gpsi->ucWheelScrollLines > 0 &&
00297 (pwnd->style & (WS_VSCROLL | WS_HSCROLL))) {
00298
00299
gcWheelDelta =
gcWheelDelta % WHEEL_DELTA;
00300
00301
if (pwnd->style & WS_VSCROLL) {
00302 cPage =
max(1, (plb->
cItemFullMax - 1));
00303 cLines = cDetants *
00304 (
int)
min((UINT) cPage,
gpsi->ucWheelScrollLines);
00305
00306 cPos =
max(0,
min(plb->
iTop + cLines, plb->
cMac - 1));
00307
if (cPos != plb->
iTop) {
00308
xxxLBoxCtlScroll(plb, SB_THUMBPOSITION, cPos);
00309
xxxLBoxCtlScroll(plb, SB_ENDSCROLL, 0);
00310 }
00311 }
else if (plb->
fMultiColumn) {
00312 cPage =
max(1, plb->
numberOfColumns);
00313 cLines = cDetants * (
int)
min((UINT) cPage,
gpsi->ucWheelScrollLines);
00314 cPos =
max(
00315 0,
00316
min((plb->
iTop / plb->
itemsPerColumn) + cLines,
00317 plb->
cMac - 1 - ((plb->
cMac - 1) % plb->
itemsPerColumn)));
00318
00319
if (cPos != plb->
iTop) {
00320
xxxLBoxCtlHScrollMultiColumn(plb, SB_THUMBPOSITION, cPos);
00321
xxxLBoxCtlHScrollMultiColumn(plb, SB_ENDSCROLL, 0);
00322 }
00323 }
else {
00324
_GetClientRect(plb->
spwnd, &rc);
00325 windowWidth = rc.right;
00326 cPage =
max(plb->
cxChar, (windowWidth / 3) * 2) /
00327 plb->
cxChar;
00328
00329 cLines = cDetants *
00330 (
int)
min((UINT) cPage,
gpsi->ucWheelScrollLines);
00331
00332 cPos =
max(
00333 0,
00334
min(plb->
xOrigin + (cLines * plb->
cxChar),
00335 plb->
maxWidth));
00336
00337
if (cPos != plb->
xOrigin) {
00338
xxxLBoxCtlHScroll(plb, SB_THUMBPOSITION, cPos);
00339
xxxLBoxCtlHScroll(plb, SB_ENDSCROLL, 0);
00340 }
00341 }
00342 }
00343 }
00344
break;
00345
00346
case WM_VSCROLL:
00347
xxxLBoxCtlScroll(plb, LOWORD(wParam), HIWORD(wParam));
00348
break;
00349
00350
case WM_HSCROLL:
00351
xxxLBoxCtlHScroll(plb, LOWORD(wParam), HIWORD(wParam));
00352
break;
00353
00354
case WM_GETDLGCODE:
00355
return DLGC_WANTARROWS | DLGC_WANTCHARS;
00356
00357
case WM_CREATE:
00358
return xxxLBCreate(plb, pwnd, (LPCREATESTRUCT) lParam);
00359
00360
case WM_SETREDRAW:
00361
00362
00363
00364
00365
00366
xxxLBSetRedraw(plb, (wParam != 0));
00367
break;
00368
00369
case WM_ENABLE:
00370
xxxLBInvalidateRect(plb, NULL, !plb->
OwnerDraw);
00371
break;
00372
00373
case WM_SETFONT:
00374
xxxLBSetFont(plb, (HANDLE)wParam, LOWORD(lParam));
00375
break;
00376
00377
case WM_GETFONT:
00378
return (LRESULT)plb->
hFont;
00379
00380
case WM_DRAGSELECT:
00381
case WM_DRAGLOOP:
00382
case WM_DRAGMOVE:
00383
case WM_DROPFILES:
00384
ThreadLock(plb->
spwndParent, &tlpwndParent);
00385 lReturn =
SendMessage(
HW(plb->
spwndParent), message, wParam, lParam);
00386
ThreadUnlock(&tlpwndParent);
00387
return lReturn;
00388
00389
00390
case WM_QUERYDROPOBJECT:
00391
case WM_DROPOBJECT:
00392
00393
00394
00395
00396
LBDropObjectHandler(plb, (PDROPSTRUCT)lParam);
00397
ThreadLock(plb->
spwndParent, &tlpwndParent);
00398 lReturn =
SendMessage(
HW(plb->
spwndParent), message, wParam, lParam);
00399
ThreadUnlock(&tlpwndParent);
00400
return lReturn;
00401
00402
case LB_GETITEMRECT:
00403
return LBGetItemRect(plb, (INT)wParam, (LPRECT)lParam);
00404
00405
case LB_GETITEMDATA:
00406
return LBGetItemData(plb, (INT)wParam);
00407
00408
case LB_SETITEMDATA:
00409
00410
00411
00412
00413
return LBSetItemData(plb, (INT)wParam, lParam);
00414
00415
case LB_ADDSTRINGUPPER:
00416 wFlags =
UPPERCASE |
LBI_ADD;
00417
goto CallInsertItem;
00418
00419
case LB_ADDSTRINGLOWER:
00420 wFlags =
LOWERCASE |
LBI_ADD;
00421
goto CallInsertItem;
00422
00423
case LB_ADDSTRING:
00424 wFlags =
LBI_ADD;
00425
goto CallInsertItem;
00426
00427
case LB_INSERTSTRINGUPPER:
00428 wFlags =
UPPERCASE;
00429
goto CallInsertItem;
00430
00431
case LB_INSERTSTRINGLOWER:
00432 wFlags =
LOWERCASE;
00433
goto CallInsertItem;
00434
00435
case LB_INSERTSTRING:
00436 wFlags = 0;
00437 CallInsertItem:
00438 lReturn = ((LRESULT)
xxxLBInsertItem(plb, (LPWSTR) lParam, (
int) wParam, wFlags));
00439
break;
00440
00441
case LB_INITSTORAGE:
00442
return xxxLBInitStorage(plb, fAnsi, (INT)wParam, (INT)lParam);
00443
00444
case LB_DELETESTRING:
00445
return xxxLBoxCtlDelete(plb, (INT)wParam);
00446
00447
case LB_DIR:
00448
00449
00450
00451
00452 lReturn =
xxxLbDir(plb, (INT)wParam, (LPWSTR)lParam);
00453
break;
00454
00455
case LB_ADDFILE:
00456 lReturn =
xxxLbInsertFile(plb, (LPWSTR)lParam);
00457
break;
00458
00459
case LB_SETSEL:
00460
return xxxLBSetSel(plb, (wParam != 0), (INT)lParam);
00461
00462
case LB_SETCURSEL:
00463
00464
00465
00466
00467
return xxxLBSetCurSel(plb, (INT)wParam);
00468
00469
case LB_GETSEL:
00470
if (wParam >= (
UINT) plb->
cMac)
00471
return((LRESULT) LB_ERR);
00472
00473
return IsSelected(plb, (INT)wParam, SELONLY);
00474
00475
case LB_GETCURSEL:
00476
if (plb->
wMultiple ==
SINGLESEL) {
00477
return plb->
iSel;
00478 }
00479
return plb->
iSelBase;
00480
00481
case LB_SELITEMRANGE:
00482
if (plb->
wMultiple ==
SINGLESEL) {
00483
00484
00485
00486 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,
"Invalid index passed to LB_SELITEMRANGE");
00487
return LB_ERR;
00488 }
00489
00490
xxxLBSelRange(plb, LOWORD(lParam), HIWORD(lParam), (wParam != 0));
00491
break;
00492
00493
case LB_SELITEMRANGEEX:
00494
if (plb->
wMultiple ==
SINGLESEL) {
00495
00496
00497
00498 RIPERR0(ERROR_INVALID_LB_MESSAGE, RIP_VERBOSE,
"LB_SELITEMRANGEEX:Can't select a range if only single selections are enabled");
00499
return LB_ERR;
00500 }
else {
00501
BOOL fHighlight = ((
DWORD)lParam > (
DWORD)wParam);
00502
if (fHighlight ==
FALSE) {
00503 ULONG_PTR temp = lParam;
00504 lParam = wParam;
00505 wParam = temp;
00506 }
00507
xxxLBSelRange(plb, (INT)wParam, (INT)lParam, fHighlight);
00508 }
00509
break;
00510
00511
case LB_GETTEXTLEN:
00512
if (lParam != 0) {
00513 RIPMSG1(RIP_WARNING,
"LB_GETTEXTLEN with lParam = %lx\n", lParam);
00514 }
00515 lReturn =
LBGetText(plb, TRUE, fAnsi, (INT)wParam, NULL);
00516
break;
00517
00518
case LB_GETTEXT:
00519 lReturn =
LBGetText(plb, FALSE, fAnsi, (INT)wParam, (LPWSTR)lParam);
00520
break;
00521
00522
case LB_GETCOUNT:
00523
00524
00525
00526
if(plb)
00527
return((LRESULT) plb->
cMac);
00528
else
00529
return(0);
00530
00531
case LB_SETCOUNT:
00532
return xxxLBSetCount(plb, (INT)wParam);
00533
00534
case LB_SELECTSTRING:
00535
case LB_FINDSTRING:
00536 iSel =
xxxFindString(plb, (LPWSTR)lParam, (INT)wParam, PREFIX, TRUE);
00537
if (message == LB_FINDSTRING || iSel == LB_ERR) {
00538 lReturn = iSel;
00539 }
else {
00540 lReturn =
xxxLBSetCurSel(plb, iSel);
00541 }
00542
break;
00543
00544
case LB_GETLOCALE:
00545
return plb->
dwLocaleId;
00546
00547
case LB_SETLOCALE:
00548
00549
00550
00551
00552 wParam = ConvertDefaultLocale((LCID)wParam);
00553
if (!IsValidLocale((LCID)wParam, LCID_INSTALLED))
00554
return LB_ERR;
00555
00556 dw = plb->
dwLocaleId;
00557 plb->
dwLocaleId = (
DWORD)wParam;
00558
return dw;
00559
00560
case WM_KEYDOWN:
00561
00562
00563
00564
00565
00566
xxxLBoxCtlKeyInput(plb, message, LOWORD(wParam));
00567
break;
00568
00569
case WM_CHAR:
00570
xxxLBoxCtlCharInput(plb, LOWORD(wParam), fAnsi);
00571
break;
00572
00573
case LB_GETSELITEMS:
00574
case LB_GETSELCOUNT:
00575
00576
00577
00578
00579
return LBoxGetSelItems(plb, (message == LB_GETSELCOUNT), (INT)wParam,
00580 (LPINT)lParam);
00581
00582
case LB_SETTABSTOPS:
00583
00584
00585
00586
00587
return LBSetTabStops(plb, (INT)wParam, (LPINT)lParam);
00588
00589
case LB_GETHORIZONTALEXTENT:
00590
00591
00592
00593
00594
return plb->
maxWidth;
00595
00596
case LB_SETHORIZONTALEXTENT:
00597
00598
00599
00600
00601
if (plb->
maxWidth != (
INT)wParam) {
00602 plb->
maxWidth = (
INT)wParam;
00603
00604
00605
00606
00607
00608
00609
xxxLBShowHideScrollBars(plb);
00610
if (plb->
fHorzBar && plb->
fRightAlign && !(plb->
fMultiColumn || plb->
OwnerDraw)) {
00611
00612
00613
00614
xxxLBoxCtlHScroll(plb, SB_BOTTOM, 0);
00615 }
00616 }
00617
break;
00618
00619
case LB_SETCOLUMNWIDTH:
00620
00621
00622
00623
00624 plb->
cxColumn = (
INT)wParam;
00625
LBCalcItemRowsAndColumns(plb);
00626
if (
IsLBoxVisible(plb))
00627
NtUserInvalidateRect(hwnd, NULL, TRUE);
00628
xxxLBShowHideScrollBars(plb);
00629
break;
00630
00631
case LB_SETANCHORINDEX:
00632
if ((
INT)wParam >= plb->
cMac) {
00633 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,
"Invalid index passed to LB_SETANCHORINDEX");
00634
return LB_ERR;
00635 }
00636 plb->
iMouseDown = (
INT)wParam;
00637 plb->
iLastMouseMove = (
INT)wParam;
00638
xxxInsureVisible(plb, (
int) wParam, (BOOL)(lParam != 0));
00639
break;
00640
00641
case LB_GETANCHORINDEX:
00642
return plb->
iMouseDown;
00643
00644
case LB_SETCARETINDEX:
00645
if ( (plb->
iSel == -1) || ((plb->
wMultiple !=
SINGLESEL) &&
00646 (plb->
cMac > (
INT)wParam))) {
00647
00648
00649
00650
00651
00652
00653
xxxInsureVisible(plb, (INT)wParam, (BOOL)LOWORD(lParam));
00654
xxxSetISelBase(plb, (INT)wParam);
00655
break;
00656 }
else {
00657
if ((
INT)wParam >= plb->
cMac) {
00658 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,
"Invalid index passed to LB_SETCARETINDEX");
00659 }
00660
return LB_ERR;
00661 }
00662
break;
00663
00664
case LB_GETCARETINDEX:
00665
return plb->
iSelBase;
00666
00667
case LB_SETITEMHEIGHT:
00668
case LB_GETITEMHEIGHT:
00669
return LBGetSetItemHeightHandler(plb, message, (INT)wParam, LOWORD(lParam));
00670
break;
00671
00672
case LB_FINDSTRINGEXACT:
00673 lReturn =
xxxFindString(plb, (LPWSTR)lParam, (INT)wParam, EQ, TRUE);
00674
break;
00675
00676
case LB_ITEMFROMPOINT: {
00677 POINT pt;
00678
BOOL bOutside;
00679
DWORD dwItem;
00680
00681 POINTSTOPOINT(pt, lParam);
00682 bOutside =
ISelFromPt(plb, pt, &dwItem);
00683 UserAssert(bOutside == 1 || bOutside == 0);
00684
return (LRESULT)MAKELONG(dwItem, bOutside);
00685 }
00686
00687
case LBCB_CARETON:
00688
00689
00690
00691
00692
CaretCreate(plb);
00693
00694 plb->
iSelBase = plb->
iSel;
00695
xxxLBSetCaret(plb, TRUE);
00696
if (
FWINABLE()) {
00697
if (
_IsWindowVisible(pwnd)) {
00698
LBEvent(plb, EVENT_OBJECT_FOCUS, plb->
iSelBase);
00699 }
00700 }
00701
return(plb->
iSel);
00702
00703
case LBCB_CARETOFF:
00704
00705
00706
00707
00708
xxxLBSetCaret(plb, FALSE);
00709
xxxCaretDestroy(plb);
00710
break;
00711
00712
case WM_NCCREATE:
00713
if ((pwnd->style & LBS_MULTICOLUMN) && (pwnd->style & WS_VSCROLL))
00714 {
00715
DWORD mask = WS_VSCROLL;
00716
DWORD flags = 0;
00717
if (!
TestWF(pwnd, WFWIN40COMPAT)) {
00718 mask |= WS_HSCROLL;
00719 flags = WS_HSCROLL;
00720 }
00721
NtUserAlterWindowStyle(hwnd, mask, flags);
00722 }
00723
goto CallDWP;
00724
00725
default:
00726 CallDWP:
00727
return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi);
00728 }
00729
00730
00731
00732
00733
if (lpwsz) {
00734
UserLocalFree(lpwsz);
00735 }
00736
00737
return lReturn;
00738 }