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

lboxctl2.c File Reference

#include "precomp.h"

Go to the source code of this file.

Defines

#define LB_KEYDOWN   WM_USER+1
#define NOMODIFIER   0 /* No modifier is down */
#define SHIFTDOWN   1 /* Shift alone */
#define CTLDOWN   2 /* Ctl alone */
#define SHCTLDOWN   (SHIFTDOWN + CTLDOWN) /* Ctrl + Shift */
#define MAX_TYPESEARCH   256
#define pODRg   ((lpLBODItem)pRg)

Functions

BOOL LBGetDC (PLBIV plb)
void LBReleaseDC (PLBIV plb)
BOOL xxxLBInvalidateRect (PLBIV plb, LPRECT lprc, BOOL fErase)
HBRUSH xxxLBGetBrush (PLBIV plb, HBRUSH *phbrOld)
void LBInitDC (PLBIV plb)
void LBTermDC (PLBIV plb)
BOOL LBGetItemRect (PLBIV plb, INT sItem, LPRECT lprc)
BOOL CALLBACK LBPrintCallback (HDC hdc, LPWSTR lpstr, PLBIV plb, int cx, int cy)
void xxxLBDrawLBItem (PLBIV plb, INT sItem, LPRECT lprect, BOOL fHilite, HBRUSH hbr)
void xxxLBSetCaret (PLBIV plb, BOOL fSetCaret)
BOOL IsSelected (PLBIV plb, INT sItem, UINT wOpFlags)
INT CItemInWindow (PLBIV plb, BOOL fPartial)
void xxxLBoxCtlScroll (PLBIV plb, INT cmd, int yAmt)
DWORD LBGetScrollFlags (PLBIV plb, DWORD dwTime)
void xxxLBoxCtlHScroll (PLBIV plb, INT cmd, int xAmt)
void xxxLBPaint (PLBIV plb, HDC hdc, LPRECT lprcBounds)
BOOL ISelFromPt (PLBIV plb, POINT pt, LPDWORD piItem)
void SetSelected (PLBIV plb, INT iSel, BOOL fSelected, UINT wOpFlags)
INT LastFullVisible (PLBIV plb)
void xxxInvertLBItem (PLBIV plb, INT i, BOOL fHilite)
void xxxResetWorld (PLBIV plb, INT iStart, INT iEnd, BOOL fSelect)
void xxxNotifyOwner (PLBIV plb, INT sEvt)
void xxxSetISelBase (PLBIV plb, INT sItem)
void xxxTrackMouse (PLBIV plb, UINT wMsg, POINT pt)
void xxxLBButtonUp (PLBIV plb, UINT uFlags)
INT IncrementISel (PLBIV plb, INT iSel, INT sInc)
void xxxNewITop (PLBIV plb, INT iTopNew)
void xxxNewITopEx (PLBIV plb, INT iTopNew, DWORD dwTime)
void xxxInsureVisible (PLBIV plb, INT iSel, BOOL fPartial)
VOID xxxLBoxCaretBlinker (HWND hwnd, UINT wMsg, UINT_PTR nIDEvent, DWORD dwTime)
void xxxLBoxCtlKeyInput (PLBIV plb, UINT msg, UINT vKey)
INT Compare (LPCWSTR pwsz1, LPCWSTR pwsz2, DWORD dwLocaleId)
INT xxxFindString (PLBIV plb, LPWSTR lpstr, INT sStart, INT code, BOOL fWrap)
void xxxLBoxCtlCharInput (PLBIV plb, UINT inputChar, BOOL fAnsi)
int LBoxGetSelItems (PLBIV plb, BOOL fCountOnly, int wParam, LPINT lParam)
void xxxLBSetRedraw (PLBIV plb, BOOL fRedraw)
void xxxLBSelRange (PLBIV plb, int iStart, int iEnd, BOOL fnewstate)
int xxxLBSetCurSel (PLBIV plb, int iSel)
int LBSetItemData (PLBIV plb, int index, LONG_PTR data)
void xxxCheckRedraw (PLBIV plb, BOOL fConditional, INT sItem)
void xxxCaretDestroy (PLBIV plb)
LONG xxxLBSetSel (PLBIV plb, BOOL fSelect, INT iSel)
void xxxLBoxDrawItem (PLBIV plb, INT item, UINT itemAction, UINT itemState, LPRECT lprect)
void xxxLBBlockHilite (PLBIV plb, INT iSelFromPt, BOOL fKeyBoard)
void xxxAlterHilite (PLBIV plb, INT i, INT j, BOOL fHilite, INT OpFlags, BOOL fSelStatus)


Define Documentation

#define CTLDOWN   2 /* Ctl alone */
 

Definition at line 19 of file lboxctl2.c.

Referenced by xxxLBoxCtlKeyInput(), and xxxTrackMouse().

#define LB_KEYDOWN   WM_USER+1
 

Definition at line 16 of file lboxctl2.c.

Referenced by xxxLBoxCtlCharInput(), and xxxLBoxCtlKeyInput().

#define MAX_TYPESEARCH   256
 

Definition at line 25 of file lboxctl2.c.

Referenced by xxxLBoxCtlCharInput().

#define NOMODIFIER   0 /* No modifier is down */
 

Definition at line 17 of file lboxctl2.c.

Referenced by xxxTrackMouse().

#define pODRg   ((lpLBODItem)pRg)
 

Referenced by xxxFindString().

#define SHCTLDOWN   (SHIFTDOWN + CTLDOWN) /* Ctrl + Shift */
 

Definition at line 20 of file lboxctl2.c.

Referenced by xxxTrackMouse().

#define SHIFTDOWN   1 /* Shift alone */
 

Definition at line 18 of file lboxctl2.c.

Referenced by xxxLBoxCtlKeyInput(), and xxxTrackMouse().


Function Documentation

INT CItemInWindow PLBIV  plb,
BOOL  fPartial
 

Definition at line 526 of file lboxctl2.c.

References _GetClientRect(), CItemInWindowVarOwnerDraw(), tagLBIV::cyChar, tagLBIV::fMultiColumn, INT, tagLBIV::itemsPerColumn, tagLBIV::numberOfColumns, tagLBIV::OwnerDraw, OWNERDRAWVAR, and tagLBIV::spwnd.

Referenced by LastFullVisible(), LBGetItemRect(), LBSetCItemFullMax(), xxxAlterHilite(), xxxCheckRedraw(), xxxInsureVisible(), xxxInvertLBItem(), xxxLBButtonUp(), xxxLBPaint(), and xxxResetWorld().

00529 { 00530 RECT rect; 00531 00532 if (plb->OwnerDraw == OWNERDRAWVAR) { 00533 return CItemInWindowVarOwnerDraw(plb, fPartial); 00534 } 00535 00536 if (plb->fMultiColumn) { 00537 return plb->itemsPerColumn * (plb->numberOfColumns + (fPartial ? 1 : 0)); 00538 } 00539 00540 _GetClientRect(plb->spwnd, &rect); 00541 00542 /* 00543 * fPartial must be considered only if the listbox height is not an 00544 * integral multiple of character height. 00545 * A part of the fix for Bug #3727 -- 01/14/91 -- SANKAR -- 00546 */ 00547 UserAssert(plb->cyChar); 00548 return (INT)((rect.bottom / plb->cyChar) + 00549 ((rect.bottom % plb->cyChar)? (fPartial ? 1 : 0) : 0)); 00550 }

INT Compare LPCWSTR  pwsz1,
LPCWSTR  pwsz2,
DWORD  dwLocaleId
 

Definition at line 2757 of file lboxctl2.c.

References EQ, GT, INT, LT, min, PREFIX, and UINT.

Referenced by FsRtlAddToTunnelCache(), FsRtlFindInTunnelCache(), KeSetup80387OrEmulate(), ObpCompareSecurityDescriptors(), and xxxFindString().

02761 { 02762 UINT len1 = wcslen(pwsz1); 02763 UINT len2 = wcslen(pwsz2); 02764 INT result; 02765 02766 /* 02767 * CompareStringW returns: 02768 * 1 = pwsz1 < pwsz2 02769 * 2 = pwsz1 == pwsz2 02770 * 3 = pwsz1 > pwsz2 02771 */ 02772 result = CompareStringW((LCID)dwLocaleId, NORM_IGNORECASE, 02773 pwsz1, min(len1,len2), pwsz2, min(len1, len2)); 02774 02775 if (result == CSTR_LESS_THAN) { 02776 return LT; 02777 } else if (result == CSTR_EQUAL) { 02778 if (len1 == len2) { 02779 return EQ; 02780 } else if (len1 < len2) { 02781 /* 02782 * LATER IanJa: should not assume shorter string is a prefix 02783 * Spanish "c" and "ch", ligatures, German sharp-s/SS etc. 02784 */ 02785 return PREFIX; 02786 } 02787 } 02788 return GT; 02789 }

INT IncrementISel PLBIV  plb,
INT  iSel,
INT  sInc
 

Definition at line 1976 of file lboxctl2.c.

References tagLBIV::cMac, and INT.

Referenced by xxxLBoxCtlKeyInput().

01980 { 01981 01982 /* 01983 * Assumes cMac > 0, return iSel+sInc in range [0..cmac). 01984 */ 01985 iSel += sInc; 01986 if (iSel < 0) { 01987 return 0; 01988 } else if (iSel >= plb->cMac) { 01989 return plb->cMac - 1; 01990 } 01991 return iSel; 01992 }

BOOL ISelFromPt PLBIV  plb,
POINT  pt,
LPDWORD  piItem
 

Definition at line 920 of file lboxctl2.c.

References _GetClientRect(), BOOL, tagLBIV::cMac, tagLBIV::cxColumn, tagLBIV::cyChar, tagLBIV::fMultiColumn, tagLBIV::fRightAlign, INT, tagLBIV::itemsPerColumn, tagLBIV::iTop, LBGetItemRect(), tagLBIV::OwnerDraw, OWNERDRAWVAR, PtInRect(), tagLBIV::spwnd, TRUE, and UINT.

Referenced by LBDropObjectHandler(), ListBoxWndProcWorker(), and xxxTrackMouse().

00924 { 00925 RECT rect; 00926 int y; 00927 UINT mouseHighWord = 0; 00928 INT sItem; 00929 INT sTmp; 00930 00931 _GetClientRect(plb->spwnd, &rect); 00932 00933 if (pt.y < 0) { 00934 00935 /* 00936 * Mouse is out of bounds above listbox 00937 */ 00938 *piItem = plb->iTop; 00939 return TRUE; 00940 } else if ((y = pt.y) > rect.bottom) { 00941 y = rect.bottom; 00942 mouseHighWord = 1; 00943 } 00944 00945 if (pt.x < 0 || pt.x > rect.right) 00946 mouseHighWord = 1; 00947 00948 /* 00949 * Now just need to check if y mouse coordinate intersects item's rectangle 00950 */ 00951 if (plb->OwnerDraw != OWNERDRAWVAR) { 00952 if (plb->fMultiColumn) { 00953 if (y < plb->itemsPerColumn * plb->cyChar) { 00954 if (plb->fRightAlign) 00955 sItem = plb->iTop + (INT)((y / plb->cyChar) + 00956 ((rect.right - pt.x) / plb->cxColumn) * plb->itemsPerColumn); 00957 else 00958 sItem = plb->iTop + (INT)((y / plb->cyChar) + 00959 (pt.x / plb->cxColumn) * plb->itemsPerColumn); 00960 00961 } else { 00962 00963 /* 00964 * User clicked in blank space at the bottom of a column. 00965 * Just select the last item in the column. 00966 */ 00967 mouseHighWord = 1; 00968 sItem = plb->iTop + (plb->itemsPerColumn - 1) + 00969 (INT)((pt.x / plb->cxColumn) * plb->itemsPerColumn); 00970 } 00971 } else { 00972 sItem = plb->iTop + (INT)(y / plb->cyChar); 00973 } 00974 } else { 00975 00976 /* 00977 * VarHeightOwnerdraw so we gotta do this the hardway... Set the x 00978 * coordinate of the mouse down point to be inside the listbox client 00979 * rectangle since we no longer care about it. This lets us use the 00980 * point in rect calls. 00981 */ 00982 pt.x = 8; 00983 pt.y = y; 00984 for (sTmp = plb->iTop; sTmp < plb->cMac; sTmp++) { 00985 (void)LBGetItemRect(plb, sTmp, &rect); 00986 if (PtInRect(&rect, pt)) { 00987 *piItem = sTmp; 00988 return mouseHighWord; 00989 } 00990 } 00991 00992 /* 00993 * Point was at the empty area at the bottom of a not full listbox 00994 */ 00995 *piItem = plb->cMac - 1; 00996 return mouseHighWord; 00997 } 00998 00999 /* 01000 * Check if user clicked on the blank area at the bottom of a not full list. 01001 * Assumes > 0 items in the listbox. 01002 */ 01003 if (sItem > plb->cMac - 1) { 01004 mouseHighWord = 1; 01005 sItem = plb->cMac - 1; 01006 } 01007 01008 *piItem = sItem; 01009 return mouseHighWord; 01010 }

BOOL IsSelected PLBIV  plb,
INT  sItem,
UINT  wOpFlags
 

Definition at line 480 of file lboxctl2.c.

References BOOL, tagLBIV::cMac, FALSE, tagLBIV::fHasData, tagLBIV::fHasStrings, HILITEONLY, tagLBIV::iSel, tagLBIV::rgpch, SINGLESEL, and tagLBIV::wMultiple.

Referenced by LBoxGetSelItems(), ListBoxWndProcWorker(), xxxAlterHilite(), xxxLBoxCtlKeyInput(), xxxLBPaint(), xxxLBSelRange(), xxxLBSetCaret(), xxxLBSetSel(), xxxResetWorld(), and xxxTrackMouse().

00484 { 00485 LPBYTE lp; 00486 00487 if ((sItem >= plb->cMac) || (sItem < 0)) { 00488 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00489 // return LB_ERR; 00490 return(FALSE); 00491 } 00492 00493 if (plb->wMultiple == SINGLESEL) { 00494 return (sItem == plb->iSel); 00495 } 00496 00497 lp = plb->rgpch + sItem + 00498 (plb->cMac * (plb->fHasStrings 00499 ? sizeof(LBItem) 00500 : (plb->fHasData 00501 ? sizeof(LBODItem) 00502 : 0))); 00503 sItem = *lp; 00504 00505 if (wOpFlags == HILITEONLY) { 00506 sItem >>= 4; 00507 } else { 00508 sItem &= 0x0F; /* SELONLY */ 00509 } 00510 00511 return sItem; 00512 }

INT LastFullVisible PLBIV  plb  ) 
 

Definition at line 1090 of file lboxctl2.c.

References tagLBIV::cItemFullMax, CItemInWindow(), tagLBIV::cMac, FALSE, tagLBIV::fMultiColumn, INT, tagLBIV::iTop, max, min, tagLBIV::OwnerDraw, and OWNERDRAWVAR.

Referenced by xxxInsureVisible().

01092 { 01093 INT iLastItem; 01094 01095 if (plb->OwnerDraw == OWNERDRAWVAR || plb->fMultiColumn) { 01096 iLastItem = plb->iTop + CItemInWindow(plb, FALSE) - 1; 01097 iLastItem = max(iLastItem, plb->iTop); 01098 } else { 01099 iLastItem = min(plb->iTop + plb->cItemFullMax - 1, plb->cMac - 1); 01100 } 01101 return iLastItem; 01102 }

BOOL LBGetDC PLBIV  plb  ) 
 

Definition at line 126 of file lboxctl2.c.

References BOOL, FALSE, tagLBIV::hdc, HWq, LBInitDC(), NtUserGetDC(), tagLBIV::spwnd, and TRUE.

Referenced by xxxInvertLBItem(), and xxxLBSetCaret().

00128 { 00129 if (plb->hdc) 00130 return(FALSE); 00131 00132 plb->hdc = NtUserGetDC(HWq(plb->spwnd)); 00133 00134 LBInitDC(plb); 00135 00136 return TRUE; 00137 }

BOOL LBGetItemRect PLBIV  plb,
INT  sItem,
LPRECT  lprc
 

Definition at line 179 of file lboxctl2.c.

References _GetClientRect(), BOOL, CItemInWindow(), tagLBIV::cMac, tagLBIV::cxColumn, tagLBIV::cyChar, FALSE, tagLBIV::fHorzBar, tagLBIV::fMultiColumn, tagLBIV::fRightAlign, INT, tagLBIV::itemsPerColumn, tagLBIV::iTop, LBGetVariableHeightItemHeight(), tagLBIV::OwnerDraw, OWNERDRAWVAR, SetRectEmpty, tagLBIV::spwnd, TRUE, UINT, tagLBIV::xOrigin, and tagLBIV::xRightOrigin.

Referenced by CItemInWindowVarOwnerDraw(), ISelFromPt(), LBCalcVarITopScrollAmt(), ListBoxWndProcWorker(), xxxInvertLBItem(), xxxLBoxCtlDelete(), xxxLBPaint(), xxxLBSelRange(), xxxLBSetCaret(), xxxLBSetSel(), and xxxLBSize().

00183 { 00184 INT sTmp; 00185 int clientbottom; 00186 00187 /* 00188 * Always allow an item number of 0 so that we can draw the caret which 00189 * indicates the listbox has the focus even though it is empty. 00190 00191 * FreeHand 3.1 passes in -1 as the itemNumber and expects 00192 * a non-null rectangle. So we check for -1 specifically. 00193 * BUGTAG: Fix for Bug #540 --Win95B-- SANKAR -- 2/20/95 -- 00194 */ 00195 00196 if (sItem && (sItem != -1) && ((UINT)sItem >= (UINT)plb->cMac)) 00197 { 00198 SetRectEmpty(lprc); 00199 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00200 return (LB_ERR); 00201 } 00202 00203 _GetClientRect(plb->spwnd, lprc); 00204 00205 if (plb->fMultiColumn) { 00206 00207 /* 00208 * itemHeight * sItem mod number ItemsPerColumn (itemsPerColumn) 00209 */ 00210 lprc->top = plb->cyChar * (sItem % plb->itemsPerColumn); 00211 lprc->bottom = lprc->top + plb->cyChar /*+(plb->OwnerDraw ? 0 : 1)*/; 00212 00213 UserAssert(plb->itemsPerColumn); 00214 00215 if (plb->fRightAlign) { 00216 lprc->right = lprc->right - plb->cxColumn * 00217 ((sItem / plb->itemsPerColumn) - (plb->iTop / plb->itemsPerColumn)); 00218 00219 lprc->left = lprc->right - plb->cxColumn; 00220 } else { 00221 /* 00222 * Remember, this is integer division here... 00223 */ 00224 lprc->left += plb->cxColumn * 00225 ((sItem / plb->itemsPerColumn) - (plb->iTop / plb->itemsPerColumn)); 00226 00227 lprc->right = lprc->left + plb->cxColumn; 00228 } 00229 } else if (plb->OwnerDraw == OWNERDRAWVAR) { 00230 00231 /* 00232 * Var height owner draw 00233 */ 00234 lprc->right += plb->xOrigin; 00235 clientbottom = lprc->bottom; 00236 00237 if (sItem >= plb->iTop) { 00238 for (sTmp = plb->iTop; sTmp < sItem; sTmp++) { 00239 lprc->top = lprc->top + LBGetVariableHeightItemHeight(plb, sTmp); 00240 } 00241 00242 /* 00243 * If item number is 0, it may be we are asking for the rect 00244 * associated with a nonexistant item so that we can draw a caret 00245 * indicating focus on an empty listbox. 00246 */ 00247 lprc->bottom = lprc->top + (sItem < plb->cMac ? LBGetVariableHeightItemHeight(plb, sItem) : plb->cyChar); 00248 return (lprc->top < clientbottom); 00249 } else { 00250 00251 /* 00252 * Item we want the rect of is before plb->iTop. Thus, negative 00253 * offsets for the rect and it is never visible. 00254 */ 00255 for (sTmp = sItem; sTmp < plb->iTop; sTmp++) { 00256 lprc->top = lprc->top - LBGetVariableHeightItemHeight(plb, sTmp); 00257 } 00258 lprc->bottom = lprc->top + LBGetVariableHeightItemHeight(plb, sItem); 00259 return FALSE; 00260 } 00261 } else { 00262 00263 /* 00264 * For fixed height listboxes 00265 */ 00266 if (plb->fRightAlign && !(plb->fMultiColumn || plb->OwnerDraw) && plb->fHorzBar) 00267 lprc->right += plb->xOrigin + (plb->xRightOrigin - plb->xOrigin); 00268 else 00269 lprc->right += plb->xOrigin; 00270 lprc->top = (sItem - plb->iTop) * plb->cyChar; 00271 lprc->bottom = lprc->top + plb->cyChar; 00272 } 00273 00274 return (sItem >= plb->iTop) && 00275 (sItem < (plb->iTop + CItemInWindow(plb, TRUE))); 00276 }

DWORD LBGetScrollFlags PLBIV  plb,
DWORD  dwTime
 

Definition at line 663 of file lboxctl2.c.

References dwFlags, DWORD, FALSE, tagLBIV::fSmoothScroll, GetAppCompatFlags(), NULL, PUSIF_LISTBOXSMOOTHSCROLLING, and TEST_EffectPUSIF.

Referenced by xxxLBoxCtlHScroll(), and xxxNewITopEx().

00664 { 00665 DWORD dwFlags; 00666 00667 if (GetAppCompatFlags(NULL) & GACF_NOSMOOTHSCROLLING) 00668 goto NoSmoothScrolling; 00669 00670 if (dwTime != 0) { 00671 dwFlags = MAKELONG(SW_SCROLLWINDOW | SW_SMOOTHSCROLL | SW_SCROLLCHILDREN, dwTime); 00672 } else if (TEST_EffectPUSIF(PUSIF_LISTBOXSMOOTHSCROLLING) && plb->fSmoothScroll) { 00673 dwFlags = SW_SCROLLWINDOW | SW_SMOOTHSCROLL | SW_SCROLLCHILDREN; 00674 plb->fSmoothScroll = FALSE; 00675 } else { 00676 NoSmoothScrolling: 00677 dwFlags = SW_SCROLLWINDOW | SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN; 00678 } 00679 00680 return dwFlags; 00681 }

void LBInitDC PLBIV  plb  ) 
 

Definition at line 102 of file lboxctl2.c.

References _GetClientRect(), tagLBIV::hdc, tagLBIV::hFont, NULL, tagLBIV::spwnd, and tagLBIV::xOrigin.

Referenced by LBGetDC(), and xxxLBPaint().

00103 { 00104 RECT rc; 00105 00106 // Set font 00107 if (plb->hFont) 00108 SelectObject(plb->hdc, plb->hFont); 00109 00110 // Set clipping area 00111 _GetClientRect(plb->spwnd, &rc); 00112 IntersectClipRect(plb->hdc, rc.left, rc.top, rc.right, rc.bottom); 00113 00114 OffsetWindowOrgEx(plb->hdc, plb->xOrigin, 0, NULL); 00115 }

int LBoxGetSelItems PLBIV  plb,
BOOL  fCountOnly,
int  wParam,
LPINT  lParam
 

Definition at line 3131 of file lboxctl2.c.

References tagLBIV::cMac, IsSelected(), SELONLY, SINGLESEL, and tagLBIV::wMultiple.

03136 { 03137 int i; 03138 int itemsselected = 0; 03139 03140 if (plb->wMultiple == SINGLESEL) 03141 return LB_ERR; 03142 03143 for (i = 0; i < plb->cMac; i++) { 03144 if (IsSelected(plb, i, SELONLY)) { 03145 if (!fCountOnly) { 03146 if (itemsselected < wParam) 03147 *lParam++ = i; 03148 else { 03149 03150 /* 03151 * That's all the items we can fit in the array. 03152 */ 03153 return itemsselected; 03154 } 03155 } 03156 itemsselected++; 03157 } 03158 } 03159 03160 return itemsselected; 03161 }

BOOL CALLBACK LBPrintCallback HDC  hdc,
LPWSTR  lpstr,
PLBIV  plb,
int  cx,
int  cy
 

Definition at line 286 of file lboxctl2.c.

References BOOL, cy, FALSE, tagLBIV::fMultiColumn, tagLBIV::fRightAlign, tagLBIV::fUseTabStops, tagLBIV::hdc, tagLBIV::iTabPixelPositions, tagLBIV::iTypeSearch, NULL, tagLBIV::OwnerDraw, SYSRGB, TabTextOut(), TRUE, UINT, and tagLBIV::wMultiple.

Referenced by xxxLBDrawLBItem().

00287 { 00288 int xStart; 00289 UINT cLen; 00290 RECT rc; 00291 UINT oldAlign; 00292 00293 if (!lpstr) { 00294 return FALSE; 00295 } 00296 00297 if (plb->fMultiColumn) 00298 xStart = 0; 00299 else 00300 xStart = 2; 00301 00302 if (plb->fRightAlign) { 00303 oldAlign = SetTextAlign(hdc, TA_RIGHT | GetTextAlign(hdc)); 00304 xStart = cx - xStart; 00305 } 00306 00307 cLen = wcslen(lpstr); 00308 00309 if (plb->fUseTabStops) { 00310 TabTextOut(hdc, xStart, 0, lpstr, cLen, 00311 (plb->iTabPixelPositions ? plb->iTabPixelPositions[0] : 0), 00312 (plb->iTabPixelPositions ? (LPINT)&plb->iTabPixelPositions[1] : NULL), 00313 plb->fRightAlign ? cx : 0, TRUE, GetTextCharset(plb->hdc)); 00314 } else { 00315 rc.left = 0; 00316 rc.top = 0; 00317 rc.right = cx; 00318 rc.bottom = cy; 00319 00320 if (plb->wMultiple) 00321 ExtTextOut(hdc, xStart, 0, ETO_OPAQUE, &rc, lpstr, cLen, NULL); 00322 else if (plb->fMultiColumn) 00323 ExtTextOut(hdc, xStart, 0, ETO_CLIPPED, &rc, lpstr, cLen, NULL); 00324 else { 00325 ExtTextOut(hdc, xStart, 0, 0, NULL, lpstr, cLen, NULL); 00326 00327 /* 00328 * When the listbox is in the incremental search mode and the item 00329 * is highlighted (so we only draw in the current item), draw the 00330 * caret for search indication. 00331 */ 00332 if ((plb->iTypeSearch != 0) && (plb->OwnerDraw == 0) && 00333 (GetBkColor(hdc) == SYSRGB(HIGHLIGHT))) { 00334 SIZE size; 00335 GetTextExtentPointW(hdc, lpstr, plb->iTypeSearch, &size); 00336 PatBlt(hdc, xStart + size.cx - 1, 1, 1, cy - 2, DSTINVERT); 00337 } 00338 } 00339 } 00340 00341 if (plb->fRightAlign) 00342 SetTextAlign(hdc, oldAlign); 00343 00344 return(TRUE); 00345 }

void LBReleaseDC PLBIV  plb  ) 
 

Definition at line 160 of file lboxctl2.c.

References tagLBIV::hdc, HWq, LBTermDC(), NtUserReleaseDC, NULL, and tagLBIV::spwnd.

Referenced by xxxInvertLBItem(), and xxxLBSetCaret().

00162 { 00163 LBTermDC(plb); 00164 NtUserReleaseDC(HWq(plb->spwnd), plb->hdc); 00165 plb->hdc = NULL; 00166 }

int LBSetItemData PLBIV  plb,
int  index,
LONG_PTR  data
 

Definition at line 3324 of file lboxctl2.c.

References tagLBIV::cMac, tagLBIV::fHasData, tagLBIV::fHasStrings, tagLBIV::rgpch, TRUE, and UINT.

03328 { 03329 LPSTR lpItemText; 03330 03331 /* 03332 * v-ronaar: fix bug #25865, don't allow negative indices! 03333 */ 03334 if ((index != -1) && ((UINT) index >= (UINT) plb->cMac)) { 03335 RIPERR1(ERROR_INVALID_INDEX, RIP_WARNING, "LBSetItemData with invalid index %x", index); 03336 return LB_ERR; 03337 } 03338 03339 /* 03340 * No-data listboxes just ignore all LB_SETITEMDATA calls 03341 */ 03342 if (!plb->fHasData) { 03343 return TRUE; 03344 } 03345 03346 lpItemText = (LPSTR)plb->rgpch; 03347 03348 if (index == -1) { 03349 03350 /* 03351 * index == -1 means set the data to all the items 03352 */ 03353 if (plb->fHasStrings) { 03354 for (index = 0; index < plb->cMac; index++) { 03355 03356 ((lpLBItem)lpItemText)->itemData = data; 03357 lpItemText += sizeof(LBItem); 03358 } 03359 } else { 03360 for (index = 0; index < plb->cMac; index++) { 03361 03362 ((lpLBODItem)lpItemText)->itemData = data; 03363 lpItemText += sizeof(LBODItem); 03364 } 03365 } 03366 return TRUE; 03367 } 03368 03369 if (plb->fHasStrings) { 03370 03371 lpItemText = (LPSTR)(lpItemText + (index * sizeof(LBItem))); 03372 ((lpLBItem)lpItemText)->itemData = data; 03373 } else { 03374 03375 lpItemText = (LPSTR)(lpItemText + (index * sizeof(LBODItem))); 03376 ((lpLBODItem)lpItemText)->itemData = data; 03377 } 03378 return TRUE; 03379 }

void LBTermDC PLBIV  plb  ) 
 

Definition at line 146 of file lboxctl2.c.

References ghFontSys, tagLBIV::hdc, and tagLBIV::hFont.

Referenced by LBReleaseDC(), and xxxLBPaint().

00147 { 00148 if (plb->hFont) 00149 SelectObject(plb->hdc, ghFontSys); 00150 }

void SetSelected PLBIV  plb,
INT  iSel,
BOOL  fSelected,
UINT  wOpFlags
 

Definition at line 1028 of file lboxctl2.c.

References BYTE, tagLBIV::cMac, tagLBIV::fHasData, tagLBIV::fHasStrings, HILITEANDSEL, HILITEONLY, tagLBIV::iSel, tagLBIV::rgpch, SELONLY, SINGLESEL, and tagLBIV::wMultiple.

Referenced by xxxAlterHilite(), xxxLBoxCtlKeyInput(), xxxLBSelRange(), xxxLBSetSel(), xxxResetWorld(), and xxxTrackMouse().

01033 { 01034 LPSTR lp; 01035 BYTE cMask; 01036 BYTE cSelStatus; 01037 01038 if (iSel < 0 || iSel >= plb->cMac) 01039 return; 01040 01041 if (plb->wMultiple == SINGLESEL) { 01042 if (fSelected) 01043 plb->iSel = iSel; 01044 } else { 01045 cSelStatus = (BYTE)fSelected; 01046 switch (wOpFlags) { 01047 case HILITEONLY: 01048 01049 /* 01050 * Mask out lo-nibble 01051 */ 01052 cSelStatus = (BYTE)(cSelStatus << 4); 01053 cMask = 0x0F; 01054 break; 01055 case SELONLY: 01056 01057 /* 01058 * Mask out hi-nibble 01059 */ 01060 cMask = 0xF0; 01061 break; 01062 case HILITEANDSEL: 01063 01064 /* 01065 * Mask the byte fully 01066 */ 01067 cSelStatus |= (cSelStatus << 4); 01068 cMask = 0; 01069 break; 01070 } 01071 lp = (LPSTR)(plb->rgpch) + iSel + 01072 (plb->cMac * (plb->fHasStrings 01073 ? sizeof(LBItem) 01074 : (plb->fHasData ? sizeof(LBODItem) : 0))); 01075 01076 *lp = (*lp & cMask) | cSelStatus; 01077 } 01078 }

void xxxAlterHilite PLBIV  plb,
INT  i,
INT  j,
BOOL  fHilite,
INT  OpFlags,
BOOL  fSelStatus
 

Definition at line 3754 of file lboxctl2.c.

References BOOL, CheckLock, CItemInWindow(), tagLBIV::cMac, FALSE, tagLBIV::fCaretOn, high, HILITEONLY, INT, IsSelected(), tagLBIV::iTop, low, max, min, SELONLY, SetSelected(), tagLBIV::spwnd, TRUE, xxxInvertLBItem(), and xxxLBSetCaret().

Referenced by xxxLBBlockHilite(), xxxLBButtonUp(), and xxxTrackMouse().

03761 { 03762 INT low; 03763 INT high; 03764 INT sLastInWindow; 03765 BOOL fCaretOn; 03766 BOOL fSelected; 03767 03768 CheckLock(plb->spwnd); 03769 03770 sLastInWindow = plb->iTop + CItemInWindow(plb, TRUE); 03771 sLastInWindow = min(sLastInWindow, plb->cMac - 1); 03772 high = max(i, j) + 1; 03773 03774 if (fCaretOn = plb->fCaretOn) { 03775 xxxLBSetCaret(plb, FALSE); 03776 } 03777 03778 for (low = min(i, j); low < high; low++) { 03779 if (low != i) { 03780 if (OpFlags & HILITEONLY) { 03781 if (fSelStatus) { 03782 fSelected = IsSelected(plb, low, SELONLY); 03783 } else { 03784 fSelected = fHilite; 03785 } 03786 if (IsSelected(plb, low, HILITEONLY) != fSelected) { 03787 if (plb->iTop <= low && low <= sLastInWindow) { 03788 03789 /* 03790 * Invert the item only if it is visible 03791 */ 03792 xxxInvertLBItem(plb, low, fSelected); 03793 } 03794 SetSelected(plb, low, fSelected, HILITEONLY); 03795 } 03796 } 03797 03798 if (OpFlags & SELONLY) { 03799 SetSelected(plb, low, fHilite, SELONLY); 03800 } 03801 } 03802 } 03803 03804 if (fCaretOn) { 03805 xxxLBSetCaret(plb, TRUE); 03806 } 03807 }

void xxxCaretDestroy PLBIV  plb  ) 
 

Definition at line 3411 of file lboxctl2.c.

References CheckLock, tagLBIV::fAddSelMode, FALSE, tagLBIV::fCaptured, tagLBIV::fCaret, tagLBIV::fMouseDown, HWq, IDSYS_CARET, LBUP_NOTIFY, LBUP_RELEASECAPTURE, LBUP_SUCCESS, NtUserKillTimer(), tagLBIV::spwnd, xxxLBButtonUp(), and xxxLBSetCaret().

Referenced by ListBoxWndProcWorker().

03413 { 03414 CheckLock(plb->spwnd); 03415 03416 /* 03417 * We're losing the focus. Act like up clicks are happening so we release 03418 * capture, set the current selection, notify the parent, etc. 03419 */ 03420 if (plb->fCaptured) 03421 03422 /* 03423 * If we have the capture and we lost the focus, that means we already 03424 * changed the selection and we have to notify also the parent about 03425 * this. So we need to add also the LBUP_SUCCESS flag in this case. 03426 */ 03427 03428 xxxLBButtonUp(plb, LBUP_RELEASECAPTURE | LBUP_NOTIFY | 03429 (plb->fMouseDown ? LBUP_SUCCESS : 0)); 03430 03431 if (plb->fAddSelMode) { 03432 03433 /* 03434 * Switch off the Caret blinking 03435 */ 03436 NtUserKillTimer(HWq(plb->spwnd), IDSYS_CARET); 03437 03438 /* 03439 * Make sure the caret goes away 03440 */ 03441 xxxLBSetCaret(plb, FALSE); 03442 plb->fAddSelMode = FALSE; 03443 } 03444 03445 plb->fCaret = FALSE; 03446 }

void xxxCheckRedraw PLBIV  plb,
BOOL  fConditional,
INT  sItem
 

Definition at line 3387 of file lboxctl2.c.

References CheckLock, CItemInWindow(), tagLBIV::cMac, tagLBIV::iTop, NULL, tagLBIV::spwnd, TRUE, and xxxLBInvalidateRect().

Referenced by ListBoxWndProcWorker(), xxxLbDir(), xxxLbInsertFile(), xxxLBInsertItem(), xxxLBoxCtlDelete(), xxxLBResetContent(), and xxxLBSetFont().

03391 { 03392 CheckLock(plb->spwnd); 03393 03394 if (fConditional && plb->cMac && 03395 (sItem > (plb->iTop + CItemInWindow(plb, TRUE)))) 03396 return; 03397 03398 /* 03399 * Don't do anything if the parent is not visible. 03400 */ 03401 xxxLBInvalidateRect(plb, (LPRECT)NULL, TRUE); 03402 }

INT xxxFindString PLBIV  plb,
LPWSTR  lpstr,
INT  sStart,
INT  code,
BOOL  fWrap
 

Definition at line 2802 of file lboxctl2.c.

References CheckLock, tagLBIV::cMac, Compare(), tagLBIV::dwLocaleId, EQ, tagLBIV::fHasData, tagLBIV::fHasStrings, tagLBIV::fSort, GT, tagLBIV::hStrings, HW, HWq, INT, LT, tagLBItem::offsz, pODRg, PREFIX, tagLBIV::rgpch, SendMessage(), tagWND::spmenu, tagLBIV::spwnd, tagLBIV::spwndParent, ThreadLock, ThreadUnlock, and UINT.

Referenced by ListBoxWndProcWorker(), and xxxLBoxCtlCharInput().

02808 { 02809 /* 02810 * Search for a prefix match (case-insensitive equal/prefix) 02811 * sStart == -1 means start from beginning, else start looking at sStart+1 02812 * assumes cMac > 0. 02813 */ 02814 INT sInd; /* index of string */ 02815 INT sStop; /* index to stop searching at */ 02816 lpLBItem pRg; 02817 TL tlpwndParent; 02818 INT sortResult; 02819 02820 /* 02821 * Owner-Draw version of pRg 02822 */ 02823 #define pODRg ((lpLBODItem)pRg) 02824 COMPAREITEMSTRUCT cis; 02825 LPWSTR listboxString; 02826 02827 CheckLock(plb->spwnd); 02828 02829 if (plb->fHasStrings && (!lpstr || !*lpstr)) 02830 return LB_ERR; 02831 02832 if (!plb->fHasData) { 02833 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "FindString called on NODATA lb"); 02834 return LB_ERR; 02835 } 02836 02837 if ((sInd = sStart + 1) >= plb->cMac) 02838 sInd = (fWrap ? 0 : plb->cMac - 1); 02839 02840 sStop = (fWrap ? sInd : 0); 02841 02842 /* 02843 * If at end and no wrap, stop right away 02844 */ 02845 if (((sStart >= plb->cMac - 1) && !fWrap) || (plb->cMac < 1)) { 02846 return LB_ERR; 02847 } 02848 02849 /* 02850 * Apps could pass in an invalid sStart like -2 and we would blow up. 02851 * Win 3.1 would not so we need to fixup sInd to be zero 02852 */ 02853 if (sInd < 0) 02854 sInd = 0; 02855 02856 pRg = (lpLBItem)(plb->rgpch); 02857 02858 do { 02859 if (plb->fHasStrings) { 02860 02861 /* 02862 * Searching for string matches. 02863 */ 02864 listboxString = (LPWSTR)((LPBYTE)plb->hStrings + pRg[sInd].offsz); 02865 02866 if (code == PREFIX && 02867 listboxString && 02868 *lpstr != TEXT('[') && 02869 *listboxString == TEXT('[')) { 02870 02871 /* 02872 * If we are looking for a prefix string and the first items 02873 * in this string are [- then we ignore them. This is so 02874 * that in a directory listbox, the user can goto drives 02875 * by selecting the drive letter. 02876 */ 02877 listboxString++; 02878 if (*listboxString == TEXT('-')) 02879 listboxString++; 02880 } 02881 02882 if (Compare(lpstr, listboxString, plb->dwLocaleId) <= code) { 02883 goto FoundIt; 02884 } 02885 02886 } else { 02887 if (plb->fSort) { 02888 02889 /* 02890 * Send compare item messages to the parent for sorting 02891 */ 02892 cis.CtlType = ODT_LISTBOX; 02893 cis.CtlID = PtrToUlong(plb->spwnd->spmenu); 02894 cis.hwndItem = HWq(plb->spwnd); 02895 cis.itemID1 = (UINT)-1; 02896 cis.itemData1 = (ULONG_PTR)lpstr; 02897 cis.itemID2 = (UINT)sInd; 02898 cis.itemData2 = pODRg[sInd].itemData; 02899 cis.dwLocaleId = plb->dwLocaleId; 02900 02901 ThreadLock(plb->spwndParent, &tlpwndParent); 02902 sortResult = (INT)SendMessage(HW(plb->spwndParent), WM_COMPAREITEM, 02903 cis.CtlID, (LPARAM)&cis); 02904 ThreadUnlock(&tlpwndParent); 02905 02906 02907 if (sortResult == -1) { 02908 sortResult = LT; 02909 } else if (sortResult == 1) { 02910 sortResult = GT; 02911 } else { 02912 sortResult = EQ; 02913 } 02914 02915 if (sortResult <= code) { 02916 goto FoundIt; 02917 } 02918 } else { 02919 02920 /* 02921 * Searching for app supplied long data matches. 02922 */ 02923 if ((ULONG_PTR)lpstr == pODRg[sInd].itemData) 02924 goto FoundIt; 02925 } 02926 } 02927 02928 /* 02929 * Wrap round to beginning of list 02930 */ 02931 if (++sInd == plb->cMac) 02932 sInd = 0; 02933 } while (sInd != sStop); 02934 02935 sInd = -1; 02936 02937 FoundIt: 02938 return sInd; 02939 }

void xxxInsureVisible PLBIV  plb,
INT  iSel,
BOOL  fPartial
 

Definition at line 2092 of file lboxctl2.c.

References CheckLock, CItemInWindow(), FALSE, tagLBIV::fMultiColumn, INT, tagLBIV::itemsPerColumn, tagLBIV::iTop, LastFullVisible(), LBPage(), max, tagLBIV::numberOfColumns, tagLBIV::OwnerDraw, OWNERDRAWVAR, tagLBIV::spwnd, TRUE, and xxxNewITop().

Referenced by ListBoxWndProcWorker(), xxxLBButtonUp(), xxxLBoxCtlDelete(), xxxLBoxCtlKeyInput(), xxxLBSetCurSel(), xxxLBSetSel(), and xxxSetISelBase().

02096 { 02097 INT sLastVisibleItem; 02098 02099 CheckLock(plb->spwnd); 02100 02101 if (iSel < plb->iTop) { 02102 xxxNewITop(plb, iSel); 02103 } else { 02104 if (fPartial) { 02105 02106 /* 02107 * 1 must be subtracted to get the last visible item 02108 * A part of the fix for Bug #3727 -- 01/14/91 -- SANKAR 02109 */ 02110 sLastVisibleItem = plb->iTop + CItemInWindow(plb, TRUE) - (INT)1; 02111 } else { 02112 sLastVisibleItem = LastFullVisible(plb); 02113 } 02114 02115 if (plb->OwnerDraw != OWNERDRAWVAR) { 02116 if (iSel > sLastVisibleItem) { 02117 if (plb->fMultiColumn) { 02118 xxxNewITop(plb, 02119 ((iSel / plb->itemsPerColumn) - 02120 max(plb->numberOfColumns-1,0)) * plb->itemsPerColumn); 02121 } else { 02122 xxxNewITop(plb, (INT)max(0, iSel - sLastVisibleItem + plb->iTop)); 02123 } 02124 } 02125 } else if (iSel > sLastVisibleItem) 02126 xxxNewITop(plb, LBPage(plb, iSel, FALSE)); 02127 } 02128 }

void xxxInvertLBItem PLBIV  plb,
INT  i,
BOOL  fHilite
 

Definition at line 1111 of file lboxctl2.c.

References BOOL, CheckLock, CItemInWindow(), FALSE, tagLBIV::fCaretOn, FillRect(), tagLBIV::fNoSel, tagLBIV::hdc, IsLBoxVisible, tagLBIV::iTop, LBGetDC(), LBGetItemRect(), LBReleaseDC(), NULL, tagLBIV::OwnerDraw, tagLBIV::spwnd, TRUE, UINT, xxxLBDrawLBItem(), xxxLBGetBrush(), xxxLBoxDrawItem(), and xxxLBSetCaret().

Referenced by ListBoxWndProcWorker(), xxxAlterHilite(), xxxLBButtonUp(), xxxLBoxCtlKeyInput(), xxxLBSetCurSel(), xxxResetWorld(), and xxxTrackMouse().

01115 { 01116 RECT rect; 01117 BOOL fCaretOn; 01118 HBRUSH hbrControl; 01119 BOOL fNewDC; 01120 01121 CheckLock(plb->spwnd); 01122 01123 // Skip if item isn't showing. 01124 if (plb->fNoSel || (i < plb->iTop) || (i >= (plb->iTop + CItemInWindow(plb, TRUE)))) 01125 return; 01126 01127 if (IsLBoxVisible(plb)) { 01128 LBGetItemRect(plb, i, &rect); 01129 01130 /* 01131 * Only turn off the caret if it is on. This avoids annoying caret 01132 * flicker when nesting xxxCaretOns and xxxCaretOffs. 01133 */ 01134 if (fCaretOn = plb->fCaretOn) { 01135 xxxLBSetCaret(plb, FALSE); 01136 } 01137 01138 fNewDC = LBGetDC(plb); 01139 01140 hbrControl = xxxLBGetBrush(plb, NULL); 01141 01142 if (!plb->OwnerDraw) { 01143 if (!fHilite) { 01144 FillRect(plb->hdc, &rect, hbrControl); 01145 hbrControl = NULL; 01146 } 01147 01148 xxxLBDrawLBItem(plb, i, &rect, fHilite, hbrControl); 01149 } else { 01150 01151 /* 01152 * We are ownerdraw so fill in the drawitem struct and send off 01153 * to the owner. 01154 */ 01155 xxxLBoxDrawItem(plb, i, ODA_SELECT, 01156 (UINT)(fHilite ? ODS_SELECTED : 0), &rect); 01157 } 01158 01159 if (fNewDC) 01160 LBReleaseDC(plb); 01161 01162 /* 01163 * Turn the caret back on only if it was originally on. 01164 */ 01165 if (fCaretOn) { 01166 xxxLBSetCaret(plb, TRUE); 01167 } 01168 } 01169 }

void xxxLBBlockHilite PLBIV  plb,
INT  iSelFromPt,
BOOL  fKeyBoard
 

Definition at line 3651 of file lboxctl2.c.

References abs, BOOL, CheckLock, FALSE, tagLBIV::fNewItemState, HILITEANDSEL, HILITEONLY, tagLBIV::iLastMouseMove, tagLBIV::iMouseDown, INT, tagLBIV::spwnd, TRUE, and xxxAlterHilite().

Referenced by xxxLBoxCtlKeyInput(), and xxxTrackMouse().

03655 { 03656 INT sCurPosOffset; 03657 INT sLastPosOffset; 03658 INT sHiliteOrSel; 03659 BOOL fUseSelStatus; 03660 BOOL DeHiliteStatus; 03661 03662 CheckLock(plb->spwnd); 03663 03664 if (fKeyBoard) { 03665 03666 /* 03667 * Set both Hilite and Selection states 03668 */ 03669 sHiliteOrSel = HILITEANDSEL; 03670 03671 /* 03672 * Do not use the Selection state while de-hiliting 03673 */ 03674 fUseSelStatus = FALSE; 03675 DeHiliteStatus = FALSE; 03676 } else { 03677 03678 /* 03679 * Set/Reset only the Hilite state 03680 */ 03681 sHiliteOrSel = HILITEONLY; 03682 03683 /* 03684 * Use the selection state for de-hilighting 03685 */ 03686 fUseSelStatus = TRUE; 03687 DeHiliteStatus = plb->fNewItemState; 03688 } 03689 03690 03691 03692 /* 03693 * The idea of the routine is to : 03694 * 1. De-hilite the old range (iMouseDown to iLastMouseDown) and 03695 * 2. Hilite the new range (iMouseDwon to iSelFromPt) 03696 */ 03697 03698 /* 03699 * Offset of current mouse position from the anchor point 03700 */ 03701 sCurPosOffset = plb->iMouseDown - iSelFromPt; 03702 03703 /* 03704 * Offset of last mouse position from the anchor point 03705 */ 03706 sLastPosOffset = plb->iMouseDown - plb->iLastMouseMove; 03707 03708 /* 03709 * Check if both current position and last position lie on the same 03710 * side of the anchor point. 03711 */ 03712 if ((sCurPosOffset * sLastPosOffset) >= 0) { 03713 03714 /* 03715 * Yes they are on the same side; So, highlight/dehighlight only 03716 * the difference. 03717 */ 03718 if (abs(sCurPosOffset) > abs(sLastPosOffset)) { 03719 xxxAlterHilite(plb, plb->iLastMouseMove, iSelFromPt, 03720 plb->fNewItemState, sHiliteOrSel, FALSE); 03721 } else { 03722 xxxAlterHilite(plb, iSelFromPt, plb->iLastMouseMove, DeHiliteStatus, 03723 sHiliteOrSel, fUseSelStatus); 03724 } 03725 } else { 03726 xxxAlterHilite(plb, plb->iMouseDown, plb->iLastMouseMove, 03727 DeHiliteStatus, sHiliteOrSel, fUseSelStatus); 03728 xxxAlterHilite(plb, plb->iMouseDown, iSelFromPt, 03729 plb->fNewItemState, sHiliteOrSel, FALSE); 03730 } 03731 }

void xxxLBButtonUp PLBIV  plb,
UINT  uFlags
 

Definition at line 1875 of file lboxctl2.c.

References CheckLock, CItemInWindow(), EXTENDEDSEL, FALSE, tagLBIV::fCaptured, tagLBIV::fDoubleClick, tagLBIV::fMouseDown, tagLBIV::fNewItemState, tagLBIV::fNotify, FWINABLE, HWq, IDSYS_SCROLL, tagLBIV::iLastMouseMove, tagLBIV::iLastSelection, tagLBIV::iMouseDown, tagLBIV::iSel, tagLBIV::iSelBase, tagLBIV::iTop, LBEvent(), LBUP_NOTIFY, LBUP_RELEASECAPTURE, LBUP_RESETSELECTION, LBUP_SELCHANGE, LBUP_SUCCESS, NtUserKillTimer(), NtUserReleaseCapture, tagLBIV::pcbox, SELONLY, tagLBIV::spwnd, TestWF, TRUE, WFWIN31COMPAT, WFWIN40COMPAT, tagLBIV::wMultiple, xxxAlterHilite(), xxxInsureVisible(), xxxInvertLBItem(), and xxxNotifyOwner().

Referenced by ListBoxWndProcWorker(), xxxCaretDestroy(), and xxxTrackMouse().

01876 { 01877 01878 CheckLock(plb->spwnd); 01879 01880 /* 01881 * If the list box is an Extended listbox, then change the select status 01882 * of all items between the anchor and the last mouse position to the 01883 * newItemState 01884 */ 01885 if (plb->wMultiple == EXTENDEDSEL) 01886 xxxAlterHilite(plb, plb->iMouseDown, plb->iLastMouseMove, 01887 plb->fNewItemState, SELONLY, FALSE); 01888 01889 /* 01890 * This is a combo box and user upclicked outside the listbox 01891 * so we want to restore the original selection. 01892 */ 01893 if (plb->pcbox && (uFlags & LBUP_RESETSELECTION)) { 01894 int iSelOld; 01895 01896 iSelOld = plb->iSel; 01897 01898 if (iSelOld >= 0) 01899 xxxInvertLBItem(plb, plb->iSel, FALSE); 01900 01901 plb->iSel = plb->iLastSelection; 01902 xxxInvertLBItem(plb, plb->iSel, TRUE); 01903 01904 /* 01905 * Note that we always send selection events before we tell the 01906 * app. This is on purpose--the app may turn around and select 01907 * something else when notified. In which case our event would 01908 * be out of order. 01909 */ 01910 if (FWINABLE()) 01911 LBEvent(plb, EVENT_OBJECT_SELECTION, plb->iSel); 01912 01913 /* 01914 * On win-95 and NT4 the check used to be !(uFlags & LBUP_NOTIFY) which 01915 * is a bug because we would notify even when the lb is not LBUP_NOTIFY 01916 */ 01917 if ((uFlags & LBUP_NOTIFY) && plb->fNotify && (iSelOld != plb->iSel)) 01918 xxxNotifyOwner(plb, LBN_SELCHANGE); 01919 } 01920 01921 NtUserKillTimer(HWq(plb->spwnd), IDSYS_SCROLL); 01922 plb->fMouseDown = FALSE; 01923 if (plb->fCaptured) { 01924 plb->fCaptured = FALSE; 01925 if (uFlags & LBUP_RELEASECAPTURE) 01926 NtUserReleaseCapture(); 01927 } 01928 /* 01929 * Don't scroll item as long as any part of it is visible 01930 */ 01931 if (plb->iSelBase < plb->iTop || 01932 plb->iSelBase > plb->iTop + CItemInWindow(plb, TRUE)) 01933 xxxInsureVisible(plb, plb->iSelBase, FALSE); 01934 01935 if (plb->fNotify) { 01936 if (uFlags & LBUP_NOTIFY) { 01937 if (uFlags & LBUP_SUCCESS) { 01938 /* 01939 * ArtMaster needs this SELCHANGE notification now! 01940 */ 01941 if ((plb->fDoubleClick) && !TestWF(plb->spwnd, WFWIN31COMPAT)) 01942 xxxNotifyOwner(plb, LBN_SELCHANGE); 01943 01944 /* 01945 * Notify owner of click or double click on selection 01946 */ 01947 xxxNotifyOwner(plb, (plb->fDoubleClick) ? LBN_DBLCLK : LBN_SELCHANGE); 01948 } else { 01949 /* 01950 * Notify owner that the attempted selection was cancelled. 01951 */ 01952 xxxNotifyOwner(plb, LBN_SELCANCEL); 01953 } 01954 } else if (uFlags & LBUP_SELCHANGE) { 01955 /* 01956 * Did we do some semi-selecting with mouse moves, then hit Enter? 01957 * If so, we need to make sure the app knows that something was 01958 * really truly selected. 01959 */ 01960 UserAssert(TestWF(plb->spwnd, WFWIN40COMPAT)); 01961 if (plb->iLastSelection != plb->iSel) 01962 xxxNotifyOwner(plb, LBN_SELCHANGE); 01963 01964 } 01965 } 01966 01967 }

void xxxLBDrawLBItem PLBIV  plb,
INT  sItem,
LPRECT  lprect,
BOOL  fHilite,
HBRUSH  hbr
 

Definition at line 354 of file lboxctl2.c.

References CheckLock, DWORD, FillRect(), tagLBIV::fRightAlign, tagLBIV::fRtoLReading, tagLBIV::fUseTabStops, GetLpszItem(), tagLBIV::hdc, tagLBIV::iSelBase, LBPrintCallback(), NULL, tagLBIV::spwnd, SYSHBR, SYSRGB, TestWF, UINT, and WFDISABLED.

Referenced by xxxInvertLBItem(), and xxxLBPaint().

00360 { 00361 LPWSTR lpstr; 00362 DWORD rgbSave; 00363 DWORD rgbBkSave; 00364 UINT uFlags; 00365 HDC hdc = plb->hdc; 00366 UINT oldAlign; 00367 00368 CheckLock(plb->spwnd); 00369 00370 /* 00371 * If the item is selected, then fill with highlight color 00372 */ 00373 if (fHilite) { 00374 FillRect(hdc, lprect, SYSHBR(HIGHLIGHT)); 00375 rgbBkSave = SetBkColor(hdc, SYSRGB(HIGHLIGHT)); 00376 rgbSave = SetTextColor(hdc, SYSRGB(HIGHLIGHTTEXT)); 00377 } else { 00378 00379 /* 00380 * If fUseTabStops, we must fill the background, because later we use 00381 * LBTabTheTextOutForWimps(), which fills the background only partially 00382 * Fix for Bug #1509 -- 01/25/91 -- SANKAR -- 00383 */ 00384 if ((hbr != NULL) && ((sItem == plb->iSelBase) || (plb->fUseTabStops))) { 00385 FillRect(hdc, lprect, hbr); 00386 } 00387 } 00388 00389 uFlags = DST_COMPLEX; 00390 lpstr = GetLpszItem(plb, sItem); 00391 00392 if (TestWF(plb->spwnd, WFDISABLED)) { 00393 if ((COLORREF)SYSRGB(GRAYTEXT) != GetBkColor(hdc)) 00394 SetTextColor(hdc, SYSRGB(GRAYTEXT)); 00395 else 00396 uFlags |= DSS_UNION; 00397 } 00398 00399 if (plb->fRightAlign) 00400 uFlags |= DSS_RIGHT; 00401 00402 if (plb->fRtoLReading) 00403 oldAlign = SetTextAlign(hdc, TA_RTLREADING | GetTextAlign(hdc)); 00404 00405 DrawState(hdc, SYSHBR(WINDOWTEXT), 00406 (DRAWSTATEPROC)LBPrintCallback, 00407 (LPARAM)lpstr, 00408 (WPARAM)plb, 00409 lprect->left, 00410 lprect->top, 00411 lprect->right-lprect->left, 00412 lprect->bottom-lprect->top, 00413 uFlags); 00414 00415 if (plb->fRtoLReading) 00416 SetTextAlign(hdc, oldAlign); 00417 00418 if (fHilite) { 00419 SetTextColor(hdc, rgbSave); 00420 SetBkColor(hdc, rgbBkSave); 00421 } 00422 }

HBRUSH xxxLBGetBrush PLBIV  plb,
HBRUSH *  phbrOld
 

Definition at line 60 of file lboxctl2.c.

References _GetDesktopWindow(), CheckLock, GetControlBrush, GetControlColor, tagLBIV::hdc, HW, HWq, NULL, REBASEPWND, tagLBIV::spwnd, tagLBIV::spwndParent, tagWND::spwndParent, ThreadLock, and ThreadUnlock.

Referenced by xxxInvertLBItem(), and xxxLBPaint().

00061 { 00062 HBRUSH hbr; 00063 HBRUSH hbrOld; 00064 TL tlpwndParent; 00065 00066 CheckLock(plb->spwnd); 00067 00068 SetBkMode(plb->hdc, OPAQUE); 00069 00070 // 00071 // Get brush & colors 00072 // 00073 if ((plb->spwnd->spwndParent == NULL) || 00074 (REBASEPWND(plb->spwnd, spwndParent) == _GetDesktopWindow())) { 00075 ThreadLock(plb->spwndParent, &tlpwndParent); 00076 hbr = GetControlColor(HW(plb->spwndParent), HWq(plb->spwnd), 00077 plb->hdc, WM_CTLCOLORLISTBOX); 00078 ThreadUnlock(&tlpwndParent); 00079 } else 00080 hbr = GetControlBrush(HWq(plb->spwnd), plb->hdc, WM_CTLCOLORLISTBOX); 00081 00082 // 00083 // Select brush into dc 00084 // 00085 if (hbr != NULL) { 00086 hbrOld = SelectObject(plb->hdc, hbr); 00087 if (phbrOld) 00088 *phbrOld = hbrOld; 00089 } 00090 00091 return(hbr); 00092 }

BOOL xxxLBInvalidateRect PLBIV  plb,
LPRECT  lprc,
BOOL  fErase
 

Definition at line 38 of file lboxctl2.c.

References BOOL, CheckLock, FALSE, tagLBIV::fDeferUpdate, tagLBIV::fRedraw, HWq, IsLBoxVisible, NtUserInvalidateRect(), tagLBIV::spwnd, and TRUE.

Referenced by ListBoxWndProcWorker(), xxxCheckRedraw(), xxxLBoxCtlDelete(), xxxLBSelRange(), xxxLBSetCount(), and xxxLBSetSel().

00039 { 00040 CheckLock(plb->spwnd); 00041 00042 if (IsLBoxVisible(plb)) { 00043 NtUserInvalidateRect(HWq(plb->spwnd), lprc, fErase); 00044 return(TRUE); 00045 } 00046 00047 if (!plb->fRedraw) 00048 plb->fDeferUpdate = TRUE; 00049 00050 return(FALSE); 00051 }

VOID xxxLBoxCaretBlinker HWND  hwnd,
UINT  wMsg,
UINT_PTR  nIDEvent,
DWORD  dwTime
 

Definition at line 2139 of file lboxctl2.c.

References tagLBIV::fCaretOn, ISREMOTESESSION, ValidateHwnd, VOID(), and xxxLBSetCaret().

Referenced by xxxLBoxCtlKeyInput().

02144 { 02145 PWND pwnd; 02146 PLBIV plb; 02147 02148 /* 02149 * Standard parameters for a timer callback function that aren't used. 02150 * Mentioned here to avoid compiler warnings 02151 */ 02152 UNREFERENCED_PARAMETER(wMsg); 02153 UNREFERENCED_PARAMETER(nIDEvent); 02154 UNREFERENCED_PARAMETER(dwTime); 02155 02156 pwnd = ValidateHwnd(hwnd); 02157 plb = ((PLBWND)pwnd)->pLBIV; 02158 02159 /* 02160 * leave caret on, don't blink it off (prevents rapid blinks?) 02161 */ 02162 if (ISREMOTESESSION() && plb->fCaretOn) { 02163 return; 02164 } 02165 02166 /* 02167 * Check if the Caret is ON, if so, switch it OFF 02168 */ 02169 xxxLBSetCaret(plb, !plb->fCaretOn); 02170 return; 02171 }

void xxxLBoxCtlCharInput PLBIV  plb,
UINT  inputChar,
BOOL  fAnsi
 

Definition at line 2948 of file lboxctl2.c.

References BOOL, BYTE, CheckLock, tagLBIV::cMac, DbcsCombine(), tagLBIV::fAddSelMode, FALSE, tagLBIV::fHasStrings, tagLBIV::fMouseDown, tagLBIV::fSort, GetKeyState(), gpsi, HWq, IDSYS_LBSEARCH, INT, IS_DBCS_ENABLED, tagLBIV::iSelBase, tagLBIV::iTypeSearch, LB_KEYDOWN, MAX_TYPESEARCH, MBToWCSEx(), MULTIPLESEL, NtUserMessageBeep, NtUserSetTimer(), NULL, PREFIX, tagLBIV::pszTypeSearch, SendMessageWorker(), tagLBIV::spwnd, tagLBIV::spwndParent, THREAD_CODEPAGE, ThreadLock, ThreadUnlock, TRUE, UserLocalAlloc, tagLBIV::wMultiple, xxxFindString(), and xxxLBoxCtlKeyInput().

Referenced by ListBoxWndProcWorker().

02952 { 02953 INT iSel; 02954 BOOL fControl; 02955 TL tlpwndParent; 02956 02957 CheckLock(plb->spwnd); 02958 02959 if (plb->cMac == 0 || plb->fMouseDown) { 02960 02961 /* 02962 * Get out if we are in the middle of mouse routines or if we have no 02963 * items in the listbox, we just return without doing anything. 02964 */ 02965 return; 02966 } 02967 02968 fControl = (GetKeyState(VK_CONTROL) < 0); 02969 02970 switch (inputChar) { 02971 case VK_ESCAPE: 02972 plb->iTypeSearch = 0; 02973 if (plb->pszTypeSearch) 02974 plb->pszTypeSearch[0] = 0; 02975 break; 02976 02977 case VK_BACK: 02978 if (plb->iTypeSearch) { 02979 plb->pszTypeSearch[plb->iTypeSearch--] = 0; 02980 if (plb->fSort) { 02981 iSel = -1; 02982 goto TypeSearch; 02983 } 02984 } 02985 break; 02986 02987 case VK_SPACE: 02988 if (plb->fAddSelMode || plb->wMultiple == MULTIPLESEL) 02989 break; 02990 /* Otherwise, for single/extended selection listboxes not in add 02991 * selection mode, let the space go thru as a type search character 02992 * FALL THRU 02993 */ 02994 02995 default: 02996 02997 /* 02998 * Move selection to first item beginning with the character the 02999 * user typed. We don't want do this if we are using owner draw. 03000 */ 03001 03002 if (fAnsi && IS_DBCS_ENABLED() && IsDBCSLeadByteEx(THREAD_CODEPAGE(), (BYTE)inputChar)) { 03003 WCHAR wch; 03004 LPWSTR lpwstr = &wch; 03005 03006 inputChar = DbcsCombine(HWq(plb->spwnd), (BYTE)inputChar); 03007 RIPMSG1(RIP_VERBOSE, "xxxLBoxCtlCharInput: combined DBCS. 0x%04x", inputChar); 03008 03009 if (inputChar == 0) { 03010 RIPMSG1(RIP_WARNING, "xxxLBoxCtlCharInput: cannot combine two DBCS. LB=0x%02x", 03011 inputChar); 03012 break; 03013 } 03014 // If it is DBCS, let's ignore the ctrl status. 03015 fControl = FALSE; 03016 03017 // Convert DBCS to UNICODE. 03018 // Note: Leading byte is in the low byte, trailing byte is in high byte. 03019 // Let's assume Little Endian CPUs only, so inputChar can directly be 03020 // input for MBSToWCSEx as an ANSI string. 03021 if (MBToWCSEx(THREAD_CODEPAGE(), (LPCSTR)&inputChar, 2, &lpwstr, 1, FALSE) == 0) { 03022 RIPMSG1(RIP_WARNING, "xxxLBoxCtlCharInput: cannot convert 0x%04x to UNICODE.", 03023 inputChar); 03024 break; 03025 } 03026 inputChar = wch; 03027 } 03028 03029 if (plb->fHasStrings) { 03030 // Incremental Type Search processing 03031 // 03032 // update szTypeSearch string and then move to the first item from 03033 // the current selection whose prefix matches szTypeSearch 03034 // 03035 // the szTypeSearch will continue to grow until a "long enough" 03036 // gap between key entries is encountered -- at which point any 03037 // more searching will start over 03038 03039 /* 03040 * Undo CONTROL-char to char 03041 */ 03042 if (fControl && inputChar < 0x20) 03043 inputChar += 0x40; 03044 03045 if (plb->iTypeSearch == MAX_TYPESEARCH) { 03046 NtUserMessageBeep(0); 03047 break; 03048 } 03049 iSel = -1; 03050 03051 if (plb->pszTypeSearch == NULL) 03052 plb->pszTypeSearch = (LPWSTR)UserLocalAlloc(HEAP_ZERO_MEMORY, sizeof(WCHAR) * (MAX_TYPESEARCH + 1)); 03053 03054 if (plb->pszTypeSearch == NULL) { 03055 NtUserMessageBeep(0); 03056 break; 03057 } 03058 03059 plb->pszTypeSearch[plb->iTypeSearch++] = (WCHAR) inputChar; 03060 plb->pszTypeSearch[plb->iTypeSearch] = 0; 03061 03062 TypeSearch: 03063 if (plb->fSort) { 03064 // Set timer to determine when to kill incremental searching 03065 NtUserSetTimer(HWq(plb->spwnd), IDSYS_LBSEARCH, 03066 gpsi->dtLBSearch, NULL); 03067 } else { 03068 // If this is not a sorted listbox, no incremental search. 03069 plb->iTypeSearch = 0; 03070 iSel = plb->iSelBase; 03071 } 03072 03073 03074 /* 03075 * Search for the item beginning with the given character starting 03076 * at iSel+1. We will wrap the search to the beginning of the 03077 * listbox if we don't find the item. If SHIFT is down and we are 03078 * a multiselection lb, then the item's state will be set to 03079 * plb->fNewItemState according to the current mode. 03080 */ 03081 iSel = xxxFindString(plb, plb->pszTypeSearch, iSel, PREFIX, TRUE); 03082 if (iSel == -1) { 03083 // no match found -- check for prefix match 03084 // (i.e. "p" find FIRST item that starts with 'p', 03085 // "pp" find NEXT item that starts with 'p') 03086 if(plb->iTypeSearch) 03087 { 03088 plb->iTypeSearch--; 03089 if ((plb->iTypeSearch == 1) && (plb->pszTypeSearch[0] == plb->pszTypeSearch[1])) 03090 { 03091 plb->pszTypeSearch[1] = 0; 03092 iSel = xxxFindString(plb, plb->pszTypeSearch, plb->iSelBase, PREFIX, TRUE); 03093 } 03094 } 03095 } 03096 // if match is found -- select it 03097 if (iSel != -1) 03098 { 03099 CtlKeyInput: 03100 xxxLBoxCtlKeyInput(plb, LB_KEYDOWN, iSel); 03101 03102 } 03103 } else { 03104 if (plb->spwndParent != NULL) { 03105 ThreadLock(plb->spwndParent, &tlpwndParent); 03106 iSel = (INT)SendMessageWorker(plb->spwndParent, WM_CHARTOITEM, 03107 MAKELONG(inputChar, plb->iSelBase), (LPARAM)HWq(plb->spwnd), fAnsi); 03108 ThreadUnlock(&tlpwndParent); 03109 } else 03110 iSel = -1; 03111 03112 if (iSel != -1 && iSel != -2) 03113 goto CtlKeyInput; 03114 03115 } 03116 break; 03117 } 03118 }

void xxxLBoxCtlHScroll PLBIV  plb,
INT  cmd,
int  xAmt
 

Definition at line 691 of file lboxctl2.c.

References _GetClientRect(), CheckLock, tagLBIV::cMac, tagLBIV::cxChar, dwFlags, DWORD, FALSE, tagLBIV::fMultiColumn, tagLBIV::fRightAlign, tagLBIV::fSmoothScroll, HWq, LBGetScrollFlags(), tagLBIV::maxWidth, NULL, ScrollWindowEx(), tagLBIV::spwnd, TRUE, UpdateWindow(), tagLBIV::xOrigin, tagLBIV::xRightOrigin, xxxLBoxCtlHScrollMultiColumn(), xxxLBSetCaret(), xxxLBShowHideScrollBars(), and xxxSetLBScrollParms().

00695 { 00696 int newOrigin = plb->xOrigin; 00697 int oldOrigin = plb->xOrigin; 00698 int windowWidth; 00699 RECT rc; 00700 DWORD dwTime = 0; 00701 00702 CheckLock(plb->spwnd); 00703 00704 /* 00705 * Update the window so that we don't run into problems with invalid 00706 * regions during the horizontal scroll. 00707 */ 00708 if (plb->fMultiColumn) { 00709 00710 /* 00711 * Handle multicolumn scrolling in a separate segment 00712 */ 00713 xxxLBoxCtlHScrollMultiColumn(plb, cmd, xAmt); 00714 return; 00715 } 00716 00717 _GetClientRect(plb->spwnd, &rc); 00718 windowWidth = rc.right; 00719 00720 if (plb->cMac) { 00721 00722 switch (cmd) { 00723 case SB_LINEUP: 00724 dwTime = xAmt; 00725 newOrigin -= plb->cxChar; 00726 break; 00727 00728 case SB_LINEDOWN: 00729 dwTime = xAmt; 00730 newOrigin += plb->cxChar; 00731 break; 00732 00733 case SB_PAGEUP: 00734 newOrigin -= (windowWidth / 3) * 2; 00735 break; 00736 00737 case SB_PAGEDOWN: 00738 newOrigin += (windowWidth / 3) * 2; 00739 break; 00740 00741 case SB_THUMBTRACK: 00742 case SB_THUMBPOSITION: 00743 newOrigin = xAmt; 00744 break; 00745 00746 case SB_TOP: 00747 newOrigin = 0; 00748 break; 00749 00750 case SB_BOTTOM: 00751 newOrigin = plb->maxWidth; 00752 break; 00753 00754 case SB_ENDSCROLL: 00755 plb->fSmoothScroll = TRUE; 00756 xxxLBSetCaret(plb, FALSE); 00757 xxxLBShowHideScrollBars(plb); 00758 xxxLBSetCaret(plb, TRUE); 00759 return; 00760 } 00761 00762 xxxLBSetCaret(plb, FALSE); 00763 plb->xOrigin = newOrigin; 00764 plb->xOrigin = xxxSetLBScrollParms(plb, SB_HORZ); 00765 00766 if ((cmd == SB_BOTTOM) && plb->fRightAlign) { 00767 /* 00768 * so we know where to draw from. 00769 */ 00770 plb->xRightOrigin = plb->xOrigin; 00771 } 00772 00773 if(oldOrigin != plb->xOrigin) { 00774 HWND hwnd = HWq(plb->spwnd); 00775 DWORD dwFlags; 00776 00777 dwFlags = LBGetScrollFlags(plb, dwTime); 00778 ScrollWindowEx(hwnd, oldOrigin-plb->xOrigin, 00779 0, NULL, &rc, NULL, NULL, dwFlags); 00780 UpdateWindow(hwnd); 00781 } 00782 00783 xxxLBSetCaret(plb, TRUE); 00784 } else { 00785 // this is a less-than-ideal fix for ImageMind ScreenSaver (Win95 00786 // B#8252) but it works and it doesn't hurt anybody -- JEFFBOG 10/28/94 00787 xxxSetLBScrollParms(plb, SB_HORZ); 00788 } 00789 }

void xxxLBoxCtlKeyInput PLBIV  plb,
UINT  msg,
UINT  vKey
 

Definition at line 2183 of file lboxctl2.c.

References BOOL, tagCBox::CBoxStyle, CheckLock, tagLBIV::cItemFullMax, tagLBIV::cMac, CTLDOWN, EXTENDEDSEL, tagLBIV::fAddSelMode, FALSE, tagCBox::fExtendedUI, tagCBox::fKeyboardSelInListBox, tagCBox::fLBoxVisible, tagLBIV::fMouseDown, tagLBIV::fMultiColumn, tagLBIV::fNewItemState, tagLBIV::fNotify, tagLBIV::fRightAlign, tagLBIV::fWantKeyboardInput, FWINABLE, GetKeyState(), gpsi, HILITEANDSEL, HILITEONLY, HW, HWq, IDSYS_CARET, tagLBIV::iLastMouseMove, tagLBIV::iLastSelection, tagLBIV::iMouseDown, IncrementISel(), INT, tagLBIV::iSel, tagLBIV::iSelBase, IsSelected(), tagLBIV::itemsPerColumn, tagLBIV::iTypeSearch, L, LB_KEYDOWN, LBEvent(), LBPage(), msg, MULTIPLESEL, NtUserKillTimer(), NtUserSetTimer(), tagLBIV::OwnerDraw, OWNERDRAWVAR, tagLBIV::pcbox, PostMessage(), SDROPPABLE, SELONLY, SendMessage(), SetSelected(), SHIFTDOWN, SINGLESEL, tagLBIV::spwnd, tagCBox::spwnd, tagLBIV::spwndParent, TestWF, ThreadLock, ThreadUnlock, TRUE, UINT, VERKEY_BACKSLASH, VERKEY_SLASH, WFHSCROLL, tagLBIV::wMultiple, xxxCBHideListBoxWindow(), xxxCBShowListBoxWindow(), xxxInsureVisible(), xxxInvertLBItem(), xxxLBBlockHilite(), xxxLBoxCaretBlinker(), xxxLBSetCaret(), xxxLBShowHideScrollBars(), xxxNotifyOwner(), xxxResetWorld(), and xxxSetISelBase().

Referenced by ListBoxWndProcWorker(), and xxxLBoxCtlCharInput().

02187 { 02188 INT i; 02189 INT iNewISel; 02190 INT cItemPageScroll; 02191 PCBOX pcbox; 02192 BOOL fDropDownComboBox; 02193 BOOL fExtendedUIComboBoxClosed; 02194 BOOL hScrollBar = TestWF(plb->spwnd, WFHSCROLL); 02195 UINT wModifiers = 0; 02196 BOOL fSelectKey = FALSE; /* assume it is a navigation key */ 02197 UINT uEvent = 0; 02198 HWND hwnd = HWq(plb->spwnd); 02199 TL tlpwndParent; 02200 TL tlpwnd; 02201 02202 CheckLock(plb->spwnd); 02203 02204 pcbox = plb->pcbox; 02205 02206 /* 02207 * Is this a dropdown style combo box/listbox ? 02208 */ 02209 fDropDownComboBox = pcbox && (pcbox->CBoxStyle & SDROPPABLE); 02210 02211 /* 02212 *Is this an extended ui combo box which is closed? 02213 */ 02214 fExtendedUIComboBoxClosed = fDropDownComboBox && pcbox->fExtendedUI && 02215 !pcbox->fLBoxVisible; 02216 02217 if (plb->fMouseDown || (!plb->cMac && vKey != VK_F4)) { 02218 02219 /* 02220 * Ignore keyboard input if we are in the middle of a mouse down deal or 02221 * if there are no items in the listbox. Note that we let F4's go 02222 * through for combo boxes so that the use can pop up and down empty 02223 * combo boxes. 02224 */ 02225 return; 02226 } 02227 02228 /* 02229 * Modifiers are considered only in EXTENDED sel list boxes. 02230 */ 02231 if (plb->wMultiple == EXTENDEDSEL) { 02232 02233 /* 02234 * If multiselection listbox, are any modifiers used ? 02235 */ 02236 if (GetKeyState(VK_SHIFT) < 0) 02237 wModifiers = SHIFTDOWN; 02238 if (GetKeyState(VK_CONTROL) < 0) 02239 wModifiers += CTLDOWN; 02240 02241 /* 02242 * Please Note that (SHIFTDOWN + CTLDOWN) == (SHCTLDOWN) 02243 */ 02244 } 02245 02246 if (msg == LB_KEYDOWN) { 02247 02248 /* 02249 * This is a listbox "go to specified item" message which means we want 02250 * to go to a particular item number (given by vKey) directly. ie. the 02251 * user has typed a character and we want to go to the item which 02252 * starts with that character. 02253 */ 02254 iNewISel = (INT)vKey; 02255 goto TrackKeyDown; 02256 } 02257 02258 cItemPageScroll = plb->cItemFullMax; 02259 02260 if (cItemPageScroll > 1) 02261 cItemPageScroll--; 02262 02263 if (plb->fWantKeyboardInput) { 02264 02265 /* 02266 * Note: msg must not be LB_KEYDOWN here or we'll be in trouble... 02267 */ 02268 ThreadLock(plb->spwndParent, &tlpwndParent); 02269 iNewISel = (INT)SendMessage(HW(plb->spwndParent), WM_VKEYTOITEM, 02270 MAKELONG(vKey, plb->iSelBase), (LPARAM)hwnd); 02271 ThreadUnlock(&tlpwndParent); 02272 02273 if (iNewISel == -2) { 02274 02275 /* 02276 * Don't move the selection... 02277 */ 02278 return; 02279 } 02280 if (iNewISel != -1) { 02281 02282 /* 02283 * Jump directly to the item provided by the app 02284 */ 02285 goto TrackKeyDown; 02286 } 02287 02288 /* 02289 * else do default processing of the character. 02290 */ 02291 } 02292 02293 switch (vKey) { 02294 // LATER IanJa: not language independent!!! 02295 // We could use VkKeyScan() to find out which is the '\' key 02296 // This is VK_OEM_5 '\|' for US English only. 02297 // Germans, Italians etc. have to type CTRL+^ (etc) for this. 02298 // This is documented as File Manager behaviour for 3.0, but apparently 02299 // not for 3.1., although functionality remains. We should still fix it, 02300 // although German (etc?) '\' is generated with AltGr (Ctrl-Alt) (???) 02301 case VERKEY_BACKSLASH: /* '\' character for US English */ 02302 02303 /* 02304 * Check if this is CONTROL-\ ; If so Deselect all items 02305 */ 02306 if ((wModifiers & CTLDOWN) && (plb->wMultiple != SINGLESEL)) { 02307 xxxLBSetCaret(plb, FALSE); 02308 xxxResetWorld(plb, plb->iSelBase, plb->iSelBase, FALSE); 02309 02310 /* 02311 * And select the current item 02312 */ 02313 SetSelected(plb, plb->iSelBase, TRUE, HILITEANDSEL); 02314 xxxInvertLBItem(plb, plb->iSelBase, TRUE); 02315 uEvent = EVENT_OBJECT_SELECTION; 02316 goto CaretOnAndNotify; 02317 } 02318 return; 02319 break; 02320 02321 case VK_DIVIDE: /* NumPad '/' character on enhanced keyboard */ 02322 // LATER IanJa: not language independent!!! 02323 // We could use VkKeyScan() to find out which is the '/' key 02324 // This is VK_OEM_2 '/?' for US English only. 02325 // Germans, Italians etc. have to type CTRL+# (etc) for this. 02326 case VERKEY_SLASH: /* '/' character */ 02327 02328 /* 02329 * Check if this is CONTROL-/ ; If so select all items 02330 */ 02331 if ((wModifiers & CTLDOWN) && (plb->wMultiple != SINGLESEL)) { 02332 xxxLBSetCaret(plb, FALSE); 02333 xxxResetWorld(plb, -1, -1, TRUE); 02334 02335 uEvent = EVENT_OBJECT_SELECTIONWITHIN; 02336 02337 CaretOnAndNotify: 02338 xxxLBSetCaret(plb, TRUE); 02339 if (FWINABLE()) { 02340 LBEvent(plb, uEvent, plb->iSelBase); 02341 } 02342 xxxNotifyOwner(plb, LBN_SELCHANGE); 02343 } 02344 return; 02345 break; 02346 02347 case VK_F8: 02348 02349 /* 02350 * The "Add" mode is possible only in Multiselection listboxes... Get 02351 * into it via SHIFT-F8... (Yes, sometimes these UI people are sillier 02352 * than your "typical dumb user"...) 02353 */ 02354 if (plb->wMultiple != SINGLESEL && wModifiers == SHIFTDOWN) { 02355 02356 /* 02357 * We have to make the caret blink! Do something... 02358 */ 02359 if (plb->fAddSelMode) { 02360 02361 /* 02362 * Switch off the Caret blinking 02363 */ 02364 NtUserKillTimer(hwnd, IDSYS_CARET); 02365 02366 /* 02367 * Make sure the caret does not vanish 02368 */ 02369 xxxLBSetCaret(plb, TRUE); 02370 } else { 02371 02372 /* 02373 * Create a timer to make the caret blink 02374 */ 02375 NtUserSetTimer(hwnd, IDSYS_CARET, gpsi->dtCaretBlink, 02376 xxxLBoxCaretBlinker); 02377 } 02378 02379 /* 02380 * Toggle the Add mode flag 02381 */ 02382 plb->fAddSelMode = (UINT)!plb->fAddSelMode; 02383 } 02384 return; 02385 case VK_SPACE: /* Selection key is space */ 02386 i = 0; 02387 fSelectKey = TRUE; 02388 break; 02389 02390 case VK_PRIOR: 02391 if (fExtendedUIComboBoxClosed) { 02392 02393 /* 02394 * Disable movement keys for TandyT. 02395 */ 02396 return; 02397 } 02398 02399 if (plb->OwnerDraw == OWNERDRAWVAR) { 02400 i = LBPage(plb, plb->iSelBase, FALSE) - plb->iSelBase; 02401 } else { 02402 i = -cItemPageScroll; 02403 } 02404 break; 02405 02406 case VK_NEXT: 02407 if (fExtendedUIComboBoxClosed) { 02408 02409 /* 02410 * Disable movement keys for TandyT. 02411 */ 02412 return; 02413 } 02414 02415 if (plb->OwnerDraw == OWNERDRAWVAR) { 02416 i = LBPage(plb, plb->iSelBase, TRUE) - plb->iSelBase; 02417 } else { 02418 i = cItemPageScroll; 02419 } 02420 break; 02421 02422 case VK_HOME: 02423 if (fExtendedUIComboBoxClosed) { 02424 02425 /* 02426 * Disable movement keys for TandyT. 02427 */ 02428 return; 02429 } 02430 02431 i = (INT_MIN/2)+1; /* A very big negative number */ 02432 break; 02433 02434 case VK_END: 02435 if (fExtendedUIComboBoxClosed) { 02436 02437 /* 02438 * Disable movement keys for TandyT. 02439 */ 02440 return; 02441 } 02442 02443 i = (INT_MAX/2)-1; /* A very big positive number */ 02444 break; 02445 02446 case VK_LEFT: 02447 if (plb->fMultiColumn) { 02448 if (plb->fRightAlign 02449 #ifdef USE_MIRRORING 02450 ^ (!!TestWF(plb->spwnd, WEFLAYOUTRTL)) 02451 02452 #endif 02453 ) 02454 goto ReallyRight; 02455 ReallyLeft: 02456 if (plb->iSelBase / plb->itemsPerColumn == 0) { 02457 i = 0; 02458 } else { 02459 i = -plb->itemsPerColumn; 02460 } 02461 break; 02462 } 02463 02464 if (hScrollBar) { 02465 goto HandleHScrolling; 02466 } else { 02467 02468 /* 02469 * Fall through and handle this as if the up arrow was pressed. 02470 */ 02471 02472 vKey = VK_UP; 02473 } 02474 02475 /* 02476 * Fall through 02477 */ 02478 02479 case VK_UP: 02480 if (fExtendedUIComboBoxClosed) 02481 // Disable movement keys for TandyT. 02482 return; 02483 02484 i = -1; 02485 break; 02486 02487 case VK_RIGHT: 02488 if (plb->fMultiColumn) { 02489 if (plb->fRightAlign 02490 #ifdef USE_MIRRORING 02491 ^ (!!TestWF(plb->spwnd, WEFLAYOUTRTL)) 02492 02493 #endif 02494 ) 02495 goto ReallyLeft; 02496 ReallyRight: 02497 if (plb->iSelBase / plb->itemsPerColumn == plb->cMac / plb->itemsPerColumn) { 02498 i = 0; 02499 } else { 02500 i = plb->itemsPerColumn; 02501 } 02502 break; 02503 } 02504 if (hScrollBar) { 02505 HandleHScrolling: 02506 PostMessage(hwnd, WM_HSCROLL, 02507 (vKey == VK_RIGHT ? SB_LINEDOWN : SB_LINEUP), 0L); 02508 return; 02509 } else { 02510 02511 /* 02512 * Fall through and handle this as if the down arrow was 02513 * pressed. 02514 */ 02515 vKey = VK_DOWN; 02516 } 02517 02518 /* 02519 * Fall through 02520 */ 02521 02522 case VK_DOWN: 02523 if (fExtendedUIComboBoxClosed) { 02524 02525 /* 02526 * If the combo box is closed, down arrow should open it. 02527 */ 02528 if (!pcbox->fLBoxVisible) { 02529 02530 /* 02531 * If the listbox isn't visible, just show it 02532 */ 02533 ThreadLock(pcbox->spwnd, &tlpwnd); 02534 xxxCBShowListBoxWindow(pcbox, TRUE); 02535 ThreadUnlock(&tlpwnd); 02536 } 02537 return; 02538 } 02539 i = 1; 02540 break; 02541 02542 case VK_ESCAPE: 02543 case VK_RETURN: 02544 if (!fDropDownComboBox || !pcbox->fLBoxVisible) 02545 return; 02546 02547 // | If this is a dropped listbox for a combobox and the ENTER | 02548 // | key is pressed, close up the listbox, so FALLTHRU | 02549 // V V 02550 02551 case VK_F4: 02552 if (fDropDownComboBox && !pcbox->fExtendedUI) { 02553 02554 /* 02555 * If we are a dropdown combo box/listbox we want to process 02556 * this key. BUT for TandtT, we don't do anything on VK_F4 if we 02557 * are in extended ui mode. 02558 */ 02559 ThreadLock(pcbox->spwnd, &tlpwnd); 02560 if (!pcbox->fLBoxVisible) { 02561 02562 /* 02563 * If the listbox isn't visible, just show it 02564 */ 02565 xxxCBShowListBoxWindow(pcbox, (vKey != VK_ESCAPE)); 02566 } else { 02567 02568 /* 02569 * Ok, the listbox is visible. So hide the listbox window. 02570 */ 02571 xxxCBHideListBoxWindow(pcbox, TRUE, (vKey != VK_ESCAPE)); 02572 } 02573 ThreadUnlock(&tlpwnd); 02574 } 02575 02576 /* 02577 * Fall through to the return 02578 */ 02579 02580 default: 02581 return; 02582 } 02583 02584 /* 02585 * Find out what the new selection should be 02586 */ 02587 iNewISel = IncrementISel(plb, plb->iSelBase, i); 02588 02589 02590 if (plb->wMultiple == SINGLESEL) { 02591 if (plb->iSel == iNewISel) { 02592 02593 /* 02594 * If we are single selection and the keystroke is moving us to an 02595 * item which is already selected, we don't have to do anything... 02596 */ 02597 return; 02598 } 02599 02600 uEvent = EVENT_OBJECT_SELECTION; 02601 02602 plb->iTypeSearch = 0; 02603 if ((vKey == VK_UP || vKey == VK_DOWN) && 02604 !IsSelected(plb, plb->iSelBase, HILITEONLY)) { 02605 02606 /* 02607 * If the caret is on an unselected item and the user just hits the 02608 * up or down arrow key (ie. with no shift or ctrl modifications), 02609 * then we will just select the item the cursor is at. This is 02610 * needed for proper behavior in combo boxes but do we always want 02611 * to run this code??? Note that this is only used in single 02612 * selection list boxes since it doesn't make sense in the 02613 * multiselection case. Note that an LB_KEYDOWN message must not be 02614 * checked here because the vKey will be an item number not a 02615 * VK_and we will goof. Thus, trackkeydown label is below this to 02616 * fix a bug caused by it being above this... 02617 */ 02618 iNewISel = (plb->iSelBase == -1) ? 0 : plb->iSelBase; 02619 } 02620 } 02621 02622 TrackKeyDown: 02623 02624 xxxSetISelBase(plb, iNewISel); 02625 02626 xxxLBSetCaret(plb, FALSE); 02627 02628 if (wModifiers & SHIFTDOWN) { 02629 // Check if iMouseDown is un-initialised 02630 if (plb->iMouseDown == -1) 02631 plb->iMouseDown = iNewISel; 02632 if (plb->iLastMouseMove == -1) 02633 plb->iLastMouseMove = iNewISel; 02634 02635 // Check if we are in ADD mode 02636 if (plb->fAddSelMode) { 02637 /* Preserve all the pre-existing selections except the 02638 * ones connected with the last anchor point; If the last 02639 * Preserve all the previous selections 02640 */ 02641 /* Deselect only the selection connected with the last 02642 * anchor point; If the last anchor point is associated 02643 * with de-selection, then do not do it 02644 */ 02645 02646 if (!plb->fNewItemState) 02647 plb->iLastMouseMove = plb->iMouseDown; 02648 02649 /* We haven't done anything here because, LBBlockHilite() 02650 * will take care of wiping out the selection between 02651 * Anchor point and iLastMouseMove and select the block 02652 * between anchor point and current cursor location 02653 */ 02654 } else { 02655 /* We are not in ADD mode */ 02656 /* Remove all selections except between the anchor point 02657 * and last mouse move because it will be taken care of in 02658 * LBBlockHilite 02659 */ 02660 xxxResetWorld(plb, plb->iMouseDown, plb->iLastMouseMove, FALSE); 02661 } 02662 02663 uEvent = EVENT_OBJECT_SELECTIONWITHIN; 02664 02665 /* LBBlockHilite takes care to deselect the block between 02666 * the anchor point and iLastMouseMove and select the block 02667 * between the anchor point and the current cursor location 02668 */ 02669 /* Toggle all items to the same selection state as the item 02670 * item at the anchor point) from the anchor point to the 02671 * current cursor location. 02672 */ 02673 plb->fNewItemState = IsSelected(plb, plb->iMouseDown, SELONLY); 02674 xxxLBBlockHilite(plb, iNewISel, TRUE); 02675 02676 plb->iLastMouseMove = iNewISel; 02677 /* Preserve the existing anchor point */ 02678 } else { 02679 /* Check if this is in ADD mode */ 02680 if ((plb->fAddSelMode) || (plb->wMultiple == MULTIPLESEL)) { 02681 /* Preserve all pre-exisiting selections */ 02682 if (fSelectKey) { 02683 /* Toggle the selection state of the current item */ 02684 plb->fNewItemState = !IsSelected(plb, iNewISel, SELONLY); 02685 SetSelected(plb, iNewISel, plb->fNewItemState, HILITEANDSEL); 02686 02687 xxxInvertLBItem(plb, iNewISel, plb->fNewItemState); 02688 02689 /* Set the anchor point at the current location */ 02690 plb->iLastMouseMove = plb->iMouseDown = iNewISel; 02691 uEvent = (plb->fNewItemState ? EVENT_OBJECT_SELECTIONADD : 02692 EVENT_OBJECT_SELECTIONREMOVE); 02693 } 02694 } else { 02695 /* We are NOT in ADD mode */ 02696 /* Remove all existing selections except iNewISel, to 02697 * avoid flickering. 02698 */ 02699 xxxResetWorld(plb, iNewISel, iNewISel, FALSE); 02700 02701 /* Select the current item */ 02702 SetSelected(plb, iNewISel, TRUE, HILITEANDSEL); 02703 xxxInvertLBItem(plb, iNewISel, TRUE); 02704 02705 /* Set the anchor point at the current location */ 02706 plb->iLastMouseMove = plb->iMouseDown = iNewISel; 02707 uEvent = EVENT_OBJECT_SELECTION; 02708 } 02709 } 02710 02711 /* 02712 * Move the cursor to the new location 02713 */ 02714 xxxInsureVisible(plb, iNewISel, FALSE); 02715 xxxLBShowHideScrollBars(plb); 02716 02717 xxxLBSetCaret(plb, TRUE); 02718 02719 if (FWINABLE() && uEvent) { 02720 LBEvent(plb, uEvent, iNewISel); 02721 } 02722 02723 /* 02724 * Should we notify our parent? 02725 */ 02726 if (plb->fNotify) { 02727 if (fDropDownComboBox && pcbox->fLBoxVisible) { 02728 02729 /* 02730 * If we are in a drop down combo box/listbox and the listbox is 02731 * visible, we need to set the fKeyboardSelInListBox bit so that the 02732 * combo box code knows not to hide the listbox since the selchange 02733 * message is caused by the user keyboarding through... 02734 */ 02735 pcbox->fKeyboardSelInListBox = TRUE; 02736 plb->iLastSelection = iNewISel; 02737 } 02738 xxxNotifyOwner(plb, LBN_SELCHANGE); 02739 } 02740 }

void xxxLBoxCtlScroll PLBIV  plb,
INT  cmd,
int  yAmt
 

Definition at line 561 of file lboxctl2.c.

References CheckLock, tagLBIV::cItemFullMax, tagLBIV::cMac, DWORD, FALSE, tagLBIV::fMultiColumn, tagLBIV::fSmoothScroll, GetScrollInfo(), HWq, INT, tagLBIV::iTop, LBPage(), tagLBIV::OwnerDraw, OWNERDRAWVAR, tagLBIV::spwnd, TRUE, xxxLBSetCaret(), xxxLBShowHideScrollBars(), and xxxNewITopEx().

00565 { 00566 INT iTopNew; 00567 INT cItemPageScroll; 00568 DWORD dwTime = 0; 00569 00570 CheckLock(plb->spwnd); 00571 00572 if (plb->fMultiColumn) { 00573 00574 /* 00575 * Don't allow vertical scrolling on a multicolumn list box. Needed 00576 * in case app sends WM_VSCROLL messages to the listbox. 00577 */ 00578 return; 00579 } 00580 00581 cItemPageScroll = plb->cItemFullMax; 00582 00583 if (cItemPageScroll > 1) 00584 cItemPageScroll--; 00585 00586 if (plb->cMac) { 00587 iTopNew = plb->iTop; 00588 switch (cmd) { 00589 case SB_LINEUP: 00590 dwTime = yAmt; 00591 iTopNew--; 00592 break; 00593 00594 case SB_LINEDOWN: 00595 dwTime = yAmt; 00596 iTopNew++; 00597 break; 00598 00599 case SB_PAGEUP: 00600 if (plb->OwnerDraw == OWNERDRAWVAR) { 00601 iTopNew = LBPage(plb, plb->iTop, FALSE); 00602 } else { 00603 iTopNew -= cItemPageScroll; 00604 } 00605 break; 00606 00607 case SB_PAGEDOWN: 00608 if (plb->OwnerDraw == OWNERDRAWVAR) { 00609 iTopNew = LBPage(plb, plb->iTop, TRUE); 00610 } else { 00611 iTopNew += cItemPageScroll; 00612 } 00613 break; 00614 00615 case SB_THUMBTRACK: 00616 case SB_THUMBPOSITION: { 00617 00618 /* 00619 * If the listbox contains more than 0xFFFF items 00620 * it means that the scrolbar can return a position 00621 * that cannot fit in a WORD (16 bits), so use 00622 * GetScrollInfo (which is slower) in this case. 00623 */ 00624 if (plb->cMac < 0xFFFF) { 00625 iTopNew = yAmt; 00626 } else { 00627 SCROLLINFO si; 00628 00629 si.cbSize = sizeof(SCROLLINFO); 00630 si.fMask = SIF_TRACKPOS; 00631 00632 GetScrollInfo( HWq(plb->spwnd), SB_VERT, &si); 00633 00634 iTopNew = si.nTrackPos; 00635 } 00636 break; 00637 } 00638 case SB_TOP: 00639 iTopNew = 0; 00640 break; 00641 00642 case SB_BOTTOM: 00643 iTopNew = plb->cMac - 1; 00644 break; 00645 00646 case SB_ENDSCROLL: 00647 plb->fSmoothScroll = TRUE; 00648 xxxLBSetCaret(plb, FALSE); 00649 xxxLBShowHideScrollBars(plb); 00650 xxxLBSetCaret(plb, TRUE); 00651 return; 00652 } 00653 00654 xxxNewITopEx(plb, iTopNew, dwTime); 00655 } 00656 }

void xxxLBoxDrawItem PLBIV  plb,
INT  item,
UINT  itemAction,
UINT  itemState,
LPRECT  lprect
 

Definition at line 3558 of file lboxctl2.c.

References CheckLock, tagLBIV::cMac, CopyRect, tagLBIV::fHasData, tagLBIV::hdc, HW, HWq, L, LBGetItemData(), SendMessage(), tagWND::spmenu, tagLBIV::spwnd, tagLBIV::spwndParent, TestWF, ThreadLock, ThreadUnlock, UINT, WEFPUIACCELHIDDEN, WEFPUIFOCUSHIDDEN, WFDISABLED, and WFWIN31COMPAT.

Referenced by xxxInvertLBItem(), xxxLBPaint(), and xxxLBSetCaret().

03564 { 03565 DRAWITEMSTRUCT dis; 03566 TL tlpwndParent; 03567 03568 CheckLock(plb->spwnd); 03569 03570 /* 03571 * Fill the DRAWITEMSTRUCT with the unchanging constants 03572 */ 03573 03574 dis.CtlType = ODT_LISTBOX; 03575 dis.CtlID = PtrToUlong(plb->spwnd->spmenu); 03576 03577 /* 03578 * Use -1 if an invalid item number is being used. This is so that the app 03579 * can detect if it should draw the caret (which indicates the lb has the 03580 * focus) in an empty listbox 03581 */ 03582 dis.itemID = (UINT)(item < plb->cMac ? item : -1); 03583 dis.itemAction = itemAction; 03584 dis.hwndItem = HWq(plb->spwnd); 03585 dis.hDC = plb->hdc; 03586 dis.itemState = itemState | 03587 (UINT)(TestWF(plb->spwnd, WFDISABLED) ? ODS_DISABLED : 0); 03588 03589 if (TestWF(plb->spwnd, WEFPUIFOCUSHIDDEN)) { 03590 dis.itemState |= ODS_NOFOCUSRECT; 03591 } 03592 if (TestWF(plb->spwnd, WEFPUIACCELHIDDEN)) { 03593 dis.itemState |= ODS_NOACCEL; 03594 } 03595 03596 /* 03597 * Set the app supplied data 03598 */ 03599 if (!plb->cMac || !plb->fHasData) { 03600 03601 /* 03602 * If no strings or no items, just use 0 for data. This is so that we 03603 * can display a caret when there are no items in the listbox. 03604 * 03605 * Lazy-eval listboxes of course have no data to pass - only itemID. 03606 */ 03607 dis.itemData = 0L; 03608 } else { 03609 dis.itemData = LBGetItemData(plb, item); 03610 } 03611 03612 CopyRect(&dis.rcItem, lprect); 03613 03614 /* 03615 * Set the window origin to the horizontal scroll position. This is so that 03616 * text can always be drawn at 0,0 and the view region will only start at 03617 * the horizontal scroll offset. We pass this as wParam 03618 */ 03619 /* 03620 * Note: Only pass the itemID in wParam for 3.1 or newer apps. We break 03621 * ccMail otherwise. 03622 */ 03623 03624 ThreadLock(plb->spwndParent, &tlpwndParent); 03625 SendMessage(HW(plb->spwndParent), WM_DRAWITEM, 03626 TestWF(plb->spwndParent, WFWIN31COMPAT) ? dis.CtlID : 0, 03627 (LPARAM)&dis); 03628 ThreadUnlock(&tlpwndParent); 03629 }

void xxxLBPaint PLBIV  plb,
HDC  hdc,
LPRECT  lprcBounds
 

Definition at line 798 of file lboxctl2.c.

References _GetClientRect(), BOOL, CheckLock, CItemInWindow(), tagLBIV::cMac, tagLBIV::cyChar, FALSE, tagLBIV::fCaretOn, tagLBIV::fHorzBar, FillRect(), tagLBIV::fMultiColumn, tagLBIV::fNoSel, tagLBIV::fRightAlign, tagLBIV::hdc, HILITEONLY, INT, IntersectRect(), IsSelected(), tagLBIV::iTop, LBGetItemRect(), LBInitDC(), LBTermDC(), min, NULL, tagLBIV::OwnerDraw, OWNERDRAWVAR, tagLBIV::spwnd, TRUE, UINT, tagLBIV::xOrigin, tagLBIV::xRightOrigin, xxxLBDrawLBItem(), xxxLBGetBrush(), xxxLBoxDrawItem(), and xxxLBSetCaret().

Referenced by ListBoxWndProcWorker().

00802 { 00803 INT i; 00804 RECT rect; 00805 RECT scratchRect; 00806 BOOL fHilite; 00807 INT iLastItem; 00808 HBRUSH hbrSave = NULL; 00809 HBRUSH hbrControl; 00810 BOOL fCaretOn; 00811 RECT rcBounds; 00812 HDC hdcSave; 00813 00814 CheckLock(plb->spwnd); 00815 00816 if (lprcBounds == NULL) { 00817 lprcBounds = &rcBounds; 00818 _GetClientRect(plb->spwnd, lprcBounds); 00819 } 00820 00821 hdcSave = plb->hdc; 00822 plb->hdc = hdc; 00823 00824 // Initialize dc. 00825 LBInitDC(plb); 00826 00827 // Turn caret off 00828 if (fCaretOn = plb->fCaretOn) 00829 xxxLBSetCaret(plb, FALSE); 00830 00831 hbrSave = NULL; 00832 hbrControl = xxxLBGetBrush(plb, &hbrSave); 00833 00834 // Get listbox's client 00835 _GetClientRect(plb->spwnd, &rect); 00836 00837 // Adjust width of client rect for scrolled amount 00838 // fix for #140, t-arthb 00839 if (plb->fRightAlign && !(plb->fMultiColumn || plb->OwnerDraw) && plb->fHorzBar) 00840 rect.right += plb->xOrigin + (plb->xRightOrigin - plb->xOrigin); 00841 else 00842 rect.right += plb->xOrigin; 00843 00844 // Get the index of the last item visible on the screen. This is also 00845 // valid for var height ownerdraw. 00846 iLastItem = plb->iTop + CItemInWindow(plb,TRUE); 00847 iLastItem = min(iLastItem, plb->cMac - 1); 00848 00849 // Fill in the background of the listbox if it's an empty listbox 00850 // or if we're doing a control print 00851 if (iLastItem == -1) 00852 FillRect(plb->hdc, &rect, hbrControl); 00853 00854 00855 // Allow AnimateWindow() catch the apps that do not use our DC when 00856 // drawing the list box 00857 SetBoundsRect(plb->hdc, NULL, DCB_RESET | DCB_ENABLE); 00858 00859 for (i = plb->iTop; i <= iLastItem; i++) { 00860 00861 /* 00862 * Note that rect contains the clientrect from when we did the 00863 * _GetClientRect so the width is correct. We just need to adjust 00864 * the top and bottom of the rectangle to the item of interest. 00865 */ 00866 rect.bottom = rect.top + plb->cyChar; 00867 00868 if ((UINT)i < (UINT)plb->cMac) { 00869 00870 /* 00871 * If var height, get the rectangle for the item. 00872 */ 00873 if (plb->OwnerDraw == OWNERDRAWVAR || plb->fMultiColumn) { 00874 LBGetItemRect(plb, i, &rect); 00875 } 00876 00877 if (IntersectRect(&scratchRect, lprcBounds, &rect)) { 00878 fHilite = !plb->fNoSel && IsSelected(plb, i, HILITEONLY); 00879 00880 if (plb->OwnerDraw) { 00881 00882 /* 00883 * Fill in the drawitem struct 00884 */ 00885 xxxLBoxDrawItem(plb, i, ODA_DRAWENTIRE, 00886 (UINT)(fHilite ? ODS_SELECTED : 0), &rect); 00887 } else { 00888 xxxLBDrawLBItem(plb, i, &rect, fHilite, hbrControl); 00889 } 00890 } 00891 } 00892 rect.top = rect.bottom; 00893 } 00894 00895 if (hbrSave != NULL) 00896 SelectObject(hdc, hbrSave); 00897 00898 if (fCaretOn) 00899 xxxLBSetCaret(plb, TRUE); 00900 00901 LBTermDC(plb); 00902 00903 plb->hdc = hdcSave; 00904 }

void xxxLBSelRange PLBIV  plb,
int  iStart,
int  iEnd,
BOOL  fnewstate
 

Definition at line 3206 of file lboxctl2.c.

References CheckLock, tagLBIV::cMac, DWORD, FALSE, FWINABLE, HILITEANDSEL, IsSelected(), LBEvent(), LBGetItemRect(), max, min, SELONLY, SetSelected(), tagLBIV::spwnd, tagLBIV::wMultiple, and xxxLBInvalidateRect().

03211 { 03212 DWORD temp; 03213 RECT rc; 03214 03215 CheckLock(plb->spwnd); 03216 03217 if (iStart > iEnd) { 03218 temp = iEnd; 03219 iEnd = iStart; 03220 iStart = temp; 03221 } 03222 03223 /* 03224 * We don't want to loop through items that don't exist. 03225 */ 03226 iEnd = min(plb->cMac, iEnd); 03227 iStart = max(iStart, 0); 03228 if (iStart > iEnd) 03229 return; 03230 03231 03232 /* 03233 * iEnd could be equal to MAXINT which is why we test temp and iEnd 03234 * as DWORDs. 03235 */ 03236 for (temp = iStart; temp <= (DWORD)iEnd; temp++) { 03237 03238 if (IsSelected(plb, temp, SELONLY) != fnewstate) { 03239 SetSelected(plb, temp, fnewstate, HILITEANDSEL); 03240 LBGetItemRect(plb, temp, &rc); 03241 03242 xxxLBInvalidateRect(plb, (LPRECT)&rc, FALSE); 03243 } 03244 03245 } 03246 UserAssert(plb->wMultiple); 03247 if (FWINABLE()) { 03248 LBEvent(plb, EVENT_OBJECT_SELECTIONWITHIN, iStart); 03249 } 03250 }

void xxxLBSetCaret PLBIV  plb,
BOOL  fSetCaret
 

Definition at line 430 of file lboxctl2.c.

References BOOL, DrawFocusRect(), tagLBIV::fCaret, tagLBIV::fCaretOn, tagLBIV::hdc, HILITEONLY, tagLBIV::iSelBase, IsLBoxVisible, IsSelected(), LBGetDC(), LBGetItemRect(), LBReleaseDC(), tagLBIV::OwnerDraw, tagLBIV::spwnd, SYSRGB, TestWF, UINT, WEFPUIFOCUSHIDDEN, WINDOW, and xxxLBoxDrawItem().

Referenced by ListBoxWndProcWorker(), xxxAlterHilite(), xxxCaretDestroy(), xxxInvertLBItem(), xxxLBoxCaretBlinker(), xxxLBoxCtlHScroll(), xxxLBoxCtlKeyInput(), xxxLBoxCtlScroll(), xxxLBPaint(), xxxLBSetCurSel(), xxxLBSetRedraw(), xxxLBSetSel(), xxxNewITopEx(), xxxResetWorld(), xxxSetISelBase(), and xxxTrackMouse().

00431 { 00432 RECT rc; 00433 BOOL fNewDC; 00434 00435 if (plb->fCaret && ((BOOL) plb->fCaretOn != !!fSetCaret)) { 00436 if (IsLBoxVisible(plb)) { 00437 /* Turn the caret (located at plb->iSelBase) on */ 00438 fNewDC = LBGetDC(plb); 00439 00440 LBGetItemRect(plb, plb->iSelBase, &rc); 00441 00442 if (fNewDC) { 00443 SetBkColor(plb->hdc, SYSRGB(WINDOW)); 00444 SetTextColor(plb->hdc, SYSRGB(WINDOWTEXT)); 00445 } 00446 00447 if (plb->OwnerDraw) { 00448 /* Fill in the drawitem struct */ 00449 UINT itemState = (fSetCaret) ? ODS_FOCUS : 0; 00450 00451 if (IsSelected(plb, plb->iSelBase, HILITEONLY)) 00452 itemState |= ODS_SELECTED; 00453 00454 xxxLBoxDrawItem(plb, plb->iSelBase, ODA_FOCUS, itemState, &rc); 00455 } else if (!TestWF(plb->spwnd, WEFPUIFOCUSHIDDEN)) { 00456 COLORREF crBk = SetBkColor(plb->hdc, SYSRGB(WINDOW)); 00457 COLORREF crText = SetTextColor(plb->hdc, SYSRGB(WINDOWTEXT)); 00458 00459 DrawFocusRect(plb->hdc, &rc); 00460 00461 SetBkColor(plb->hdc, crBk); 00462 SetTextColor(plb->hdc, crText); 00463 } 00464 00465 if (fNewDC) 00466 LBReleaseDC(plb); 00467 } 00468 plb->fCaretOn = !!fSetCaret; 00469 } 00470 }

int xxxLBSetCurSel PLBIV  plb,
int  iSel
 

Definition at line 3259 of file lboxctl2.c.

References _IsWindowVisible(), CheckLock, tagLBIV::cMac, FALSE, FWINABLE, tagLBIV::iSel, tagLBIV::iSelBase, LBEvent(), min, tagLBIV::spwnd, TRUE, tagLBIV::wMultiple, xxxInsureVisible(), xxxInvertLBItem(), and xxxLBSetCaret().

03262 { 03263 CheckLock(plb->spwnd); 03264 03265 if (!(plb->wMultiple || iSel < -1 || iSel >= plb->cMac)) { 03266 xxxLBSetCaret(plb, FALSE); 03267 if (plb->iSel != -1) { 03268 03269 /* 03270 * This prevents scrolling when iSel == -1 03271 */ 03272 if (iSel != -1) 03273 xxxInsureVisible(plb, iSel, FALSE); 03274 03275 /* 03276 * Turn off old selection 03277 */ 03278 xxxInvertLBItem(plb, plb->iSel, FALSE); 03279 } 03280 03281 if (iSel != -1) { 03282 xxxInsureVisible(plb, iSel, FALSE); 03283 plb->iSelBase = plb->iSel = iSel; 03284 03285 /* 03286 * Highlight new selection 03287 */ 03288 xxxInvertLBItem(plb, plb->iSel, TRUE); 03289 } else { 03290 plb->iSel = -1; 03291 if (plb->cMac) 03292 plb->iSelBase = min(plb->iSelBase, plb->cMac-1); 03293 else 03294 plb->iSelBase = 0; 03295 } 03296 03297 if (FWINABLE()) { 03298 /* 03299 * Send both focus and selection events 03300 */ 03301 if (_IsWindowVisible(plb->spwnd)) { 03302 LBEvent(plb, EVENT_OBJECT_FOCUS, plb->iSelBase); 03303 LBEvent(plb, EVENT_OBJECT_SELECTION, plb->iSel); 03304 } 03305 } 03306 03307 xxxLBSetCaret(plb, TRUE); 03308 return plb->iSel; 03309 } 03310 03311 return LB_ERR; 03312 }

void xxxLBSetRedraw PLBIV  plb,
BOOL  fRedraw
 

Definition at line 3172 of file lboxctl2.c.

References CheckLock, FALSE, tagLBIV::fDeferUpdate, tagLBIV::fRedraw, HWq, NULL, RedrawWindow, tagLBIV::spwnd, TRUE, UINT, xxxLBSetCaret(), and xxxLBShowHideScrollBars().

Referenced by ListBoxWndProcWorker(), and xxxLBSetCount().

03175 { 03176 CheckLock(plb->spwnd); 03177 03178 if (fRedraw) 03179 fRedraw = TRUE; 03180 03181 if (plb->fRedraw != (UINT)fRedraw) { 03182 plb->fRedraw = !!fRedraw; 03183 03184 if (fRedraw) { 03185 xxxLBSetCaret(plb, TRUE); 03186 xxxLBShowHideScrollBars(plb); 03187 03188 if (plb->fDeferUpdate) { 03189 plb->fDeferUpdate = FALSE; 03190 RedrawWindow(HWq(plb->spwnd), NULL, NULL, 03191 RDW_INVALIDATE | RDW_ERASE | 03192 RDW_FRAME | RDW_ALLCHILDREN); 03193 } 03194 } 03195 } 03196 }

LONG xxxLBSetSel PLBIV  plb,
BOOL  fSelect,
INT  iSel
 

Definition at line 3455 of file lboxctl2.c.

References _IsWindowVisible(), CheckLock, tagLBIV::cMac, FALSE, tagLBIV::fCaret, tagLBIV::fCaretOn, FWINABLE, HILITEANDSEL, tagLBIV::iLastMouseMove, tagLBIV::iMouseDown, INT, tagLBIV::iSel, tagLBIV::iSelBase, IsSelected(), LBEvent(), LBGetItemRect(), SELONLY, SetSelected(), SINGLESEL, tagLBIV::spwnd, TRUE, UINT, tagLBIV::wMultiple, xxxInsureVisible(), xxxLBInvalidateRect(), and xxxLBSetCaret().

Referenced by ListBoxWndProcWorker().

03459 { 03460 INT sItem; 03461 RECT rc; 03462 UINT uEvent = 0; 03463 03464 CheckLock(plb->spwnd); 03465 03466 /* 03467 * Bug 17656. WinZip's accelerator key for 'DeSelect All' sends a LB_SETSEL 03468 * message with lparam = 0x0000ffff instead of 0xffffffff(-1). If iSel 03469 * is equal to 0x0000ffff and there are less than 0xffff elements in the 03470 * list we set iSel equal to 0xffffffff. 03471 */ 03472 if ((iSel == (UINT)0xffff) && (iSel >= plb->cMac)) { 03473 iSel = -1; 03474 RIPMSG0(RIP_WARNING, "Sign extending iSel=0xffff to 0xffffffff"); 03475 } 03476 03477 03478 if ((plb->wMultiple == SINGLESEL) || (iSel != -1 && iSel >= plb->cMac)) { 03479 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, 03480 "xxxLBSetSel:Invalid iSel or SINGLESEL listbox"); 03481 return LB_ERR; 03482 } 03483 03484 xxxLBSetCaret(plb, FALSE); 03485 03486 if (iSel == -1/*(INT)0xffff*/) { 03487 03488 /* 03489 * Set/clear selection from all items if -1 03490 */ 03491 for (sItem = 0; sItem < plb->cMac; sItem++) { 03492 if (IsSelected(plb, sItem, SELONLY) != fSelect) { 03493 SetSelected(plb, sItem, fSelect, HILITEANDSEL); 03494 if (LBGetItemRect(plb, sItem, &rc)) { 03495 xxxLBInvalidateRect(plb, &rc, FALSE); 03496 } 03497 } 03498 } 03499 xxxLBSetCaret(plb, TRUE); 03500 uEvent = EVENT_OBJECT_SELECTIONWITHIN; 03501 } else { 03502 if (fSelect) { 03503 03504 /* 03505 * Check if the item if fully hidden and scroll it into view if it 03506 * is. Note that we don't want to scroll partially visible items 03507 * into full view because this breaks the shell... 03508 */ 03509 xxxInsureVisible(plb, iSel, TRUE); 03510 plb->iSelBase = plb->iSel = iSel; 03511 03512 plb->iMouseDown = plb->iLastMouseMove = iSel; 03513 uEvent = EVENT_OBJECT_FOCUS; 03514 } else { 03515 uEvent = EVENT_OBJECT_SELECTIONREMOVE; 03516 } 03517 SetSelected(plb, iSel, fSelect, HILITEANDSEL); 03518 03519 /* 03520 * Note that we set the caret on bit directly so that we avoid flicker 03521 * when drawing this item. ie. We turn on the caret, redraw the item and 03522 * turn it back on again. 03523 */ 03524 if (!fSelect && plb->iSelBase != iSel) { 03525 xxxLBSetCaret(plb, TRUE); 03526 } else if (plb->fCaret) { 03527 plb->fCaretOn = TRUE; 03528 } 03529 03530 if (LBGetItemRect(plb, iSel, &rc)) { 03531 xxxLBInvalidateRect(plb, &rc, FALSE); 03532 } 03533 } 03534 03535 if (FWINABLE() && _IsWindowVisible(plb->spwnd)) { 03536 if (uEvent == EVENT_OBJECT_FOCUS) { 03537 LBEvent(plb, uEvent, plb->iSelBase); 03538 uEvent = EVENT_OBJECT_SELECTION; 03539 } 03540 LBEvent(plb, uEvent, iSel); 03541 } 03542 03543 return 0; 03544 }

void xxxNewITop PLBIV  plb,
INT  iTopNew
 

Definition at line 2000 of file lboxctl2.c.

References xxxNewITopEx().

Referenced by LBCalcItemRowsAndColumns(), ListBoxWndProcWorker(), xxxInsureVisible(), xxxLBoxCtlHScrollMultiColumn(), xxxLBShowHideScrollBars(), and xxxLBSize().

02001 { 02002 xxxNewITopEx(plb, iTopNew, 0); 02003 }

void xxxNewITopEx PLBIV  plb,
INT  iTopNew,
DWORD  dwTime
 

Definition at line 2012 of file lboxctl2.c.

References _GetClientRect(), abs, BOOL, CheckLock, tagLBIV::cItemFullMax, tagLBIV::cxColumn, tagLBIV::cyChar, dwFlags, DWORD, FALSE, tagLBIV::fCaretOn, tagLBIV::fMultiColumn, tagLBIV::fRightAlign, HWq, IsLBoxVisible, tagLBIV::itemsPerColumn, tagLBIV::iTop, LBCalcVarITopScrollAmt(), LBGetScrollFlags(), NULL, tagLBIV::numberOfColumns, tagLBIV::OwnerDraw, OWNERDRAWVAR, ScrollWindowEx(), tagLBIV::spwnd, TRUE, UpdateWindow(), xxxLBSetCaret(), and xxxSetLBScrollParms().

Referenced by xxxLBoxCtlScroll(), and xxxNewITop().

02016 { 02017 int iTopOld; 02018 BOOL fCaretOn; 02019 BOOL fMulti = plb->fMultiColumn; 02020 02021 CheckLock(plb->spwnd); 02022 02023 // Always try to turn off caret whether or not redraw is on 02024 if (fCaretOn = plb->fCaretOn) 02025 xxxLBSetCaret(plb, FALSE); 02026 02027 iTopOld = (fMulti) ? (plb->iTop / plb->itemsPerColumn) : plb->iTop; 02028 plb->iTop = iTopNew; 02029 iTopNew = xxxSetLBScrollParms(plb, (fMulti) ? SB_HORZ : SB_VERT); 02030 plb->iTop = (fMulti) ? (iTopNew * plb->itemsPerColumn) : iTopNew; 02031 02032 if (!IsLBoxVisible(plb)) { 02033 return; 02034 } 02035 02036 if (iTopNew != iTopOld) { 02037 int xAmt, yAmt; 02038 RECT rc; 02039 DWORD dwFlags; 02040 02041 _GetClientRect(plb->spwnd, &rc); 02042 02043 if (fMulti) { 02044 yAmt = 0; 02045 if (abs(iTopNew - iTopOld) > plb->numberOfColumns) 02046 // Handle scrolling a large number of columns properly so that 02047 // we don't overflow the size of a rect. 02048 xAmt = 32000; 02049 else { 02050 xAmt = (iTopOld - iTopNew) * plb->cxColumn; 02051 if (plb->fRightAlign) 02052 xAmt = -xAmt; 02053 } 02054 } else { 02055 xAmt = 0; 02056 if (plb->OwnerDraw == OWNERDRAWVAR) { 02057 // 02058 // Have to fake iTopOld for OWNERDRAWVAR listboxes so that 02059 // the scrolling amount calculations work properly. 02060 // 02061 plb->iTop = iTopOld; 02062 yAmt = LBCalcVarITopScrollAmt(plb, iTopOld, iTopNew); 02063 plb->iTop = iTopNew; 02064 } else if (abs(iTopNew - iTopOld) > plb->cItemFullMax) 02065 yAmt = 32000; 02066 else 02067 yAmt = (iTopOld - iTopNew) * plb->cyChar; 02068 } 02069 02070 dwFlags = LBGetScrollFlags(plb, dwTime); 02071 ScrollWindowEx(HWq(plb->spwnd), xAmt, yAmt, NULL, &rc, NULL, 02072 NULL, dwFlags); 02073 UpdateWindow(HWq(plb->spwnd)); 02074 } 02075 02076 // Note that although we turn off the caret regardless of redraw, we 02077 // only turn it on if redraw is true. Slimy thing to fixup many 02078 // caret related bugs... 02079 if (fCaretOn) 02080 // Turn the caret back on only if we turned it off. This avoids 02081 // annoying caret flicker. 02082 xxxLBSetCaret(plb, TRUE); 02083 }

void xxxNotifyOwner PLBIV  plb,
INT  sEvt
 

Definition at line 1244 of file lboxctl2.c.

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

Referenced by ListBoxWndProcWorker(), xxxLBButtonUp(), xxxLbDir(), xxxLBInitStorage(), xxxLbInsertFile(), xxxLBInsertItem(), xxxLBoxCtlKeyInput(), and xxxLBSetCount().

01247 { 01248 TL tlpwndParent; 01249 01250 CheckLock(plb->spwnd); 01251 01252 ThreadLock(plb->spwndParent, &tlpwndParent); 01253 SendMessage(HW(plb->spwndParent), WM_COMMAND, 01254 MAKELONG(PTR_TO_ID(plb->spwnd->spmenu), sEvt), (LPARAM)HWq(plb->spwnd)); 01255 ThreadUnlock(&tlpwndParent); 01256 }

void xxxResetWorld PLBIV  plb,
INT  iStart,
INT  iEnd,
BOOL  fSelect
 

Definition at line 1181 of file lboxctl2.c.

References BOOL, CheckLock, CItemInWindow(), tagLBIV::cMac, FALSE, tagLBIV::fCaretOn, HILITEANDSEL, HILITEONLY, INT, tagLBIV::iSel, IsSelected(), tagLBIV::iTop, SetSelected(), SINGLESEL, tagLBIV::spwnd, TRUE, tagLBIV::wMultiple, xxxInvertLBItem(), and xxxLBSetCaret().

Referenced by xxxLBoxCtlKeyInput(), and xxxTrackMouse().

01186 { 01187 INT i; 01188 INT iLastInWindow; 01189 BOOL fCaretOn; 01190 01191 CheckLock(plb->spwnd); 01192 01193 /* 01194 * If iStart and iEnd are not in correct order we swap them 01195 */ 01196 01197 if (iStart > iEnd) { 01198 i = iStart; 01199 iStart = iEnd; 01200 iEnd = i; 01201 } 01202 01203 if (plb->wMultiple == SINGLESEL) { 01204 if (plb->iSel != -1 && ((plb->iSel < iStart) || (plb->iSel > iEnd))) { 01205 xxxInvertLBItem(plb, plb->iSel, fSelect); 01206 plb->iSel = -1; 01207 } 01208 return; 01209 } 01210 01211 iLastInWindow = plb->iTop + CItemInWindow(plb, TRUE); 01212 01213 if (fCaretOn = plb->fCaretOn) 01214 xxxLBSetCaret(plb, FALSE); 01215 01216 for (i = 0; i < plb->cMac; i++) { 01217 if (i == iStart) 01218 // skip range to be preserved 01219 i = iEnd; 01220 else { 01221 if ((plb->iTop <= i) && (i <= iLastInWindow) && 01222 (fSelect != IsSelected(plb, i, HILITEONLY))) 01223 // Only invert the item if it is visible and present Selection 01224 // state is different from what is required. 01225 xxxInvertLBItem(plb, i, fSelect); 01226 01227 // Set all items outside of preserved range to unselected 01228 SetSelected(plb, i, fSelect, HILITEANDSEL); 01229 } 01230 } 01231 01232 if (fCaretOn) 01233 xxxLBSetCaret(plb, TRUE); 01234 01235 }

void xxxSetISelBase PLBIV  plb,
INT  sItem
 

Definition at line 1265 of file lboxctl2.c.

References _IsWindowVisible(), CheckLock, FALSE, FWINABLE, tagLBIV::iSelBase, LBEvent(), tagLBIV::spwnd, TRUE, xxxInsureVisible(), and xxxLBSetCaret().

Referenced by ListBoxWndProcWorker(), xxxLBoxCtlKeyInput(), and xxxTrackMouse().

01268 { 01269 CheckLock(plb->spwnd); 01270 01271 xxxLBSetCaret(plb, FALSE); 01272 plb->iSelBase = sItem; 01273 xxxLBSetCaret(plb, TRUE); 01274 01275 if (FWINABLE()) { 01276 xxxInsureVisible(plb, plb->iSelBase, FALSE); 01277 if (_IsWindowVisible(plb->spwnd)) { 01278 LBEvent(plb, EVENT_OBJECT_FOCUS, sItem); 01279 } 01280 } 01281 }

void xxxTrackMouse PLBIV  plb,
UINT  wMsg,
POINT  pt
 

Definition at line 1290 of file lboxctl2.c.

References _ClientToScreen(), _GetClientRect(), BOOL, CheckLock, tagLBIV::cMac, CTLDOWN, DWORD, EXTENDEDSEL, tagLBIV::fAddSelMode, FALSE, tagLBIV::fCaptured, tagLBIV::fCaret, tagLBIV::fDoubleClick, FindNCHit(), tagLBIV::fMouseDown, tagLBIV::fMultiColumn, tagLBIV::fNewItemState, tagLBIV::fRightAlign, FWINABLE, GetKeyState(), gpsi, HILITE, HILITEANDSEL, HILITEONLY, HW, HWq, IDSYS_CARET, IDSYS_SCROLL, tagLBIV::iLastMouseMove, tagLBIV::iLastSelection, tagLBIV::iMouseDown, INT, tagLBIV::iSel, tagLBIV::iSelBase, ISelFromPt(), IsSelected(), LBEvent(), LBUP_NOTIFY, LBUP_RELEASECAPTURE, LBUP_RESETSELECTION, LBUP_SUCCESS, max, MULTIPLESEL, NOMODIFIER, NtUserCallNoParam(), NtUserDragDetect(), NtUserKillTimer(), NtUserReleaseCapture, NtUserSetCapture(), NtUserSetFocus(), NtUserSetTimer(), NULL, tagLBIV::pcbox, PtInRect(), tagLBIV::ptPrev, tagWND::rcClient, tagWND::rcWindow, SendMessage(), SendMessageWorker(), SetSelected(), SHCTLDOWN, SHIFTDOWN, SINGLESEL, tagLBIV::spwnd, tagCBox::spwndEdit, tagLBIV::spwndParent, TestWF, ThreadLock, ThreadUnlock, TRUE, UINT, WEFDRAGOBJECT, tagLBIV::wMultiple, tagLBIV::xOrigin, xxxAlterHilite(), xxxCBHideListBoxWindow(), xxxInvertLBItem(), xxxLBBlockHilite(), xxxLBButtonUp(), xxxLBoxCtlHScrollMultiColumn(), xxxLBoxCtlScroll(), xxxLBSetCaret(), xxxResetWorld(), and xxxSetISelBase().

Referenced by ListBoxWndProcWorker().

01294 { 01295 INT iSelFromPt; 01296 INT iSelTemp; 01297 BOOL mousetemp; 01298 BOOL fMouseInRect; 01299 RECT rcClient; 01300 UINT wModifiers = 0; 01301 BOOL fSelected; 01302 UINT uEvent = 0; 01303 INT trackPtRetn; 01304 HWND hwnd = HWq(plb->spwnd); 01305 TL tlpwndEdit; 01306 TL tlpwndParent; 01307 01308 CheckLock(plb->spwnd); 01309 01310 /* 01311 * Optimization: do nothing if mouse not captured 01312 */ 01313 if ((wMsg != WM_LBUTTONDOWN) && (wMsg != WM_LBUTTONDBLCLK)) { 01314 if (!plb->fCaptured) { 01315 return; 01316 } 01317 /* 01318 * If we are processing a WM_MOUSEMOVE but the mouse has not moved from 01319 * the previous point, then we may be dealing with a mouse "jiggle" sent 01320 * from the kernel (see zzzInvalidateDCCache). If we process this, we will 01321 * snap the listbox selection back to where the mouse cursor is pointing, 01322 * even if the user has not touched the mouse. FritzS: NT5 bug 220722. 01323 * Some apps (like MSMoney98) rely on this, so added the bLastRITWasKeyboard 01324 * check. MCostea #244450 01325 */ 01326 if ((wMsg == WM_MOUSEMOVE) && RtlEqualMemory(&pt, &(plb->ptPrev), sizeof(POINT)) 01327 && gpsi->bLastRITWasKeyboard) { 01328 RIPMSG0(RIP_WARNING, "xxxTrackMouse ignoring WM_MOUSEMOVE with no mouse movement"); 01329 return; 01330 } 01331 } 01332 01333 mousetemp = ISelFromPt(plb, pt, &iSelFromPt); 01334 01335 /* 01336 * If we allow the user to cancel his selection then fMouseInRect is true if 01337 * the mouse is in the listbox client area otherwise it is false. If we 01338 * don't allow the user to cancel his selection, then fMouseInRect will 01339 * always be true. This allows us to implement cancelable selection 01340 * listboxes ie. The selection reverts to the origional one if the user 01341 * releases the mouse outside of the listbox. 01342 */ 01343 fMouseInRect = !mousetemp || !plb->pcbox; 01344 01345 _GetClientRect(plb->spwnd, &rcClient); 01346 01347 switch (wMsg) { 01348 case WM_LBUTTONDBLCLK: 01349 case WM_LBUTTONDOWN: 01350 /* 01351 * We want to divert mouse clicks. If the user clicks outside 01352 * of a dropped down listbox, we want to popup it up, using 01353 * the current selection. 01354 */ 01355 if (plb->fCaptured) { 01356 /* 01357 * If plb->pcbox is NULL, this is a listbox that 01358 * received a WM_LBUTTONDOWN again w/o receiving 01359 * a WM_LBUTTONUP for the previous WM_LBUTTONDOWN 01360 * bug 01361 */ 01362 if (plb->pcbox && mousetemp) { 01363 _ClientToScreen(plb->spwnd, &pt); 01364 01365 if (!PtInRect(&plb->spwnd->rcWindow, pt)) { 01366 /* 01367 * Cancel selection if clicked outside of combo; 01368 * Accept if clicked on combo button or item. 01369 */ 01370 xxxCBHideListBoxWindow(plb->pcbox, TRUE, FALSE); 01371 } else if (!PtInRect(&plb->spwnd->rcClient, pt)) { 01372 /* 01373 * Let it pass through. Save, restore capture in 01374 * case user is clicking on scrollbar. 01375 */ 01376 plb->fCaptured = FALSE; 01377 NtUserReleaseCapture(); 01378 01379 SendMessageWorker(plb->spwnd, WM_NCLBUTTONDOWN, 01380 FindNCHit(plb->spwnd, POINTTOPOINTS(pt)), 01381 MAKELONG(pt.x, pt.y), FALSE); 01382 01383 NtUserSetCapture(hwnd); 01384 plb->fCaptured = TRUE; 01385 } 01386 01387 break; 01388 } 01389 01390 plb->fCaptured = FALSE; 01391 NtUserReleaseCapture(); 01392 } 01393 01394 if (plb->pcbox) { 01395 01396 /* 01397 * If this listbox is in a combo box, set the focus to the combo 01398 * box window so that the edit control/static text is also 01399 * activated 01400 */ 01401 ThreadLock(plb->pcbox->spwndEdit, &tlpwndEdit); 01402 NtUserSetFocus(HWq(plb->pcbox->spwndEdit)); 01403 ThreadUnlock(&tlpwndEdit); 01404 } else { 01405 01406 /* 01407 * Get the focus if the listbox is clicked in and we don't 01408 * already have the focus. If we don't have the focus after 01409 * this, run away... 01410 */ 01411 NtUserSetFocus(hwnd); 01412 if (!plb->fCaret) 01413 return; 01414 } 01415 01416 if (plb->fAddSelMode) { 01417 01418 /* 01419 * If it is in "Add" mode, quit it using shift f8 key... 01420 * However, since we can't send shift key state, we have to turn 01421 * this off directly... 01422 */ 01423 01424 /* 01425 *SendMessage(HW(plb->spwnd),WM_KEYDOWN, (UINT)VK_F8, 0L); 01426 */ 01427 01428 /* 01429 * Switch off the Caret blinking 01430 */ 01431 NtUserKillTimer(hwnd, IDSYS_CARET); 01432 01433 /* 01434 * Make sure the caret does not vanish 01435 */ 01436 xxxLBSetCaret(plb, TRUE); 01437 plb->fAddSelMode = FALSE; 01438 } 01439 01440 if (!plb->cMac) { 01441 01442 /* 01443 * Don't even bother handling the mouse if no items in the 01444 * listbox since the code below assumes >0 items in the 01445 * listbox. We will just get the focus (the statement above) if 01446 * we don't already have it. 01447 */ 01448 break; 01449 } 01450 01451 if (mousetemp) { 01452 01453 /* 01454 * Mouse down occurred in a empty spot. Just ignore it. 01455 */ 01456 break; 01457 } 01458 01459 plb->fDoubleClick = (wMsg == WM_LBUTTONDBLCLK); 01460 01461 if (!plb->fDoubleClick) { 01462 01463 /* 01464 * This hack put in for the shell. Tell the shell where in the 01465 * listbox the user clicked and at what item number. The shell 01466 * can return 0 to continue normal mouse tracking or TRUE to 01467 * abort mouse tracking. 01468 */ 01469 ThreadLock(plb->spwndParent, &tlpwndParent); 01470 trackPtRetn = (INT)SendMessage(HW(plb->spwndParent), WM_LBTRACKPOINT, 01471 (DWORD)iSelFromPt, MAKELONG(pt.x+plb->xOrigin, pt.y)); 01472 ThreadUnlock(&tlpwndParent); 01473 if (trackPtRetn) { 01474 if (trackPtRetn == 2) { 01475 01476 /* 01477 * Ignore double clicks 01478 */ 01479 NtUserCallNoParam(SFI__RESETDBLCLK); 01480 } 01481 return; 01482 } 01483 } 01484 01485 if (plb->pcbox) { 01486 01487 /* 01488 * Save the last selection if this is a combo box. So that it 01489 * can be restored if user decides to cancel the selection by up 01490 * clicking outside the listbox. 01491 */ 01492 plb->iLastSelection = plb->iSel; 01493 } 01494 01495 /* 01496 * Save for timer 01497 */ 01498 plb->ptPrev = pt; 01499 01500 plb->fMouseDown = TRUE; 01501 NtUserSetCapture(hwnd); 01502 plb->fCaptured = TRUE; 01503 01504 if (plb->fDoubleClick) { 01505 01506 /* 01507 * Double click. Fake a button up and exit 01508 */ 01509 xxxTrackMouse(plb, WM_LBUTTONUP, pt); 01510 return; 01511 } 01512 01513 /* 01514 * Set the system timer so that we can autoscroll if the mouse is 01515 * outside the bounds of the listbox rectangle 01516 */ 01517 NtUserSetTimer(hwnd, IDSYS_SCROLL, gpsi->dtScroll, NULL); 01518 01519 01520 01521 /* 01522 * If extended multiselection listbox, are any modifier key pressed? 01523 */ 01524 if (plb->wMultiple == EXTENDEDSEL) { 01525 if (GetKeyState(VK_SHIFT) < 0) 01526 wModifiers = SHIFTDOWN; 01527 if (GetKeyState(VK_CONTROL) < 0) 01528 wModifiers += CTLDOWN; 01529 01530 /* 01531 * Please Note that (SHIFTDOWN + CTLDOWN) == (SHCTLDOWN) 01532 */ 01533 } 01534 01535 01536 switch (wModifiers) { 01537 case NOMODIFIER: 01538 MouseMoveHandler: 01539 if (plb->iSelBase != iSelFromPt) { 01540 xxxLBSetCaret(plb, FALSE); 01541 } 01542 01543 /* 01544 * We only look at the mouse if the point it is pointing to is 01545 * not selected. Since we are not in ExtendedSelMode, anywhere 01546 * the mouse points, we have to set the selection to that item. 01547 * Hence, if the item isn't selected, it means the mouse never 01548 * pointed to it before so we can select it. We ignore already 01549 * selected items so that we avoid flashing the inverted 01550 * selection rectangle. Also, we could get WM_SYSTIMER simulated 01551 * mouse moves which would cause flashing otherwise... 01552 */ 01553 01554 iSelTemp = (fMouseInRect ? iSelFromPt : -1); 01555 01556 /* 01557 * If the LB is either SingleSel or Extended multisel, clear all 01558 * old selections except the new one being made. 01559 */ 01560 if (plb->wMultiple != MULTIPLESEL) { 01561 xxxResetWorld(plb, iSelTemp, iSelTemp, FALSE); 01562 /* 01563 * This will be TRUE if iSelTemp isn't -1 (like below) 01564 * and also if it is but there is a current selection. 01565 */ 01566 if ((iSelTemp == -1) && (plb->iSel != -1)) { 01567 uEvent = EVENT_OBJECT_SELECTIONREMOVE; 01568 } 01569 } 01570 01571 fSelected = IsSelected(plb, iSelTemp, HILITEONLY); 01572 if (iSelTemp != -1) { 01573 01574 /* 01575 * If it is MULTIPLESEL, then toggle; For others, only if 01576 * not selected already, select it. 01577 */ 01578 if (((plb->wMultiple == MULTIPLESEL) && (wMsg != WM_LBUTTONDBLCLK)) || !fSelected) { 01579 SetSelected(plb, iSelTemp, !fSelected, HILITEANDSEL); 01580 01581 /* 01582 * And invert it 01583 */ 01584 xxxInvertLBItem(plb, iSelTemp, !fSelected); 01585 fSelected = !fSelected; /* Set the new state */ 01586 if (plb->wMultiple == MULTIPLESEL) { 01587 uEvent = (fSelected ? EVENT_OBJECT_SELECTIONADD : 01588 EVENT_OBJECT_SELECTIONREMOVE); 01589 } else { 01590 uEvent = EVENT_OBJECT_SELECTION; 01591 } 01592 } 01593 } 01594 01595 /* 01596 * We have to set iSel in case this is a multisel lb. 01597 */ 01598 plb->iSel = iSelTemp; 01599 01600 /* 01601 * Set the new anchor point 01602 */ 01603 plb->iMouseDown = iSelFromPt; 01604 plb->iLastMouseMove = iSelFromPt; 01605 plb->fNewItemState = fSelected; 01606 01607 break; 01608 case SHIFTDOWN: 01609 01610 /* 01611 * This is so that we can handle click and drag for multisel 01612 * listboxes using Shift modifier key . 01613 */ 01614 plb->iLastMouseMove = plb->iSel = iSelFromPt; 01615 01616 01617 01618 /* 01619 * Check if an anchor point already exists 01620 */ 01621 if (plb->iMouseDown == -1) { 01622 plb->iMouseDown = iSelFromPt; 01623 01624 /* 01625 * Reset all the previous selections 01626 */ 01627 xxxResetWorld(plb, plb->iMouseDown, plb->iMouseDown, FALSE); 01628 01629 /* 01630 * Select the current position 01631 */ 01632 SetSelected(plb, plb->iMouseDown, TRUE, HILITEANDSEL); 01633 xxxInvertLBItem(plb, plb->iMouseDown, TRUE); 01634 /* 01635 * We are changing the selction to this item only 01636 */ 01637 uEvent = EVENT_OBJECT_SELECTION; 01638 } else { 01639 01640 /* 01641 * Reset all the previous selections 01642 */ 01643 xxxResetWorld(plb, plb->iMouseDown, plb->iMouseDown, FALSE); 01644 01645 /* 01646 * Select all items from anchor point upto current click pt 01647 */ 01648 xxxAlterHilite(plb, plb->iMouseDown, iSelFromPt, HILITE, HILITEONLY, FALSE); 01649 uEvent = EVENT_OBJECT_SELECTIONWITHIN; 01650 } 01651 plb->fNewItemState = (UINT)TRUE; 01652 break; 01653 01654 case CTLDOWN: 01655 01656 /* 01657 * This is so that we can handle click and drag for multisel 01658 * listboxes using Control modifier key. 01659 */ 01660 01661 /* 01662 * Reset the anchor point to the current point 01663 */ 01664 plb->iMouseDown = plb->iLastMouseMove = plb->iSel = iSelFromPt; 01665 01666 /* 01667 * The state we will be setting items to 01668 */ 01669 plb->fNewItemState = (UINT)!IsSelected(plb, iSelFromPt, (UINT)HILITEONLY); 01670 01671 /* 01672 * Toggle the current point 01673 */ 01674 SetSelected(plb, iSelFromPt, plb->fNewItemState, HILITEANDSEL); 01675 xxxInvertLBItem(plb, iSelFromPt, plb->fNewItemState); 01676 uEvent = (plb->fNewItemState ? EVENT_OBJECT_SELECTIONADD : 01677 EVENT_OBJECT_SELECTIONREMOVE); 01678 break; 01679 01680 case SHCTLDOWN: 01681 01682 /* 01683 * This is so that we can handle click and drag for multisel 01684 * listboxes using Shift and Control modifier keys. 01685 */ 01686 01687 /* 01688 * Preserve all the previous selections 01689 */ 01690 01691 /* 01692 * Deselect only the selection connected with the last 01693 * anchor point; If the last anchor point is associated with a 01694 * de-selection, then do not do it 01695 */ 01696 if (plb->fNewItemState) { 01697 xxxAlterHilite(plb, plb->iMouseDown, plb->iLastMouseMove, FALSE, HILITEANDSEL, FALSE); 01698 } 01699 plb->iLastMouseMove = plb->iSel = iSelFromPt; 01700 01701 /* 01702 * Check if an anchor point already exists 01703 */ 01704 if (plb->iMouseDown == -1) { 01705 01706 /* 01707 * No existing anchor point; Make the current pt as anchor 01708 */ 01709 plb->iMouseDown = iSelFromPt; 01710 } 01711 01712 /* 01713 * If one exists preserve the most recent anchor point 01714 */ 01715 01716 /* 01717 * The state we will be setting items to 01718 */ 01719 plb->fNewItemState = (UINT)IsSelected(plb, plb->iMouseDown, HILITEONLY); 01720 01721 /* 01722 * Select all items from anchor point upto current click pt 01723 */ 01724 xxxAlterHilite(plb, plb->iMouseDown, iSelFromPt, plb->fNewItemState, HILITEONLY, FALSE); 01725 uEvent = EVENT_OBJECT_SELECTIONWITHIN; 01726 break; 01727 } 01728 01729 /* 01730 * Set the new base point (the outline frame caret). We do the check 01731 * first to avoid flashing the caret unnecessarly. 01732 */ 01733 if (plb->iSelBase != iSelFromPt) { 01734 01735 /* 01736 * Since xxxSetISelBase always turns on the caret, we don't need to 01737 * do it here... 01738 */ 01739 xxxSetISelBase(plb, iSelFromPt); 01740 } 01741 01742 /* 01743 * SetISelBase will change the focus and send a focus event. 01744 * Then we send the selection event. 01745 */ 01746 if (FWINABLE() && uEvent) { 01747 LBEvent(plb, uEvent, iSelFromPt); 01748 } 01749 if (wMsg == WM_LBUTTONDOWN && TestWF(plb->spwnd, WEFDRAGOBJECT)) { 01750 if (NtUserDragDetect(hwnd, pt)) { 01751 01752 /* 01753 * User is trying to drag object... 01754 */ 01755 01756 /* 01757 * Fake an up click so that the item is selected... 01758 */ 01759 xxxTrackMouse(plb, WM_LBUTTONUP, pt); 01760 01761 /* 01762 * Notify parent 01763 * #ifndef WIN16 (32-bit Windows), plb->iSelBase gets 01764 * zero-extended to LONG wParam automatically by the compiler. 01765 */ 01766 ThreadLock(plb->spwndParent, &tlpwndParent); 01767 SendMessage(HW(plb->spwndParent), WM_BEGINDRAG, plb->iSelBase, 01768 (LPARAM)hwnd); 01769 ThreadUnlock(&tlpwndParent); 01770 } else { 01771 xxxTrackMouse(plb, WM_LBUTTONUP, pt); 01772 } 01773 return; 01774 } 01775 break; 01776 01777 case WM_MOUSEMOVE: { 01778 int dist; 01779 int iTimer; 01780 01781 /* 01782 * Save for timer. 01783 */ 01784 plb->ptPrev = pt; 01785 /* 01786 * Autoscroll listbox if mouse button is held down and mouse is 01787 * moved outside of the listbox 01788 */ 01789 if (plb->fMouseDown) { 01790 if (plb->fMultiColumn) { 01791 if ((pt.x < 0) || (pt.x >= rcClient.right - 1)) { 01792 /* 01793 * Reset timer interval based on distance from listbox. 01794 * use a longer default interval because each multicolumn 01795 * scrolling increment is larger 01796 */ 01797 dist = pt.x < 0 ? -pt.x : (pt.x - rcClient.right + 1); 01798 iTimer = ((gpsi->dtScroll * 3) / 2) - ((WORD) dist << 4); 01799 01800 if (plb->fRightAlign) 01801 xxxLBoxCtlHScrollMultiColumn(plb, (pt.x < 0 ? SB_LINEDOWN : SB_LINEUP), 0); 01802 else 01803 xxxLBoxCtlHScrollMultiColumn(plb, (pt.x < 0 ? SB_LINEUP : SB_LINEDOWN), 0); 01804 01805 goto SetTimerAndSel; 01806 } 01807 } else if ((pt.y < 0) || (pt.y >= rcClient.bottom - 1)) { 01808 /* 01809 * Reset timer interval based on distance from listbox. 01810 */ 01811 dist = pt.y < 0 ? -pt.y : (pt.y - rcClient.bottom + 1); 01812 iTimer = gpsi->dtScroll - ((WORD) dist << 4); 01813 01814 xxxLBoxCtlScroll(plb, (pt.y < 0 ? SB_LINEUP : SB_LINEDOWN), 0); 01815 SetTimerAndSel: 01816 NtUserSetTimer(hwnd, IDSYS_SCROLL, max(iTimer, 1), NULL); 01817 ISelFromPt(plb, pt, &iSelFromPt); 01818 } 01819 } else { 01820 /* 01821 * Ignore if not in client since we don't autoscroll 01822 */ 01823 if (!PtInRect(&rcClient, pt)) 01824 break; 01825 } 01826 01827 switch (plb->wMultiple) { 01828 case SINGLESEL: 01829 01830 /* 01831 * If it is a single selection or plain multisel list box 01832 */ 01833 goto MouseMoveHandler; 01834 break; 01835 01836 case MULTIPLESEL: 01837 case EXTENDEDSEL: 01838 01839 /* 01840 * Handle mouse movement with extended selection of items 01841 */ 01842 if (plb->iSelBase != iSelFromPt) { 01843 xxxSetISelBase(plb, iSelFromPt); 01844 01845 /* 01846 * If this is an extended Multi sel list box, then 01847 * adjust the display of the range due to the mouse move 01848 */ 01849 if (plb->wMultiple == EXTENDEDSEL) { 01850 xxxLBBlockHilite(plb, iSelFromPt, FALSE); 01851 if (FWINABLE()) 01852 LBEvent(plb, EVENT_OBJECT_SELECTIONWITHIN, iSelFromPt); 01853 } 01854 plb->iLastMouseMove = iSelFromPt; 01855 } 01856 break; 01857 } 01858 break; 01859 } 01860 case WM_LBUTTONUP: 01861 if (plb->fMouseDown) 01862 xxxLBButtonUp(plb, LBUP_RELEASECAPTURE | LBUP_NOTIFY | 01863 (mousetemp ? LBUP_RESETSELECTION : 0) | 01864 (fMouseInRect ? LBUP_SUCCESS : 0)); 01865 } 01866 }


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