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

combo.c File Reference

#include "precomp.h"

Go to the source code of this file.

Functions

BOOL NtUserTrackMouseEvent (TRACKMOUSEEVENT *ptme)
LONG xxxCBGetTextLengthHelper (PCBOX pcbox, BOOL fAnsi)
LONG xxxCBGetTextHelper (PCBOX pcbox, int len, LPWSTR lpstr, BOOL fAnsi)
void xxxPressButton (PCBOX pcbox, BOOL fPress)
LRESULT ComboBoxDBCharHandler (PCBOX pcbox, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
BOOL ComboBoxMsgOKInInit (UINT message, LRESULT *plRet)
LRESULT APIENTRY ComboBoxWndProcWorker (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, DWORD fAnsi)
LRESULT WINAPI ComboBoxWndProcA (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT WINAPI ComboBoxWndProcW (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT xxxCBMessageItemHandler (PCBOX pcbox, UINT message, LPVOID lpfoo)
void xxxCBPaint (PCBOX pcbox, HDC hdc)
long xxxCBCommandHandler (PCBOX pcbox, DWORD wParam, HWND hwndControl)
void xxxCBNotifyParent (PCBOX pcbox, short notificationCode)
void xxxCBCompleteEditWindow (PCBOX pcbox)
BOOL xxxCBHideListBoxWindow (PCBOX pcbox, BOOL fNotifyParent, BOOL fSelEndOK)
void xxxCBShowListBoxWindow (PCBOX pcbox, BOOL fTrack)
void xxxCBInternalUpdateEditWindow (PCBOX pcbox, HDC hdcPaint)
void xxxCBInvertStaticWindow (PCBOX pcbox, BOOL fNewSelectionState, HDC hdc)
void xxxCBUpdateListBoxWindow (PCBOX pcbox, BOOL fSelectionAlso)
void xxxCBGetFocusHelper (PCBOX pcbox)
void xxxCBKillFocusHelper (PCBOX pcbox)

Variables

LOOKASIDE ComboboxLookaside


Function Documentation

LRESULT ComboBoxDBCharHandler PCBOX  pcbox,
HWND  hwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 104 of file combo.c.

References BYTE, CrackCombinedDbcsTB, DbcsCombine(), FALSE, tagCBox::fNoEdit, HWq, MBToWCSEx(), SendMessageWorker(), tagCBox::spwndEdit, tagCBox::spwndList, TestWF, THREAD_CODEPAGE, TRUE, and WFANSIPROC.

Referenced by ComboBoxWndProcWorker().

00110 { 00111 WORD w; 00112 PWND pwndSend; 00113 00114 w = DbcsCombine(hwnd, (BYTE)wParam); 00115 if (w == 0) { 00116 return CB_ERR; // Failed to assemble DBCS 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 // If receiver is not ANSI WndProc (may be subclassed?), 00135 // send a UNICODE message. 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 * Post the Trailing byte to the target 00149 * so that they can peek the second WM_CHAR 00150 * message later. 00151 * Note: it's safe since sender is A and receiver is A, 00152 * translation layer does not perform any DBCS combining and cracking. 00153 */ 00154 PostMessageA(HWq(pwndSend), message, CrackCombinedDbcsTB(w), lParam); 00155 return SendMessageWorker(pwndSend, message, wParam, lParam, TRUE); 00156 }

BOOL ComboBoxMsgOKInInit UINT  message,
LRESULT *  plRet
 

Definition at line 158 of file combo.c.

References BOOL, FALSE, and TRUE.

Referenced by ComboBoxWndProcWorker().

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 * Cannot handle those messages yet. Bail out. 00192 */ 00193 *plRet = CB_ERR; 00194 return FALSE; 00195 } 00196 return TRUE; 00197 }

LRESULT WINAPI ComboBoxWndProcA HWND  hwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 1335 of file combo.c.

References ComboBoxWndProcWorker(), DefWindowProcWorker(), FNID_COMBOBOX, FWINDOWMSG, L, NULL, SYSMET, TRUE, and ValidateHwnd.

Referenced by ClientThreadSetup().

01340 { 01341 PWND pwnd; 01342 01343 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 01344 return (0L); 01345 } 01346 01347 /* 01348 * If the control is not interested in this message, 01349 * pass it to DefWindowProc. 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 }

LRESULT WINAPI ComboBoxWndProcW HWND  hwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 1359 of file combo.c.

References ComboBoxWndProcWorker(), DefWindowProcWorker(), FALSE, FNID_COMBOBOX, FWINDOWMSG, L, NULL, SYSMET, and ValidateHwnd.

Referenced by ClientThreadSetup(), and RW_RegisterControls().

01364 { 01365 PWND pwnd; 01366 01367 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 01368 return (0L); 01369 } 01370 01371 /* 01372 * If the control is not interested in this message, 01373 * pass it to DefWindowProc. 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 }

LRESULT APIENTRY ComboBoxWndProcWorker PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam,
DWORD  fAnsi
 

Definition at line 207 of file combo.c.

References _ClientToScreen(), _IsChild(), _ScreenToClient(), abs, APIENTRY, BOOL, tagCBox::buttonrc, BYTE, CBNcCreateHandler(), CBOX, tagCBox::CBoxStyle, CheckLock, ComboBoxDBCharHandler(), ComboboxLookaside, ComboBoxMsgOKInInit(), tagCBox::cxCombo, tagCBox::cxDrop, tagCBox::cyCombo, tagCBox::cyDrop, DefWindowProcWorker(), DWORD, tagCBox::editrc, FALSE, tagCBox::fButtonPressed, tagCBox::fCase, tagCBox::fExtendedUI, tagCBox::fFocus, tagCBox::fLBoxVisible, tagCBox::fMouseDown, FNID_COMBOBOX, tagCBox::fNoEdit, tagCBox::fNoRedraw, tagCBox::fRightAlign, tagCBox::fRtoLReading, FWINABLE, GetContextHelpId(), GetKeyState(), tagCBox::hFont, HW, HWq, INITCONTROLLOOKASIDE, IS_DBCS_ENABLED, IsComboVisible, tagLBIV::iTypeSearch, L, LPVOID, max, NotifyWinEvent(), NtUserBeginPaint(), NtUserEnableWindow, NtUserEndPaint(), NtUserInvalidateRect(), NtUserReleaseCapture, NtUserSetCapture(), NtUserSetFocus(), NULL, PLBIV, PLBWND, tagLBIV::pszTypeSearch, PtInRect(), PTR_TO_ID, tagWND::rcClient, tagWND::rcWindow, REBASEPWND, SDROPDOWN, SDROPDOWNLIST, SDROPPABLE, SEDITABLE, SendMessage(), SendMessageWorker(), SHORT, tagWND::spmenu, tagCBox::spwndEdit, tagCBox::spwndList, SYSMET, TestWF, THREAD_CODEPAGE, ThreadLock, ThreadUnlock, TRUE, UINT, UPPERCASE, UserLocalFree, VALIDATECLASSANDSIZE, ValidateHwnd, WEFRIGHT, WEFRTLREADING, WFDISABLED, WFVISIBLE, WFWIN40COMPAT, xxxCBCommandHandler(), xxxCBCompleteEditWindow(), xxxCBCreateHandler(), xxxCBDir(), xxxCBGetFocusHelper(), xxxCBGetTextHelper(), xxxCBGetTextLengthHelper(), xxxCBHideListBoxWindow(), xxxCBInternalUpdateEditWindow(), xxxCBKillFocusHelper(), xxxCBMessageItemHandler(), xxxCBNcDestroyHandler(), xxxCBPaint(), xxxCBPosition(), xxxCBSetEditItemHeight(), xxxCBSetFontHandler(), xxxCBShowListBoxWindow(), xxxCBSizeHandler(), xxxCBUpdateListBoxWindow(), and xxxPressButton().

Referenced by ClientThreadSetup(), ComboBoxWndProcA(), ComboBoxWndProcW(), ECNcDestroyHandler(), and xxxDestroyLBox().

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 * Get the pcbox for the given window now since we will use it a lot in 00232 * various handlers. This is stored by NtUserSetWindowLongPtr() in the 00233 * INITCONTROLLOOKASIDE macro above. 00234 */ 00235 pcbox = ((PCOMBOWND)pwnd)->pcbox; 00236 00237 /* 00238 * Protect the combobox during the initialization. 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 * Dispatch the various messages we can receive 00252 */ 00253 switch (message) { 00254 case CBEC_KILLCOMBOFOCUS: 00255 00256 /* 00257 * Private message coming from editcontrol informing us that the combo 00258 * box is losing the focus to a window which isn't in this combo box. 00259 */ 00260 xxxCBKillFocusHelper(pcbox); 00261 break; 00262 00263 case WM_COMMAND: 00264 00265 /* 00266 * So that we can handle notification messages from the listbox and 00267 * edit control. 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 // Causes compatibility problems for 3.X apps. Forward only 00310 // for 4.0 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 * If the is not edit control, CBS_DROPDOWNLIST, then we have to 00337 * ask the list box for the size 00338 */ 00339 00340 if (pcbox->fNoEdit) { 00341 return xxxCBGetTextLengthHelper(pcbox, fAnsi); 00342 } 00343 00344 // FALL THROUGH 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 * wParam - not used 00358 * lParam - Points to the CREATESTRUCT data structure for the window. 00359 */ 00360 return xxxCBCreateHandler(pcbox, pwnd); 00361 00362 case WM_ERASEBKGND: 00363 00364 /* 00365 * Just return 1L so that the background isn't erased 00366 */ 00367 return 1L; 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 * wParam - perhaps a hdc 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 * wParam - not used 00411 * lParam - not used 00412 */ 00413 { 00414 LRESULT code = DLGC_WANTCHARS | DLGC_WANTARROWS; 00415 00416 // If the listbox is dropped and the ENTER key is pressed, 00417 // we want this message so we can close up the listbox 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 * No fall through 00429 */ 00430 00431 case WM_SETFONT: 00432 xxxCBSetFontHandler(pcbox, (HANDLE)wParam, LOWORD(lParam)); 00433 break; 00434 00435 case WM_SYSKEYDOWN: 00436 if (lParam & 0x20000000L) /* Check if the alt key is down */ { 00437 00438 /* 00439 * Handle Combobox support. We want alt up or down arrow to behave 00440 * like F4 key which completes the combo box selection 00441 */ 00442 if (lParam & 0x1000000) { 00443 00444 /* 00445 * This is an extended key such as the arrow keys not on the 00446 * numeric keypad so just drop the combobox. 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 * If numlock down, just send all system keys to dwp 00457 */ 00458 goto CallDWP; 00459 } else { 00460 00461 /* 00462 * We just want to ignore keys on the number pad... 00463 */ 00464 if (!(wParam == VK_DOWN || wParam == VK_UP)) 00465 goto CallDWP; 00466 } 00467 DropCombo: 00468 if (!pcbox->fLBoxVisible) { 00469 00470 /* 00471 * If the listbox isn't visible, just show it 00472 */ 00473 xxxCBShowListBoxWindow(pcbox, TRUE); 00474 } else { 00475 00476 /* 00477 * Ok, the listbox is visible. So hide the listbox window. 00478 */ 00479 if (!xxxCBHideListBoxWindow(pcbox, TRUE, TRUE)) 00480 return(0L); 00481 } 00482 } 00483 goto CallDWP; 00484 break; 00485 00486 case WM_KEYDOWN: 00487 /* 00488 * If the listbox is dropped and the ENTER key is pressed, 00489 * close up the listbox successfully. If ESCAPE is pressed, 00490 * close it up like cancel. 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 // FALL THROUGH 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 * Set the focus to the combo box if we get a mouse click on it. 00521 */ 00522 if (!pcbox->fFocus) { 00523 NtUserSetFocus(hwnd); 00524 if (!pcbox->fFocus) { 00525 00526 /* 00527 * Don't do anything if we still don't have the focus. 00528 */ 00529 break; 00530 } 00531 } 00532 00533 /* 00534 * If user clicked in button rect and we are a combobox with edit, then 00535 * drop the listbox. (The button rect is 0 if there is no button so the 00536 * ptinrect will return false.) If a drop down list (no edit), clicking 00537 * anywhere on the face causes the list to drop. 00538 */ 00539 00540 POINTSTOPOINT(pt, lParam); 00541 if ((pcbox->CBoxStyle == SDROPDOWN && 00542 PtInRect(&pcbox->buttonrc, pt)) || 00543 pcbox->CBoxStyle == SDROPDOWNLIST) { 00544 00545 /* 00546 * Set the fMouseDown flag so that we can handle clicking on 00547 * the popdown button and dragging into the listbox (when it just 00548 * dropped down) to make a selection. 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(0L); 00560 } else { 00561 xxxCBShowListBoxWindow(pcbox, FALSE); 00562 00563 // Setting and resetting this flag must always be followed 00564 // imediately by SetCapture or ReleaseCapture 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 * Handle only scrolling. 00578 */ 00579 if (wParam & (MK_CONTROL | MK_SHIFT)) 00580 goto CallDWP; 00581 00582 /* 00583 * If the listbox is visible, send it the message to scroll. 00584 */ 00585 if (pcbox->fLBoxVisible) 00586 goto CallListSendMessage; 00587 00588 /* 00589 * If we're in extended UI mode or the edit control isn't yet created, 00590 * bail. 00591 */ 00592 if (pcbox->fExtendedUI || pcbox->spwndEdit == NULL) 00593 return TRUE; 00594 00595 /* 00596 * Emulate arrow up/down messages to the edit control. 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 // Pop combo listbox back up, canceling. 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 * Clear this flag so that mouse moves aren't sent to the listbox 00630 */ 00631 if (pcbox->fMouseDown) { 00632 pcbox->fMouseDown = FALSE; 00633 00634 if (pcbox->CBoxStyle == SDROPDOWN) { 00635 // If an item in the listbox matches the text in the edit 00636 // control, scroll it to the top of the listbox. Select the 00637 // item only if the mouse button isn't down otherwise we 00638 // will select the item when the mouse button goes up. 00639 xxxCBUpdateListBoxWindow(pcbox, TRUE); 00640 xxxCBCompleteEditWindow(pcbox); 00641 } 00642 NtUserReleaseCapture(); 00643 00644 // Now, we want listbox to track mouse moves while mouse up 00645 // until mouse down, and select items as though they were 00646 // clicked on. 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 // Note conversion of INT bit field to BOOL (1 or 0) 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 * This handles dropdown comboboxes/listboxes so that clicking 00679 * on the dropdown button and dragging into the listbox window 00680 * will let the user make a listbox selection. 00681 */ 00682 pcbox->fMouseDown = FALSE; 00683 NtUserReleaseCapture(); 00684 00685 if (pcbox->CBoxStyle & SEDITABLE) { 00686 00687 /* 00688 * If an item in the listbox matches the text in the edit 00689 * control, scroll it to the top of the listbox. Select the 00690 * item only if the mouse button isn't down otherwise we 00691 * will select the item when the mouse button goes up. 00692 */ 00693 00694 /* 00695 * We need to select the item which matches the editcontrol 00696 * so that if the user drags out of the listbox, we don't 00697 * cancel back to his origonal selection 00698 */ 00699 xxxCBUpdateListBoxWindow(pcbox, TRUE); 00700 } 00701 00702 /* 00703 * Convert point to listbox coordinates and send a buttondown 00704 * message to the listbox window. 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 * There is no editcontrol so set the focus to the combo box itself. 00727 */ 00728 xxxCBGetFocusHelper(pcbox); 00729 } else if (pcbox->spwndEdit) { 00730 /* 00731 * Set the focus to the edit control window if there is one 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 * wParam has the new focus hwnd 00743 */ 00744 if (wParam != 0) 00745 wParam = (WPARAM)ValidateHwnd((HWND)wParam); 00746 if ((wParam == 0) || !_IsChild(pwnd, (PWND)wParam)) { 00747 00748 /* 00749 * We only give up the focus if the new window getting the focus 00750 * doesn't belong to the combo box. 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 * wParam - specifies state of the redraw flag. nonzero = redraw 00773 * lParam - not used 00774 */ 00775 00776 /* 00777 * effects: Sets the state of the redraw flag for this combo box 00778 * and its children. 00779 */ 00780 pcbox->fNoRedraw = (UINT)!((BOOL)wParam); 00781 00782 /* 00783 * Must check pcbox->spwnEdit in case we get this message before 00784 * WM_CREATE - PCBOX won't be initialized yet. (Eudora does this) 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 * Invalidate the rect to cause it to be drawn in grey for its 00798 * disabled view or ungreyed for non-disabled view. 00799 */ 00800 NtUserInvalidateRect(hwnd, NULL, FALSE); 00801 if ((pcbox->CBoxStyle & SEDITABLE) && pcbox->spwndEdit) { 00802 00803 /* 00804 * Enable/disable the edit control window 00805 */ 00806 ThreadLock(pcbox->spwndEdit, &tlpwndEdit); 00807 NtUserEnableWindow(HWq(pcbox->spwndEdit), (TestWF(pwnd, WFDISABLED) == 0)); 00808 ThreadUnlock(&tlpwndEdit); 00809 } 00810 00811 /* 00812 * Enable/disable the listbox window 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 * wParam - defines the type of resizing fullscreen, sizeiconic, 00824 * sizenormal etc. 00825 * lParam - new width in LOWORD, new height in HIGHUINT of client area 00826 */ 00827 UserAssert(pcbox->spwndList); 00828 if (LOWORD(lParam) == 0 || HIWORD(lParam) == 0) { 00829 00830 /* 00831 * If being sized to a zero width or to a zero height or we aren't 00832 * fully initialized, just return. 00833 */ 00834 return 0; 00835 } 00836 00837 // OPTIMIZATIONS -- first check if old and new widths are the same 00838 if (pcbox->cxCombo == pwnd->rcWindow.right - pwnd->rcWindow.left) { 00839 int iNewHeight = pwnd->rcWindow.bottom - pwnd->rcWindow.top; 00840 00841 // now check if new height is the dropped down height 00842 if (pcbox->fLBoxVisible) { 00843 // Check if new height is the full size height 00844 if (pcbox->cyDrop + pcbox->cyCombo == iNewHeight) 00845 return(0L); 00846 } else { 00847 // Check if new height is the closed up height 00848 if (pcbox->cyCombo == iNewHeight) 00849 return(0L); 00850 } 00851 } 00852 00853 xxxCBSizeHandler(pcbox); 00854 break; 00855 00856 case CB_GETDROPPEDSTATE: 00857 00858 /* 00859 * returns 1 if combo is dropped down else 0 00860 * wParam - not used 00861 * lParam - not used 00862 */ 00863 return pcbox->fLBoxVisible; 00864 00865 case CB_GETDROPPEDCONTROLRECT: 00866 00867 /* 00868 * wParam - not used 00869 * lParam - lpRect which will get the dropped down window rect in 00870 * screen coordinates. 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 // fall thru 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 * wParam - Dos attribute value. 00902 * lParam - Points to a file specification string 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 * wParam - specifies state to set extendui flag to. 00919 * Currently only 1 is allowed. Return CB_ERR (-1) if 00920 * failure else 0 if success. 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 * wParam - not used 00958 * lParam - not used 00959 * effects: Gets the selection range for the given edit control. The 00960 * starting BYTE-position is in the low order word. It contains the 00961 * the BYTE-position of the first nonselected character after the end 00962 * of the selection in the high order word. Returns CB_ERR if no 00963 * editcontrol. 00964 */ 00965 message = EM_GETSEL; 00966 goto CallEditSendMessage; 00967 break; 00968 00969 case CB_LIMITTEXT: 00970 00971 /* 00972 * wParam - max number of bytes that can be entered 00973 * lParam - not used 00974 * effects: Specifies the maximum number of bytes of text the user may 00975 * enter. If maxLength is 0, we may enter MAXINT number of BYTES. 00976 */ 00977 message = EM_LIMITTEXT; 00978 goto CallEditSendMessage; 00979 break; 00980 00981 case CB_SETEDITSEL: 00982 00983 /* 00984 * wParam - ichStart 00985 * lParam - ichEnd 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 * wParam - not used 00999 * lParam - Points to null terminated string to be added to listbox 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 * wParam - index to string to be deleted 01012 * lParam - not used 01013 */ 01014 message = LB_DELETESTRING; 01015 goto CallListSendMessage; 01016 break; 01017 01018 case CB_INITSTORAGE: 01019 // wParamLo - number of items 01020 // lParam - number of bytes of string space 01021 message = LB_INITSTORAGE; 01022 goto CallListSendMessage; 01023 01024 case CB_SETTOPINDEX: 01025 // wParamLo - index to make top 01026 // lParam - not used 01027 message = LB_SETTOPINDEX; 01028 goto CallListSendMessage; 01029 01030 case CB_GETTOPINDEX: 01031 // wParamLo / lParam - not used 01032 message = LB_GETTOPINDEX; 01033 goto CallListSendMessage; 01034 01035 case CB_GETCOUNT: 01036 01037 /* 01038 * wParam - not used 01039 * lParam - not used 01040 */ 01041 message = LB_GETCOUNT; 01042 goto CallListSendMessage; 01043 break; 01044 01045 case CB_GETCURSEL: 01046 01047 /* 01048 * wParam - not used 01049 * lParam - not used 01050 */ 01051 message = LB_GETCURSEL; 01052 goto CallListSendMessage; 01053 break; 01054 01055 case CB_GETLBTEXT: 01056 01057 /* 01058 * wParam - index of string to be copied 01059 * lParam - buffer that is to receive the string 01060 */ 01061 message = LB_GETTEXT; 01062 goto CallListSendMessage; 01063 break; 01064 01065 case CB_GETLBTEXTLEN: 01066 01067 /* 01068 * wParam - index to string 01069 * lParam - now used for cbANSI 01070 */ 01071 message = LB_GETTEXTLEN; 01072 goto CallListSendMessage; 01073 break; 01074 01075 case CB_INSERTSTRING: 01076 01077 /* 01078 * wParam - position to receive the string 01079 * lParam - points to the string 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 * wParam - not used 01092 * lParam - not used 01093 * If we come here before WM_CREATE has been processed, 01094 * pcbox->spwndList will be NULL. 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 * wParam - index of starting point for search 01115 * lParam - points to prefix string 01116 */ 01117 message = LB_FINDSTRING; 01118 goto CallListSendMessage; 01119 break; 01120 01121 case CB_FINDSTRINGEXACT: 01122 01123 /* 01124 * wParam - index of starting point for search 01125 * lParam - points to a exact string 01126 */ 01127 message = LB_FINDSTRINGEXACT; 01128 goto CallListSendMessage; 01129 break; 01130 01131 case CB_SELECTSTRING: 01132 01133 /* 01134 * wParam - index of starting point for search 01135 * lParam - points to prefix string 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 * wParam - Contains index to be selected 01149 * lParam - not used 01150 * If we come here before WM_CREATE has been processed, 01151 * pcbox->spwndList will be NULL. 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 * wParam - True then drop down the listbox if possible else hide it 01198 * lParam - not used 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 * wParam - locale id 01213 * lParam - not used 01214 */ 01215 message = LB_SETLOCALE; 01216 goto CallListSendMessage; 01217 break; 01218 01219 case CB_GETLOCALE: 01220 01221 /* 01222 * wParam - not used 01223 * lParam - not used 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 * wParam - Contains a handle to the window being created 01239 * lParam - Points to the CREATESTRUCT data structure for the window. 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 * Propagate the change to the list control, if any 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 /* Check if this message is form a child of this combo 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 // BUGBUG - What to do here? 01278 lpHelpInfo->iCtrlId = (SHORT)(PTR_TO_ID(pwnd->spmenu)); 01279 lpHelpInfo->hItemHandle = hwnd; 01280 lpHelpInfo->dwContextId = GetContextHelpId(pwnd); 01281 } 01282 } 01283 /* 01284 * Fall through to DefWindowProc 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 } /* switch (message) */ 01296 01297 return TRUE; 01298 01299 /* 01300 * The following forward messages off to the child controls. 01301 */ 01302 CallEditSendMessage: 01303 if (!pcbox->fNoEdit && pcbox->spwndEdit) { 01304 /* 01305 * pcbox->spwndEdit will be NULL if we haven't done WM_CREATE yet! 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 * pcbox->spwndList will be NULL if we haven't done WM_CREATE yet! 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 } /* ComboBoxWndProcWorker */

BOOL NtUserTrackMouseEvent TRACKMOUSEEVENT *  ptme  ) 
 

long xxxCBCommandHandler PCBOX  pcbox,
DWORD  wParam,
HWND  hwndControl
 

Definition at line 1494 of file combo.c.

References CheckLock, FALSE, tagCBox::fFocus, tagCBox::fKeyboardSelInListBox, tagCBox::fNoEdit, HWq, L, NULL, SAMEWOWHANDLE, tagCBox::spwnd, tagCBox::spwndEdit, tagCBox::spwndList, TRUE, xxxCBGetFocusHelper(), xxxCBHideListBoxWindow(), xxxCBInternalUpdateEditWindow(), xxxCBNotifyParent(), and xxxCBUpdateListBoxWindow().

Referenced by ComboBoxWndProcWorker().

01498 { 01499 01500 CheckLock(pcbox->spwnd); 01501 01502 /* 01503 * Check the edit control notification codes. Note that currently, edit 01504 * controls don't send EN_KILLFOCUS messages to the parent. 01505 */ 01506 if (!pcbox->fNoEdit && 01507 SAMEWOWHANDLE(hwndControl, HWq(pcbox->spwndEdit))) { 01508 01509 /* 01510 * Edit control notification codes 01511 */ 01512 switch (HIWORD(wParam)) { 01513 case EN_SETFOCUS: 01514 if (!pcbox->fFocus) { 01515 01516 /* 01517 * The edit control has the focus for the first time which means 01518 * this is the first time the combo box has received the focus 01519 * and the parent must be notified that we have the focus. 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 * Check listbox control notification codes 01542 */ 01543 if (SAMEWOWHANDLE(hwndControl, HWq(pcbox->spwndList))) { 01544 01545 /* 01546 * Listbox control notification codes 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 * If the selchange is caused by the user keyboarding through, 01563 * we don't want to hide the listbox. 01564 */ 01565 if (!xxxCBHideListBoxWindow(pcbox, TRUE, TRUE)) 01566 return(0L); 01567 } else { 01568 pcbox->fKeyboardSelInListBox = FALSE; 01569 } 01570 01571 xxxCBNotifyParent(pcbox, CBN_SELCHANGE); 01572 xxxCBInternalUpdateEditWindow(pcbox, NULL); 01573 break; 01574 } 01575 } 01576 01577 return 0L; 01578 }

void xxxCBCompleteEditWindow PCBOX  pcbox  ) 
 

Definition at line 1624 of file combo.c.

References CheckLock, FALSE, NULL, SendMessageWorker(), tagCBox::spwnd, tagCBox::spwndEdit, tagCBox::spwndList, TestWF, ThreadLock, ThreadUnlock, Unlock, UserLocalAlloc, UserLocalFree, and WFANSIPROC.

Referenced by ComboBoxWndProcWorker(), xxxCBHideListBoxWindow(), and xxxCBShowListBoxWindow().

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 * Firstly check the edit control. 01638 */ 01639 if (pcbox->spwndEdit == NULL) { 01640 return; 01641 } 01642 01643 ThreadLock(pcbox->spwndEdit, &tlpwndEdit); 01644 ThreadLock(pcbox->spwndList, &tlpwndList); 01645 01646 /* 01647 * +1 for null terminator 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 * We want to be sure to free the above allocated memory even if 01658 * the client dies during callback (xxx) or some of the following 01659 * window revalidation fails. 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 * No close match. Blow off. 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 * We want to be sure to free the above allocated memory even if 01689 * the client dies during callback (xxx) or some of the following 01690 * window revalidation fails. 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 }

void xxxCBGetFocusHelper PCBOX  pcbox  ) 
 

Definition at line 2343 of file combo.c.

References tagCBox::CBoxStyle, CheckLock, FALSE, tagCBox::fFocus, tagCBox::fNoEdit, NULL, SDROPDOWNLIST, SendMessageWorker(), tagCBox::spwnd, tagCBox::spwndEdit, tagCBox::spwndList, TestWF, ThreadLock, ThreadUnlock, TRUE, WFANSIPROC, xxxCBInvertStaticWindow(), and xxxCBNotifyParent().

Referenced by ComboBoxWndProcWorker(), and xxxCBCommandHandler().

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 * The combo box has gotten the focus for the first time. 02359 */ 02360 02361 /* 02362 * First turn on the listbox caret 02363 */ 02364 02365 if (pcbox->CBoxStyle == SDROPDOWNLIST) 02366 SendMessageWorker(pcbox->spwndList, LBCB_CARETON, 0, 0, FALSE); 02367 02368 /* 02369 * and select all the text in the editcontrol or static text rectangle. 02370 */ 02371 02372 if (pcbox->fNoEdit) { 02373 02374 /* 02375 * Invert the static text rectangle 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 * Notify the parent we have the focus 02387 */ 02388 xxxCBNotifyParent(pcbox, CBN_SETFOCUS); 02389 02390 ThreadUnlock(&tlpwndEdit); 02391 ThreadUnlock(&tlpwndList); 02392 }

LONG xxxCBGetTextHelper PCBOX  pcbox,
int  len,
LPWSTR  lpstr,
BOOL  fAnsi
 

Definition at line 2496 of file combo.c.

References CheckLock, DWORD, PBYTE, SendMessageWorker(), tagCBox::spwnd, tagCBox::spwndList, TestWF, ThreadLock, ThreadUnlock, UserLocalAlloc, UserLocalFree, and WFWIN31COMPAT.

Referenced by ComboBoxWndProcWorker().

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 * Null the buffer to be nice. 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 * No selection so no text. 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 * Just do the copy if the given buffer size is large enough to hold 02541 * everything. Or if old 3.0 app. (Norton used to pass 2 & expect 3 02542 * chars including the \0 in 3.0; Bug #7018 win31: vatsanp) 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 * Bail. Not enough memory to chop up the text. 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 }

LONG xxxCBGetTextLengthHelper PCBOX  pcbox,
BOOL  fAnsi
 

Definition at line 2460 of file combo.c.

References SendMessageWorker(), tagCBox::spwndList, ThreadLock, and ThreadUnlock.

Referenced by ComboBoxWndProcWorker().

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 * No selection so no text. 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 }

BOOL xxxCBHideListBoxWindow PCBOX  pcbox,
BOOL  fNotifyParent,
BOOL  fSelEndOK
 

Definition at line 1719 of file combo.c.

References BOOL, tagCBox::CBoxStyle, CheckLock, tagCBox::cxCombo, tagCBox::cyCombo, tagCBox::editrc, FALSE, tagCBox::fLBoxVisible, HWq, IsWindow(), NtUserInvalidateRect(), NtUserSetWindowPos(), NtUserShowWindow(), SDROPPABLE, SEDITABLE, SendMessageWorker(), tagCBox::spwnd, tagCBox::spwndList, TestWF, ThreadLock, ThreadUnlock, TRUE, UpdateWindow(), WFWIN31COMPAT, xxxCBCompleteEditWindow(), and xxxCBNotifyParent().

Referenced by ComboBoxWndProcWorker(), xxxCBCommandHandler(), xxxCBKillFocusHelper(), xxxCBSetDroppedSize(), xxxLBoxCtlKeyInput(), and xxxTrackMouse().

01723 { 01724 HWND hwnd = HWq(pcbox->spwnd); 01725 HWND hwndList = HWq(pcbox->spwndList); 01726 TL tlpwndList; 01727 01728 01729 CheckLock(pcbox->spwnd); 01730 01731 // For 3.1+ apps, send CBN_SELENDOK to all types of comboboxes but only 01732 // allow CBN_SELENDCANCEL to be sent for droppable comboboxes 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 * return, we don't hide simple combo boxes. 01749 */ 01750 if (!(pcbox->CBoxStyle & SDROPPABLE)) { 01751 return TRUE; 01752 } 01753 01754 /* 01755 * Send a faked buttonup message to the listbox so that it can release 01756 * the capture and all. 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 * Hide the listbox window 01772 */ 01773 NtUserShowWindow(hwndList, SW_HIDE); 01774 01775 // 01776 // Invalidate the item area now since SWP() might update stuff. 01777 // Since the combo is CS_VREDRAW/CS_HREDRAW, a size change will 01778 // redraw the whole thing, including the item rect. But if it 01779 // isn't changing size, we still want to redraw the item anyway 01780 // to show focus/selection. 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 // In case size didn't change 01789 UpdateWindow(hwnd); 01790 01791 if (pcbox->CBoxStyle & SEDITABLE) { 01792 xxxCBCompleteEditWindow(pcbox); 01793 } 01794 01795 if (fNotifyParent) { 01796 01797 /* 01798 * Notify parent we will be popping up the combo box. 01799 */ 01800 xxxCBNotifyParent(pcbox, CBN_CLOSEUP); 01801 if (!IsWindow(hwnd)) 01802 return(FALSE); 01803 } 01804 } 01805 01806 ThreadUnlock(&tlpwndList); 01807 01808 return(TRUE); 01809 }

void xxxCBInternalUpdateEditWindow PCBOX  pcbox,
HDC  hdcPaint
 

Definition at line 2028 of file combo.c.

References CBFHASSTRINGS, CheckLock, CopyInflateRect(), CopyRect, DrawFocusRect(), DWORD, tagCBox::editrc, FALSE, tagCBox::fFocus, FillRect(), tagCBox::fLBoxVisible, tagCBox::fNoEdit, tagCBox::fRightAlign, tagCBox::fRtoLReading, GetControlBrush, tagCBox::hFont, HW, HWq, InflateRect(), IsComboVisible, msg, NtUserGetDC(), NtUserReleaseDC, NULL, tagCBox::OwnerDraw, SendMessage(), SendMessageWorker(), SetWindowText(), tagWND::spmenu, tagCBox::spwnd, tagCBox::spwndEdit, tagCBox::spwndList, tagCBox::spwndParent, SYSHBR, SYSMET, SYSRGB, TestWF, ThreadLock, ThreadUnlock, UINT, UserLocalAlloc, UserLocalFree, WEFPUIACCELHIDDEN, WEFPUIFOCUSHIDDEN, WFANSIPROC, WFDISABLED, and WFWIN40COMPAT.

Referenced by ComboBoxWndProcWorker(), xxxCBCommandHandler(), xxxCBInvertStaticWindow(), xxxCBPaint(), and xxxLBoxCtlDelete().

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 /* This check is also commented out in Win3.1 and Win95 */ 02050 // if (!TestWF(pcbox->spwnd, WFVISIBLE)) { 02051 // return; 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 * This 'try-finally' block ensures that the allocated 'pText' will 02062 * be freed no matter how this routine is exited. 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 * Only hilite the text if we have the focus. 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 // Fill in the selected area 02114 // 02115 02116 02117 // only do the FillRect if we know its not 02118 // ownerdraw item, otherwise we mess up people up 02119 // BUT: for Compat's sake we still do this for Win 3.1 guys 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 * Let the app draw the stuff in the static text box. 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 // Don't let ownerdraw dudes draw outside of the combo client 02156 // bounds. 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 * Start the text one pixel within the rect so that we leave a 02168 * nice hilite border around the text. 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 // Draw the text, leaving a gap on the left & top for selection. 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 }

void xxxCBInvertStaticWindow PCBOX  pcbox,
BOOL  fNewSelectionState,
HDC  hdc
 

Definition at line 2230 of file combo.c.

References BOOL, CheckLock, tagCBox::fFocus, tagCBox::spwnd, UINT, and xxxCBInternalUpdateEditWindow().

Referenced by xxxCBGetFocusHelper(), and xxxCBKillFocusHelper().

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 }

void xxxCBKillFocusHelper PCBOX  pcbox  ) 
 

Definition at line 2402 of file combo.c.

References tagCBox::CBoxStyle, CheckLock, FALSE, tagCBox::fFocus, tagCBox::fNoEdit, L, NULL, SDROPDOWNLIST, SendMessageWorker(), tagCBox::spwnd, tagCBox::spwndEdit, tagCBox::spwndList, TestWF, ThreadLock, ThreadUnlock, TRUE, WFANSIPROC, xxxCBHideListBoxWindow(), xxxCBInvertStaticWindow(), and xxxCBNotifyParent().

Referenced by ComboBoxWndProcWorker().

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 * The combo box is losing the focus. Send buttonup clicks so that 02418 * things release the mouse capture if they have it... If the 02419 * pwndListBox is null, don't do anything. This occurs if the combo box 02420 * is destroyed while it has the focus. 02421 */ 02422 SendMessageWorker(pcbox->spwnd, WM_LBUTTONUP, 0L, 0xFFFFFFFFL, FALSE); 02423 if (!xxxCBHideListBoxWindow(pcbox, TRUE, FALSE)) 02424 return; 02425 02426 /* 02427 * Turn off the listbox caret 02428 */ 02429 02430 if (pcbox->CBoxStyle == SDROPDOWNLIST) 02431 SendMessageWorker(pcbox->spwndList, LBCB_CARETOFF, 0, 0, FALSE); 02432 02433 if (pcbox->fNoEdit) { 02434 02435 /* 02436 * Invert the static text rectangle 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 }

LRESULT xxxCBMessageItemHandler PCBOX  pcbox,
UINT  message,
LPVOID  lpfoo
 

Definition at line 1393 of file combo.c.

References CheckLock, HW, HWq, SendMessage(), tagWND::spmenu, tagCBox::spwnd, tagCBox::spwndParent, ThreadLock, and ThreadUnlock.

Referenced by ComboBoxWndProcWorker().

01397 { 01398 LRESULT lRet; 01399 TL tlpwndParent; 01400 01401 CheckLock(pcbox->spwnd); 01402 01403 /* 01404 * Send the <foo>item message back to the application after changing some 01405 * parameters to their combo box specific versions. 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 }

void xxxCBNotifyParent PCBOX  pcbox,
short  notificationCode
 

Definition at line 1589 of file combo.c.

References CheckLock, FALSE, HWq, PTR_TO_ID, SendMessageWorker(), tagWND::spmenu, tagCBox::spwnd, tagCBox::spwndParent, ThreadLock, and ThreadUnlock.

01592 { 01593 PWND pwndParent; // Parent if it exists 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 * wParam contains Control ID and notification code. 01605 * lParam contains Handle to window 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 }

void xxxCBPaint PCBOX  pcbox,
HDC  hdc
 

Definition at line 1431 of file combo.c.

References tagCBox::buttonrc, CheckLock, tagCBox::cxCombo, tagCBox::cyCombo, DrawEdge(), DrawFrameControl(), EFREADONLY, tagCBox::f3DCombo, tagCBox::fButtonPressed, FillRect(), tagCBox::fNoEdit, tagCBox::fRightAlign, GetControlBrush, HWq, msg, tagCBox::spwnd, tagCBox::spwndEdit, TestWF, UINT, WFDISABLED, WFWIN40COMPAT, and xxxCBInternalUpdateEditWindow().

Referenced by ComboBoxWndProcWorker().

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 // Draw in the dropdown arrow button 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 // Erase the background behind the edit/static item. Since a combo 01465 // is an edit field/list box hybrid, we use the same coloring 01466 // conventions. 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 }

void xxxCBShowListBoxWindow PCBOX  pcbox,
BOOL  fTrack
 

Definition at line 1819 of file combo.c.

References _MonitorFromWindow(), AnimateWindow(), BOOL, tagCBox::buttonrc, CBFNOINTEGRALHEIGHT, tagCBox::CBoxStyle, CheckLock, CMS_QANIMATION, tagCBox::cxCombo, tagCBox::cxDrop, tagCBox::cyCombo, tagCBox::cyDrop, DWORD, tagCBox::editrc, tagCBox::f3DCombo, FALSE, tagCBox::fLBoxVisible, tagCBox::fMouseDown, GetAppCompatFlags2(), gpsi, HWq, tagLBIV::iTypeSearch, max, min, NtUserInvalidateRect(), NtUserSetWindowPos(), NtUserShowWindow(), NULL, PUSIF_COMBOBOXANIMATION, tagMONITOR::rcMonitor, tagWND::rcWindow, SDROPDOWN, SDROPPABLE, SendMessageWorker(), tagCBox::spwnd, tagCBox::spwndList, SYSMET, TEST_EffectPUSIF, TestWF, ThreadLock, ThreadUnlock, TRUE, UpdateWindow(), VER40, WFWIN40COMPAT, xxxCBCompleteEditWindow(), xxxCBNotifyParent(), and xxxCBUpdateListBoxWindow().

Referenced by ComboBoxWndProcWorker(), and xxxLBoxCtlKeyInput().

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 // THIS FUNCTION IS ONLY CALLED FOR DROPPABLE LIST COMBOBOXES 01836 // 01837 UserAssert(pcbox->CBoxStyle & SDROPPABLE); 01838 01839 CheckLock(pcbox->spwnd); 01840 01841 ThreadLock(pcbox->spwndList, &tlpwndList); 01842 01843 /* 01844 * Notify parent we will be dropping down the combo box. 01845 */ 01846 01847 xxxCBNotifyParent(pcbox, CBN_DROPDOWN); 01848 /* 01849 * Invalidate the button rect so that the depressed arrow is drawn. 01850 */ 01851 NtUserInvalidateRect(hwnd, &pcbox->buttonrc, TRUE); 01852 01853 pcbox->fLBoxVisible = TRUE; 01854 01855 if (pcbox->CBoxStyle == SDROPDOWN) { 01856 01857 /* 01858 * If an item in the listbox matches the text in the edit control, 01859 * scroll it to the top of the listbox. Select the item only if the 01860 * mouse button isn't down otherwise we will select the item when the 01861 * mouse button goes up. 01862 */ 01863 xxxCBUpdateListBoxWindow(pcbox, !pcbox->fMouseDown); 01864 if (!pcbox->fMouseDown) 01865 xxxCBCompleteEditWindow(pcbox); 01866 } else { 01867 01868 /* 01869 * Scroll the currently selected item to the top of the listbox. 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 * We need to invalidate the edit rect so that the focus frame/invert 01881 * will be turned off when the listbox is visible. Tandy wants this for 01882 * his typical reasons... 01883 */ 01884 NtUserInvalidateRect(hwnd, &pcbox->editrc, TRUE); 01885 } 01886 01887 // 01888 // Figure out where to position the dropdown listbox. We want it just 01889 // touching the edge around the edit rectangle. Note that since the 01890 // listbox is a popup, we need the position in screen coordinates. 01891 // 01892 01893 // We want the dropdown to pop below or above the combo 01894 01895 // Get screen coords 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 // List area 01902 cyItem = (int)SendMessageWorker(pcbox->spwndList, LB_GETITEMHEIGHT, 0, 0, FALSE); 01903 01904 if (cyItem == 0) { 01905 // Make sure that it's not 0 01906 RIPMSG0( RIP_WARNING, "LB_GETITEMHEIGHT is returning 0\n" ); 01907 01908 cyItem = gpsi->cySysFontChar; 01909 } 01910 01911 // we shoulda' just been able to use cyDrop here, but thanks to VB's need 01912 // to do things their OWN SPECIAL WAY, we have to keep monitoring the size 01913 // of the listbox 'cause VB changes it directly (jeffbog 03/21/94) 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 // Other 1/2 of old app combo fix. Make dropdown overlap combo window 01932 // a little. That way we can have a chance of invalidating the overlap 01933 // and causing a repaint to help out Publisher 2.0's toolbar combos. 01934 // See comments for PressButton() above. 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 // fix for Winword B#7504, Combo-ListBox text gets 01954 // truncated by a small width, this is do to us 01955 // now setting size here in SetWindowPos, rather than 01956 // earlier where we did this in Win3.1 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 * Get any drawing in the combo box window out of the way so it doesn't 01969 * invalidate any of the SPB underneath the list window. 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 // we don't have sys modal windows. 01984 // 01985 if (pwndSysModal) { 01986 01987 /* 01988 * If this combo is in a system modal dialog box, we need to explicitly 01989 * call update window otherwise we won't automatically send paint 01990 * messages to the toplevel listbox window. This is especially 01991 * noticeable in the File Open/Save sys modal dlgs which are put up at 01992 * ExitWindows time. 01993 */ 01994 UpdateWindow(hwndList); 01995 } 01996 #endif 01997 01998 /* 01999 * Restart search buffer from first char 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 }

void xxxCBUpdateListBoxWindow PCBOX  pcbox,
BOOL  fSelectionAlso
 

Definition at line 2255 of file combo.c.

References CheckLock, DWORD, FALSE, L, NULL, SendMessageWorker(), tagCBox::spwnd, tagCBox::spwndEdit, tagCBox::spwndList, TestWF, ThreadLock, ThreadUnlock, UserLocalAlloc, UserLocalFree, and WFWIN40COMPAT.

Referenced by ComboBoxWndProcWorker(), xxxCBCommandHandler(), and xxxCBShowListBoxWindow().

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 * +1 for null terminator 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)-1L, (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 // Old apps: w/ editable combos, selected 1st item in list even if 02308 // it didn't match text in edit field. This is not desirable 02309 // behavior for 4.0 dudes esp. with cancel allowed. Reason: 02310 // (1) User types in text that doesn't match list choices 02311 // (2) User drops combo 02312 // (3) User pops combo back up 02313 // (4) User presses OK in dialog that does stuff w/ combo 02314 // contents. 02315 // In 3.1, when the combo dropped, we'd select the 1st item anyway. 02316 // So the last CBN_SELCHANGE the owner got would be 0--which is 02317 // bogus because it really should be -1. In fact if you type anything 02318 // into the combo afterwards it will reset itself to -1. 02319 // 02320 // 4.0 dudes won't get this bogus 0 selection. 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 }

void xxxPressButton PCBOX  pcbox,
BOOL  fPress
 

Definition at line 29 of file combo.c.

References tagCBox::buttonrc, CopyRect, tagCBox::f3DCombo, tagCBox::fButtonPressed, FWINABLE, HWq, InflateRect(), NotifyWinEvent(), NtUserInvalidateRect(), tagCBox::spwnd, SYSMET, TRUE, and UpdateWindow().

Referenced by ComboBoxWndProcWorker().

00030 { 00031 // 00032 // Publisher relies on getting a WM_PAINT message after the combo list 00033 // pops back up. On a WM_PAINT they change the focus, which causes 00034 // toolbar combos to send CBN_SELENDCANCEL notifications. On this 00035 // notification they apply the font/pt size change you made to the 00036 // selection. 00037 // 00038 // This happened in 3.1 because the dropdown list overlapped the button 00039 // on the bottom or top by a pixel. Since we'd end up painting under 00040 // the list SPB, when it went away USER would reinvalidate the dirty 00041 // area. This would cause a paint message. 00042 // 00043 // In 4.0, this doesn't happen because the dropdown doesn't overlap. So 00044 // we need to make sure Publisher gets a WM_PAINT anyway. We do this 00045 // by changing where the dropdown shows up for 3.x apps 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 }


Variable Documentation

LOOKASIDE ComboboxLookaside
 

Definition at line 16 of file combo.c.

Referenced by ComboBoxWndProcWorker(), and xxxCBNcDestroyHandler().


Generated on Sat May 15 19:43:12 2004 for test by doxygen 1.3.7