00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#include "precomp.h"
00014
#pragma hdrstop
00015
00016 LOOKASIDE ComboboxLookaside;
00017
00018
BOOL NtUserTrackMouseEvent(TRACKMOUSEEVENT *ptme);
00019 LONG
xxxCBGetTextLengthHelper(
PCBOX pcbox, BOOL fAnsi);
00020 LONG
xxxCBGetTextHelper(
PCBOX pcbox,
int len, LPWSTR lpstr, BOOL fAnsi);
00021
00022
00023
00024
00025
00026
00027
00028
00029 void xxxPressButton(
PCBOX pcbox, BOOL fPress)
00030 {
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
if ((pcbox->
fButtonPressed != 0) != (fPress != 0)) {
00050
00051 HWND hwnd =
HWq(pcbox->
spwnd);
00052
00053 pcbox->
fButtonPressed = (fPress != 0);
00054
if (pcbox->
f3DCombo)
00055
NtUserInvalidateRect(hwnd, &pcbox->
buttonrc,
TRUE);
00056
else
00057 {
00058 RECT rc;
00059
00060
CopyRect(&rc, &pcbox->
buttonrc);
00061
InflateRect(&rc, 0,
SYSMET(CYEDGE));
00062
NtUserInvalidateRect(hwnd, &rc,
TRUE);
00063 }
00064
UpdateWindow(hwnd);
00065
00066
if (
FWINABLE()) {
00067
NotifyWinEvent(EVENT_OBJECT_STATECHANGE, hwnd, OBJID_CLIENT, INDEX_COMBOBOX_BUTTON);
00068 }
00069 }
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
#ifdef COLOR_HOTTRACKING
00081
00082
void HotTrack(
PCBOX pcbox)
00083 {
00084
if (!pcbox->fButtonHotTracked && !pcbox->
fMouseDown) {
00085 HWND hwnd =
HWq(pcbox->
spwnd);
00086 TRACKMOUSEEVENT tme = {
sizeof(TRACKMOUSEEVENT), TME_LEAVE, hwnd, 0};
00087
if (
NtUserTrackMouseEvent(&tme)) {
00088 pcbox->fButtonHotTracked =
TRUE;
00089
NtUserInvalidateRect(hwnd, &pcbox->
buttonrc, TRUE);
00090 }
00091 }
00092 }
00093
00094
#endif // COLOR_HOTTRACKING
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 LRESULT
ComboBoxDBCharHandler(
00105
PCBOX pcbox,
00106 HWND hwnd,
00107 UINT message,
00108 WPARAM wParam,
00109 LPARAM lParam)
00110 {
00111 WORD w;
00112
PWND pwndSend;
00113
00114 w =
DbcsCombine(hwnd, (
BYTE)wParam);
00115
if (w == 0) {
00116
return CB_ERR;
00117 }
00118
00119 UserAssert(pcbox->
spwndList);
00120
if (pcbox->
fNoEdit) {
00121 pwndSend = pcbox->
spwndList;
00122 }
else if (pcbox->
spwndEdit) {
00123 RIPMSG1(RIP_WARNING,
"ComboBoxWndProcWorker: WM_CHAR is posted to Combobox itself(%08x).",
00124 hwnd);
00125 pwndSend = pcbox->
spwndEdit;
00126 }
else {
00127
return CB_ERR;
00128 }
00129
00130 RIPMSG1(RIP_VERBOSE,
"ComboBoxWndProcWorker: sending WM_CHAR %04x", w);
00131
00132
if (!
TestWF(pwndSend,
WFANSIPROC)) {
00133
00134
00135
00136
00137 WCHAR wChar;
00138 LPWSTR lpwstr = &wChar;
00139
00140
if (
MBToWCSEx(
THREAD_CODEPAGE(), (LPCSTR)&w, 2, &lpwstr, 1,
FALSE) == 0) {
00141 RIPMSG1(RIP_WARNING,
"ComboBoxWndProcWorker: cannot convert 0x%04x to UNICODE.", w);
00142
return CB_ERR;
00143 }
00144
return SendMessageWorker(pwndSend, message, wChar, lParam,
FALSE);
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154 PostMessageA(
HWq(pwndSend), message,
CrackCombinedDbcsTB(w), lParam);
00155
return SendMessageWorker(pwndSend, message, wParam, lParam,
TRUE);
00156 }
00157
00158 BOOL ComboBoxMsgOKInInit(UINT message, LRESULT* plRet)
00159 {
00160
switch (message) {
00161
default:
00162
break;
00163
case WM_SIZE:
00164 *plRet = 0;
00165
return FALSE;
00166
case WM_STYLECHANGED:
00167
case WM_GETTEXT:
00168
case WM_GETTEXTLENGTH:
00169
case WM_PRINT:
00170
case WM_COMMAND:
00171
case CBEC_KILLCOMBOFOCUS:
00172
case WM_PRINTCLIENT:
00173
case WM_SETFONT:
00174
case WM_SYSKEYDOWN:
00175
case WM_KEYDOWN:
00176
case WM_CHAR:
00177
case WM_LBUTTONDBLCLK:
00178
case WM_LBUTTONDOWN:
00179
case WM_MOUSEWHEEL:
00180
case WM_CAPTURECHANGED:
00181
case WM_LBUTTONUP:
00182
case WM_MOUSEMOVE:
00183
case WM_SETFOCUS:
00184
case WM_KILLFOCUS:
00185
case WM_SETREDRAW:
00186
case WM_ENABLE:
00187
case CB_SETDROPPEDWIDTH:
00188
case CB_DIR:
00189
case CB_ADDSTRING:
00190
00191
00192
00193 *plRet = CB_ERR;
00194
return FALSE;
00195 }
00196
return TRUE;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 LRESULT
APIENTRY ComboBoxWndProcWorker(
00208
PWND pwnd,
00209 UINT message,
00210 WPARAM wParam,
00211 LPARAM lParam,
00212 DWORD fAnsi)
00213 {
00214 HWND hwnd =
HWq(pwnd);
00215
PCBOX pcbox;
00216 POINT pt;
00217
TL tlpwndEdit;
00218
TL tlpwndList;
00219 PAINTSTRUCT ps;
00220 LPWSTR lpwsz =
NULL;
00221 LRESULT lReturn;
00222
static BOOL fInit =
TRUE;
00223
int i;
00224
00225
CheckLock(pwnd);
00226
00227
VALIDATECLASSANDSIZE(pwnd,
FNID_COMBOBOX);
00228
INITCONTROLLOOKASIDE(&
ComboboxLookaside,
CBOX, spwnd, 8);
00229
00230
00231
00232
00233
00234
00235 pcbox = ((
PCOMBOWND)pwnd)->pcbox;
00236
00237
00238
00239
00240
if (pcbox->
spwndList ==
NULL) {
00241 LRESULT lRet;
00242
00243
if (!
ComboBoxMsgOKInInit(message, &lRet)) {
00244 RIPMSG2(RIP_WARNING,
"ComboBoxWndProcWorker: msg=%04x is sent to hwnd=%08x in the middle of initialization.",
00245 message, hwnd);
00246
return lRet;
00247 }
00248 }
00249
00250
00251
00252
00253
switch (message) {
00254
case CBEC_KILLCOMBOFOCUS:
00255
00256
00257
00258
00259
00260
xxxCBKillFocusHelper(pcbox);
00261
break;
00262
00263
case WM_COMMAND:
00264
00265
00266
00267
00268
00269
return xxxCBCommandHandler(pcbox, (
DWORD)wParam, (HWND)lParam);
00270
00271
case WM_STYLECHANGED:
00272 UserAssert(pcbox->
spwndList !=
NULL);
00273 {
00274 LONG OldStyle;
00275 LONG NewStyle = 0;
00276
00277 pcbox->
fRtoLReading = (
TestWF(pwnd,
WEFRTLREADING) != 0);
00278 pcbox->
fRightAlign = (
TestWF(pwnd,
WEFRIGHT) != 0);
00279
if (pcbox->
fRtoLReading)
00280 NewStyle |= (WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR);
00281
if (pcbox->
fRightAlign)
00282 NewStyle |= WS_EX_RIGHT;
00283
00284
ThreadLock(pcbox->
spwndList, &tlpwndList);
00285 OldStyle = GetWindowLong(
HWq(pcbox->
spwndList), GWL_EXSTYLE) & ~(WS_EX_RIGHT|WS_EX_RTLREADING|WS_EX_LEFTSCROLLBAR);
00286 SetWindowLong(
HWq(pcbox->
spwndList), GWL_EXSTYLE, OldStyle|NewStyle);
00287
ThreadUnlock(&tlpwndList);
00288
00289
if (!pcbox->
fNoEdit && pcbox->
spwndEdit) {
00290
ThreadLock(pcbox->
spwndEdit, &tlpwndEdit);
00291 OldStyle = GetWindowLong(
HWq(pcbox->
spwndEdit), GWL_EXSTYLE) & ~(WS_EX_RIGHT|WS_EX_RTLREADING|WS_EX_LEFTSCROLLBAR);
00292 SetWindowLong(
HWq(pcbox->
spwndEdit), GWL_EXSTYLE, OldStyle|NewStyle);
00293
ThreadUnlock(&tlpwndEdit);
00294 }
00295
xxxCBPosition(pcbox);
00296
NtUserInvalidateRect(hwnd,
NULL,
FALSE);
00297 }
00298
break;
00299
00300
case WM_CTLCOLORMSGBOX:
00301
case WM_CTLCOLOREDIT:
00302
case WM_CTLCOLORLISTBOX:
00303
case WM_CTLCOLORBTN:
00304
case WM_CTLCOLORDLG:
00305
case WM_CTLCOLORSCROLLBAR:
00306
case WM_CTLCOLORSTATIC:
00307
case WM_CTLCOLOR:
00308
00309
00310
00311
00312
if (
TestWF(pwnd,
WFWIN40COMPAT)) {
00313
TL tlpwndParent;
00314 LRESULT ret;
00315
PWND pwndParent;
00316
00317 pwndParent =
REBASEPWND(pwnd, spwndParent);
00318
ThreadLock(pwndParent, &tlpwndParent);
00319 ret =
SendMessage(
HW(pwndParent), message, wParam, lParam);
00320
ThreadUnlock(tlpwndParent);
00321
return ret;
00322 }
else
00323
return(
DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi));
00324
break;
00325
00326
case WM_GETTEXT:
00327
if (pcbox->
fNoEdit) {
00328
return xxxCBGetTextHelper(pcbox, (
int)wParam, (LPWSTR)lParam, fAnsi);
00329 }
00330
goto CallEditSendMessage;
00331
break;
00332
00333
case WM_GETTEXTLENGTH:
00334
00335
00336
00337
00338
00339
00340
if (pcbox->
fNoEdit) {
00341
return xxxCBGetTextLengthHelper(pcbox, fAnsi);
00342 }
00343
00344
00345
00346
case WM_CLEAR:
00347
case WM_CUT:
00348
case WM_PASTE:
00349
case WM_COPY:
00350
case WM_SETTEXT:
00351
goto CallEditSendMessage;
00352
break;
00353
00354
case WM_CREATE:
00355
00356
00357
00358
00359
00360
return xxxCBCreateHandler(pcbox, pwnd);
00361
00362
case WM_ERASEBKGND:
00363
00364
00365
00366
00367
return 1
L;
00368
00369
case WM_GETFONT:
00370
return (LRESULT)pcbox->
hFont;
00371
00372
case WM_PRINT:
00373
if (!
DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi))
00374
return(
FALSE);
00375
00376
if ((lParam & PRF_OWNED) && (pcbox->
CBoxStyle &
SDROPPABLE) &&
00377
TestWF(pcbox->
spwndList,
WFVISIBLE)) {
00378
TL tpwndList;
00379
int iDC = SaveDC((HDC) wParam);
00380 OffsetWindowOrgEx((HDC) wParam, 0, pwnd->
rcWindow.top - pcbox->
spwndList->
rcWindow.top,
NULL);
00381 lParam &= ~PRF_CHECKVISIBLE;
00382
ThreadLock(pcbox->
spwndList, &tpwndList);
00383
SendMessageWorker(pcbox->
spwndList, WM_PRINT, wParam, lParam,
FALSE);
00384 RestoreDC((HDC) wParam, iDC);
00385 }
00386
return TRUE;
00387
00388
case WM_PRINTCLIENT:
00389
xxxCBPaint(pcbox, (HDC) wParam);
00390
break;
00391
00392
case WM_PAINT: {
00393 HDC hdc;
00394
00395
00396
00397
00398 hdc = (wParam) ? (HDC) wParam :
NtUserBeginPaint(hwnd, &ps);
00399
00400
if (
IsComboVisible(pcbox))
00401
xxxCBPaint(pcbox, hdc);
00402
00403
if (!wParam)
00404
NtUserEndPaint(hwnd, &ps);
00405
break;
00406 }
00407
case WM_GETDLGCODE:
00408
00409
00410
00411
00412
00413 {
00414 LRESULT code = DLGC_WANTCHARS | DLGC_WANTARROWS;
00415
00416
00417
00418
if ((lParam != 0) &&
00419 (((LPMSG)lParam)->message == WM_KEYDOWN) &&
00420 pcbox->
fLBoxVisible &&
00421 ((wParam == VK_RETURN) || (wParam == VK_ESCAPE)))
00422 {
00423 code |= DLGC_WANTMESSAGE;
00424 }
00425
return code;
00426 }
00427
00428
00429
00430
00431
case WM_SETFONT:
00432
xxxCBSetFontHandler(pcbox, (HANDLE)wParam, LOWORD(lParam));
00433
break;
00434
00435
case WM_SYSKEYDOWN:
00436
if (lParam & 0x20000000
L) {
00437
00438
00439
00440
00441
00442
if (lParam & 0x1000000) {
00443
00444
00445
00446
00447
00448
if (wParam == VK_DOWN || wParam == VK_UP)
00449
goto DropCombo;
00450
00451
goto CallDWP;
00452 }
00453
00454
if (
GetKeyState(VK_NUMLOCK) & 0x1) {
00455
00456
00457
00458
goto CallDWP;
00459 }
else {
00460
00461
00462
00463
00464
if (!(wParam == VK_DOWN || wParam == VK_UP))
00465
goto CallDWP;
00466 }
00467 DropCombo:
00468
if (!pcbox->
fLBoxVisible) {
00469
00470
00471
00472
00473
xxxCBShowListBoxWindow(pcbox,
TRUE);
00474 }
else {
00475
00476
00477
00478
00479
if (!
xxxCBHideListBoxWindow(pcbox,
TRUE,
TRUE))
00480
return(0
L);
00481 }
00482 }
00483
goto CallDWP;
00484
break;
00485
00486
case WM_KEYDOWN:
00487
00488
00489
00490
00491
00492
if (pcbox->
fLBoxVisible) {
00493
if ((wParam == VK_RETURN) || (wParam == VK_ESCAPE)) {
00494
xxxCBHideListBoxWindow(pcbox,
TRUE, (wParam != VK_ESCAPE));
00495
break;
00496 }
00497 }
00498
00499
00500
case WM_CHAR:
00501
if (fAnsi &&
IS_DBCS_ENABLED() && IsDBCSLeadByteEx(
THREAD_CODEPAGE(), (
BYTE)wParam)) {
00502
return ComboBoxDBCharHandler(pcbox, hwnd, message, wParam, lParam);
00503 }
00504
00505
if (pcbox->
fNoEdit) {
00506
goto CallListSendMessage;
00507 }
00508
else
00509
goto CallEditSendMessage;
00510
break;
00511
00512
case WM_LBUTTONDBLCLK:
00513
case WM_LBUTTONDOWN:
00514
00515
#ifdef COLOR_HOTTRACKING
00516
pcbox->fButtonHotTracked =
FALSE;
00517
#endif // COLOR_HOTTRACKING
00518
00519
00520
00521
00522
if (!pcbox->
fFocus) {
00523
NtUserSetFocus(hwnd);
00524
if (!pcbox->
fFocus) {
00525
00526
00527
00528
00529
break;
00530 }
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540 POINTSTOPOINT(pt, lParam);
00541
if ((pcbox->
CBoxStyle ==
SDROPDOWN &&
00542
PtInRect(&pcbox->
buttonrc, pt)) ||
00543 pcbox->
CBoxStyle ==
SDROPDOWNLIST) {
00544
00545
00546
00547
00548
00549
00550 pcbox->
fButtonPressed =
TRUE;
00551
if (pcbox->
fLBoxVisible) {
00552
if (pcbox->
fMouseDown) {
00553 pcbox->
fMouseDown =
FALSE;
00554
NtUserReleaseCapture();
00555 }
00556
xxxPressButton(pcbox,
FALSE);
00557
00558
if (!
xxxCBHideListBoxWindow(pcbox,
TRUE,
TRUE))
00559
return(0
L);
00560 }
else {
00561
xxxCBShowListBoxWindow(pcbox,
FALSE);
00562
00563
00564
00565
00566 pcbox->
fMouseDown =
TRUE;
00567
NtUserSetCapture(hwnd);
00568
if (
FWINABLE()) {
00569
NotifyWinEvent(EVENT_OBJECT_STATECHANGE, hwnd, OBJID_CLIENT, INDEX_COMBOBOX_BUTTON);
00570 }
00571 }
00572 }
00573
break;
00574
00575
case WM_MOUSEWHEEL:
00576
00577
00578
00579
if (wParam & (MK_CONTROL | MK_SHIFT))
00580
goto CallDWP;
00581
00582
00583
00584
00585
if (pcbox->
fLBoxVisible)
00586
goto CallListSendMessage;
00587
00588
00589
00590
00591
00592
if (pcbox->
fExtendedUI || pcbox->
spwndEdit ==
NULL)
00593
return TRUE;
00594
00595
00596
00597
00598 i =
abs(((
short)HIWORD(wParam))/WHEEL_DELTA);
00599 wParam = ((
short)HIWORD(wParam) > 0) ? VK_UP : VK_DOWN;
00600
00601
ThreadLock(pcbox->
spwndEdit, &tlpwndEdit);
00602
while (i-- > 0) {
00603
SendMessageWorker(
00604 pcbox->
spwndEdit, WM_KEYDOWN, wParam, 0, fAnsi);
00605 }
00606
ThreadUnlock(&tlpwndEdit);
00607
return TRUE;
00608
00609
case WM_CAPTURECHANGED:
00610
if (!(
TestWF(pwnd,
WFWIN40COMPAT)))
00611
return 0;
00612
00613
if ((pcbox->
fMouseDown)) {
00614 pcbox->
fMouseDown =
FALSE;
00615
xxxPressButton(pcbox,
FALSE);
00616
00617
00618
00619
00620
if (pcbox->
fLBoxVisible)
00621
xxxCBHideListBoxWindow(pcbox,
TRUE,
FALSE);
00622 }
00623
break;
00624
00625
case WM_LBUTTONUP:
00626
xxxPressButton(pcbox,
FALSE);
00627
00628
00629
00630
00631
if (pcbox->
fMouseDown) {
00632 pcbox->
fMouseDown =
FALSE;
00633
00634
if (pcbox->
CBoxStyle ==
SDROPDOWN) {
00635
00636
00637
00638
00639
xxxCBUpdateListBoxWindow(pcbox,
TRUE);
00640
xxxCBCompleteEditWindow(pcbox);
00641 }
00642
NtUserReleaseCapture();
00643
00644
00645
00646
00647
if (
TestWF(pwnd,
WFWIN40COMPAT)) {
00648
00649
ThreadLock(pcbox->
spwndList, &tlpwndList);
00650
SendMessageWorker(pcbox->
spwndList, LBCB_STARTTRACK,
FALSE, 0,
FALSE);
00651
ThreadUnlock(&tlpwndList);
00652 }
00653 }
00654
#ifdef COLOR_HOTTRACKING
00655
HotTrack(pcbox);
00656
break;
00657
00658
case WM_MOUSELEAVE:
00659 pcbox->fButtonHotTracked =
FALSE;
00660
NtUserInvalidateRect(hwnd, &pcbox->
buttonrc,
TRUE);
00661
#endif // COLOR_HOTTRACKING
00662
break;
00663
00664
case WM_MOUSEMOVE:
00665
if (pcbox->
fMouseDown) {
00666 POINTSTOPOINT(pt, lParam);
00667
00668
00669
00670
if (
PtInRect(&pcbox->
buttonrc, pt) != !!pcbox->
fButtonPressed) {
00671
xxxPressButton(pcbox, (pcbox->
fButtonPressed == 0));
00672 }
00673
00674
_ClientToScreen(pwnd, &pt);
00675
if (
PtInRect(&pcbox->
spwndList->
rcClient, pt)) {
00676
00677
00678
00679
00680
00681
00682 pcbox->
fMouseDown =
FALSE;
00683
NtUserReleaseCapture();
00684
00685
if (pcbox->
CBoxStyle &
SEDITABLE) {
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
xxxCBUpdateListBoxWindow(pcbox,
TRUE);
00700 }
00701
00702
00703
00704
00705
00706
_ScreenToClient(pcbox->
spwndList, &pt);
00707 lParam = POINTTOPOINTS(pt);
00708 message = WM_LBUTTONDOWN;
00709
goto CallListSendMessage;
00710 }
00711 }
00712
#ifdef COLOR_HOTTRACKING
00713
HotTrack(pcbox);
00714
#endif // COLOR_HOTTRACKING
00715
break;
00716
00717
case WM_NCDESTROY:
00718
case WM_FINALDESTROY:
00719
xxxCBNcDestroyHandler(pwnd, pcbox);
00720
break;
00721
00722
case WM_SETFOCUS:
00723
if (pcbox->
fNoEdit) {
00724
00725
00726
00727
00728
xxxCBGetFocusHelper(pcbox);
00729 }
else if (pcbox->
spwndEdit) {
00730
00731
00732
00733
ThreadLock(pcbox->
spwndEdit, &tlpwndEdit);
00734
NtUserSetFocus(
HWq(pcbox->
spwndEdit));
00735
ThreadUnlock(&tlpwndEdit);
00736 }
00737
break;
00738
00739
case WM_KILLFOCUS:
00740
00741
00742
00743
00744
if (wParam != 0)
00745 wParam = (WPARAM)
ValidateHwnd((HWND)wParam);
00746
if ((wParam == 0) || !
_IsChild(pwnd, (
PWND)wParam)) {
00747
00748
00749
00750
00751
00752
xxxCBKillFocusHelper(pcbox);
00753 }
00754
00755 UserAssert(pcbox->
spwndList);
00756 {
00757
PLBIV plb = ((
PLBWND)pcbox->
spwndList)->pLBIV;
00758
00759
if ((plb !=
NULL) && (plb != (
PLBIV)-1)) {
00760 plb->
iTypeSearch = 0;
00761
if (plb->
pszTypeSearch) {
00762
UserLocalFree(plb->
pszTypeSearch);
00763 plb->
pszTypeSearch =
NULL;
00764 }
00765 }
00766 }
00767
break;
00768
00769
case WM_SETREDRAW:
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 pcbox->
fNoRedraw = (
UINT)!((
BOOL)wParam);
00781
00782
00783
00784
00785
00786
if (!pcbox->
fNoEdit && pcbox->
spwndEdit) {
00787
ThreadLock(pcbox->
spwndEdit, &tlpwndEdit);
00788
SendMessageWorker(pcbox->
spwndEdit, message, wParam, lParam,
FALSE);
00789
ThreadUnlock(&tlpwndEdit);
00790 }
00791
goto CallListSendMessage;
00792
break;
00793
00794
case WM_ENABLE:
00795
00796
00797
00798
00799
00800
NtUserInvalidateRect(hwnd,
NULL,
FALSE);
00801
if ((pcbox->
CBoxStyle &
SEDITABLE) && pcbox->
spwndEdit) {
00802
00803
00804
00805
00806
ThreadLock(pcbox->
spwndEdit, &tlpwndEdit);
00807
NtUserEnableWindow(
HWq(pcbox->
spwndEdit), (
TestWF(pwnd,
WFDISABLED) == 0));
00808
ThreadUnlock(&tlpwndEdit);
00809 }
00810
00811
00812
00813
00814 UserAssert(pcbox->
spwndList);
00815
ThreadLock(pcbox->
spwndList, &tlpwndList);
00816
NtUserEnableWindow(
HWq(pcbox->
spwndList), (
TestWF(pwnd,
WFDISABLED) == 0));
00817
ThreadUnlock(&tlpwndList);
00818
break;
00819
00820
case WM_SIZE:
00821
00822
00823
00824
00825
00826
00827 UserAssert(pcbox->
spwndList);
00828
if (LOWORD(lParam) == 0 || HIWORD(lParam) == 0) {
00829
00830
00831
00832
00833
00834
return 0;
00835 }
00836
00837
00838
if (pcbox->
cxCombo == pwnd->
rcWindow.right - pwnd->
rcWindow.left) {
00839
int iNewHeight = pwnd->
rcWindow.bottom - pwnd->
rcWindow.top;
00840
00841
00842
if (pcbox->
fLBoxVisible) {
00843
00844
if (pcbox->
cyDrop + pcbox->
cyCombo == iNewHeight)
00845
return(0
L);
00846 }
else {
00847
00848
if (pcbox->
cyCombo == iNewHeight)
00849
return(0
L);
00850 }
00851 }
00852
00853
xxxCBSizeHandler(pcbox);
00854
break;
00855
00856
case CB_GETDROPPEDSTATE:
00857
00858
00859
00860
00861
00862
00863
return pcbox->
fLBoxVisible;
00864
00865
case CB_GETDROPPEDCONTROLRECT:
00866
00867
00868
00869
00870
00871
00872 ((LPRECT)lParam)->left = pwnd->
rcWindow.left;
00873 ((LPRECT)lParam)->top = pwnd->
rcWindow.top;
00874 ((LPRECT)lParam)->right = pwnd->
rcWindow.left +
max(pcbox->
cxDrop, pcbox->
cxCombo);
00875 ((LPRECT)lParam)->bottom = pwnd->
rcWindow.top + pcbox->
cyCombo + pcbox->
cyDrop;
00876
break;
00877
00878
case CB_SETDROPPEDWIDTH:
00879
if (pcbox->
CBoxStyle &
SDROPPABLE) {
00880
if (wParam) {
00881 wParam =
max(wParam, (
UINT)pcbox->
cxCombo);
00882
00883
if (wParam != (
UINT) pcbox->
cxDrop)
00884 {
00885 pcbox->
cxDrop = (
int)wParam;
00886
xxxCBPosition(pcbox);
00887 }
00888 }
00889 }
00890
00891
00892
case CB_GETDROPPEDWIDTH:
00893
if (pcbox->
CBoxStyle &
SDROPPABLE)
00894
return((LRESULT)
max(pcbox->
cxDrop, pcbox->
cxCombo));
00895
else
00896
return(CB_ERR);
00897
break;
00898
00899
case CB_DIR:
00900
00901
00902
00903
00904
if (fAnsi && lParam != 0) {
00905
if (MBToWCS((LPSTR)lParam, -1, &lpwsz, -1,
TRUE) == 0)
00906
return CB_ERR;
00907 lParam = (LPARAM)lpwsz;
00908 }
00909 lReturn =
xxxCBDir(pcbox, LOWORD(wParam), (LPWSTR)lParam);
00910
if (fAnsi && lParam != 0) {
00911
UserLocalFree(lpwsz);
00912 }
00913
return lReturn;
00914
00915
case CB_SETEXTENDEDUI:
00916
00917
00918
00919
00920
00921
00922
if (pcbox->
CBoxStyle &
SDROPPABLE) {
00923
if (!wParam) {
00924 pcbox->
fExtendedUI = 0;
00925
return 0;
00926 }
00927
00928
if (wParam == 1) {
00929 pcbox->
fExtendedUI = 1;
00930
return 0;
00931 }
00932
00933 RIPERR1(ERROR_INVALID_PARAMETER,
00934 RIP_WARNING,
00935
"Invalid parameter \"wParam\" (%ld) to ComboBoxWndProcWorker",
00936 wParam);
00937
00938 }
else {
00939 RIPERR1(ERROR_INVALID_MESSAGE,
00940 RIP_WARNING,
00941
"Invalid message (%ld) sent to ComboBoxWndProcWorker",
00942 message);
00943 }
00944
00945
return CB_ERR;
00946
00947
case CB_GETEXTENDEDUI:
00948
if (pcbox->
CBoxStyle &
SDROPPABLE) {
00949
if (pcbox->
fExtendedUI)
00950
return TRUE;
00951 }
00952
return FALSE;
00953
00954
case CB_GETEDITSEL:
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 message = EM_GETSEL;
00966
goto CallEditSendMessage;
00967
break;
00968
00969
case CB_LIMITTEXT:
00970
00971
00972
00973
00974
00975
00976
00977 message = EM_LIMITTEXT;
00978
goto CallEditSendMessage;
00979
break;
00980
00981
case CB_SETEDITSEL:
00982
00983
00984
00985
00986
00987
00988 message = EM_SETSEL;
00989
00990 wParam = (
int)(
SHORT)LOWORD(lParam);
00991 lParam = (
int)(
SHORT)HIWORD(lParam);
00992
goto CallEditSendMessage;
00993
break;
00994
00995
case CB_ADDSTRING:
00996
00997
00998
00999
01000
01001
if (!pcbox->
fCase)
01002 message = LB_ADDSTRING;
01003
else
01004 message = (pcbox->
fCase &
UPPERCASE) ? LB_ADDSTRINGUPPER : LB_ADDSTRINGLOWER;
01005
goto CallListSendMessage;
01006
break;
01007
01008
case CB_DELETESTRING:
01009
01010
01011
01012
01013
01014 message = LB_DELETESTRING;
01015
goto CallListSendMessage;
01016
break;
01017
01018
case CB_INITSTORAGE:
01019
01020
01021 message = LB_INITSTORAGE;
01022
goto CallListSendMessage;
01023
01024
case CB_SETTOPINDEX:
01025
01026
01027 message = LB_SETTOPINDEX;
01028
goto CallListSendMessage;
01029
01030
case CB_GETTOPINDEX:
01031
01032 message = LB_GETTOPINDEX;
01033
goto CallListSendMessage;
01034
01035
case CB_GETCOUNT:
01036
01037
01038
01039
01040
01041 message = LB_GETCOUNT;
01042
goto CallListSendMessage;
01043
break;
01044
01045
case CB_GETCURSEL:
01046
01047
01048
01049
01050
01051 message = LB_GETCURSEL;
01052
goto CallListSendMessage;
01053
break;
01054
01055
case CB_GETLBTEXT:
01056
01057
01058
01059
01060
01061 message = LB_GETTEXT;
01062
goto CallListSendMessage;
01063
break;
01064
01065
case CB_GETLBTEXTLEN:
01066
01067
01068
01069
01070
01071 message = LB_GETTEXTLEN;
01072
goto CallListSendMessage;
01073
break;
01074
01075
case CB_INSERTSTRING:
01076
01077
01078
01079
01080
01081
if (!pcbox->
fCase)
01082 message = LB_INSERTSTRING;
01083
else
01084 message = (pcbox->
fCase &
UPPERCASE) ? LB_INSERTSTRINGUPPER : LB_INSERTSTRINGLOWER;
01085
goto CallListSendMessage;
01086
break;
01087
01088
case CB_RESETCONTENT:
01089
01090
01091
01092
01093
01094
01095
01096 UserAssert(pcbox->
spwndList);
01097
ThreadLock(pcbox->
spwndList, &tlpwndList);
01098
SendMessageWorker(pcbox->
spwndList, LB_RESETCONTENT, 0, 0,
FALSE);
01099
ThreadUnlock(&tlpwndList);
01100
xxxCBInternalUpdateEditWindow(pcbox,
NULL);
01101
break;
01102
01103
case CB_GETHORIZONTALEXTENT:
01104 message = LB_GETHORIZONTALEXTENT;
01105
goto CallListSendMessage;
01106
01107
case CB_SETHORIZONTALEXTENT:
01108 message = LB_SETHORIZONTALEXTENT;
01109
goto CallListSendMessage;
01110
01111
case CB_FINDSTRING:
01112
01113
01114
01115
01116
01117 message = LB_FINDSTRING;
01118
goto CallListSendMessage;
01119
break;
01120
01121
case CB_FINDSTRINGEXACT:
01122
01123
01124
01125
01126
01127 message = LB_FINDSTRINGEXACT;
01128
goto CallListSendMessage;
01129
break;
01130
01131
case CB_SELECTSTRING:
01132
01133
01134
01135
01136
01137 UserAssert(pcbox->
spwndList);
01138
ThreadLock(pcbox->
spwndList, &tlpwndList);
01139 lParam =
SendMessageWorker(pcbox->
spwndList, LB_SELECTSTRING,
01140 wParam, lParam, fAnsi);
01141
ThreadUnlock(&tlpwndList);
01142
xxxCBInternalUpdateEditWindow(pcbox,
NULL);
01143
return lParam;
01144
01145
case CB_SETCURSEL:
01146
01147
01148
01149
01150
01151
01152
01153
01154 UserAssert(pcbox->
spwndList);
01155
01156
ThreadLock(pcbox->
spwndList, &tlpwndList);
01157 lParam =
SendMessageWorker(pcbox->
spwndList, LB_SETCURSEL, wParam, lParam,
FALSE);
01158
if (lParam != -1) {
01159
SendMessageWorker(pcbox->
spwndList, LB_SETTOPINDEX, wParam, 0,
FALSE);
01160 }
01161
ThreadUnlock(&tlpwndList);
01162
xxxCBInternalUpdateEditWindow(pcbox,
NULL);
01163
return lParam;
01164
01165
case CB_GETITEMDATA:
01166 message = LB_GETITEMDATA;
01167
goto CallListSendMessage;
01168
break;
01169
01170
case CB_SETITEMDATA:
01171 message = LB_SETITEMDATA;
01172
goto CallListSendMessage;
01173
break;
01174
01175
case CB_SETITEMHEIGHT:
01176
if (wParam == -1) {
01177
if (HIWORD(lParam) != 0)
01178
return CB_ERR;
01179
return xxxCBSetEditItemHeight(pcbox, LOWORD(lParam));
01180 }
01181
01182 message = LB_SETITEMHEIGHT;
01183
goto CallListSendMessage;
01184
break;
01185
01186
case CB_GETITEMHEIGHT:
01187
if (wParam == -1)
01188
return pcbox->
editrc.bottom - pcbox->
editrc.top;
01189
01190 message = LB_GETITEMHEIGHT;
01191
goto CallListSendMessage;
01192
break;
01193
01194
case CB_SHOWDROPDOWN:
01195
01196
01197
01198
01199
01200
if (wParam && !pcbox->
fLBoxVisible) {
01201
xxxCBShowListBoxWindow(pcbox,
TRUE);
01202 }
else {
01203
if (!wParam && pcbox->
fLBoxVisible) {
01204
xxxCBHideListBoxWindow(pcbox,
TRUE,
FALSE);
01205 }
01206 }
01207
break;
01208
01209
case CB_SETLOCALE:
01210
01211
01212
01213
01214
01215 message = LB_SETLOCALE;
01216
goto CallListSendMessage;
01217
break;
01218
01219
case CB_GETLOCALE:
01220
01221
01222
01223
01224
01225 message = LB_GETLOCALE;
01226
goto CallListSendMessage;
01227
break;
01228
01229
case WM_MEASUREITEM:
01230
case WM_DELETEITEM:
01231
case WM_DRAWITEM:
01232
case WM_COMPAREITEM:
01233
return xxxCBMessageItemHandler(pcbox, message, (
LPVOID)lParam);
01234
01235
case WM_NCCREATE:
01236
01237
01238
01239
01240
01241
return CBNcCreateHandler(pcbox, pwnd);
01242
01243
case WM_PARENTNOTIFY:
01244
if (LOWORD(wParam) == WM_DESTROY) {
01245
if ((HWND)lParam ==
HW(pcbox->
spwndEdit)) {
01246 pcbox->
CBoxStyle &= ~
SEDITABLE;
01247 pcbox->
fNoEdit =
TRUE;
01248 pcbox->
spwndEdit = pwnd;
01249 }
else if ((HWND)lParam ==
HW(pcbox->
spwndList)) {
01250 pcbox->
CBoxStyle &= ~
SDROPPABLE;
01251 pcbox->
spwndList =
NULL;
01252 }
01253 }
01254
break;
01255
01256
case WM_UPDATEUISTATE:
01257
01258
01259
01260 UserAssert(pcbox->
spwndList);
01261
ThreadLock(pcbox->
spwndList, &tlpwndList);
01262
SendMessageWorker(pcbox->
spwndList, WM_UPDATEUISTATE,
01263 wParam, lParam, fAnsi);
01264
ThreadUnlock(&tlpwndList);
01265
goto CallDWP;
01266
01267
case WM_HELP:
01268 {
01269 LPHELPINFO lpHelpInfo;
01270
01271
01272
01273
if ((lpHelpInfo = (LPHELPINFO)lParam) !=
NULL &&
01274 ((pcbox->
spwndEdit && lpHelpInfo->iCtrlId == (
SHORT)(
PTR_TO_ID(pcbox->
spwndEdit->
spmenu))) ||
01275 lpHelpInfo->iCtrlId == (
SHORT)(
PTR_TO_ID(pcbox->
spwndList->
spmenu)) )) {
01276
01277
01278 lpHelpInfo->iCtrlId = (
SHORT)(
PTR_TO_ID(pwnd->
spmenu));
01279 lpHelpInfo->hItemHandle = hwnd;
01280 lpHelpInfo->dwContextId =
GetContextHelpId(pwnd);
01281 }
01282 }
01283
01284
01285
01286
01287
default:
01288
01289
if (
SYSMET(PENWINDOWS) &&
01290 (message >= WM_PENWINFIRST && message <= WM_PENWINLAST))
01291
goto CallEditSendMessage;
01292
01293 CallDWP:
01294
return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi);
01295 }
01296
01297
return TRUE;
01298
01299
01300
01301
01302 CallEditSendMessage:
01303
if (!pcbox->
fNoEdit && pcbox->
spwndEdit) {
01304
01305
01306
01307
ThreadLock(pcbox->
spwndEdit, &tlpwndEdit);
01308 lReturn =
SendMessageWorker(pcbox->
spwndEdit, message,
01309 wParam, lParam, fAnsi);
01310
ThreadUnlock(&tlpwndEdit);
01311 }
01312
else {
01313 RIPERR0(ERROR_INVALID_COMBOBOX_MESSAGE, RIP_VERBOSE,
"");
01314 lReturn = CB_ERR;
01315 }
01316
return lReturn;
01317
01318 CallListSendMessage:
01319
01320
01321
01322 UserAssert(pcbox->
spwndList);
01323
ThreadLock(pcbox->
spwndList, &tlpwndList);
01324 lReturn =
SendMessageWorker(pcbox->
spwndList, message,
01325 wParam, lParam, fAnsi);
01326
ThreadUnlock(&tlpwndList);
01327
return lReturn;
01328
01329 }
01330
01331
01332
01333
01334
01335 LRESULT WINAPI
ComboBoxWndProcA(
01336 HWND hwnd,
01337 UINT message,
01338 WPARAM wParam,
01339 LPARAM lParam)
01340 {
01341
PWND pwnd;
01342
01343
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL) {
01344
return (0
L);
01345 }
01346
01347
01348
01349
01350
01351
if (!
FWINDOWMSG(message,
FNID_COMBOBOX) &&
01352 !(
SYSMET(PENWINDOWS) &&
01353 (message >= WM_PENWINFIRST && message <= WM_PENWINLAST)))
01354
return DefWindowProcWorker(pwnd, message, wParam, lParam,
TRUE);
01355
01356
return ComboBoxWndProcWorker(pwnd, message, wParam, lParam,
TRUE);
01357 }
01358
01359 LRESULT WINAPI
ComboBoxWndProcW(
01360 HWND hwnd,
01361 UINT message,
01362 WPARAM wParam,
01363 LPARAM lParam)
01364 {
01365
PWND pwnd;
01366
01367
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL) {
01368
return (0
L);
01369 }
01370
01371
01372
01373
01374
01375
if (!
FWINDOWMSG(message,
FNID_COMBOBOX) &&
01376 !(
SYSMET(PENWINDOWS) &&
01377 (message >= WM_PENWINFIRST && message <= WM_PENWINLAST)))
01378
return DefWindowProcWorker(pwnd, message, wParam, lParam,
FALSE);
01379
01380
return ComboBoxWndProcWorker(pwnd, message, wParam, lParam,
FALSE);
01381 }
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393 LRESULT
xxxCBMessageItemHandler(
01394
PCBOX pcbox,
01395 UINT message,
01396 LPVOID lpfoo)
01397 {
01398 LRESULT lRet;
01399
TL tlpwndParent;
01400
01401
CheckLock(pcbox->
spwnd);
01402
01403
01404
01405
01406
01407 ((LPMEASUREITEMSTRUCT)lpfoo)->CtlType = ODT_COMBOBOX;
01408 ((LPMEASUREITEMSTRUCT)lpfoo)->CtlID = PtrToUlong(pcbox->
spwnd->
spmenu);
01409
if (message == WM_DRAWITEM)
01410 ((LPDRAWITEMSTRUCT)lpfoo)->hwndItem =
HWq(pcbox->
spwnd);
01411
else if (message == WM_DELETEITEM)
01412 ((LPDELETEITEMSTRUCT)lpfoo)->hwndItem =
HWq(pcbox->
spwnd);
01413
else if (message == WM_COMPAREITEM)
01414 ((LPCOMPAREITEMSTRUCT)lpfoo)->hwndItem =
HWq(pcbox->
spwnd);
01415
01416
ThreadLock(pcbox->
spwndParent, &tlpwndParent);
01417 lRet =
SendMessage(
HW(pcbox->
spwndParent), message,
01418 (WPARAM)pcbox->
spwnd->
spmenu, (LPARAM)lpfoo);
01419
ThreadUnlock(&tlpwndParent);
01420
01421
return lRet;
01422 }
01423
01424
01425
01426
01427
01428
01429
01430
01431 void xxxCBPaint(
01432
PCBOX pcbox,
01433 HDC hdc)
01434 {
01435 RECT rc;
01436
UINT msg;
01437 HBRUSH hbr;
01438
01439
CheckLock(pcbox->
spwnd);
01440
01441 rc.left = rc.top = 0;
01442 rc.right = pcbox->
cxCombo;
01443 rc.bottom = pcbox->
cyCombo;
01444
if (pcbox->
f3DCombo)
01445
DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
01446
else
01447
DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST | BF_FLAT | BF_MONO);
01448
01449
if (pcbox->
buttonrc.left != 0) {
01450
01451
DrawFrameControl(hdc, &pcbox->
buttonrc, DFC_SCROLL,
01452 DFCS_SCROLLCOMBOBOX |
01453 (pcbox->
fButtonPressed ? DFCS_PUSHED | DFCS_FLAT : 0) |
01454 (
TestWF(pcbox->
spwnd,
WFDISABLED) ? DFCS_INACTIVE : 0));
01455
#ifdef COLOR_HOTTRACKING
01456
(pcbox->fButtonHotTracked ? DFCS_HOT: 0)));
01457
#endif // COLOR_HOTTRACKING
01458
if (pcbox->
fRightAlign )
01459 rc.left = pcbox->
buttonrc.right;
01460
else
01461 rc.right = pcbox->
buttonrc.left;
01462 }
01463
01464
01465
01466
01467
msg = WM_CTLCOLOREDIT;
01468
if (
TestWF(pcbox->
spwnd,
WFWIN40COMPAT)) {
01469
if (
TestWF(pcbox->
spwnd,
WFDISABLED) ||
01470 (!pcbox->
fNoEdit && pcbox->
spwndEdit &&
TestWF(pcbox->
spwndEdit,
EFREADONLY)))
01471
msg = WM_CTLCOLORSTATIC;
01472 }
else
01473
msg = WM_CTLCOLORLISTBOX;
01474
01475 hbr =
GetControlBrush(
HWq(pcbox->
spwnd), hdc,
msg);
01476
01477
if (pcbox->
fNoEdit)
01478
xxxCBInternalUpdateEditWindow(pcbox, hdc);
01479
else
01480
FillRect(hdc, &rc, hbr);
01481 }
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494 long xxxCBCommandHandler(
01495
PCBOX pcbox,
01496 DWORD wParam,
01497 HWND hwndControl)
01498 {
01499
01500
CheckLock(pcbox->
spwnd);
01501
01502
01503
01504
01505
01506
if (!pcbox->
fNoEdit &&
01507
SAMEWOWHANDLE(hwndControl,
HWq(pcbox->
spwndEdit))) {
01508
01509
01510
01511
01512
switch (HIWORD(wParam)) {
01513
case EN_SETFOCUS:
01514
if (!pcbox->
fFocus) {
01515
01516
01517
01518
01519
01520
01521
xxxCBGetFocusHelper(pcbox);
01522 }
01523
break;
01524
01525
case EN_CHANGE:
01526
xxxCBNotifyParent(pcbox, CBN_EDITCHANGE);
01527
xxxCBUpdateListBoxWindow(pcbox,
FALSE);
01528
break;
01529
01530
case EN_UPDATE:
01531
xxxCBNotifyParent(pcbox, CBN_EDITUPDATE);
01532
break;
01533
01534
case EN_ERRSPACE:
01535
xxxCBNotifyParent(pcbox, CBN_ERRSPACE);
01536
break;
01537 }
01538 }
01539
01540
01541
01542
01543
if (
SAMEWOWHANDLE(hwndControl,
HWq(pcbox->
spwndList))) {
01544
01545
01546
01547
01548
switch ((
int)HIWORD(wParam)) {
01549
case LBN_DBLCLK:
01550
xxxCBNotifyParent(pcbox, CBN_DBLCLK);
01551
break;
01552
01553
case LBN_ERRSPACE:
01554
xxxCBNotifyParent(pcbox, CBN_ERRSPACE);
01555
break;
01556
01557
case LBN_SELCHANGE:
01558
case LBN_SELCANCEL:
01559
if (!pcbox->
fKeyboardSelInListBox) {
01560
01561
01562
01563
01564
01565
if (!
xxxCBHideListBoxWindow(pcbox,
TRUE,
TRUE))
01566
return(0
L);
01567 }
else {
01568 pcbox->
fKeyboardSelInListBox =
FALSE;
01569 }
01570
01571
xxxCBNotifyParent(pcbox, CBN_SELCHANGE);
01572
xxxCBInternalUpdateEditWindow(pcbox,
NULL);
01573
break;
01574 }
01575 }
01576
01577
return 0
L;
01578 }
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 void xxxCBNotifyParent(
01590
PCBOX pcbox,
01591
short notificationCode)
01592 {
01593
PWND pwndParent;
01594
TL tlpwndParent;
01595
01596
CheckLock(pcbox->
spwnd);
01597
01598
if (pcbox->
spwndParent)
01599 pwndParent = pcbox->
spwndParent;
01600
else
01601 pwndParent = pcbox->
spwnd;
01602
01603
01604
01605
01606
01607
ThreadLock(pwndParent, &tlpwndParent);
01608
SendMessageWorker(pwndParent, WM_COMMAND,
01609 MAKELONG(
PTR_TO_ID(pcbox->
spwnd->
spmenu), notificationCode),
01610 (LPARAM)
HWq(pcbox->
spwnd),
FALSE);
01611
ThreadUnlock(&tlpwndParent);
01612 }
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624 void xxxCBCompleteEditWindow(
01625
PCBOX pcbox)
01626 {
01627
int cchText;
01628
int cchItemText;
01629
int itemNumber;
01630 LPWSTR pText;
01631
TL tlpwndEdit;
01632
TL tlpwndList;
01633
01634
CheckLock(pcbox->
spwnd);
01635
01636
01637
01638
01639
if (pcbox->
spwndEdit ==
NULL) {
01640
return;
01641 }
01642
01643
ThreadLock(pcbox->
spwndEdit, &tlpwndEdit);
01644
ThreadLock(pcbox->
spwndList, &tlpwndList);
01645
01646
01647
01648
01649 cchText = (
int)
SendMessageWorker(pcbox->
spwndEdit, WM_GETTEXTLENGTH, 0, 0,
FALSE);
01650
01651
if (cchText) {
01652 cchText++;
01653
if (!(pText = (LPWSTR)
UserLocalAlloc(HEAP_ZERO_MEMORY, cchText*
sizeof(WCHAR))))
01654
goto Unlock;
01655
01656
01657
01658
01659
01660
01661
try {
01662
SendMessageWorker(pcbox->
spwndEdit, WM_GETTEXT, cchText, (LPARAM)pText,
FALSE);
01663 itemNumber = (
int)
SendMessageWorker(pcbox->
spwndList,
01664 LB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)pText,
FALSE);
01665
if (itemNumber == -1)
01666 itemNumber = (
int)
SendMessageWorker(pcbox->
spwndList,
01667 LB_FINDSTRING, (WPARAM)-1, (LPARAM)pText,
FALSE);
01668 } finally {
01669
UserLocalFree((HANDLE)pText);
01670 }
01671
01672
if (itemNumber == -1) {
01673
01674
01675
01676
01677
goto Unlock;
01678 }
01679
01680 cchItemText = (
int)
SendMessageWorker(pcbox->
spwndList, LB_GETTEXTLEN,
01681 itemNumber, 0,
FALSE);
01682
if (cchItemText) {
01683 cchItemText++;
01684
if (!(pText = (LPWSTR)
UserLocalAlloc(HEAP_ZERO_MEMORY, cchItemText*
sizeof(WCHAR))))
01685
goto Unlock;
01686
01687
01688
01689
01690
01691
01692
try {
01693
SendMessageWorker(pcbox->
spwndList, LB_GETTEXT,
01694 itemNumber, (LPARAM)pText,
FALSE);
01695
SendMessageWorker(pcbox->
spwndEdit, WM_SETTEXT,
01696 0, (LPARAM)pText,
FALSE);
01697 } finally {
01698
UserLocalFree((HANDLE)pText);
01699 }
01700
01701
SendMessageWorker(pcbox->
spwndEdit, EM_SETSEL, 0, MAXLONG, !!
TestWF(pcbox->
spwnd,
WFANSIPROC));
01702 }
01703 }
01704
01705
Unlock:
01706
ThreadUnlock(&tlpwndList);
01707
ThreadUnlock(&tlpwndEdit);
01708 }
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719 BOOL xxxCBHideListBoxWindow(
01720
PCBOX pcbox,
01721 BOOL fNotifyParent,
01722 BOOL fSelEndOK)
01723 {
01724 HWND hwnd =
HWq(pcbox->
spwnd);
01725 HWND hwndList =
HWq(pcbox->
spwndList);
01726
TL tlpwndList;
01727
01728
01729
CheckLock(pcbox->
spwnd);
01730
01731
01732
01733
if (fNotifyParent &&
TestWF(pcbox->
spwnd,
WFWIN31COMPAT) &&
01734 ((pcbox->
CBoxStyle &
SDROPPABLE) || fSelEndOK)) {
01735
if (fSelEndOK)
01736 {
01737
xxxCBNotifyParent(pcbox, CBN_SELENDOK);
01738 }
01739
else
01740 {
01741
xxxCBNotifyParent(pcbox, CBN_SELENDCANCEL);
01742 }
01743
if (!
IsWindow(hwnd))
01744
return(
FALSE);
01745 }
01746
01747
01748
01749
01750
if (!(pcbox->
CBoxStyle &
SDROPPABLE)) {
01751
return TRUE;
01752 }
01753
01754
01755
01756
01757
01758
ThreadLock(pcbox->
spwndList, &tlpwndList);
01759
01760
SendMessageWorker(pcbox->
spwndList, LBCB_ENDTRACK, fSelEndOK, 0,
FALSE);
01761
01762
if (pcbox->
fLBoxVisible) {
01763 WORD swpFlags = SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE;
01764
01765
if (!
TestWF(pcbox->
spwnd,
WFWIN31COMPAT))
01766 swpFlags |= SWP_FRAMECHANGED;
01767
01768 pcbox->
fLBoxVisible =
FALSE;
01769
01770
01771
01772
01773
NtUserShowWindow(hwndList, SW_HIDE);
01774
01775
01776
01777
01778
01779
01780
01781
01782
if (!(pcbox->
CBoxStyle &
SEDITABLE))
01783
NtUserInvalidateRect(hwnd, &pcbox->
editrc,
TRUE);
01784
01785
NtUserSetWindowPos(hwnd, HWND_TOP, 0, 0,
01786 pcbox->
cxCombo, pcbox->
cyCombo, swpFlags);
01787
01788
01789
UpdateWindow(hwnd);
01790
01791
if (pcbox->
CBoxStyle &
SEDITABLE) {
01792
xxxCBCompleteEditWindow(pcbox);
01793 }
01794
01795
if (fNotifyParent) {
01796
01797
01798
01799
01800
xxxCBNotifyParent(pcbox, CBN_CLOSEUP);
01801
if (!
IsWindow(hwnd))
01802
return(
FALSE);
01803 }
01804 }
01805
01806
ThreadUnlock(&tlpwndList);
01807
01808
return(
TRUE);
01809 }
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819 void xxxCBShowListBoxWindow(
01820
PCBOX pcbox, BOOL fTrack)
01821 {
01822 RECT editrc;
01823
int itemNumber;
01824
int iHeight;
01825
int yTop;
01826
DWORD dwMult;
01827
int cyItem;
01828 HWND hwnd =
HWq(pcbox->
spwnd);
01829 HWND hwndList =
HWq(pcbox->
spwndList);
01830
BOOL fAnimPos;
01831
TL tlpwndList;
01832
PMONITOR pMonitor;
01833
01834
01835
01836
01837 UserAssert(pcbox->
CBoxStyle &
SDROPPABLE);
01838
01839
CheckLock(pcbox->
spwnd);
01840
01841
ThreadLock(pcbox->
spwndList, &tlpwndList);
01842
01843
01844
01845
01846
01847
xxxCBNotifyParent(pcbox, CBN_DROPDOWN);
01848
01849
01850
01851
NtUserInvalidateRect(hwnd, &pcbox->
buttonrc,
TRUE);
01852
01853 pcbox->
fLBoxVisible =
TRUE;
01854
01855
if (pcbox->
CBoxStyle ==
SDROPDOWN) {
01856
01857
01858
01859
01860
01861
01862
01863
xxxCBUpdateListBoxWindow(pcbox, !pcbox->
fMouseDown);
01864
if (!pcbox->
fMouseDown)
01865
xxxCBCompleteEditWindow(pcbox);
01866 }
else {
01867
01868
01869
01870
01871 itemNumber = (
int)
SendMessageWorker(pcbox->
spwndList, LB_GETCURSEL,
01872 0, 0,
FALSE);
01873
if (itemNumber == -1) {
01874 itemNumber = 0;
01875 }
01876
SendMessageWorker(pcbox->
spwndList, LB_SETTOPINDEX, itemNumber, 0,
FALSE);
01877
SendMessageWorker(pcbox->
spwndList, LBCB_CARETON, 0, 0,
FALSE);
01878
01879
01880
01881
01882
01883
01884
NtUserInvalidateRect(hwnd, &pcbox->
editrc,
TRUE);
01885 }
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896 editrc.left = pcbox->
spwnd->
rcWindow.left;
01897 editrc.top = pcbox->
spwnd->
rcWindow.top;
01898 editrc.right = pcbox->
spwnd->
rcWindow.left + pcbox->
cxCombo;
01899 editrc.bottom = pcbox->
spwnd->
rcWindow.top + pcbox->
cyCombo;
01900
01901
01902 cyItem = (
int)
SendMessageWorker(pcbox->
spwndList, LB_GETITEMHEIGHT, 0, 0,
FALSE);
01903
01904
if (cyItem == 0) {
01905
01906 RIPMSG0( RIP_WARNING,
"LB_GETITEMHEIGHT is returning 0\n" );
01907
01908 cyItem =
gpsi->cySysFontChar;
01909 }
01910
01911
01912
01913
01914 iHeight =
max(pcbox->
cyDrop, pcbox->
spwndList->
rcWindow.bottom -
01915 pcbox->
spwndList->
rcWindow.top);
01916
01917
if (dwMult = (
DWORD)
SendMessageWorker(pcbox->
spwndList, LB_GETCOUNT, 0, 0,
FALSE)) {
01918 dwMult = (
DWORD)(LOWORD(dwMult) * cyItem);
01919 dwMult +=
SYSMET(CYEDGE);
01920
01921
if (dwMult < 0x7FFF)
01922 iHeight =
min(LOWORD(dwMult), iHeight);
01923 }
01924
01925
if (!
TestWF(pcbox->
spwnd,
CBFNOINTEGRALHEIGHT)) {
01926 UserAssert(cyItem);
01927 iHeight = ((iHeight -
SYSMET(CYEDGE)) / cyItem) * cyItem +
SYSMET(CYEDGE);
01928 }
01929
01930
01931
01932
01933
01934
01935
01936 pMonitor =
_MonitorFromWindow(pcbox->
spwnd, MONITOR_DEFAULTTOPRIMARY);
01937
if (editrc.bottom + iHeight <= pMonitor->
rcMonitor.bottom) {
01938 yTop = editrc.bottom;
01939
if (!pcbox->
f3DCombo)
01940 yTop -=
SYSMET(CYBORDER);
01941
01942 fAnimPos =
TRUE;
01943 }
else {
01944 yTop =
max(editrc.top - iHeight, pMonitor->
rcMonitor.top);
01945
if (!pcbox->
f3DCombo)
01946 yTop +=
SYSMET(CYBORDER);
01947
01948 fAnimPos =
FALSE;
01949 }
01950
01951
if ( !
TestWF( pcbox->
spwnd,
WFWIN40COMPAT) )
01952 {
01953
01954
01955
01956
01957
01958
if ( (pcbox->
spwndList->
rcWindow.right - pcbox->
spwndList->
rcWindow.left ) >
01959 pcbox->
cxDrop )
01960
01961 pcbox->
cxDrop = pcbox->
spwndList->
rcWindow.right - pcbox->
spwndList->
rcWindow.left;
01962 }
01963
01964
NtUserSetWindowPos(hwndList, HWND_TOPMOST, editrc.left,
01965 yTop,
max(pcbox->
cxDrop, pcbox->
cxCombo), iHeight, SWP_NOACTIVATE);
01966
01967
01968
01969
01970
01971
UpdateWindow(hwnd);
01972
01973
if (!(
TEST_EffectPUSIF(
PUSIF_COMBOBOXANIMATION))
01974 || (
GetAppCompatFlags2(
VER40) & GACF2_ANIMATIONOFF)) {
01975
NtUserShowWindow(hwndList, SW_SHOWNA);
01976 }
else {
01977
AnimateWindow(hwndList,
CMS_QANIMATION, (fAnimPos ? AW_VER_POSITIVE :
01978 AW_VER_NEGATIVE) | AW_SLIDE);
01979 }
01980
01981
#ifdef LATER
01982
01983
01984
01985
if (pwndSysModal) {
01986
01987
01988
01989
01990
01991
01992
01993
01994
UpdateWindow(hwndList);
01995 }
01996
#endif
01997
01998
01999
02000
02001 {
02002
PLBIV plb = ((
PLBWND)pcbox->
spwndList)->pLBIV;
02003
02004
if ((plb !=
NULL) && (plb != (
PLBIV)-1)) {
02005 plb->
iTypeSearch = 0;
02006 }
02007 }
02008
02009
if (fTrack &&
TestWF(pcbox->
spwnd,
WFWIN40COMPAT))
02010
SendMessageWorker(pcbox->
spwndList, LBCB_STARTTRACK,
FALSE, 0,
FALSE);
02011
02012
ThreadUnlock(&tlpwndList);
02013 }
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028 void xxxCBInternalUpdateEditWindow(
02029
PCBOX pcbox,
02030 HDC hdcPaint)
02031 {
02032
int cchText = 0;
02033 LPWSTR pText =
NULL;
02034
int sItem;
02035 HDC hdc;
02036
UINT msg;
02037 HBRUSH hbrSave;
02038 HBRUSH hbrControl;
02039 HANDLE hOldFont;
02040 DRAWITEMSTRUCT dis;
02041 RECT rc;
02042 HWND hwnd =
HWq(pcbox->
spwnd);
02043
TL tlpwndList;
02044
TL tlpwndEdit;
02045
TL tlpwndParent;
02046
02047
CheckLock(pcbox->
spwnd);
02048
02049
02050
02051
02052
02053
02054
ThreadLock(pcbox->
spwndParent, &tlpwndParent);
02055
ThreadLock(pcbox->
spwndList, &tlpwndList);
02056
ThreadLock(pcbox->
spwndEdit, &tlpwndEdit);
02057
02058 sItem = (
int)
SendMessageWorker(pcbox->
spwndList, LB_GETCURSEL, 0, 0,
FALSE);
02059
02060
02061
02062
02063
02064
try {
02065
if (sItem != -1) {
02066 cchText = (
int)
SendMessageWorker(pcbox->
spwndList, LB_GETTEXTLEN,
02067 (
DWORD)sItem, 0,
FALSE);
02068
if ((pText = (LPWSTR)
UserLocalAlloc(HEAP_ZERO_MEMORY, (cchText+1) *
sizeof(WCHAR)))) {
02069 cchText = (
int)
SendMessageWorker(pcbox->
spwndList, LB_GETTEXT,
02070 (
DWORD)sItem, (LPARAM)pText,
FALSE);
02071 }
02072 }
02073
02074
if (!pcbox->
fNoEdit) {
02075
02076
if (pcbox->
spwndEdit) {
02077
if (
TestWF(pcbox->
spwnd,
CBFHASSTRINGS))
02078
SetWindowText(
HWq(pcbox->
spwndEdit), pText ? pText : TEXT(
""));
02079
02080
if (pcbox->
fFocus) {
02081
02082
02083
02084
SendMessageWorker(pcbox->
spwndEdit, EM_SETSEL, 0, MAXLONG, !!
TestWF(pcbox->
spwnd,
WFANSIPROC));
02085 }
02086 }
02087 }
else if (
IsComboVisible(pcbox)) {
02088
if (hdcPaint) {
02089 hdc = hdcPaint;
02090 }
else {
02091 hdc =
NtUserGetDC(hwnd);
02092 }
02093
02094 SetBkMode(hdc, OPAQUE);
02095
if (
TestWF(pcbox->
spwnd,
WFWIN40COMPAT)) {
02096
if (
TestWF(pcbox->
spwnd,
WFDISABLED))
02097
msg = WM_CTLCOLORSTATIC;
02098
else
02099
msg = WM_CTLCOLOREDIT;
02100 }
else
02101
msg = WM_CTLCOLORLISTBOX;
02102
02103 hbrControl =
GetControlBrush(hwnd, hdc,
msg);
02104 hbrSave = SelectObject(hdc, hbrControl);
02105
02106
CopyInflateRect(&rc, &pcbox->
editrc,
SYSMET(CXBORDER),
SYSMET(CYBORDER));
02107 PatBlt(hdc, rc.left, rc.top, rc.right - rc.left,
02108 rc.bottom - rc.top, PATCOPY);
02109
InflateRect(&rc, -
SYSMET(CXBORDER), -
SYSMET(CYBORDER));
02110
02111
if (pcbox->
fFocus && !pcbox->
fLBoxVisible) {
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
if (!
TestWF( pcbox->
spwnd,
WFWIN40COMPAT) || !pcbox->
OwnerDraw)
02122
FillRect(hdc, &rc,
SYSHBR(HIGHLIGHT));
02123
02124 SetBkColor(hdc,
SYSRGB(HIGHLIGHT));
02125 SetTextColor(hdc,
SYSRGB(HIGHLIGHTTEXT));
02126 }
else if (
TestWF(pcbox->
spwnd,
WFDISABLED) && !pcbox->
OwnerDraw) {
02127
if ((COLORREF)
SYSRGB(GRAYTEXT) != GetBkColor(hdc))
02128 SetTextColor(hdc,
SYSRGB(GRAYTEXT));
02129 }
02130
02131
if (pcbox->
hFont !=
NULL)
02132 hOldFont = SelectObject(hdc, pcbox->
hFont);
02133
02134
if (pcbox->
OwnerDraw) {
02135
02136
02137
02138
02139 dis.CtlType = ODT_COMBOBOX;
02140 dis.CtlID = PtrToUlong(pcbox->
spwnd->
spmenu);
02141 dis.itemID = sItem;
02142 dis.itemAction = ODA_DRAWENTIRE;
02143 dis.itemState = (
UINT)
02144 ((pcbox->
fFocus && !pcbox->
fLBoxVisible ? ODS_SELECTED : 0) |
02145 (
TestWF(pcbox->
spwnd,
WFDISABLED) ? ODS_DISABLED : 0) |
02146 (pcbox->
fFocus && !pcbox->
fLBoxVisible ? ODS_FOCUS : 0) |
02147 (
TestWF(pcbox->
spwnd,
WFWIN40COMPAT) ? ODS_COMBOBOXEDIT : 0) |
02148 (
TestWF(pcbox->
spwnd,
WEFPUIFOCUSHIDDEN) ? ODS_NOFOCUSRECT : 0) |
02149 (
TestWF(pcbox->
spwnd,
WEFPUIACCELHIDDEN) ? ODS_NOACCEL : 0));
02150
02151 dis.hwndItem = hwnd;
02152 dis.hDC = hdc;
02153
CopyRect(&dis.rcItem, &rc);
02154
02155
02156
02157 IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);
02158
02159 dis.itemData = (ULONG_PTR)
SendMessageWorker(pcbox->
spwndList,
02160 LB_GETITEMDATA, (
UINT)sItem, 0,
FALSE);
02161
02162
SendMessage(
HW(pcbox->
spwndParent), WM_DRAWITEM, dis.CtlID,
02163 (LPARAM)&dis);
02164 }
else {
02165
02166
02167
02168
02169
02170
02171
int x ;
02172
UINT align ;
02173
02174
if (pcbox->
fRightAlign ) {
02175 align = TA_RIGHT;
02176 x = rc.right -
SYSMET(CXBORDER);
02177 }
else {
02178 x = rc.left +
SYSMET(CXBORDER);
02179 align = 0;
02180 }
02181
02182
if (pcbox->
fRtoLReading )
02183 align |= TA_RTLREADING;
02184
02185
if (align)
02186 SetTextAlign(hdc, GetTextAlign(hdc) | align);
02187
02188
02189 ExtTextOut(hdc, x, rc.top +
SYSMET(CYBORDER), ETO_CLIPPED | ETO_OPAQUE,
02190 &rc, pText ? pText : TEXT(
""), cchText,
NULL);
02191
if (pcbox->
fFocus && !pcbox->
fLBoxVisible) {
02192
if (!
TestWF(pcbox->
spwnd,
WEFPUIFOCUSHIDDEN)) {
02193
DrawFocusRect(hdc, &rc);
02194 }
02195 }
02196 }
02197
02198
if (pcbox->
hFont && hOldFont) {
02199 SelectObject(hdc, hOldFont);
02200 }
02201
02202
if (hbrSave) {
02203 SelectObject(hdc, hbrSave);
02204 }
02205
02206
if (!hdcPaint) {
02207
NtUserReleaseDC(hwnd, hdc);
02208 }
02209 }
02210
02211 } finally {
02212
if (pText !=
NULL)
02213
UserLocalFree((HANDLE)pText);
02214 }
02215
02216
ThreadUnlock(&tlpwndEdit);
02217
ThreadUnlock(&tlpwndList);
02218
ThreadUnlock(&tlpwndParent);
02219 }
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230 void xxxCBInvertStaticWindow(
02231
PCBOX pcbox,
02232 BOOL fNewSelectionState,
02233 HDC hdc)
02234 {
02235
BOOL focusSave = pcbox->
fFocus;
02236
02237
CheckLock(pcbox->
spwnd);
02238
02239 pcbox->
fFocus = (
UINT)fNewSelectionState;
02240
xxxCBInternalUpdateEditWindow(pcbox, hdc);
02241
02242 pcbox->
fFocus = (
UINT)focusSave;
02243 }
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255 void xxxCBUpdateListBoxWindow(
02256
PCBOX pcbox,
02257 BOOL fSelectionAlso)
02258 {
02259
int cchText;
02260
int sItem, sSel;
02261 LPWSTR pText =
NULL;
02262
TL tlpwndEdit;
02263
TL tlpwndList;
02264
02265
if (pcbox->
spwndEdit ==
NULL) {
02266
return;
02267 }
02268
02269
CheckLock(pcbox->
spwnd);
02270
02271
ThreadLock(pcbox->
spwndList, &tlpwndList);
02272
ThreadLock(pcbox->
spwndEdit, &tlpwndEdit);
02273
02274
02275
02276
02277
02278 cchText = (
int)
SendMessageWorker(pcbox->
spwndEdit, WM_GETTEXTLENGTH, 0, 0,
FALSE);
02279
02280
if (cchText) {
02281 cchText++;
02282 pText = (LPWSTR)
UserLocalAlloc(HEAP_ZERO_MEMORY, cchText*
sizeof(WCHAR));
02283
if (pText !=
NULL) {
02284
try {
02285
SendMessageWorker(pcbox->
spwndEdit, WM_GETTEXT, cchText, (LPARAM)pText,
FALSE);
02286 sItem = (
int)
SendMessageWorker(pcbox->
spwndList, LB_FINDSTRING,
02287 (WPARAM)-1
L, (LPARAM)pText,
FALSE);
02288 } finally {
02289
UserLocalFree((HANDLE)pText);
02290 }
02291 }
02292 }
02293
else
02294 sItem = -1;
02295
02296
if (fSelectionAlso) {
02297 sSel = sItem;
02298 }
else {
02299 sSel = -1;
02300 }
02301
02302
if (sItem == -1)
02303 {
02304 sItem = 0;
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
if (fSelectionAlso && !
TestWF(pcbox->
spwnd,
WFWIN40COMPAT))
02323 sSel = 0;
02324 }
02325
02326
02327
SendMessageWorker(pcbox->
spwndList, LB_SETCURSEL, (
DWORD)sSel, 0,
FALSE);
02328
SendMessageWorker(pcbox->
spwndList, LB_SETCARETINDEX, (
DWORD)sItem, 0,
FALSE);
02329
SendMessageWorker(pcbox->
spwndList, LB_SETTOPINDEX, (
DWORD)sItem, 0,
FALSE);
02330
02331
ThreadUnlock(&tlpwndEdit);
02332
ThreadUnlock(&tlpwndList);
02333 }
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343 void xxxCBGetFocusHelper(
02344
PCBOX pcbox)
02345 {
02346
TL tlpwndList;
02347
TL tlpwndEdit;
02348
02349
CheckLock(pcbox->
spwnd);
02350
02351
if (pcbox->
fFocus)
02352
return;
02353
02354
ThreadLock(pcbox->
spwndList, &tlpwndList);
02355
ThreadLock(pcbox->
spwndEdit, &tlpwndEdit);
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
if (pcbox->
CBoxStyle ==
SDROPDOWNLIST)
02366
SendMessageWorker(pcbox->
spwndList, LBCB_CARETON, 0, 0,
FALSE);
02367
02368
02369
02370
02371
02372
if (pcbox->
fNoEdit) {
02373
02374
02375
02376
02377
xxxCBInvertStaticWindow(pcbox,
TRUE, (HDC)
NULL);
02378 }
else if (pcbox->
spwndEdit) {
02379 UserAssert(pcbox->
spwnd);
02380
SendMessageWorker(pcbox->
spwndEdit, EM_SETSEL, 0, MAXLONG, !!
TestWF(pcbox->
spwnd,
WFANSIPROC));
02381 }
02382
02383 pcbox->
fFocus =
TRUE;
02384
02385
02386
02387
02388
xxxCBNotifyParent(pcbox, CBN_SETFOCUS);
02389
02390
ThreadUnlock(&tlpwndEdit);
02391
ThreadUnlock(&tlpwndList);
02392 }
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402 void xxxCBKillFocusHelper(
02403
PCBOX pcbox)
02404 {
02405
TL tlpwndList;
02406
TL tlpwndEdit;
02407
02408
CheckLock(pcbox->
spwnd);
02409
02410
if (!pcbox->
fFocus || pcbox->
spwndList ==
NULL)
02411
return;
02412
02413
ThreadLock(pcbox->
spwndList, &tlpwndList);
02414
ThreadLock(pcbox->
spwndEdit, &tlpwndEdit);
02415
02416
02417
02418
02419
02420
02421
02422
SendMessageWorker(pcbox->
spwnd, WM_LBUTTONUP, 0
L, 0xFFFFFFFFL,
FALSE);
02423
if (!
xxxCBHideListBoxWindow(pcbox,
TRUE,
FALSE))
02424
return;
02425
02426
02427
02428
02429
02430
if (pcbox->
CBoxStyle ==
SDROPDOWNLIST)
02431
SendMessageWorker(pcbox->
spwndList, LBCB_CARETOFF, 0, 0,
FALSE);
02432
02433
if (pcbox->
fNoEdit) {
02434
02435
02436
02437
02438
xxxCBInvertStaticWindow(pcbox,
FALSE, (HDC)
NULL);
02439 }
else if (pcbox->
spwndEdit) {
02440
SendMessageWorker(pcbox->
spwndEdit, EM_SETSEL, 0, 0, !!
TestWF(pcbox->
spwnd,
WFANSIPROC));
02441 }
02442
02443 pcbox->
fFocus =
FALSE;
02444
xxxCBNotifyParent(pcbox, CBN_KILLFOCUS);
02445
02446
ThreadUnlock(&tlpwndEdit);
02447
ThreadUnlock(&tlpwndList);
02448 }
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460 LONG
xxxCBGetTextLengthHelper(
02461
PCBOX pcbox,
02462 BOOL fAnsi)
02463 {
02464
int item;
02465
int cchText;
02466
TL tlpwndList;
02467
02468
ThreadLock(pcbox->
spwndList, &tlpwndList);
02469 item = (
int)
SendMessageWorker(pcbox->
spwndList, LB_GETCURSEL, 0, 0, fAnsi);
02470
02471
if (item == LB_ERR) {
02472
02473
02474
02475
02476 cchText = 0;
02477 }
else {
02478 cchText = (
int)
SendMessageWorker(pcbox->
spwndList, LB_GETTEXTLEN,
02479 item, 0, fAnsi);
02480 }
02481
02482
ThreadUnlock(&tlpwndList);
02483
02484
return cchText;
02485 }
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496 LONG
xxxCBGetTextHelper(
02497
PCBOX pcbox,
02498
int cchString,
02499 LPWSTR pString,
02500 BOOL fAnsi)
02501 {
02502
int item;
02503
int cchText;
02504 LPWSTR pText;
02505
DWORD dw;
02506
TL tlpwndList;
02507
02508
CheckLock(pcbox->
spwnd);
02509
02510
if (!cchString || !pString)
02511
return 0;
02512
02513
02514
02515
02516
if (fAnsi) {
02517 *((LPSTR)pString) = 0;
02518 }
else {
02519 *((LPWSTR)pString) = 0;
02520 }
02521
02522
ThreadLock(pcbox->
spwndList, &tlpwndList);
02523 item = (
int)
SendMessageWorker(pcbox->
spwndList, LB_GETCURSEL, 0, 0, fAnsi);
02524
02525
if (item == LB_ERR) {
02526
02527
02528
02529
02530
ThreadUnlock(&tlpwndList);
02531
return 0;
02532 }
02533
02534 cchText = (
int)
SendMessageWorker(pcbox->
spwndList, LB_GETTEXTLEN, item, 0, fAnsi);
02535
02536 cchText++;
02537
if ((cchText <= cchString) ||
02538 (!
TestWF(pcbox->
spwnd,
WFWIN31COMPAT) && cchString == 2)) {
02539
02540
02541
02542
02543
02544 dw = (
int)
SendMessageWorker(pcbox->
spwndList, LB_GETTEXT, item,
02545 (LPARAM)pString, fAnsi);
02546
ThreadUnlock(&tlpwndList);
02547
return dw;
02548 }
02549
02550
if (!(pText = (LPWSTR)
UserLocalAlloc(HEAP_ZERO_MEMORY, cchText*
sizeof(WCHAR)))) {
02551
02552
02553
02554
02555
ThreadUnlock(&tlpwndList);
02556
return 0;
02557 }
02558
02559
try {
02560
SendMessageWorker(pcbox->
spwndList, LB_GETTEXT, item, (LPARAM)pText, fAnsi);
02561
if (fAnsi) {
02562 RtlCopyMemory((
PBYTE)pString, (
PBYTE)pText, cchString);
02563 ((LPSTR)pString)[cchString - 1] = 0;
02564 }
else {
02565 RtlCopyMemory((
PBYTE)pString, (
PBYTE)pText, cchString *
sizeof(WCHAR));
02566 ((LPWSTR)pString)[cchString - 1] = 0;
02567 }
02568 } finally {
02569
UserLocalFree((HANDLE)pText);
02570 }
02571
02572
ThreadUnlock(&tlpwndList);
02573
return cchString;
02574 }