test: lb1.c Source File

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

# lb1.c

Go to the documentation of this file.

    00001 /****************************** Module Header ********************************\
    00002 * Module Name: lb1.c
    00003 *
    00004 * Copyright (c) 1985 - 1999, Microsoft Corporation
    00005 *
    00006 * ListBox routines
    00007 *
    00008 * History:
    00009 * ??-???-???? ianja    Ported from Win 3.0 sources
    00010 * 14-Feb-1991 mikeke   Added Revalidation code
    00011 \*****************************************************************************/
    00012
    00013 #include "precomp.h"
    00014 #pragma hdrstop
    00015
    00016 LOOKASIDE ListboxLookaside;
    00017
    00018
    00019 /***************************************************************************\
    00020 * xxxLBoxCtlWndProc
    00021 *
    00022 * Window Procedure for ListBox AND ComboLBox control.
    00023 * NOTE: All window procedures are APIENTRY
    00024 * WARNING: This listbox code contains some internal messages and styles which
    00025 * are defined in combcom.h and in combcom.inc.  They may be redefined
    00026 * (or renumbered) as needed to extend the windows API.
    00027 *
    00028 * History:
    00029 * 16-Apr-1992 beng      Added LB_SETCOUNT
    00030 \***************************************************************************/
    00031
    00032 LRESULT APIENTRY ListBoxWndProcWorker(
    00033     PWND pwnd,
    00034     UINT message,
    00035     WPARAM wParam,
    00036     LPARAM lParam,
    00037     DWORD fAnsi)
    00038 {
    00039     HWND hwnd = HWq(pwnd);
    00040     PAINTSTRUCT ps;
    00041     HDC         hdc;
    00042     LPRECT      lprc;
    00043     PLBIV plb;    /* List Box Instance Variable */
    00044     INT iSel;     /* Index of selected item */
    00045     DWORD dw;
    00046     TL tlpwndParent;
    00047     UINT wFlags;
    00048     LPWSTR lpwsz = NULL;
    00049     LRESULT lReturn = 0;
    00050     static BOOL fInit = TRUE;
    00051
    00052     CheckLock(pwnd);
    00053
    00054     VALIDATECLASSANDSIZE(pwnd, FNID_LISTBOX);
    00055     INITCONTROLLOOKASIDE(&ListboxLookaside, LBIV, spwnd, 4);
    00056
    00057     /*
    00058      * Get the plb for the given window now since we will use it a lot in
    00059      * various handlers. This was stored using SetWindowLong(hwnd,0,plb)
    00060      * when the listbox was first created (by INITCONTROLLOOKASIDE above)
    00061      */
    00062     plb = ((PLBWND)pwnd)->pLBIV;
    00063
    00064     /*
    00065      * Handle ANSI translations of input parameters
    00066      */
    00067     if (fAnsi) {
    00068         switch (message) {
    00069         case LB_ADDSTRING:
    00070         case LB_ADDSTRINGUPPER:
    00071         case LB_ADDSTRINGLOWER:
    00072         case LB_FINDSTRING:
    00073         case LB_FINDSTRINGEXACT:
    00074         case LB_INSERTSTRING:
    00075         case LB_INSERTSTRINGUPPER:
    00076         case LB_INSERTSTRINGLOWER:
    00077         case LB_SELECTSTRING:
    00078             if (!plb->fHasStrings) {
    00079                 break;
    00080             }
    00081             // Fall through...
    00082         case LB_ADDFILE:
    00083         case LB_DIR:
    00084             if (lParam) {
    00085                 if (!MBToWCS((LPSTR)lParam, -1, &lpwsz, -1, TRUE))
    00086                     return LB_ERR;
    00087             }
    00088             break;
    00089         default:
    00090             break;
    00091         }
    00092         if (lpwsz) {
    00093             lParam = (LPARAM)lpwsz;
    00094         }
    00095     }
    00096
    00097     switch (message) {
    00098
    00099     case LB_GETTOPINDEX:        // Return index of top item displayed.
    00100         return plb->iTop;
    00101
    00102     case LB_SETTOPINDEX:
    00103         if (wParam && ((INT)wParam < 0 || (INT)wParam >= plb->cMac)) {
    00104             RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, "");
    00105             return LB_ERR;
    00106         }
    00107         if (plb->cMac) {
    00108             xxxNewITop(plb, (INT)wParam);
    00109         }
    00110         break;
    00111
    00112     case WM_STYLECHANGED:
    00113         plb->fRtoLReading = (TestWF(pwnd, WEFRTLREADING) != 0);
    00114         plb->fRightAlign  = (TestWF(pwnd, WEFRIGHT) != 0);
    00115         xxxCheckRedraw(plb, FALSE, 0);
    00116         break;
    00117
    00118     case WM_WINDOWPOSCHANGED:
    00119
    00120         /*
    00121          * If we are in the middle of creation, ignore this
    00122          * message because it will generate a WM_SIZE message.
    00123          * See xxxLBCreate().
    00124          */
    00125         if (!plb->fIgnoreSizeMsg)
    00126             goto CallDWP;
    00127         break;
    00128
    00129     case WM_SIZE:
    00130
    00131         /*
    00132          * If we are in the middle of creation, ignore size
    00133          * messages.  See xxxLBCreate().
    00134          */
    00135         if (!plb->fIgnoreSizeMsg)
    00136             xxxLBSize(plb, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
    00137         break;
    00138
    00139     case WM_ERASEBKGND:
    00140         ThreadLock(plb->spwndParent, &tlpwndParent);
    00141         FillWindow(HW(plb->spwndParent), hwnd, (HDC)wParam,
    00142                 (HBRUSH)CTLCOLOR_LISTBOX);
    00143         ThreadUnlock(&tlpwndParent);
    00144         return TRUE;
    00145
    00146     case LB_RESETCONTENT:
    00147         xxxLBResetContent(plb);
    00148         break;
    00149
    00150     case WM_TIMER:
    00151         if (wParam == IDSYS_LBSEARCH) {
    00152             plb->iTypeSearch = 0;
    00153             NtUserKillTimer(hwnd, IDSYS_LBSEARCH);
    00154             xxxInvertLBItem(plb, plb->iSel, TRUE);
    00155             break;
    00156         }
    00157
    00158         message = WM_MOUSEMOVE;
    00159         xxxTrackMouse(plb, message, plb->ptPrev);
    00160         break;
    00161
    00162         /*
    00163          * Fall through
    00164          */
    00165     case WM_MOUSEMOVE:
    00166     case WM_LBUTTONDOWN:
    00167     case WM_LBUTTONUP:
    00168     case WM_LBUTTONDBLCLK:
    00169         {
    00170             POINT pt;
    00171
    00172             POINTSTOPOINT(pt, lParam);
    00173             xxxTrackMouse(plb, message, pt);
    00174         }
    00175         break;
    00176
    00177     case WM_MBUTTONDOWN:
    00178         EnterReaderModeHelper(hwnd);
    00179         break;
    00180
    00181     case WM_CAPTURECHANGED:
    00182             //
    00183             // Note that this message should be handled only on unexpected
    00184             // capture changes currently.
    00185             //
    00186         UserAssert(TestWF(pwnd, WFWIN40COMPAT));
    00187         if (plb->fCaptured)
    00188             xxxLBButtonUp(plb, LBUP_NOTIFY);
    00189         break;
    00190
    00191     case LBCB_STARTTRACK:
    00192         //
    00193         // Start tracking mouse moves in the listbox, setting capture
    00194         //
    00195         if (!plb->pcbox)
    00196             break;
    00197
    00198         plb->fCaptured = FALSE;
    00199         if (wParam) {
    00200             POINT pt;
    00201
    00202             POINTSTOPOINT(pt, lParam);
    00203
    00204             _ScreenToClient(pwnd, &pt);
    00205             xxxTrackMouse(plb, WM_LBUTTONDOWN, pt);
    00206         } else {
    00207             NtUserSetCapture(hwnd);
    00208             plb->fCaptured = TRUE;
    00209             plb->iLastSelection = plb->iSel;
    00210         }
    00211         break;
    00212
    00213     case LBCB_ENDTRACK:
    00214         // Kill capture, tracking, etc.
    00215         if (plb->fCaptured)
    00216             xxxLBButtonUp(plb, LBUP_RELEASECAPTURE | (wParam ? LBUP_SELCHANGE :
    00217                 LBUP_RESETSELECTION));
    00218         break;
    00219
    00220     case WM_PRINTCLIENT:
    00221         xxxLBPaint(plb, (HDC) wParam, NULL);
    00222         break;
    00223
    00224     case WM_PAINT:
    00225         if (wParam) {
    00226             hdc = (HDC) wParam;
    00227             lprc = NULL;
    00228         } else {
    00229             hdc = NtUserBeginPaint(hwnd, &ps);
    00230             lprc = &(ps.rcPaint);
    00231         }
    00232
    00233         if (IsLBoxVisible(plb))
    00234             xxxLBPaint(plb, hdc, lprc);
    00235
    00236         if (!wParam)
    00237             NtUserEndPaint(hwnd, &ps);
    00238         break;
    00239
    00240     case WM_NCDESTROY:
    00241     case WM_FINALDESTROY:
    00242         xxxDestroyLBox(plb, pwnd);
    00243         break;
    00244
    00245     case WM_SETFOCUS:
    00246 // DISABLED in Win 3.1        xxxUpdateWindow(pwnd);
    00247         CaretCreate(plb);
    00248         xxxLBSetCaret(plb, TRUE);
    00249         xxxNotifyOwner(plb, LBN_SETFOCUS);
    00250         if (FWINABLE()) {
    00251             if (_IsWindowVisible(pwnd)) {
    00252                 LBEvent(plb, EVENT_OBJECT_FOCUS, plb->iSelBase);
    00253             }
    00254         }
    00255         break;
    00256
    00257     case WM_KILLFOCUS:
    00258         /*
    00259          * Reset the wheel delta count.
    00260          */
    00261         gcWheelDelta = 0;
    00262
    00263         xxxLBSetCaret(plb, FALSE);
    00264         xxxCaretDestroy(plb);
    00265         xxxNotifyOwner(plb, LBN_KILLFOCUS);
    00266         if (plb->iTypeSearch) {
    00267             plb->iTypeSearch = 0;
    00268             NtUserKillTimer(hwnd, IDSYS_LBSEARCH);
    00269         }
    00270         if (plb->pszTypeSearch) {
    00271             UserLocalFree(plb->pszTypeSearch);
    00272             plb->pszTypeSearch = NULL;
    00273         }
    00274         break;
    00275
    00276     case WM_MOUSEWHEEL:
    00277         {
    00278             int     cDetants;
    00279             int     cPage;
    00280             int     cLines;
    00281             RECT    rc;
    00282             int     windowWidth;
    00283             int     cPos;
    00284
    00285             /*
    00286              * Don't handle zoom and datazoom.
    00287              */
    00288             if (wParam & (MK_SHIFT | MK_CONTROL)) {
    00289                 goto CallDWP;
    00290             }
    00291
    00292             lReturn = 1;
    00293             gcWheelDelta -= (short) HIWORD(wParam);
    00294             cDetants = gcWheelDelta / WHEEL_DELTA;
    00295             if (    cDetants != 0 &&
    00296                     gpsi->ucWheelScrollLines > 0 &&
    00297                     (pwnd->style & (WS_VSCROLL | WS_HSCROLL))) {
    00298
    00299                 gcWheelDelta = gcWheelDelta % WHEEL_DELTA;
    00300
    00301                 if (pwnd->style & WS_VSCROLL) {
    00302                     cPage = max(1, (plb->cItemFullMax - 1));
    00303                     cLines = cDetants *
    00304                             (int) min((UINT) cPage, gpsi->ucWheelScrollLines);
    00305
    00306                     cPos = max(0, min(plb->iTop + cLines, plb->cMac - 1));
    00307                     if (cPos != plb->iTop) {
    00308                         xxxLBoxCtlScroll(plb, SB_THUMBPOSITION, cPos);
    00309                         xxxLBoxCtlScroll(plb, SB_ENDSCROLL, 0);
    00310                     }
    00311                 } else if (plb->fMultiColumn) {
    00312                     cPage = max(1, plb->numberOfColumns);
    00313                     cLines = cDetants * (int) min((UINT) cPage, gpsi->ucWheelScrollLines);
    00314                     cPos = max(
    00315                             0,
    00316                             min((plb->iTop / plb->itemsPerColumn) + cLines,
    00317                                 plb->cMac - 1 - ((plb->cMac - 1) % plb->itemsPerColumn)));
    00318
    00319                     if (cPos != plb->iTop) {
    00320                         xxxLBoxCtlHScrollMultiColumn(plb, SB_THUMBPOSITION, cPos);
    00321                         xxxLBoxCtlHScrollMultiColumn(plb, SB_ENDSCROLL, 0);
    00322                     }
    00323                 } else {
    00324                     _GetClientRect(plb->spwnd, &rc);
    00325                     windowWidth = rc.right;
    00326                     cPage = max(plb->cxChar, (windowWidth / 3) * 2) /
    00327                             plb->cxChar;
    00328
    00329                     cLines = cDetants *
    00330                             (int) min((UINT) cPage, gpsi->ucWheelScrollLines);
    00331
    00332                     cPos = max(
    00333                             0,
    00334                             min(plb->xOrigin + (cLines * plb->cxChar),
    00335                                 plb->maxWidth));
    00336
    00337                     if (cPos != plb->xOrigin) {
    00338                         xxxLBoxCtlHScroll(plb, SB_THUMBPOSITION, cPos);
    00339                         xxxLBoxCtlHScroll(plb, SB_ENDSCROLL, 0);
    00340                     }
    00341                 }
    00342             }
    00343         }
    00344         break;
    00345
    00346     case WM_VSCROLL:
    00347         xxxLBoxCtlScroll(plb, LOWORD(wParam), HIWORD(wParam));
    00348         break;
    00349
    00350     case WM_HSCROLL:
    00351         xxxLBoxCtlHScroll(plb, LOWORD(wParam), HIWORD(wParam));
    00352         break;
    00353
    00354     case WM_GETDLGCODE:
    00355         return DLGC_WANTARROWS | DLGC_WANTCHARS;
    00356
    00357     case WM_CREATE:
    00358         return xxxLBCreate(plb, pwnd, (LPCREATESTRUCT) lParam);
    00359
    00360     case WM_SETREDRAW:
    00361
    00362         /*
    00363          * If wParam is nonzero, the redraw flag is set
    00364          * If wParam is zero, the flag is cleared
    00365          */
    00366         xxxLBSetRedraw(plb, (wParam != 0));
    00367         break;
    00368
    00369     case WM_ENABLE:
    00370         xxxLBInvalidateRect(plb, NULL, !plb->OwnerDraw);
    00371         break;
    00372
    00373     case WM_SETFONT:
    00374         xxxLBSetFont(plb, (HANDLE)wParam, LOWORD(lParam));
    00375         break;
    00376
    00377     case WM_GETFONT:
    00378         return (LRESULT)plb->hFont;
    00379
    00380     case WM_DRAGSELECT:
    00381     case WM_DRAGLOOP:
    00382     case WM_DRAGMOVE:
    00383     case WM_DROPFILES:
    00384         ThreadLock(plb->spwndParent, &tlpwndParent);
    00385         lReturn = SendMessage(HW(plb->spwndParent), message, wParam, lParam);
    00386         ThreadUnlock(&tlpwndParent);
    00387         return lReturn;
    00388
    00389
    00390     case WM_QUERYDROPOBJECT:
    00391     case WM_DROPOBJECT:
    00392
    00393         /*
    00394          * fix up control data, then pass message to parent
    00395          */
    00396         LBDropObjectHandler(plb, (PDROPSTRUCT)lParam);
    00397         ThreadLock(plb->spwndParent, &tlpwndParent);
    00398         lReturn = SendMessage(HW(plb->spwndParent), message, wParam, lParam);
    00399         ThreadUnlock(&tlpwndParent);
    00400         return lReturn;
    00401
    00402     case LB_GETITEMRECT:
    00403         return LBGetItemRect(plb, (INT)wParam, (LPRECT)lParam);
    00404
    00405     case LB_GETITEMDATA:
    00406         return LBGetItemData(plb, (INT)wParam);  // wParam = item index
    00407
    00408     case LB_SETITEMDATA:
    00409
    00410         /*
    00411          * wParam is item index
    00412          */
    00413         return LBSetItemData(plb, (INT)wParam, lParam);
    00414
    00415     case LB_ADDSTRINGUPPER:
    00416         wFlags = UPPERCASE | LBI_ADD;
    00417         goto CallInsertItem;
    00418
    00419     case LB_ADDSTRINGLOWER:
    00420         wFlags = LOWERCASE | LBI_ADD;
    00421         goto CallInsertItem;
    00422
    00423     case LB_ADDSTRING:
    00424         wFlags = LBI_ADD;
    00425         goto CallInsertItem;
    00426
    00427     case LB_INSERTSTRINGUPPER:
    00428         wFlags = UPPERCASE;
    00429         goto CallInsertItem;
    00430
    00431     case LB_INSERTSTRINGLOWER:
    00432         wFlags = LOWERCASE;
    00433         goto CallInsertItem;
    00434
    00435     case LB_INSERTSTRING:
    00436         wFlags = 0;
    00437 CallInsertItem:
    00438         lReturn = ((LRESULT) xxxLBInsertItem(plb, (LPWSTR) lParam, (int) wParam, wFlags));
    00439         break;
    00440
    00441     case LB_INITSTORAGE:
    00442         return xxxLBInitStorage(plb, fAnsi, (INT)wParam, (INT)lParam);
    00443
    00444     case LB_DELETESTRING:
    00445         return xxxLBoxCtlDelete(plb, (INT)wParam);
    00446
    00447     case LB_DIR:
    00448         /*
    00449          * wParam - Dos attribute value.
    00450          * lParam - Points to a file specification string
    00451          */
    00452         lReturn = xxxLbDir(plb, (INT)wParam, (LPWSTR)lParam);
    00453         break;
    00454
    00455     case LB_ADDFILE:
    00456         lReturn = xxxLbInsertFile(plb, (LPWSTR)lParam);
    00457         break;
    00458
    00459     case LB_SETSEL:
    00460         return xxxLBSetSel(plb, (wParam != 0), (INT)lParam);
    00461
    00462     case LB_SETCURSEL:
    00463         /*
    00464          * If window obscured, update so invert will work correctly
    00465          */
    00466 // DISABLED in Win 3.1        xxxUpdateWindow(pwnd);
    00467         return xxxLBSetCurSel(plb, (INT)wParam);
    00468
    00469     case LB_GETSEL:
    00470         if (wParam >= (UINT) plb->cMac)
    00471                 return((LRESULT) LB_ERR);
    00472
    00473         return IsSelected(plb, (INT)wParam, SELONLY);
    00474
    00475     case LB_GETCURSEL:
    00476         if (plb->wMultiple == SINGLESEL) {
    00477             return plb->iSel;
    00478         }
    00479         return plb->iSelBase;
    00480
    00481     case LB_SELITEMRANGE:
    00482         if (plb->wMultiple == SINGLESEL) {
    00483             /*
    00484              * Can't select a range if only single selections are enabled
    00485              */
    00486             RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SELITEMRANGE");
    00487             return LB_ERR;
    00488         }
    00489
    00490         xxxLBSelRange(plb, LOWORD(lParam), HIWORD(lParam), (wParam != 0));
    00491         break;
    00492
    00493     case LB_SELITEMRANGEEX:
    00494         if (plb->wMultiple == SINGLESEL) {
    00495             /*
    00496              * Can't select a range if only single selections are enabled
    00497              */
    00498             RIPERR0(ERROR_INVALID_LB_MESSAGE, RIP_VERBOSE,"LB_SELITEMRANGEEX:Can't select a range if only single selections are enabled");
    00499             return LB_ERR;
    00500         } else {
    00501             BOOL fHighlight = ((DWORD)lParam > (DWORD)wParam);
    00502             if (fHighlight == FALSE) {
    00503                 ULONG_PTR temp = lParam;
    00504                 lParam = wParam;
    00505                 wParam = temp;
    00506             }
    00507             xxxLBSelRange(plb, (INT)wParam, (INT)lParam, fHighlight);
    00508         }
    00509         break;
    00510
    00511     case LB_GETTEXTLEN:
    00512         if (lParam != 0) {
    00513             RIPMSG1(RIP_WARNING, "LB_GETTEXTLEN with lParam = %lx\n", lParam);
    00514         }
    00515         lReturn = LBGetText(plb, TRUE, fAnsi, (INT)wParam, NULL);
    00516         break;
    00517
    00518     case LB_GETTEXT:
    00519         lReturn = LBGetText(plb, FALSE, fAnsi, (INT)wParam, (LPWSTR)lParam);
    00520         break;
    00521
    00522     case LB_GETCOUNT:
    00523         // Lotus Approach calls CallWndProc(ListWndProc, LB_GETCOUNT,...)
    00524         // on a window that doesn't have a plb yet. So, we need to make
    00525         // this check. Bug #6675 - 11/7/94 --
    00526         if(plb)
    00527             return((LRESULT) plb->cMac);
    00528         else
    00529             return(0);
    00530
    00531     case LB_SETCOUNT:
    00532         return xxxLBSetCount(plb, (INT)wParam);
    00533
    00534     case LB_SELECTSTRING:
    00535     case LB_FINDSTRING:
    00536         iSel = xxxFindString(plb, (LPWSTR)lParam, (INT)wParam, PREFIX, TRUE);
    00537         if (message == LB_FINDSTRING || iSel == LB_ERR) {
    00538             lReturn = iSel;
    00539         } else {
    00540             lReturn = xxxLBSetCurSel(plb, iSel);
    00541         }
    00542         break;
    00543
    00544     case LB_GETLOCALE:
    00545         return plb->dwLocaleId;
    00546
    00547     case LB_SETLOCALE:
    00548
    00549         /*
    00550          * Validate locale
    00551          */
    00552         wParam = ConvertDefaultLocale((LCID)wParam);
    00553         if (!IsValidLocale((LCID)wParam, LCID_INSTALLED))
    00554             return LB_ERR;
    00555
    00556         dw = plb->dwLocaleId;
    00557         plb->dwLocaleId = (DWORD)wParam;
    00558         return dw;
    00559
    00560     case WM_KEYDOWN:
    00561
    00562         /*
    00563          * IanJa: Use LOWORD() to get low 16-bits of wParam - this should
    00564          * work for Win16 & Win32.  The value obtained is the virtual key
    00565          */
    00566         xxxLBoxCtlKeyInput(plb, message, LOWORD(wParam));
    00567         break;
    00568
    00569     case WM_CHAR:
    00570         xxxLBoxCtlCharInput(plb, LOWORD(wParam), fAnsi);
    00571         break;
    00572
    00573     case LB_GETSELITEMS:
    00574     case LB_GETSELCOUNT:
    00575
    00576         /*
    00577          * IanJa/Win32 should this be LPWORD now?
    00578          */
    00579         return LBoxGetSelItems(plb, (message == LB_GETSELCOUNT), (INT)wParam,
    00580                 (LPINT)lParam);
    00581
    00582     case LB_SETTABSTOPS:
    00583
    00584         /*
    00585          * IanJa/Win32: Tabs given by array of INT for backwards compatability
    00586          */
    00587         return LBSetTabStops(plb, (INT)wParam, (LPINT)lParam);
    00588
    00589     case LB_GETHORIZONTALEXTENT:
    00590
    00591         /*
    00592          * Return the max width of the listbox used for horizontal scrolling
    00593          */
    00594         return plb->maxWidth;
    00595
    00596     case LB_SETHORIZONTALEXTENT:
    00597
    00598         /*
    00599          * Set the max width of the listbox used for horizontal scrolling
    00600          */
    00601         if (plb->maxWidth != (INT)wParam) {
    00602             plb->maxWidth = (INT)wParam;
    00603
    00604             /*
    00605              * When horizontal extent is set, Show/hide the scroll bars.
    00606              * NOTE: LBShowHideScrollBars() takes care if Redraw is OFF.
    00607              * Fix for Bug #2477 -- 01/14/91 -- SANKAR --
    00608              */
    00609             xxxLBShowHideScrollBars(plb); //Try to show or hide scroll bars
    00610             if (plb->fHorzBar && plb->fRightAlign && !(plb->fMultiColumn || plb->OwnerDraw)) {
    00611                 /*
    00612                  * origin to right
    00613                  */
    00614                 xxxLBoxCtlHScroll(plb, SB_BOTTOM, 0);
    00615             }
    00616         }
    00617         break;    /* originally returned register ax (message) ! */
    00618
    00619     case LB_SETCOLUMNWIDTH:
    00620
    00621         /*
    00622          * Set the width of a column in a multicolumn listbox
    00623          */
    00624         plb->cxColumn = (INT)wParam;
    00625         LBCalcItemRowsAndColumns(plb);
    00626         if (IsLBoxVisible(plb))
    00627             NtUserInvalidateRect(hwnd, NULL, TRUE);
    00628         xxxLBShowHideScrollBars(plb);
    00629         break;
    00630
    00631     case LB_SETANCHORINDEX:
    00632         if ((INT)wParam >= plb->cMac) {
    00633             RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SETANCHORINDEX");
    00634             return LB_ERR;
    00635         }
    00636         plb->iMouseDown = (INT)wParam;
    00637         plb->iLastMouseMove = (INT)wParam;
    00638         xxxInsureVisible(plb, (int) wParam, (BOOL)(lParam != 0));
    00639         break;
    00640
    00641     case LB_GETANCHORINDEX:
    00642         return plb->iMouseDown;
    00643
    00644     case LB_SETCARETINDEX:
    00645         if ( (plb->iSel == -1) || ((plb->wMultiple != SINGLESEL) &&
    00646                     (plb->cMac > (INT)wParam))) {
    00647
    00648             /*
    00649              * Set's the iSelBase to the wParam
    00650              * if lParam, then don't scroll if partially visible
    00651              * else scroll into view if not fully visible
    00652              */
    00653             xxxInsureVisible(plb, (INT)wParam, (BOOL)LOWORD(lParam));
    00654             xxxSetISelBase(plb, (INT)wParam);
    00655             break;
    00656         } else {
    00657             if ((INT)wParam >= plb->cMac) {
    00658                 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SETCARETINDEX");
    00659             }
    00660             return LB_ERR;
    00661         }
    00662         break;
    00663
    00664     case LB_GETCARETINDEX:
    00665         return plb->iSelBase;
    00666
    00667     case LB_SETITEMHEIGHT:
    00668     case LB_GETITEMHEIGHT:
    00669         return LBGetSetItemHeightHandler(plb, message, (INT)wParam, LOWORD(lParam));
    00670         break;
    00671
    00672     case LB_FINDSTRINGEXACT:
    00673         lReturn = xxxFindString(plb, (LPWSTR)lParam, (INT)wParam, EQ, TRUE);
    00674         break;
    00675
    00676     case LB_ITEMFROMPOINT: {
    00677         POINT pt;
    00678         BOOL bOutside;
    00679         DWORD dwItem;
    00680
    00681         POINTSTOPOINT(pt, lParam);
    00682         bOutside = ISelFromPt(plb, pt, &dwItem);
    00683         UserAssert(bOutside == 1 || bOutside == 0);
    00684         return (LRESULT)MAKELONG(dwItem, bOutside);
    00685     }
    00686
    00687     case LBCB_CARETON:
    00688
    00689         /*
    00690          * Internal message for combo box support
    00691          */
    00692         CaretCreate(plb);
    00693         // Set up the caret in the proper location for drop downs.
    00694         plb->iSelBase = plb->iSel;
    00695         xxxLBSetCaret(plb, TRUE);
    00696         if (FWINABLE()) {
    00697             if (_IsWindowVisible(pwnd)) {
    00698                 LBEvent(plb, EVENT_OBJECT_FOCUS, plb->iSelBase);
    00699             }
    00700         }
    00701         return(plb->iSel);
    00702
    00703     case LBCB_CARETOFF:
    00704
    00705         /*
    00706          * Internal message for combo box support
    00707          */
    00708         xxxLBSetCaret(plb, FALSE);
    00709         xxxCaretDestroy(plb);
    00710         break;
    00711
    00712     case WM_NCCREATE:
    00713         if ((pwnd->style & LBS_MULTICOLUMN) && (pwnd->style & WS_VSCROLL))
    00714         {
    00715             DWORD mask = WS_VSCROLL;
    00716             DWORD flags = 0;
    00717             if (!TestWF(pwnd, WFWIN40COMPAT)) {
    00718                 mask |= WS_HSCROLL;
    00719                 flags = WS_HSCROLL;
    00720             }
    00721             NtUserAlterWindowStyle(hwnd, mask, flags);
    00722         }
    00723         goto CallDWP;
    00724
    00725      default:
    00726 CallDWP:
    00727         return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi);
    00728     }
    00729
    00730     /*
    00731      * Handle translation of ANSI output data and free buffer
    00732      */
    00733     if (lpwsz) {
    00734         UserLocalFree(lpwsz);
    00735     }
    00736
    00737     return lReturn;
    00738 }
    00739
    00740
    00741 /***************************************************************************\
    00742 \***************************************************************************/
    00743
    00744 LRESULT WINAPI ListBoxWndProcA(
    00745     HWND hwnd,
    00746     UINT message,
    00747     WPARAM wParam,
    00748     LPARAM lParam)
    00749 {
    00750     PWND pwnd;
    00751
    00752     if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
    00753         return (0L);
    00754     }
    00755
    00756     /*
    00757      * If the control is not interested in this message,
    00758      * pass it to DefWindowProc.
    00759      */
    00760     if (!FWINDOWMSG(message, FNID_LISTBOX))
    00761         return DefWindowProcWorker(pwnd, message, wParam, lParam, TRUE);
    00762
    00763     return ListBoxWndProcWorker(pwnd, message, wParam, lParam, TRUE);
    00764 }
    00765
    00766 LRESULT WINAPI ListBoxWndProcW(
    00767     HWND hwnd,
    00768     UINT message,
    00769     WPARAM wParam,
    00770     LPARAM lParam)
    00771 {
    00772     PWND pwnd;
    00773
    00774     if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
    00775         return (0L);
    00776     }
    00777
    00778     /*
    00779      * If the control is not interested in this message,
    00780      * pass it to DefWindowProc.
    00781      */
    00782     if (!FWINDOWMSG(message, FNID_LISTBOX))
    00783         return DefWindowProcWorker(pwnd, message, wParam, lParam, FALSE);
    00784
    00785     return ListBoxWndProcWorker(pwnd, message, wParam, lParam, FALSE);
    00786 }
    00787
    00788 LRESULT WINAPI ComboListBoxWndProcA(
    00789     HWND hwnd,
    00790     UINT message,
    00791     WPARAM wParam,
    00792     LPARAM lParam)
    00793 {
    00794     PWND pwnd;
    00795
    00796     if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
    00797         return (0L);
    00798     }
    00799
    00800     /*
    00801      * If the control is not interested in this message,
    00802      * pass it to DefWindowProc.
    00803      */
    00804     if (!FWINDOWMSG(message, FNID_LISTBOX))
    00805         return DefWindowProcWorker(pwnd, message, wParam, lParam, TRUE);
    00806
    00807     return ListBoxWndProcWorker(pwnd, message, wParam, lParam, TRUE);
    00808 }
    00809
    00810 LRESULT WINAPI ComboListBoxWndProcW(
    00811     HWND hwnd,
    00812     UINT message,
    00813     WPARAM wParam,
    00814     LPARAM lParam)
    00815 {
    00816     PWND pwnd;
    00817
    00818     if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
    00819         return (0L);
    00820     }
    00821
    00822     /*
    00823      * If the control is not interested in this message,
    00824      * pass it to DefWindowProc.
    00825      */
    00826     if (!FWINDOWMSG(message, FNID_LISTBOX))
    00827         return DefWindowProcWorker(pwnd, message, wParam, lParam, FALSE);
    00828
    00829     return ListBoxWndProcWorker(pwnd, message, wParam, lParam, FALSE);
    00830 }
    00831
    00832
    00833 /***************************************************************************\
    00834 * GetLpszItem
    00835 *
    00836 * Returns a far pointer to the string belonging to item sItem
    00837 * ONLY for Listboxes maintaining their own strings (pLBIV->fHasStrings == TRUE)
    00838 *
    00839 * History:
    00840 \***************************************************************************/
    00841
    00842 LPWSTR GetLpszItem(
    00843     PLBIV pLBIV,
    00844     INT sItem)
    00845 {
    00846     LONG offsz;
    00847     lpLBItem plbi;
    00848
    00849     if (sItem < 0 || sItem >= pLBIV->cMac) {
    00850         RIPERR1(ERROR_INVALID_PARAMETER,
    00851                 RIP_WARNING,
    00852                 "Invalid parameter \"sItem\" (%ld) to GetLpszItem",
    00853                 sItem);
    00854
    00855         return NULL;
    00856     }
    00857
    00858     /*
    00859      * get pointer to item index array
    00860      * NOTE: NOT OWNERDRAW
    00861      */
    00862     plbi = (lpLBItem)(pLBIV->rgpch);
    00863     offsz = plbi[sItem].offsz;
    00864     return (LPWSTR)((PBYTE)(pLBIV->hStrings) + offsz);
    00865 }