Ejemplo n.º 1
0
int DlgDirListComboBoxA(
    HWND hwndDlg,
    LPSTR lpszPathSpecClient,
    int idComboBox,
    int idStaticPath,
    UINT attrib)
{
    LPWSTR lpszPathSpec;
    TL tlpwndDlg;
    PWND pwndDlg;
    BOOL fRet;

    pwndDlg = ValidateHwnd(hwndDlg);

    if (pwndDlg == NULL)
        return FALSE;

    lpszPathSpec = NULL;
    if (lpszPathSpecClient) {
        if (!MBToWCS(lpszPathSpecClient, -1, &lpszPathSpec, -1, TRUE))
            return FALSE;
    }

    ThreadLock(pwndDlg, &tlpwndDlg);
    fRet = xxxDlgDirListHelper(pwndDlg, lpszPathSpec, lpszPathSpecClient,
            idComboBox, idStaticPath, attrib, FALSE);
    ThreadUnlock(&tlpwndDlg);

    if (lpszPathSpec) {
        if (fRet) {
            /*
             * Non-zero retval means some text to copy out.  Copy out up to
             * the nul terminator (buffer will be big enough).
             */
            WCSToMB(lpszPathSpec, -1, &lpszPathSpecClient, MAXLONG, FALSE);
        }
        UserLocalFree(lpszPathSpec);
    }

    return fRet;
}
Ejemplo n.º 2
0
int DlgDirSelectComboBoxExA(
    HWND hwndDlg,
    LPSTR pszOut,
    int cchOut,
    int idComboBox)
{
    LPWSTR lpwsz;
    BOOL fRet;

    lpwsz = (LPWSTR)UserLocalAlloc(HEAP_ZERO_MEMORY, cchOut * sizeof(WCHAR));
    if (!lpwsz) {
        return FALSE;
    }

    fRet = DlgDirSelectComboBoxExW(hwndDlg, lpwsz, cchOut, idComboBox);

    WCSToMB(lpwsz, -1, &pszOut, cchOut, FALSE);

    UserLocalFree(lpwsz);

    return fRet;
}
Ejemplo n.º 3
0
int SmartStretchDIBits(
    HDC          hdc,
    int          xD,
    int          yD,
    int          dxD,
    int          dyD,
    int          xS,
    int          yS,
    int          dxS,
    int          dyS,
    LPVOID       lpBits,
    LPBITMAPINFO lpbi,
    UINT         wUsage,
    DWORD        rop)
{
    LPBYTE             lpBitsNew;
    UINT               bpp;
    RGBQUAD            rgb;
    LPBITMAPINFOHEADER lpbiNew = NULL;

    int i;

    /*
     * thunk to USER32
     */
    UserAssert(rop == SRCCOPY);
    UserAssert(wUsage == DIB_RGB_COLORS);
    UserAssert(xS == 0 && yS == 0);

    if ((GetDIBColorTable(hdc, 0, 1, &rgb) != 1) &&
        (dxD != dxS || dyD != dyS) &&           // 1:1 stretch just call GDI
        (dxD >= dxS/2) && (dyD >= dyS/2) &&     // less than 1:2 shrink call GDI
        (lpbi->bmiHeader.biCompression == 0) && // must be un-compressed
        (lpbi->bmiHeader.biBitCount == 4 ||     // input must be 4,8,24
         lpbi->bmiHeader.biBitCount == 8 ||
         lpbi->bmiHeader.biBitCount == 24)) {

        bpp = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);

        bpp = (bpp > 8 ? 24 : 8);

        lpbiNew = (LPBITMAPINFOHEADER)UserLocalAlloc(0,
                 sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD)) +
                 (UINT)((((dxD * bpp) / 8) + 3) & ~3) * (UINT)dyD);

        if (lpbiNew) {

            *lpbiNew            = lpbi->bmiHeader;
            lpbiNew->biWidth    = dxD;
            lpbiNew->biHeight   = dyD;
            lpbiNew->biBitCount = bpp;
            lpBitsNew = (LPBYTE)lpbiNew          +
                        sizeof(BITMAPINFOHEADER) +
                        (256 * sizeof(RGBQUAD));

            if (ScaleDIB((LPBITMAPINFOHEADER)lpbi,
                         (LPVOID)lpBits,
                         lpbiNew,
                         lpBitsNew)) {

                lpbi   = (LPBITMAPINFO)lpbiNew;
                lpBits = lpBitsNew;
                dxS    = dxD;
                dyS    = dyD;
            }
        }
    }

    i = StretchDIBits(hdc,
                      xD,
                      yD,
                      dxD,
                      dyD,
                      xS,
                      yS,
                      dxS,
                      dyS,
                      lpBits,
                      lpbi,
                      wUsage,
                      rop);

    if (lpbiNew)
        UserLocalFree(lpbiNew);

    return i;
}
Ejemplo n.º 4
0
int DrawTextExA(
    HDC hdc,
    LPSTR lpchText,
    int cchText,
    LPRECT lprc,
    UINT format,
    LPDRAWTEXTPARAMS lpdtp)
{
    LPWSTR lpwstr;
    int iRet;
    int iUniString;
    WORD wCodePage = (WORD)GdiGetCodePage(hdc);

    if (cchText == -1) {
        // USER_AWCONV_COUNTSTRINGSZ does not count/convert trailing \0.
        cchText = USER_AWCONV_COUNTSTRINGSZ;
    } else if (cchText < -1) {
        return 0;
    }

    if ((iUniString = MBToWCSEx(wCodePage, lpchText, cchText, &lpwstr, -1, TRUE)) == 0) {
        if (cchText == USER_AWCONV_COUNTSTRINGSZ) {
            lpwstr = (LPWSTR)gwszNullStr;
            format &= ~DT_MODIFYSTRING;
        } else {
            return 0;
        }
    }

    /*
     * Grow the buffer to accomodate the ellipsis (see AddEllipsisAndDrawLine)
     */
    if (format & DT_MODIFYSTRING) {
        int iNewLen = (iUniString + CCHELLIPSIS + 1) * sizeof(*lpwstr);
        LPWSTR lpwstrNew = UserLocalReAlloc(lpwstr, iNewLen, HEAP_ZERO_MEMORY);
        if (lpwstrNew == NULL) {
            UserLocalFree((HANDLE)lpwstr);
            return FALSE;
        }
        lpwstr = lpwstrNew;
    }

    iRet = DrawTextExWorker(hdc, lpwstr, iUniString, lprc, format, lpdtp, GetTextCharset(hdc));

    if (format & DT_MODIFYSTRING) {
        /*
         * Note that if the buffer grew and the caller provided the string size,
         *  then we won't return the additional characters... fixing this
         *  might break some apps so let's leave it alone until some one complains
         */
        if (cchText < 0) {
            UserAssert(cchText == USER_AWCONV_COUNTSTRINGSZ);
            // Guess how many bytes we can put in the buffer...
            // We can safely assume the maximum bytes available.
            // At worst, even for DBCS, the buffer size required
            // will be smaller than or equal to the orignal size,
            // because some DBCS characters would be substituted
            // to SBC ".", which is one byte each.
            // On the other hand, the number of characters converted
            // is limited by both iUniString and cchText.
            //
            if (IS_DBCS_ENABLED()) {
                cchText = iUniString * DBCS_CHARSIZE;
            } else {
                cchText = iUniString * sizeof(CHAR);
            }
        }
        WCSToMBEx(wCodePage, lpwstr, iUniString, &lpchText, cchText, FALSE);
    }

    if (lpwstr != gwszNullStr) {
        UserLocalFree((HANDLE)lpwstr);
    }

    return iRet;
}
Ejemplo n.º 5
0
/***************************************************************************\
* _ClientEventCallback
*
* Description:
* Called from the server side to perform event callbacks.
*
* History:
* 11-12-91 sanfords Created.
\***************************************************************************/
DWORD _ClientEventCallback(
PCL_INSTANCE_INFO pcii,
PEVENT_PACKET pep)
{
    HDDEDATA hData;

    EnterDDECrit;

    switch (pep->EventType) {
    case 0: // MonitorFlags change event - everybody gets it
        pcii->MonitorFlags = pep->Data;
        break;

    case MF_CALLBACKS:
        {
            MONCBSTRUCT mcb;

            mcb = *((MONCBSTRUCT *)&pep->Data);
            mcb.hsz1 = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)mcb.hsz1));
            mcb.hsz2 = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)mcb.hsz2));
            if (    mcb.wType == XTYP_REGISTER ||
                    mcb.wType == XTYP_UNREGISTER) {
                mcb.hsz2 = INST_SPECIFIC_HSZ_FROM_LATOM((LATOM)mcb.hsz2);
            }
            hData = InternalCreateDataHandle(pcii, (LPSTR)&mcb,
                    pep->cbEventData, 0,
                    HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0);
            if (hData) {
                DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0L,
                        pep->EventType);
                InternalFreeDataHandle((HDDEDATA)hData, TRUE);
                DeleteAtom(LATOM_FROM_HSZ(mcb.hsz1));
                DeleteAtom(LATOM_FROM_HSZ(mcb.hsz2));
            }
        }
        break;

    case MF_LINKS:
        {
            MONLINKSTRUCT ml;

            ml = *((MONLINKSTRUCT *)&pep->Data);
            ml.hszSvc = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)ml.hszSvc));
            ml.hszTopic = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)ml.hszTopic));
            ml.hszItem = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)ml.hszItem));
            hData = InternalCreateDataHandle(pcii, (LPSTR)&ml,
                    pep->cbEventData, 0,
                    HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0);
            if (hData) {
                DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0L,
                        pep->EventType);
                InternalFreeDataHandle((HDDEDATA)hData, TRUE);
                DeleteAtom(LATOM_FROM_HSZ(ml.hszSvc));
                DeleteAtom(LATOM_FROM_HSZ(ml.hszTopic));
                DeleteAtom(LATOM_FROM_HSZ(ml.hszItem));
            }
        }
        break;

    case MF_CONV:
        {
            MONCONVSTRUCT mc;

            mc = *((MONCONVSTRUCT *)&pep->Data);
            mc.hszSvc = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)mc.hszSvc));
            mc.hszTopic = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)mc.hszTopic));
            hData = InternalCreateDataHandle(pcii, (LPSTR)&mc,
                    pep->cbEventData, 0,
                    HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0);
            if (hData) {
                DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0L,
                        pep->EventType);
                InternalFreeDataHandle((HDDEDATA)hData, TRUE);
                DeleteAtom(LATOM_FROM_HSZ(mc.hszSvc));
                DeleteAtom(LATOM_FROM_HSZ(mc.hszTopic));
            }
        }
        break;

    case MF_HSZ_INFO:
        if (!(pcii->flags & IIF_UNICODE)) {
            LPSTR pszAnsi;
            /*
             * Translate HSZ string back into ANSI
             */
            if (WCSToMB(((PMONHSZSTRUCT)&pep->Data)->str,
                    ((int)pep->cbEventData - (int)((PMONHSZSTRUCT)&pep->Data)->cb) / sizeof(WCHAR),
                    &pszAnsi,
                    (int)pep->cbEventData - (int)((PMONHSZSTRUCT)&pep->Data)->cb,
                    TRUE)) {
                strcpy(((PMONHSZSTRUCTA)&pep->Data)->str, pszAnsi);
                UserLocalFree(pszAnsi);
            }
            ((PMONHSZSTRUCT)&pep->Data)->cb = sizeof(MONHSZSTRUCTA);
        }
        // fall through
    case MF_SENDMSGS:
    case MF_POSTMSGS:
        if (pep->EventType == MF_POSTMSGS) {
            PMONMSGSTRUCT pmms = (PMONMSGSTRUCT)&pep->Data;
            BYTE buf[32];

            /*
             * We may need to translate the Execute string to/from
             * UNICODE depending on what type of monitor this is
             * going to.
             */
            if (pmms->wMsg == WM_DDE_EXECUTE) {
                BOOL fUnicodeText;
                int flags;

                flags = (IS_TEXT_UNICODE_UNICODE_MASK |
                        IS_TEXT_UNICODE_REVERSE_MASK |
                        (IS_TEXT_UNICODE_NOT_UNICODE_MASK &
                        (~IS_TEXT_UNICODE_ILLEGAL_CHARS)) |
                        IS_TEXT_UNICODE_NOT_ASCII_MASK);
#ifdef ISTEXTUNICODE_WORKS
                fUnicodeText = RtlIsTextUnicode(pmms->dmhd.Data,
                        min(32, pmms->dmhd.cbData), &flags);
#else
                fUnicodeText = (*(LPSTR)pmms->dmhd.Data == '\0');
#endif

                if (pcii->flags & IIF_UNICODE && !fUnicodeText) {
                    /* Ascii->UNICODE */
                    RtlMultiByteToUnicodeN((LPWSTR)buf, 32, NULL,
                            (LPSTR)&pmms->dmhd.Data,
                            min(32, pmms->dmhd.cbData));
                    RtlCopyMemory(&pmms->dmhd.Data, buf, 32);
                } else if (!(pcii->flags & IIF_UNICODE) && fUnicodeText) {
                    /* UNICODE->Ascii */
                    RtlUnicodeToMultiByteN((LPSTR)buf, 32, NULL,
                            (LPWSTR)&pmms->dmhd.Data,
                            min(32, pmms->dmhd.cbData));
                    RtlCopyMemory(&pmms->dmhd.Data, buf, 32);
                }
            }
        }
    case MF_ERRORS:
        hData = InternalCreateDataHandle(pcii, (LPSTR)&pep->Data,
                pep->cbEventData, 0,
                HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0);
        if (hData) {
            DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0L,
                    pep->EventType);
            InternalFreeDataHandle((HDDEDATA)hData, TRUE);
        }
        break;
    }

    LeaveDDECrit;
    return (0);
}
Ejemplo n.º 6
0
WINUSERAPI HANDLE WINAPI SetSysColorsTemp(
    CONST COLORREF *lpRGBs,
    CONST HBRUSH   *lpBrushes,
    UINT_PTR       cBrushes)      // Count of brushes or handle
{
    UINT cbRGBSize;
    UINT i;
    UINT abElements[COLOR_MAX];

    /*
     * See if we are resetting the colors back to a saved state
     */
    if (lpRGBs == NULL) {

        /*
         * When restoring cBrushes is really a handle to the old global
         * handle.  Make sure that is true.  Also lpBrushes is unused
         */
        UNREFERENCED_PARAMETER(lpBrushes);
        UserAssert(lpBrushes == NULL);
        UserAssert(cBrushes == (ULONG_PTR)gpOriginalRGBs);

        if (gpOriginalRGBs == NULL) {
            RIPMSG0(RIP_ERROR, "SetSysColorsTemp: Can not restore if not saved");
            return NULL;
        }

        /*
         * reset the global Colors
         */
        UserAssert((sizeof(abElements)/sizeof(abElements[0])) >= gcOriginalRGBs);
        for (i = 0; i < gcOriginalRGBs; i++)
            abElements[i] = i;

        NtUserSetSysColors(gcOriginalRGBs, abElements, gpOriginalRGBs, 0);

        UserLocalFree(gpOriginalRGBs);

        gpOriginalRGBs = NULL;
        gcOriginalRGBs = 0;

        return (HANDLE)TRUE;
    }

    /*
     * Make sure we aren't trying to set too many colors
     * If we allow more then COLOR_MAX change the abElements array
     */
    if (cBrushes > COLOR_MAX) {
        RIPMSG1(RIP_ERROR, "SetSysColorsTemp: trying to set too many colors %lX", cBrushes);
        return NULL;
    }

    /*
     * If we have already a saved state then don't let them save it again
     */
    if (gpOriginalRGBs != NULL) {
        RIPMSG0(RIP_ERROR, "SetSysColorsTemp: temp colors already set");
        return NULL;
    }

    /*
     * If we are here then we must be setting the new temp colors
     *
     * First save the old colors
     */
    cbRGBSize = sizeof(COLORREF) * (UINT)cBrushes;

    UserAssert(sizeof(COLORREF) == sizeof(int));
    gpOriginalRGBs = UserLocalAlloc(HEAP_ZERO_MEMORY, cbRGBSize);

    if (gpOriginalRGBs == NULL) {
        RIPMSG0(RIP_WARNING, "SetSysColorsTemp: unable to alloc temp colors buffer");
    }

    RtlCopyMemory(gpOriginalRGBs, gpsi->argbSystem, cbRGBSize);

    /*
     * Now set the new colors.
     */
    UserAssert( (sizeof(abElements)/sizeof(abElements[0])) >= cBrushes);

    for (i = 0; i < cBrushes; i++)
        abElements[i] = i;

    NtUserSetSysColors((UINT)cBrushes, abElements, lpRGBs, 0);

    gcOriginalRGBs = (UINT)cBrushes;

    return gpOriginalRGBs;
}
Ejemplo n.º 7
0
/***************************************************************************\
* ImmInitializeHotkeys()
*
* Called from user\client\UpdatePerUserSystemParameters()
*
*  Read the User registry and set the IME hotkey.
*
* History:
* 25-Mar-1996 TakaoK       Created
\***************************************************************************/
VOID CliImmInitializeHotKeys(DWORD dwAction, HKL hkl)
{
    FE_KEYBOARDS feKbds = { 0, 0, 0, 0, };
    BOOL fFoundAny;

    UNREFERENCED_PARAMETER(hkl);

    // First, initialize the hotkey list
    CliImmSetHotKeyWorker(0, 0, 0, NULL, ISHK_INITIALIZE);

    // Check if the user has customized IME hotkeys
    // (they're stored in the registry)
    fFoundAny = CliGetImeHotKeysFromRegistry();

    if (dwAction == ISHK_INITIALIZE) {
        TAGMSG0(DBGTAG_IMM, "Setting IME HotKeys for Init.\n");

        // Get the user's default locale and set its flag
        SetFeKeyboardFlags(LANGIDFROMLCID(GetUserDefaultLCID()), &feKbds);

        // Get preloaded keyboards' locales and set their flags
        CliGetPreloadKeyboardLayouts(&feKbds);

    }
    else {
        UINT i;
        UINT nLayouts;
        LPHKL lphkl;

        TAGMSG0(DBGTAG_IMM, "Setting IME HotKeys for Add.\n");

        nLayouts = NtUserGetKeyboardLayoutList(0, NULL);
        if (nLayouts == 0) {
            return;
        }
        lphkl = UserLocalAlloc(0, nLayouts * sizeof(HKL));
        if (lphkl == NULL) {
            return;
        }
        NtUserGetKeyboardLayoutList(nLayouts, lphkl);
        for (i = 0; i < nLayouts; ++i) {
            //
            // Set language flags. By its definition, LOWORD(hkl) is LANGID
            //
            SetFeKeyboardFlags(LOWORD(HandleToUlong(lphkl[i])), &feKbds);
        }
        UserLocalFree(lphkl);
    }

    if (feKbds.fJPN) {
        TAGMSG0(DBGTAG_IMM, "JPN KL Preloaded.\n");
        CliSetDefaultImeHotKeys(DefaultHotKeyTableJ, DefaultHotKeyNumJ, fFoundAny);
    }

    if (feKbds.fKOR) {
        TAGMSG0(DBGTAG_IMM, "KOR KL Preloaded, but KOR hotkeys will not be registered.\n");
    }

    if (feKbds.fCHT) {
        TAGMSG0(DBGTAG_IMM, "CHT KL Preloaded.\n");
        CliSetDefaultImeHotKeys(DefaultHotKeyTableT, DefaultHotKeyNumT, fFoundAny);
    }
    if (feKbds.fCHS) {
        TAGMSG0(DBGTAG_IMM, "CHS KL Preloaded.\n");
        CliSetDefaultImeHotKeys(DefaultHotKeyTableC, DefaultHotKeyNumC, fFoundAny);
    }
}
Ejemplo n.º 8
0
LRESULT APIENTRY ListBoxWndProcWorker(
    PWND pwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam,
    DWORD fAnsi)
{
    HWND hwnd = HWq(pwnd);
    PAINTSTRUCT ps;
    HDC         hdc;
    LPRECT      lprc;
    PLBIV plb;    /* List Box Instance Variable */
    INT iSel;     /* Index of selected item */
    DWORD dw;
    TL tlpwndParent;
    UINT wFlags;
    LPWSTR lpwsz = NULL;
    LRESULT lReturn = 0;
    static BOOL fInit = TRUE;

    CheckLock(pwnd);

    VALIDATECLASSANDSIZE(pwnd, FNID_LISTBOX);
    INITCONTROLLOOKASIDE(&ListboxLookaside, LBIV, spwnd, 4);

    /*
     * Get the plb for the given window now since we will use it a lot in
     * various handlers. This was stored using SetWindowLong(hwnd,0,plb)
     * when the listbox was first created (by INITCONTROLLOOKASIDE above)
     */
    plb = ((PLBWND)pwnd)->pLBIV;

    /*
     * Handle ANSI translations of input parameters
     */
    if (fAnsi) {
        switch (message) {
        case LB_ADDSTRING:
        case LB_ADDSTRINGUPPER:
        case LB_ADDSTRINGLOWER:
        case LB_FINDSTRING:
        case LB_FINDSTRINGEXACT:
        case LB_INSERTSTRING:
        case LB_INSERTSTRINGUPPER:
        case LB_INSERTSTRINGLOWER:
        case LB_SELECTSTRING:
            if (!plb->fHasStrings) {
                break;
            }
            // Fall through...
        case LB_ADDFILE:
        case LB_DIR:
            if (lParam) {
                if (!MBToWCS((LPSTR)lParam, -1, &lpwsz, -1, TRUE))
                    return LB_ERR;
            }
            break;
        default:
            break;
        }
        if (lpwsz) {
            lParam = (LPARAM)lpwsz;
        }
    }

    switch (message) {

    case LB_GETTOPINDEX:        // Return index of top item displayed.
        return plb->iTop;

    case LB_SETTOPINDEX:
        if (wParam && ((INT)wParam < 0 || (INT)wParam >= plb->cMac)) {
            RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, "");
            return LB_ERR;
        }
        if (plb->cMac) {
            xxxNewITop(plb, (INT)wParam);
        }
        break;

    case WM_STYLECHANGED:
        plb->fRtoLReading = (TestWF(pwnd, WEFRTLREADING) != 0);
        plb->fRightAlign  = (TestWF(pwnd, WEFRIGHT) != 0);
        xxxCheckRedraw(plb, FALSE, 0);
        break;

    case WM_WINDOWPOSCHANGED:

        /*
         * If we are in the middle of creation, ignore this
         * message because it will generate a WM_SIZE message.
         * See xxxLBCreate().
         */
        if (!plb->fIgnoreSizeMsg)
            goto CallDWP;
        break;

    case WM_SIZE:

        /*
         * If we are in the middle of creation, ignore size
         * messages.  See xxxLBCreate().
         */
        if (!plb->fIgnoreSizeMsg)
            xxxLBSize(plb, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
        break;

    case WM_ERASEBKGND:
        ThreadLock(plb->spwndParent, &tlpwndParent);
        FillWindow(HW(plb->spwndParent), hwnd, (HDC)wParam,
                (HBRUSH)CTLCOLOR_LISTBOX);
        ThreadUnlock(&tlpwndParent);
        return TRUE;

    case LB_RESETCONTENT:
        xxxLBResetContent(plb);
        break;

    case WM_TIMER:
        if (wParam == IDSYS_LBSEARCH) {
            plb->iTypeSearch = 0;
            NtUserKillTimer(hwnd, IDSYS_LBSEARCH);
            xxxInvertLBItem(plb, plb->iSel, TRUE);
            break;
        }

        message = WM_MOUSEMOVE;
        xxxTrackMouse(plb, message, plb->ptPrev);
        break;

        /*
         * Fall through
         */
    case WM_MOUSEMOVE:
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_LBUTTONDBLCLK:
        {
            POINT pt;

            POINTSTOPOINT(pt, lParam);
            xxxTrackMouse(plb, message, pt);
        }
        break;

    case WM_MBUTTONDOWN:
        EnterReaderModeHelper(hwnd);
        break;

    case WM_CAPTURECHANGED:
            //
            // Note that this message should be handled only on unexpected
            // capture changes currently.
            //
        UserAssert(TestWF(pwnd, WFWIN40COMPAT));
        if (plb->fCaptured)
            xxxLBButtonUp(plb, LBUP_NOTIFY);
        break;

    case LBCB_STARTTRACK:
        //
        // Start tracking mouse moves in the listbox, setting capture
        //
        if (!plb->pcbox)
            break;

        plb->fCaptured = FALSE;
        if (wParam) {
            POINT pt;

            POINTSTOPOINT(pt, lParam);

            _ScreenToClient(pwnd, &pt);
            xxxTrackMouse(plb, WM_LBUTTONDOWN, pt);
        } else {
            NtUserSetCapture(hwnd);
            plb->fCaptured = TRUE;
            plb->iLastSelection = plb->iSel;
        }
        break;

    case LBCB_ENDTRACK:
        // Kill capture, tracking, etc.
        if (plb->fCaptured)
            xxxLBButtonUp(plb, LBUP_RELEASECAPTURE | (wParam ? LBUP_SELCHANGE :
                LBUP_RESETSELECTION));
        break;

    case WM_PRINTCLIENT:
        xxxLBPaint(plb, (HDC) wParam, NULL);
        break;

    case WM_PAINT:
        if (wParam) {
            hdc = (HDC) wParam;
            lprc = NULL;
        } else {
            hdc = NtUserBeginPaint(hwnd, &ps);
            lprc = &(ps.rcPaint);
        }

        if (IsLBoxVisible(plb))
            xxxLBPaint(plb, hdc, lprc);

        if (!wParam)
            NtUserEndPaint(hwnd, &ps);
        break;

    case WM_NCDESTROY:
    case WM_FINALDESTROY:
        xxxDestroyLBox(plb, pwnd);
        break;

    case WM_SETFOCUS:
// DISABLED in Win 3.1        xxxUpdateWindow(pwnd);
        CaretCreate(plb);
        xxxLBSetCaret(plb, TRUE);
        xxxNotifyOwner(plb, LBN_SETFOCUS);
        if (FWINABLE()) {
            if (_IsWindowVisible(pwnd)) {
                LBEvent(plb, EVENT_OBJECT_FOCUS, plb->iSelBase);
            }
        }
        break;

    case WM_KILLFOCUS:
        /*
         * Reset the wheel delta count.
         */
        gcWheelDelta = 0;

        xxxLBSetCaret(plb, FALSE);
        xxxCaretDestroy(plb);
        xxxNotifyOwner(plb, LBN_KILLFOCUS);
        if (plb->iTypeSearch) {
            plb->iTypeSearch = 0;
            NtUserKillTimer(hwnd, IDSYS_LBSEARCH);
        }
        if (plb->pszTypeSearch) {
            UserLocalFree(plb->pszTypeSearch);
            plb->pszTypeSearch = NULL;
        }
        break;

    case WM_MOUSEWHEEL:
        {
            int     cDetants;
            int     cPage;
            int     cLines;
            RECT    rc;
            int     windowWidth;
            int     cPos;

            /*
             * Don't handle zoom and datazoom.
             */
            if (wParam & (MK_SHIFT | MK_CONTROL)) {
                goto CallDWP;
            }

            lReturn = 1;
            gcWheelDelta -= (short) HIWORD(wParam);
            cDetants = gcWheelDelta / WHEEL_DELTA;
            if (    cDetants != 0 &&
                    gpsi->ucWheelScrollLines > 0 &&
                    (pwnd->style & (WS_VSCROLL | WS_HSCROLL))) {

                gcWheelDelta = gcWheelDelta % WHEEL_DELTA;

                if (pwnd->style & WS_VSCROLL) {
                    cPage = max(1, (plb->cItemFullMax - 1));
                    cLines = cDetants *
                            (int) min((UINT) cPage, gpsi->ucWheelScrollLines);

                    cPos = max(0, min(plb->iTop + cLines, plb->cMac - 1));
                    if (cPos != plb->iTop) {
                        xxxLBoxCtlScroll(plb, SB_THUMBPOSITION, cPos);
                        xxxLBoxCtlScroll(plb, SB_ENDSCROLL, 0);
                    }
                } else if (plb->fMultiColumn) {
                    cPage = max(1, plb->numberOfColumns);
                    cLines = cDetants * (int) min((UINT) cPage, gpsi->ucWheelScrollLines);
                    cPos = max(
                            0,
                            min((plb->iTop / plb->itemsPerColumn) + cLines,
                                plb->cMac - 1 - ((plb->cMac - 1) % plb->itemsPerColumn)));

                    if (cPos != plb->iTop) {
                        xxxLBoxCtlHScrollMultiColumn(plb, SB_THUMBPOSITION, cPos);
                        xxxLBoxCtlHScrollMultiColumn(plb, SB_ENDSCROLL, 0);
                    }
                } else {
                    _GetClientRect(plb->spwnd, &rc);
                    windowWidth = rc.right;
                    cPage = max(plb->cxChar, (windowWidth / 3) * 2) /
                            plb->cxChar;

                    cLines = cDetants *
                            (int) min((UINT) cPage, gpsi->ucWheelScrollLines);

                    cPos = max(
                            0,
                            min(plb->xOrigin + (cLines * plb->cxChar),
                                plb->maxWidth));

                    if (cPos != plb->xOrigin) {
                        xxxLBoxCtlHScroll(plb, SB_THUMBPOSITION, cPos);
                        xxxLBoxCtlHScroll(plb, SB_ENDSCROLL, 0);
                    }
                }
            }
        }
        break;

    case WM_VSCROLL:
        xxxLBoxCtlScroll(plb, LOWORD(wParam), HIWORD(wParam));
        break;

    case WM_HSCROLL:
        xxxLBoxCtlHScroll(plb, LOWORD(wParam), HIWORD(wParam));
        break;

    case WM_GETDLGCODE:
        return DLGC_WANTARROWS | DLGC_WANTCHARS;

    case WM_CREATE:
        return xxxLBCreate(plb, pwnd, (LPCREATESTRUCT) lParam);

    case WM_SETREDRAW:

        /*
         * If wParam is nonzero, the redraw flag is set
         * If wParam is zero, the flag is cleared
         */
        xxxLBSetRedraw(plb, (wParam != 0));
        break;

    case WM_ENABLE:
        xxxLBInvalidateRect(plb, NULL, !plb->OwnerDraw);
        break;

    case WM_SETFONT:
        xxxLBSetFont(plb, (HANDLE)wParam, LOWORD(lParam));
        break;

    case WM_GETFONT:
        return (LRESULT)plb->hFont;

    case WM_DRAGSELECT:
    case WM_DRAGLOOP:
    case WM_DRAGMOVE:
    case WM_DROPFILES:
        ThreadLock(plb->spwndParent, &tlpwndParent);
        lReturn = SendMessage(HW(plb->spwndParent), message, wParam, lParam);
        ThreadUnlock(&tlpwndParent);
        return lReturn;


    case WM_QUERYDROPOBJECT:
    case WM_DROPOBJECT:

        /*
         * fix up control data, then pass message to parent
         */
        LBDropObjectHandler(plb, (PDROPSTRUCT)lParam);
        ThreadLock(plb->spwndParent, &tlpwndParent);
        lReturn = SendMessage(HW(plb->spwndParent), message, wParam, lParam);
        ThreadUnlock(&tlpwndParent);
        return lReturn;

    case LB_GETITEMRECT:
        return LBGetItemRect(plb, (INT)wParam, (LPRECT)lParam);

    case LB_GETITEMDATA:
        return LBGetItemData(plb, (INT)wParam);  // wParam = item index

    case LB_SETITEMDATA:

        /*
         * wParam is item index
         */
        return LBSetItemData(plb, (INT)wParam, lParam);

    case LB_ADDSTRINGUPPER:
        wFlags = UPPERCASE | LBI_ADD;
        goto CallInsertItem;

    case LB_ADDSTRINGLOWER:
        wFlags = LOWERCASE | LBI_ADD;
        goto CallInsertItem;

    case LB_ADDSTRING:
        wFlags = LBI_ADD;
        goto CallInsertItem;

    case LB_INSERTSTRINGUPPER:
        wFlags = UPPERCASE;
        goto CallInsertItem;

    case LB_INSERTSTRINGLOWER:
        wFlags = LOWERCASE;
        goto CallInsertItem;

    case LB_INSERTSTRING:
        wFlags = 0;
CallInsertItem:
        lReturn = ((LRESULT) xxxLBInsertItem(plb, (LPWSTR) lParam, (int) wParam, wFlags));
        break;

    case LB_INITSTORAGE:
        return xxxLBInitStorage(plb, fAnsi, (INT)wParam, (INT)lParam);

    case LB_DELETESTRING:
        return xxxLBoxCtlDelete(plb, (INT)wParam);

    case LB_DIR:
        /*
         * wParam - Dos attribute value.
         * lParam - Points to a file specification string
         */
        lReturn = xxxLbDir(plb, (INT)wParam, (LPWSTR)lParam);
        break;

    case LB_ADDFILE:
        lReturn = xxxLbInsertFile(plb, (LPWSTR)lParam);
        break;

    case LB_SETSEL:
        return xxxLBSetSel(plb, (wParam != 0), (INT)lParam);

    case LB_SETCURSEL:
        /*
         * If window obscured, update so invert will work correctly
         */
// DISABLED in Win 3.1        xxxUpdateWindow(pwnd);
        return xxxLBSetCurSel(plb, (INT)wParam);

    case LB_GETSEL:
        if (wParam >= (UINT) plb->cMac)
                return((LRESULT) LB_ERR);

        return IsSelected(plb, (INT)wParam, SELONLY);

    case LB_GETCURSEL:
        if (plb->wMultiple == SINGLESEL) {
            return plb->iSel;
        }
        return plb->iSelBase;

    case LB_SELITEMRANGE:
        if (plb->wMultiple == SINGLESEL) {
            /*
             * Can't select a range if only single selections are enabled
             */
            RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SELITEMRANGE");
            return LB_ERR;
        }

        xxxLBSelRange(plb, LOWORD(lParam), HIWORD(lParam), (wParam != 0));
        break;

    case LB_SELITEMRANGEEX:
        if (plb->wMultiple == SINGLESEL) {
            /*
             * Can't select a range if only single selections are enabled
             */
            RIPERR0(ERROR_INVALID_LB_MESSAGE, RIP_VERBOSE,"LB_SELITEMRANGEEX:Can't select a range if only single selections are enabled");
            return LB_ERR;
        } else {
            BOOL fHighlight = ((DWORD)lParam > (DWORD)wParam);
            if (fHighlight == FALSE) {
                ULONG_PTR temp = lParam;
                lParam = wParam;
                wParam = temp;
            }
            xxxLBSelRange(plb, (INT)wParam, (INT)lParam, fHighlight);
        }
        break;

    case LB_GETTEXTLEN:
        if (lParam != 0) {
            RIPMSG1(RIP_WARNING, "LB_GETTEXTLEN with lParam = %lx\n", lParam);
        }
        lReturn = LBGetText(plb, TRUE, fAnsi, (INT)wParam, NULL);
        break;

    case LB_GETTEXT:
        lReturn = LBGetText(plb, FALSE, fAnsi, (INT)wParam, (LPWSTR)lParam);
        break;

    case LB_GETCOUNT:
        // Lotus Approach calls CallWndProc(ListWndProc, LB_GETCOUNT,...)
        // on a window that doesn't have a plb yet. So, we need to make
        // this check. Bug #6675 - 11/7/94 --
        if(plb)
            return((LRESULT) plb->cMac);
        else
            return(0);

    case LB_SETCOUNT:
        return xxxLBSetCount(plb, (INT)wParam);

    case LB_SELECTSTRING:
    case LB_FINDSTRING:
        iSel = xxxFindString(plb, (LPWSTR)lParam, (INT)wParam, PREFIX, TRUE);
        if (message == LB_FINDSTRING || iSel == LB_ERR) {
            lReturn = iSel;
        } else {
            lReturn = xxxLBSetCurSel(plb, iSel);
        }
        break;

    case LB_GETLOCALE:
        return plb->dwLocaleId;

    case LB_SETLOCALE:

        /*
         * Validate locale
         */
        wParam = ConvertDefaultLocale((LCID)wParam);
        if (!IsValidLocale((LCID)wParam, LCID_INSTALLED))
            return LB_ERR;

        dw = plb->dwLocaleId;
        plb->dwLocaleId = (DWORD)wParam;
        return dw;

    case WM_KEYDOWN:

        /*
         * IanJa: Use LOWORD() to get low 16-bits of wParam - this should
         * work for Win16 & Win32.  The value obtained is the virtual key
         */
        xxxLBoxCtlKeyInput(plb, message, LOWORD(wParam));
        break;

    case WM_CHAR:
        xxxLBoxCtlCharInput(plb, LOWORD(wParam), fAnsi);
        break;

    case LB_GETSELITEMS:
    case LB_GETSELCOUNT:

        /*
         * IanJa/Win32 should this be LPWORD now?
         */
        return LBoxGetSelItems(plb, (message == LB_GETSELCOUNT), (INT)wParam,
                (LPINT)lParam);

    case LB_SETTABSTOPS:

        /*
         * IanJa/Win32: Tabs given by array of INT for backwards compatability
         */
        return LBSetTabStops(plb, (INT)wParam, (LPINT)lParam);

    case LB_GETHORIZONTALEXTENT:

        /*
         * Return the max width of the listbox used for horizontal scrolling
         */
        return plb->maxWidth;

    case LB_SETHORIZONTALEXTENT:

        /*
         * Set the max width of the listbox used for horizontal scrolling
         */
        if (plb->maxWidth != (INT)wParam) {
            plb->maxWidth = (INT)wParam;

            /*
             * When horizontal extent is set, Show/hide the scroll bars.
             * NOTE: LBShowHideScrollBars() takes care if Redraw is OFF.
             * Fix for Bug #2477 -- 01/14/91 -- SANKAR --
             */
            xxxLBShowHideScrollBars(plb); //Try to show or hide scroll bars
            if (plb->fHorzBar && plb->fRightAlign && !(plb->fMultiColumn || plb->OwnerDraw)) {
                /*
                 * origin to right
                 */
                xxxLBoxCtlHScroll(plb, SB_BOTTOM, 0);
            }
        }
        break;    /* originally returned register ax (message) ! */

    case LB_SETCOLUMNWIDTH:

        /*
         * Set the width of a column in a multicolumn listbox
         */
        plb->cxColumn = (INT)wParam;
        LBCalcItemRowsAndColumns(plb);
        if (IsLBoxVisible(plb))
            NtUserInvalidateRect(hwnd, NULL, TRUE);
        xxxLBShowHideScrollBars(plb);
        break;

    case LB_SETANCHORINDEX:
        if ((INT)wParam >= plb->cMac) {
            RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SETANCHORINDEX");
            return LB_ERR;
        }
        plb->iMouseDown = (INT)wParam;
        plb->iLastMouseMove = (INT)wParam;
        xxxInsureVisible(plb, (int) wParam, (BOOL)(lParam != 0));
        break;

    case LB_GETANCHORINDEX:
        return plb->iMouseDown;

    case LB_SETCARETINDEX:
        if ( (plb->iSel == -1) || ((plb->wMultiple != SINGLESEL) &&
                    (plb->cMac > (INT)wParam))) {

            /*
             * Set's the iSelBase to the wParam
             * if lParam, then don't scroll if partially visible
             * else scroll into view if not fully visible
             */
            xxxInsureVisible(plb, (INT)wParam, (BOOL)LOWORD(lParam));
            xxxSetISelBase(plb, (INT)wParam);
            break;
        } else {
            if ((INT)wParam >= plb->cMac) {
                RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SETCARETINDEX");
            }
            return LB_ERR;
        }
        break;

    case LB_GETCARETINDEX:
        return plb->iSelBase;

    case LB_SETITEMHEIGHT:
    case LB_GETITEMHEIGHT:
        return LBGetSetItemHeightHandler(plb, message, (INT)wParam, LOWORD(lParam));
        break;

    case LB_FINDSTRINGEXACT:
        lReturn = xxxFindString(plb, (LPWSTR)lParam, (INT)wParam, EQ, TRUE);
        break;

    case LB_ITEMFROMPOINT: {
        POINT pt;
        BOOL bOutside;
        DWORD dwItem;

        POINTSTOPOINT(pt, lParam);
        bOutside = ISelFromPt(plb, pt, &dwItem);
        UserAssert(bOutside == 1 || bOutside == 0);
        return (LRESULT)MAKELONG(dwItem, bOutside);
    }

    case LBCB_CARETON:

        /*
         * Internal message for combo box support
         */
        CaretCreate(plb);
        // Set up the caret in the proper location for drop downs.
        plb->iSelBase = plb->iSel;
        xxxLBSetCaret(plb, TRUE);
        if (FWINABLE()) {
            if (_IsWindowVisible(pwnd)) {
                LBEvent(plb, EVENT_OBJECT_FOCUS, plb->iSelBase);
            }
        }
        return(plb->iSel);

    case LBCB_CARETOFF:

        /*
         * Internal message for combo box support
         */
        xxxLBSetCaret(plb, FALSE);
        xxxCaretDestroy(plb);
        break;

    case WM_NCCREATE:
        if ((pwnd->style & LBS_MULTICOLUMN) && (pwnd->style & WS_VSCROLL))
        {
            DWORD mask = WS_VSCROLL;
            DWORD flags = 0;
            if (!TestWF(pwnd, WFWIN40COMPAT)) {
                mask |= WS_HSCROLL;
                flags = WS_HSCROLL;
            }
            NtUserAlterWindowStyle(hwnd, mask, flags);
        }
        goto CallDWP;

     default:
CallDWP:
        return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi);
    }

    /*
     * Handle translation of ANSI output data and free buffer
     */
    if (lpwsz) {
        UserLocalFree(lpwsz);
    }

    return lReturn;
}