/*
 * Listbox controls
 *
 * Copyright 1996 Alexandre Julliard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "windef.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "wine/winbase16.h"
#include "wine/unicode.h"
#include "winuser.h"
#include "winerror.h"
#include "spy.h"
#include "user.h"
#include "controls.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(listbox);
WINE_DECLARE_DEBUG_CHANNEL(combo);

/* Unimplemented yet:
 * - LBS_USETABSTOPS
 * - Locale handling
 *
 * Probably needs improvement:
 * - LBS_NOSEL
 */

/* Items array granularity */
#define LB_ARRAY_GRANULARITY 16

/* Scrolling timeout in ms */
#define LB_SCROLL_TIMEOUT 50

/* Listbox system timer id */
#define LB_TIMER_ID  2

/* flag listbox changed while setredraw false - internal style */
#define LBS_DISPLAYCHANGED 0x80000000

/* Item structure */
typedef struct
{
    LPWSTR  str;       /* Item text */
    BOOL    selected;  /* Is item selected? */
    UINT    height;    /* Item height (only for OWNERDRAWVARIABLE) */
    DWORD   data;      /* User data */
} LB_ITEMDATA;

/* Listbox structure */
typedef struct
{
    HWND        owner;          /* Owner window to send notifications to */
    UINT        style;          /* Window style */
    INT         width;          /* Window width */
    INT         height;         /* Window height */
    LB_ITEMDATA  *items;          /* Array of items */
    INT         nb_items;       /* Number of items */
    INT         top_item;       /* Top visible item */
    INT         selected_item;  /* Selected item */
    INT         focus_item;     /* Item that has the focus */
    INT         anchor_item;    /* Anchor item for extended selection */
    INT         item_height;    /* Default item height */
    INT         page_size;      /* Items per listbox page */
    INT         column_width;   /* Column width for multi-column listboxes */
    INT         horz_extent;    /* Horizontal extent (0 if no hscroll) */
    INT         horz_pos;       /* Horizontal position */
    INT         nb_tabs;        /* Number of tabs in array */
    INT        *tabs;           /* Array of tabs */
    BOOL        caret_on;       /* Is caret on? */
    BOOL        captured;       /* Is mouse captured? */
    BOOL	in_focus;
    HFONT       font;           /* Current font */
    LCID          locale;         /* Current locale for string comparisons */
    LPHEADCOMBO   lphc;		  /* ComboLBox */
} LB_DESCR;


#define IS_OWNERDRAW(descr) \
    ((descr)->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE))

#define HAS_STRINGS(descr) \
    (!IS_OWNERDRAW(descr) || ((descr)->style & LBS_HASSTRINGS))


#define IS_MULTISELECT(descr) \
    ((descr)->style & LBS_MULTIPLESEL || ((descr)->style & LBS_EXTENDEDSEL))

#define SEND_NOTIFICATION(hwnd,descr,code) \
    (SendMessageW( (descr)->owner, WM_COMMAND, \
     MAKEWPARAM( GetWindowLongA((hwnd),GWL_ID), (code)), (hwnd) ))

#define ISWIN31 (LOWORD(GetVersion()) == 0x0a03)

/* Current timer status */
typedef enum
{
    LB_TIMER_NONE,
    LB_TIMER_UP,
    LB_TIMER_LEFT,
    LB_TIMER_DOWN,
    LB_TIMER_RIGHT
} TIMER_DIRECTION;

static TIMER_DIRECTION LISTBOX_Timer = LB_TIMER_NONE;

static LRESULT WINAPI ComboLBWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
static LRESULT WINAPI ComboLBWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
static LRESULT WINAPI ListBoxWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );

static LRESULT LISTBOX_GetItemRect( LB_DESCR *descr, INT index, RECT *rect );

/*********************************************************************
 * listbox class descriptor
 */
const struct builtin_class_descr LISTBOX_builtin_class =
{
    "ListBox",            /* name */
    CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/,  /* style */
    ListBoxWndProcA,      /* procA */
    ListBoxWndProcW,      /* procW */
    sizeof(LB_DESCR *),   /* extra */
    IDC_ARROWA,           /* cursor */
    0                     /* brush */
};


/*********************************************************************
 * combolbox class descriptor
 */
const struct builtin_class_descr COMBOLBOX_builtin_class =
{
    "ComboLBox",          /* name */
    CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS,  /* style */
    ComboLBWndProcA,      /* procA */
    ComboLBWndProcW,      /* procW */
    sizeof(LB_DESCR *),   /* extra */
    IDC_ARROWA,           /* cursor */
    0                     /* brush */
};


/* check whether app is a Win 3.1 app */
inline static BOOL is_old_app( HWND hwnd )
{
    return (GetExpWinVer16( GetWindowLongA(hwnd,GWL_HINSTANCE) ) & 0xFF00 ) == 0x0300;
}


/***********************************************************************
 *           LISTBOX_Dump
 */
void LISTBOX_Dump( HWND hwnd )
{
    INT i;
    LB_ITEMDATA *item;
    LB_DESCR *descr = (LB_DESCR *)GetWindowLongA( hwnd, 0 );

    TRACE( "Listbox:\n" );
    TRACE( "hwnd=%04x descr=%08x items=%d top=%d\n",
                     hwnd, (UINT)descr, descr->nb_items,
                     descr->top_item );
    for (i = 0, item = descr->items; i < descr->nb_items; i++, item++)
    {
        TRACE( "%4d: %-40s %d %08lx %3d\n",
               i, debugstr_w(item->str), item->selected, item->data, item->height );
    }
}


/***********************************************************************
 *           LISTBOX_GetCurrentPageSize
 *
 * Return the current page size
 */
static INT LISTBOX_GetCurrentPageSize( LB_DESCR *descr )
{
    INT i, height;
    if (!(descr->style & LBS_OWNERDRAWVARIABLE)) return descr->page_size;
    for (i = descr->top_item, height = 0; i < descr->nb_items; i++)
    {
        if ((height += descr->items[i].height) > descr->height) break;
    }
    if (i == descr->top_item) return 1;
    else return i - descr->top_item;
}


/***********************************************************************
 *           LISTBOX_GetMaxTopIndex
 *
 * Return the maximum possible index for the top of the listbox.
 */
static INT LISTBOX_GetMaxTopIndex( LB_DESCR *descr )
{
    INT max, page;

    if (descr->style & LBS_OWNERDRAWVARIABLE)
    {
        page = descr->height;
        for (max = descr->nb_items - 1; max >= 0; max--)
            if ((page -= descr->items[max].height) < 0) break;
        if (max < descr->nb_items - 1) max++;
    }
    else if (descr->style & LBS_MULTICOLUMN)
    {
        if ((page = descr->width / descr->column_width) < 1) page = 1;
        max = (descr->nb_items + descr->page_size - 1) / descr->page_size;
        max = (max - page) * descr->page_size;
    }
    else
    {
        max = descr->nb_items - descr->page_size;
    }
    if (max < 0) max = 0;
    return max;
}


/***********************************************************************
 *           LISTBOX_UpdateScroll
 *
 * Update the scrollbars. Should be called whenever the content
 * of the listbox changes.
 */
static void LISTBOX_UpdateScroll( HWND hwnd, LB_DESCR *descr )
{
    SCROLLINFO info;

    /* Check the listbox scroll bar flags individually before we call
       SetScrollInfo otherwise when the listbox style is WS_HSCROLL and
       no WS_VSCROLL, we end up with an uninitialized, visible horizontal
       scroll bar when we do not need one.
    if (!(descr->style & WS_VSCROLL)) return;
    */

    /*   It is important that we check descr->style, and not wnd->dwStyle, 
       for WS_VSCROLL, as the former is exactly the one passed in 
       argument to CreateWindow.  
         In Windows (and from now on in Wine :) a listbox created 
       with such a style (no WS_SCROLL) does not update 
       the scrollbar with listbox-related data, thus letting 
       the programmer use it for his/her own purposes. */

    if (descr->style & LBS_NOREDRAW) return;
    info.cbSize = sizeof(info);

    if (descr->style & LBS_MULTICOLUMN)
    {
        info.nMin  = 0;
        info.nMax  = (descr->nb_items - 1) / descr->page_size;
        info.nPos  = descr->top_item / descr->page_size;
        info.nPage = descr->width / descr->column_width;
        if (info.nPage < 1) info.nPage = 1;
        info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
        if (descr->style & LBS_DISABLENOSCROLL)
            info.fMask |= SIF_DISABLENOSCROLL;
        if (descr->style & WS_HSCROLL)
            SetScrollInfo( hwnd, SB_HORZ, &info, TRUE );
        info.nMax = 0;
        info.fMask = SIF_RANGE;
        if (descr->style & WS_VSCROLL)
            SetScrollInfo( hwnd, SB_VERT, &info, TRUE );
    }
    else
    {
        info.nMin  = 0;
        info.nMax  = descr->nb_items - 1;
        info.nPos  = descr->top_item;
        info.nPage = LISTBOX_GetCurrentPageSize( descr );
        info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
        if (descr->style & LBS_DISABLENOSCROLL)
            info.fMask |= SIF_DISABLENOSCROLL;
        if (descr->style & WS_VSCROLL)
            SetScrollInfo( hwnd, SB_VERT, &info, TRUE );

        if (descr->horz_extent)
        {
            info.nMin  = 0;
            info.nMax  = descr->horz_extent - 1;
            info.nPos  = descr->horz_pos;
            info.nPage = descr->width;
            info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
            if (descr->style & LBS_DISABLENOSCROLL)
                info.fMask |= SIF_DISABLENOSCROLL;
            if (descr->style & WS_HSCROLL)
                SetScrollInfo( hwnd, SB_HORZ, &info, TRUE );
        }
    }
}


/***********************************************************************
 *           LISTBOX_SetTopItem
 *
 * Set the top item of the listbox, scrolling up or down if necessary.
 */
static LRESULT LISTBOX_SetTopItem( HWND hwnd, LB_DESCR *descr, INT index,
                                   BOOL scroll )
{
    INT max = LISTBOX_GetMaxTopIndex( descr );
    if (index > max) index = max;
    if (index < 0) index = 0;
    if (descr->style & LBS_MULTICOLUMN) index -= index % descr->page_size;
    if (descr->top_item == index) return LB_OKAY;
    if (descr->style & LBS_MULTICOLUMN)
    {
        INT diff = (descr->top_item - index) / descr->page_size * descr->column_width;
        if (scroll && (abs(diff) < descr->width))
            ScrollWindowEx( hwnd, diff, 0, NULL, NULL, 0, NULL,
                              SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );

        else
            scroll = FALSE;
    }
    else if (scroll)
    {
        INT diff;
        if (descr->style & LBS_OWNERDRAWVARIABLE)
        {
            INT i;
            diff = 0;
            if (index > descr->top_item)
            {
                for (i = index - 1; i >= descr->top_item; i--)
                    diff -= descr->items[i].height;
            }
            else
            {
                for (i = index; i < descr->top_item; i++)
                    diff += descr->items[i].height;
            }
        }
        else
            diff = (descr->top_item - index) * descr->item_height;

        if (abs(diff) < descr->height)
            ScrollWindowEx( hwnd, 0, diff, NULL, NULL, 0, NULL,
                              SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
        else
            scroll = FALSE;
    }
    if (!scroll) InvalidateRect( hwnd, NULL, TRUE );
    descr->top_item = index;
    LISTBOX_UpdateScroll( hwnd, descr );
    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_UpdatePage
 *
 * Update the page size. Should be called when the size of
 * the client area or the item height changes.
 */
static void LISTBOX_UpdatePage( HWND hwnd, LB_DESCR *descr )
{
    INT page_size;

    if ((descr->item_height == 0) || (page_size = descr->height / descr->item_height) < 1)
                       page_size = 1;
    if (page_size == descr->page_size) return;
    descr->page_size = page_size;
    if (descr->style & LBS_MULTICOLUMN)
        InvalidateRect( hwnd, NULL, TRUE );
    LISTBOX_SetTopItem( hwnd, descr, descr->top_item, FALSE );
}


/***********************************************************************
 *           LISTBOX_UpdateSize
 *
 * Update the size of the listbox. Should be called when the size of
 * the client area changes.
 */
static void LISTBOX_UpdateSize( HWND hwnd, LB_DESCR *descr )
{
    RECT rect;

    GetClientRect( hwnd, &rect );
    descr->width  = rect.right - rect.left;
    descr->height = rect.bottom - rect.top;
    if (!(descr->style & LBS_NOINTEGRALHEIGHT) && !(descr->style & LBS_OWNERDRAWVARIABLE))
    {
        INT remaining;
        RECT rect;

        GetWindowRect( hwnd, &rect );
        if(descr->item_height != 0)
            remaining = descr->height % descr->item_height;
        else
            remaining = 0;
        if ((descr->height > descr->item_height) && remaining)
        {
            if (is_old_app(hwnd))
            { /* give a margin for error to 16 bits programs - if we need
                 less than the height of the nonclient area, round to the
                 *next* number of items */
                int ncheight = rect.bottom - rect.top - descr->height;
                if ((descr->item_height - remaining) <= ncheight)
                    remaining = remaining - descr->item_height;
            }
            TRACE("[%04x]: changing height %d -> %d\n",
                  hwnd, descr->height, descr->height - remaining );
            SetWindowPos( hwnd, 0, 0, 0, rect.right - rect.left,
                            rect.bottom - rect.top - remaining,
                            SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE );
            return;
        }
    }
    TRACE("[%04x]: new size = %d,%d\n", hwnd, descr->width, descr->height );
    LISTBOX_UpdatePage( hwnd, descr );
    LISTBOX_UpdateScroll( hwnd, descr );

    /* Invalidate the focused item so it will be repainted correctly */
    if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) == 1)
    {
        InvalidateRect( hwnd, &rect, FALSE );
    }
}


/***********************************************************************
 *           LISTBOX_GetItemRect
 *
 * Get the rectangle enclosing an item, in listbox client coordinates.
 * Return 1 if the rectangle is (partially) visible, 0 if hidden, -1 on error.
 */
static LRESULT LISTBOX_GetItemRect( LB_DESCR *descr, INT index, RECT *rect )
{
    /* Index <= 0 is legal even on empty listboxes */
    if (index && (index >= descr->nb_items)) return -1;
    SetRect( rect, 0, 0, descr->width, descr->height );
    if (descr->style & LBS_MULTICOLUMN)
    {
        INT col = (index / descr->page_size) -
                        (descr->top_item / descr->page_size);
        rect->left += col * descr->column_width;
        rect->right = rect->left + descr->column_width;
        rect->top += (index % descr->page_size) * descr->item_height;
        rect->bottom = rect->top + descr->item_height;
    }
    else if (descr->style & LBS_OWNERDRAWVARIABLE)
    {
        INT i;
        rect->right += descr->horz_pos;
        if ((index >= 0) && (index < descr->nb_items))
        {
            if (index < descr->top_item)
            {
                for (i = descr->top_item-1; i >= index; i--)
                    rect->top -= descr->items[i].height;
            }
            else
            {
                for (i = descr->top_item; i < index; i++)
                    rect->top += descr->items[i].height;
            }
            rect->bottom = rect->top + descr->items[index].height;

        }
    }
    else
    {
        rect->top += (index - descr->top_item) * descr->item_height;
        rect->bottom = rect->top + descr->item_height;
        rect->right += descr->horz_pos;
    }

    return ((rect->left < descr->width) && (rect->right > 0) &&
            (rect->top < descr->height) && (rect->bottom > 0));
}


/***********************************************************************
 *           LISTBOX_GetItemFromPoint
 *
 * Return the item nearest from point (x,y) (in client coordinates).
 */
static INT LISTBOX_GetItemFromPoint( LB_DESCR *descr, INT x, INT y )
{
    INT index = descr->top_item;

    if (!descr->nb_items) return -1;  /* No items */
    if (descr->style & LBS_OWNERDRAWVARIABLE)
    {
        INT pos = 0;
        if (y >= 0)
        {
            while (index < descr->nb_items)
            {
                if ((pos += descr->items[index].height) > y) break;
                index++;
            }
        }
        else
        {
            while (index > 0)
            {
                index--;
                if ((pos -= descr->items[index].height) <= y) break;
            }
        }
    }
    else if (descr->style & LBS_MULTICOLUMN)
    {
        if (y >= descr->item_height * descr->page_size) return -1;
        if (y >= 0) index += y / descr->item_height;
        if (x >= 0) index += (x / descr->column_width) * descr->page_size;
        else index -= (((x + 1) / descr->column_width) - 1) * descr->page_size;
    }
    else
    {
        index += (y / descr->item_height);
    }
    if (index < 0) return 0;
    if (index >= descr->nb_items) return -1;
    return index;
}


/***********************************************************************
 *           LISTBOX_PaintItem
 *
 * Paint an item.
 */
static void LISTBOX_PaintItem( HWND hwnd, LB_DESCR *descr, HDC hdc,
                               const RECT *rect, INT index, UINT action, BOOL ignoreFocus )
{
    LB_ITEMDATA *item = NULL;
    if (index < descr->nb_items) item = &descr->items[index];

    if (IS_OWNERDRAW(descr))
    {
        DRAWITEMSTRUCT dis;
        RECT r;
        HRGN hrgn;
        UINT id = GetWindowLongA( hwnd, GWL_ID );

	if (!item)
	{
	    if (action == ODA_FOCUS)
		DrawFocusRect( hdc, rect );
	    else
	        FIXME("called with an out of bounds index %d(%d) in owner draw, Not good.\n",index,descr->nb_items);
	    return;
	}

        /* some programs mess with the clipping region when
        drawing the item, *and* restore the previous region
        after they are done, so a region has better to exist
        else everything ends clipped */
        GetClientRect(hwnd, &r);
        hrgn = CreateRectRgnIndirect(&r);
        SelectClipRgn( hdc, hrgn);
        DeleteObject( hrgn );

        dis.CtlType      = ODT_LISTBOX;
        dis.CtlID        = id;
        dis.hwndItem     = hwnd;
        dis.itemAction   = action;
        dis.hDC          = hdc;
        dis.itemID       = index;
        dis.itemState    = 0;
        if (item && item->selected) dis.itemState |= ODS_SELECTED;
        if (!ignoreFocus && (descr->focus_item == index) &&
            (descr->caret_on) &&
            (descr->in_focus)) dis.itemState |= ODS_FOCUS;
        if (!IsWindowEnabled(hwnd)) dis.itemState |= ODS_DISABLED;
        dis.itemData     = item ? item->data : 0;
        dis.rcItem       = *rect;
        TRACE("[%04x]: drawitem %d (%s) action=%02x state=%02x rect=%d,%d-%d,%d\n",
              hwnd, index, item ? debugstr_w(item->str) : "", action,
              dis.itemState, rect->left, rect->top, rect->right, rect->bottom );
        SendMessageW(descr->owner, WM_DRAWITEM, id, (LPARAM)&dis);
    }
    else
    {
        COLORREF oldText = 0, oldBk = 0;

        if (action == ODA_FOCUS)
        {
            DrawFocusRect( hdc, rect );
            return;
        }
        if (item && item->selected)
        {
            oldBk = SetBkColor( hdc, GetSysColor( COLOR_HIGHLIGHT ) );
            oldText = SetTextColor( hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
        }

        TRACE("[%04x]: painting %d (%s) action=%02x rect=%d,%d-%d,%d\n",
              hwnd, index, item ? debugstr_w(item->str) : "", action,
              rect->left, rect->top, rect->right, rect->bottom );
        if (!item)
            ExtTextOutW( hdc, rect->left + 1, rect->top,
                           ETO_OPAQUE | ETO_CLIPPED, rect, NULL, 0, NULL );
        else if (!(descr->style & LBS_USETABSTOPS))
            ExtTextOutW( hdc, rect->left + 1, rect->top,
                         ETO_OPAQUE | ETO_CLIPPED, rect, item->str,
                         strlenW(item->str), NULL );
        else
	{
	    /* Output empty string to paint background in the full width. */
            ExtTextOutW( hdc, rect->left + 1, rect->top,
                         ETO_OPAQUE | ETO_CLIPPED, rect, NULL, 0, NULL );
            TabbedTextOutW( hdc, rect->left + 1 , rect->top,
                            item->str, strlenW(item->str),
                            descr->nb_tabs, descr->tabs, 0);
	}
        if (item && item->selected)
        {
            SetBkColor( hdc, oldBk );
            SetTextColor( hdc, oldText );
        }
        if (!ignoreFocus && (descr->focus_item == index) &&
            (descr->caret_on) &&
            (descr->in_focus)) DrawFocusRect( hdc, rect );
    }
}


/***********************************************************************
 *           LISTBOX_SetRedraw
 *
 * Change the redraw flag.
 */
static void LISTBOX_SetRedraw( HWND hwnd, LB_DESCR *descr, BOOL on )
{
    if (on)
    {
        if (!(descr->style & LBS_NOREDRAW)) return;
        descr->style &= ~LBS_NOREDRAW;
        if (descr->style & LBS_DISPLAYCHANGED)
        {     /* page was changed while setredraw false, refresh automatically */
            InvalidateRect(hwnd, NULL, TRUE);
            if ((descr->top_item + descr->page_size) > descr->nb_items)
            {      /* reset top of page if less than number of items/page */
                descr->top_item = descr->nb_items - descr->page_size;
                if (descr->top_item < 0) descr->top_item = 0;
            }
            descr->style &= ~LBS_DISPLAYCHANGED;
        }
        LISTBOX_UpdateScroll( hwnd, descr );
    }
    else descr->style |= LBS_NOREDRAW;
}


/***********************************************************************
 *           LISTBOX_RepaintItem
 *
 * Repaint a single item synchronously.
 */
static void LISTBOX_RepaintItem( HWND hwnd, LB_DESCR *descr, INT index,
                                 UINT action )
{
    HDC hdc;
    RECT rect;
    HFONT oldFont = 0;
    HBRUSH hbrush, oldBrush = 0;

    /* Do not repaint the item if the item is not visible */
    if (!IsWindowVisible(hwnd)) return;
    if (descr->style & LBS_NOREDRAW)
    {
       descr->style |= LBS_DISPLAYCHANGED;
       return;
    }
    if (LISTBOX_GetItemRect( descr, index, &rect ) != 1) return;
    if (!(hdc = GetDCEx( hwnd, 0, DCX_CACHE ))) return;
    if (descr->font) oldFont = SelectObject( hdc, descr->font );
    hbrush = SendMessageW( descr->owner, WM_CTLCOLORLISTBOX,
                             hdc, (LPARAM)hwnd );
    if (hbrush) oldBrush = SelectObject( hdc, hbrush );
    if (!IsWindowEnabled(hwnd))
        SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) );
    SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
    LISTBOX_PaintItem( hwnd, descr, hdc, &rect, index, action, FALSE );
    if (oldFont) SelectObject( hdc, oldFont );
    if (oldBrush) SelectObject( hdc, oldBrush );
    ReleaseDC( hwnd, hdc );
}


/***********************************************************************
 *           LISTBOX_InitStorage
 */
static LRESULT LISTBOX_InitStorage( HWND hwnd, LB_DESCR *descr, INT nb_items )
{
    LB_ITEMDATA *item;

    nb_items += LB_ARRAY_GRANULARITY - 1;
    nb_items -= (nb_items % LB_ARRAY_GRANULARITY);
    if (descr->items)
        nb_items += HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(*item);
    if (!(item = HeapReAlloc( GetProcessHeap(), 0, descr->items,
                              nb_items * sizeof(LB_ITEMDATA) )))
    {
        SEND_NOTIFICATION( hwnd, descr, LBN_ERRSPACE );
        return LB_ERRSPACE;
    }
    descr->items = item;
    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_SetTabStops
 */
static BOOL LISTBOX_SetTabStops( HWND hwnd, LB_DESCR *descr, INT count,
                                   LPINT tabs, BOOL short_ints )
{
    if (!(descr->style & LBS_USETABSTOPS)) return TRUE;
    if (descr->tabs) HeapFree( GetProcessHeap(), 0, descr->tabs );
    if (!(descr->nb_tabs = count))
    {
        descr->tabs = NULL;
        return TRUE;
    }
    /* FIXME: count = 1 */
    if (!(descr->tabs = (INT *)HeapAlloc( GetProcessHeap(), 0,
                                            descr->nb_tabs * sizeof(INT) )))
        return FALSE;
    if (short_ints)
    {
        INT i;
        LPINT16 p = (LPINT16)tabs;

        TRACE("[%04x]: settabstops ", hwnd );
        for (i = 0; i < descr->nb_tabs; i++) {
	    descr->tabs[i] = *p++<<1; /* FIXME */
            if (TRACE_ON(listbox)) DPRINTF("%hd ", descr->tabs[i]);
	}
        if (TRACE_ON(listbox)) DPRINTF("\n");
    }
    else memcpy( descr->tabs, tabs, descr->nb_tabs * sizeof(INT) );
    /* FIXME: repaint the window? */
    return TRUE;
}


/***********************************************************************
 *           LISTBOX_GetText
 */
static LRESULT LISTBOX_GetText( LB_DESCR *descr, INT index, LPARAM lParam, BOOL unicode )
{
    if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
    if (HAS_STRINGS(descr))
    {
        if (!lParam)
            return strlenW(descr->items[index].str);

	TRACE("index %d (0x%04x) %s\n", index, index, debugstr_w(descr->items[index].str));

        if(unicode)
        {
            LPWSTR buffer = (LPWSTR)lParam;
            strcpyW( buffer, descr->items[index].str );
            return strlenW(buffer);
        }
        else
        {
            LPSTR buffer = (LPSTR)lParam;
            return WideCharToMultiByte(CP_ACP, 0, descr->items[index].str, -1, buffer, 0x7FFFFFFF, NULL, NULL) - 1;
        }
    } else {
        if (lParam)
            *((LPDWORD)lParam)=*(LPDWORD)(&descr->items[index].data);
        return sizeof(DWORD);
    }
}


/***********************************************************************
 *           LISTBOX_FindStringPos
 *
 * Find the nearest string located before a given string in sort order.
 * If 'exact' is TRUE, return an error if we don't get an exact match.
 */
static INT LISTBOX_FindStringPos( HWND hwnd, LB_DESCR *descr, LPCWSTR str,
                                    BOOL exact )
{
    INT index, min, max, res = -1;

    if (!(descr->style & LBS_SORT)) return -1;  /* Add it at the end */
    min = 0;
    max = descr->nb_items;
    while (min != max)
    {
        index = (min + max) / 2;
        if (HAS_STRINGS(descr))
            res = lstrcmpiW( descr->items[index].str, str );
        else
        {
            COMPAREITEMSTRUCT cis;
            UINT id = GetWindowLongA( hwnd, GWL_ID );

            cis.CtlType    = ODT_LISTBOX;
            cis.CtlID      = id;
            cis.hwndItem   = hwnd;
            cis.itemID1    = index;
            cis.itemData1  = descr->items[index].data;
            cis.itemID2    = -1;
            cis.itemData2  = (DWORD)str;
            cis.dwLocaleId = descr->locale;
            res = SendMessageW( descr->owner, WM_COMPAREITEM, id, (LPARAM)&cis );
        }
        if (!res) return index;
        if (res > 0) max = index;
        else min = index + 1;
    }
    return exact ? -1 : max;
}


/***********************************************************************
 *           LISTBOX_FindFileStrPos
 *
 * Find the nearest string located before a given string in directory
 * sort order (i.e. first files, then directories, then drives).
 */
static INT LISTBOX_FindFileStrPos( HWND hwnd, LB_DESCR *descr, LPCWSTR str )
{
    INT min, max, res = -1;

    if (!HAS_STRINGS(descr))
        return LISTBOX_FindStringPos( hwnd, descr, str, FALSE );
    min = 0;
    max = descr->nb_items;
    while (min != max)
    {
        INT index = (min + max) / 2;
        LPCWSTR p = descr->items[index].str;
        if (*p == '[')  /* drive or directory */
        {
            if (*str != '[') res = -1;
            else if (p[1] == '-')  /* drive */
            {
                if (str[1] == '-') res = str[2] - p[2];
                else res = -1;
            }
            else  /* directory */
            {
                if (str[1] == '-') res = 1;
                else res = lstrcmpiW( str, p );
            }
        }
        else  /* filename */
        {
            if (*str == '[') res = 1;
            else res = lstrcmpiW( str, p );
        }
        if (!res) return index;
        if (res < 0) max = index;
        else min = index + 1;
    }
    return max;
}


/***********************************************************************
 *           LISTBOX_FindString
 *
 * Find the item beginning with a given string.
 */
static INT LISTBOX_FindString( HWND hwnd, LB_DESCR *descr, INT start,
                                 LPCWSTR str, BOOL exact )
{
    INT i;
    LB_ITEMDATA *item;

    if (start >= descr->nb_items) start = -1;
    item = descr->items + start + 1;
    if (HAS_STRINGS(descr))
    {
        if (!str || ! str[0] ) return LB_ERR;
        if (exact)
        {
            for (i = start + 1; i < descr->nb_items; i++, item++)
                if (!lstrcmpiW( str, item->str )) return i;
            for (i = 0, item = descr->items; i <= start; i++, item++)
                if (!lstrcmpiW( str, item->str )) return i;
        }
        else
        {
 /* Special case for drives and directories: ignore prefix */
#define CHECK_DRIVE(item) \
    if ((item)->str[0] == '[') \
    { \
        if (!strncmpiW( str, (item)->str+1, len )) return i; \
        if (((item)->str[1] == '-') && !strncmpiW(str, (item)->str+2, len)) \
        return i; \
    }

            INT len = strlenW(str);
            for (i = start + 1; i < descr->nb_items; i++, item++)
            {
               if (!strncmpiW( str, item->str, len )) return i;
               CHECK_DRIVE(item);
            }
            for (i = 0, item = descr->items; i <= start; i++, item++)
            {
               if (!strncmpiW( str, item->str, len )) return i;
               CHECK_DRIVE(item);
            }
#undef CHECK_DRIVE
        }
    }
    else
    {
        if (exact && (descr->style & LBS_SORT))
            /* If sorted, use a WM_COMPAREITEM binary search */
            return LISTBOX_FindStringPos( hwnd, descr, str, TRUE );

        /* Otherwise use a linear search */
        for (i = start + 1; i < descr->nb_items; i++, item++)
            if (item->data == (DWORD)str) return i;
        for (i = 0, item = descr->items; i <= start; i++, item++)
            if (item->data == (DWORD)str) return i;
    }
    return LB_ERR;
}


/***********************************************************************
 *           LISTBOX_GetSelCount
 */
static LRESULT LISTBOX_GetSelCount( LB_DESCR *descr )
{
    INT i, count;
    LB_ITEMDATA *item = descr->items;

    if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
    for (i = count = 0; i < descr->nb_items; i++, item++)
        if (item->selected) count++;
    return count;
}


/***********************************************************************
 *           LISTBOX_GetSelItems16
 */
static LRESULT LISTBOX_GetSelItems16( LB_DESCR *descr, INT16 max, LPINT16 array )
{
    INT i, count;
    LB_ITEMDATA *item = descr->items;

    if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
    for (i = count = 0; (i < descr->nb_items) && (count < max); i++, item++)
        if (item->selected) array[count++] = (INT16)i;
    return count;
}


/***********************************************************************
 *           LISTBOX_GetSelItems
 */
static LRESULT LISTBOX_GetSelItems( LB_DESCR *descr, INT max, LPINT array )
{
    INT i, count;
    LB_ITEMDATA *item = descr->items;

    if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
    for (i = count = 0; (i < descr->nb_items) && (count < max); i++, item++)
        if (item->selected) array[count++] = i;
    return count;
}


/***********************************************************************
 *           LISTBOX_Paint
 */
static LRESULT LISTBOX_Paint( HWND hwnd, LB_DESCR *descr, HDC hdc )
{
    INT i, col_pos = descr->page_size - 1;
    RECT rect;
    RECT focusRect = {-1, -1, -1, -1};
    HFONT oldFont = 0;
    HBRUSH hbrush, oldBrush = 0;

    if (descr->style & LBS_NOREDRAW) return 0;

    SetRect( &rect, 0, 0, descr->width, descr->height );
    if (descr->style & LBS_MULTICOLUMN)
        rect.right = rect.left + descr->column_width;
    else if (descr->horz_pos)
    {
        SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
        rect.right += descr->horz_pos;
    }

    if (descr->font) oldFont = SelectObject( hdc, descr->font );
    hbrush = SendMessageW( descr->owner, WM_CTLCOLORLISTBOX,
                             hdc, (LPARAM)hwnd );
    if (hbrush) oldBrush = SelectObject( hdc, hbrush );
    if (!IsWindowEnabled(hwnd)) SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) );

    if (!descr->nb_items && (descr->focus_item != -1) && descr->caret_on &&
        (descr->in_focus))
    {
        /* Special case for empty listbox: paint focus rect */
        rect.bottom = rect.top + descr->item_height;
        LISTBOX_PaintItem( hwnd, descr, hdc, &rect, descr->focus_item,
                           ODA_FOCUS, FALSE );
        rect.top = rect.bottom;
    }

    /* Paint all the item, regarding the selection
       Focus state will be painted after  */

    for (i = descr->top_item; i < descr->nb_items; i++)
    {
        if (!(descr->style & LBS_OWNERDRAWVARIABLE))
            rect.bottom = rect.top + descr->item_height;
        else
            rect.bottom = rect.top + descr->items[i].height;

        if (i == descr->focus_item)
        {
	    /* keep the focus rect, to paint the focus item after */
	    focusRect.left = rect.left;
	    focusRect.right = rect.right;
	    focusRect.top = rect.top;
	    focusRect.bottom = rect.bottom;
        }
        LISTBOX_PaintItem( hwnd, descr, hdc, &rect, i, ODA_DRAWENTIRE, TRUE );
        rect.top = rect.bottom;

        if ((descr->style & LBS_MULTICOLUMN) && !col_pos)
        {
            if (!IS_OWNERDRAW(descr))
            {
                /* Clear the bottom of the column */
                if (rect.top < descr->height)
                {
                    rect.bottom = descr->height;
                    ExtTextOutW( hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED,
                                   &rect, NULL, 0, NULL );
                }
            }

            /* Go to the next column */
            rect.left += descr->column_width;
            rect.right += descr->column_width;
            rect.top = 0;
            col_pos = descr->page_size - 1;
        }
        else
        {
            col_pos--;
            if (rect.top >= descr->height) break;
        }
    }

    /* Paint the focus item now */
    if (focusRect.top != focusRect.bottom && descr->caret_on)
        LISTBOX_PaintItem( hwnd, descr, hdc, &focusRect, descr->focus_item, ODA_FOCUS, FALSE );

    if (!IS_OWNERDRAW(descr))
    {
        /* Clear the remainder of the client area */
        if (rect.top < descr->height)
        {
            rect.bottom = descr->height;
            ExtTextOutW( hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED,
                           &rect, NULL, 0, NULL );
        }
        if (rect.right < descr->width)
        {
            rect.left   = rect.right;
            rect.right  = descr->width;
            rect.top    = 0;
            rect.bottom = descr->height;
            ExtTextOutW( hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED,
                           &rect, NULL, 0, NULL );
        }
    }
    if (oldFont) SelectObject( hdc, oldFont );
    if (oldBrush) SelectObject( hdc, oldBrush );
    return 0;
}


/***********************************************************************
 *           LISTBOX_InvalidateItems
 *
 * Invalidate all items from a given item. If the specified item is not
 * visible, nothing happens.
 */
static void LISTBOX_InvalidateItems( HWND hwnd, LB_DESCR *descr, INT index )
{
    RECT rect;

    if (LISTBOX_GetItemRect( descr, index, &rect ) == 1)
    {
        if (descr->style & LBS_NOREDRAW)
        {
            descr->style |= LBS_DISPLAYCHANGED;
            return;
        }
        rect.bottom = descr->height;
        InvalidateRect( hwnd, &rect, TRUE );
        if (descr->style & LBS_MULTICOLUMN)
        {
            /* Repaint the other columns */
            rect.left  = rect.right;
            rect.right = descr->width;
            rect.top   = 0;
            InvalidateRect( hwnd, &rect, TRUE );
        }
    }
}


/***********************************************************************
 *           LISTBOX_GetItemHeight
 */
static LRESULT LISTBOX_GetItemHeight( LB_DESCR *descr, INT index )
{
    if (descr->style & LBS_OWNERDRAWVARIABLE)
    {
        if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
        return descr->items[index].height;
    }
    else return descr->item_height;
}


/***********************************************************************
 *           LISTBOX_SetItemHeight
 */
static LRESULT LISTBOX_SetItemHeight( HWND hwnd, LB_DESCR *descr, INT index,
                                      INT height, BOOL repaint )
{
    if (!height) height = 1;

    if (descr->style & LBS_OWNERDRAWVARIABLE)
    {
        if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
        TRACE("[%04x]: item %d height = %d\n", hwnd, index, height );
        descr->items[index].height = height;
        LISTBOX_UpdateScroll( hwnd, descr );
	if (repaint)
	    LISTBOX_InvalidateItems( hwnd, descr, index );
    }
    else if (height != descr->item_height)
    {
        TRACE("[%04x]: new height = %d\n", hwnd, height );
        descr->item_height = height;
        LISTBOX_UpdatePage( hwnd, descr );
        LISTBOX_UpdateScroll( hwnd, descr );
	if (repaint)
	    InvalidateRect( hwnd, 0, TRUE );
    }
    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_SetHorizontalPos
 */
static void LISTBOX_SetHorizontalPos( HWND hwnd, LB_DESCR *descr, INT pos )
{
    INT diff;

    if (pos > descr->horz_extent - descr->width)
        pos = descr->horz_extent - descr->width;
    if (pos < 0) pos = 0;
    if (!(diff = descr->horz_pos - pos)) return;
    TRACE("[%04x]: new horz pos = %d\n", hwnd, pos );
    descr->horz_pos = pos;
    LISTBOX_UpdateScroll( hwnd, descr );
    if (abs(diff) < descr->width)
        ScrollWindowEx( hwnd, diff, 0, NULL, NULL, 0, NULL,
                          SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
    else
        InvalidateRect( hwnd, NULL, TRUE );
}


/***********************************************************************
 *           LISTBOX_SetHorizontalExtent
 */
static LRESULT LISTBOX_SetHorizontalExtent( HWND hwnd, LB_DESCR *descr,
                                            INT extent )
{
    if (!descr->horz_extent || (descr->style & LBS_MULTICOLUMN))
        return LB_OKAY;
    if (extent <= 0) extent = 1;
    if (extent == descr->horz_extent) return LB_OKAY;
    TRACE("[%04x]: new horz extent = %d\n", hwnd, extent );
    descr->horz_extent = extent;
    if (descr->horz_pos > extent - descr->width)
        LISTBOX_SetHorizontalPos( hwnd, descr, extent - descr->width );
    else
        LISTBOX_UpdateScroll( hwnd, descr );
    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_SetColumnWidth
 */
static LRESULT LISTBOX_SetColumnWidth( HWND hwnd, LB_DESCR *descr, INT width)
{
    if (width == descr->column_width) return LB_OKAY;
    TRACE("[%04x]: new column width = %d\n", hwnd, width );
    descr->column_width = width;
    LISTBOX_UpdatePage( hwnd, descr );
    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_SetFont
 *
 * Returns the item height.
 */
static INT LISTBOX_SetFont( HWND hwnd, LB_DESCR *descr, HFONT font )
{
    HDC hdc;
    HFONT oldFont = 0;
    TEXTMETRICW tm;

    descr->font = font;

    if (!(hdc = GetDCEx( hwnd, 0, DCX_CACHE )))
    {
        ERR("unable to get DC.\n" );
        return 16;
    }
    if (font) oldFont = SelectObject( hdc, font );
    GetTextMetricsW( hdc, &tm );
    if (oldFont) SelectObject( hdc, oldFont );
    ReleaseDC( hwnd, hdc );
    if (!IS_OWNERDRAW(descr))
        LISTBOX_SetItemHeight( hwnd, descr, 0, tm.tmHeight, FALSE );
    return tm.tmHeight ;
}


/***********************************************************************
 *           LISTBOX_MakeItemVisible
 *
 * Make sure that a given item is partially or fully visible.
 */
static void LISTBOX_MakeItemVisible( HWND hwnd, LB_DESCR *descr, INT index,
                                     BOOL fully )
{
    INT top;

    if (index <= descr->top_item) top = index;
    else if (descr->style & LBS_MULTICOLUMN)
    {
        INT cols = descr->width;
        if (!fully) cols += descr->column_width - 1;
        if (cols >= descr->column_width) cols /= descr->column_width;
        else cols = 1;
        if (index < descr->top_item + (descr->page_size * cols)) return;
        top = index - descr->page_size * (cols - 1);
    }
    else if (descr->style & LBS_OWNERDRAWVARIABLE)
    {
        INT height = fully ? descr->items[index].height : 1;
        for (top = index; top > descr->top_item; top--)
            if ((height += descr->items[top-1].height) > descr->height) break;
    }
    else
    {
        if (index < descr->top_item + descr->page_size) return;
        if (!fully && (index == descr->top_item + descr->page_size) &&
            (descr->height > (descr->page_size * descr->item_height))) return;
        top = index - descr->page_size + 1;
    }
    LISTBOX_SetTopItem( hwnd, descr, top, TRUE );
}

/***********************************************************************
 *           LISTBOX_SetCaretIndex
 *
 * NOTES
 *   index must be between 0 and descr->nb_items-1, or LB_ERR is returned.
 *
 */
static LRESULT LISTBOX_SetCaretIndex( HWND hwnd, LB_DESCR *descr, INT index,
                                      BOOL fully_visible )
{
    INT oldfocus = descr->focus_item;

    if (descr->style & LBS_NOSEL) return LB_ERR;
    if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
    if (index == oldfocus) return LB_OKAY;
    descr->focus_item = index;
    if ((oldfocus != -1) && descr->caret_on && (descr->in_focus))
        LISTBOX_RepaintItem( hwnd, descr, oldfocus, ODA_FOCUS );

    LISTBOX_MakeItemVisible( hwnd, descr, index, fully_visible );
    if (descr->caret_on && (descr->in_focus))
        LISTBOX_RepaintItem( hwnd, descr, index, ODA_FOCUS );

    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_SelectItemRange
 *
 * Select a range of items. Should only be used on a MULTIPLESEL listbox.
 */
static LRESULT LISTBOX_SelectItemRange( HWND hwnd, LB_DESCR *descr, INT first,
                                        INT last, BOOL on )
{
    INT i;

    /* A few sanity checks */

    if (descr->style & LBS_NOSEL) return LB_ERR;
    if ((last == -1) && (descr->nb_items == 0)) return LB_OKAY;
    if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
    if (last == -1) last = descr->nb_items - 1;
    if ((first < 0) || (first >= descr->nb_items)) return LB_ERR;
    if ((last < 0) || (last >= descr->nb_items)) return LB_ERR;
    /* selected_item reflects last selected/unselected item on multiple sel */
    descr->selected_item = last;

    if (on)  /* Turn selection on */
    {
        for (i = first; i <= last; i++)
        {
            if (descr->items[i].selected) continue;
            descr->items[i].selected = TRUE;
            LISTBOX_RepaintItem( hwnd, descr, i, ODA_SELECT );
        }
        LISTBOX_SetCaretIndex( hwnd, descr, last, TRUE );
    }
    else  /* Turn selection off */
    {
        for (i = first; i <= last; i++)
        {
            if (!descr->items[i].selected) continue;
            descr->items[i].selected = FALSE;
            LISTBOX_RepaintItem( hwnd, descr, i, ODA_SELECT );
        }
    }
    return LB_OKAY;
}

/***********************************************************************
 *           LISTBOX_SetSelection
 */
static LRESULT LISTBOX_SetSelection( HWND hwnd, LB_DESCR *descr, INT index,
                                     BOOL on, BOOL send_notify )
{
    TRACE( "index=%d notify=%s\n", index, send_notify ? "YES" : "NO" );

    if (descr->style & LBS_NOSEL) return LB_ERR;
    if ((index < -1) || (index >= descr->nb_items)) return LB_ERR;
    if (descr->style & LBS_MULTIPLESEL)
    {
        if (index == -1)  /* Select all items */
            return LISTBOX_SelectItemRange( hwnd, descr, 0, -1, on );
        else  /* Only one item */
            return LISTBOX_SelectItemRange( hwnd, descr, index, index, on );
    }
    else
    {
        INT oldsel = descr->selected_item;
        if (index == oldsel) return LB_OKAY;
        if (oldsel != -1) descr->items[oldsel].selected = FALSE;
        if (index != -1) descr->items[index].selected = TRUE;
        descr->selected_item = index;
        if (oldsel != -1) LISTBOX_RepaintItem( hwnd, descr, oldsel, ODA_SELECT );
        if (index != -1) LISTBOX_RepaintItem( hwnd, descr, index, ODA_SELECT );
        if (send_notify && descr->nb_items) SEND_NOTIFICATION( hwnd, descr,
                               (index != -1) ? LBN_SELCHANGE : LBN_SELCANCEL );
	else
	    if( descr->lphc ) /* set selection change flag for parent combo */
		descr->lphc->wState |= CBF_SELCHANGE;
    }
    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_MoveCaret
 *
 * Change the caret position and extend the selection to the new caret.
 */
static void LISTBOX_MoveCaret( HWND hwnd, LB_DESCR *descr, INT index,
                               BOOL fully_visible )
{
    INT oldfocus = descr->focus_item;

    if ((index <  0) || (index >= descr->nb_items))
        return;

    /* Important, repaint needs to be done in this order if
       you want to mimic Windows behavior:
       1. Remove the focus and paint the item  
       2. Remove the selection and paint the item(s)
       3. Set the selection and repaint the item(s)
       4. Set the focus to 'index' and repaint the item */

    /* 1. remove the focus and repaint the item */
    descr->focus_item = -1;
    if ((oldfocus != -1) && descr->caret_on && (descr->in_focus))
        LISTBOX_RepaintItem( hwnd, descr, oldfocus, ODA_FOCUS );

    /* 2. then turn off the previous selection */
    /* 3. repaint the new selected item */
    if (descr->style & LBS_EXTENDEDSEL)
    {
        if (descr->anchor_item != -1)
        {
            INT first = min( index, descr->anchor_item );
            INT last  = max( index, descr->anchor_item );
            if (first > 0)
                LISTBOX_SelectItemRange( hwnd, descr, 0, first - 1, FALSE );
            LISTBOX_SelectItemRange( hwnd, descr, last + 1, -1, FALSE );
            LISTBOX_SelectItemRange( hwnd, descr, first, last, TRUE );
        }
    }
    else if (!(descr->style & LBS_MULTIPLESEL))
    {
        /* Set selection to new caret item */
        LISTBOX_SetSelection( hwnd, descr, index, TRUE, FALSE );
    }

    /* 4. repaint the new item with the focus */
    descr->focus_item = index;
    LISTBOX_MakeItemVisible( hwnd, descr, index, fully_visible );
    if (descr->caret_on && (descr->in_focus))
        LISTBOX_RepaintItem( hwnd, descr, index, ODA_FOCUS );
}


/***********************************************************************
 *           LISTBOX_InsertItem
 */
static LRESULT LISTBOX_InsertItem( HWND hwnd, LB_DESCR *descr, INT index,
                                   LPWSTR str, DWORD data )
{
    LB_ITEMDATA *item;
    INT max_items;
    INT oldfocus = descr->focus_item;

    if (index == -1) index = descr->nb_items;
    else if ((index < 0) || (index > descr->nb_items)) return LB_ERR;
    if (!descr->items) max_items = 0;
    else max_items = HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(*item);
    if (descr->nb_items == max_items)
    {
        /* We need to grow the array */
        max_items += LB_ARRAY_GRANULARITY;
        if (!(item = HeapReAlloc( GetProcessHeap(), 0, descr->items,
                                  max_items * sizeof(LB_ITEMDATA) )))
        {
            SEND_NOTIFICATION( hwnd, descr, LBN_ERRSPACE );
            return LB_ERRSPACE;
        }
        descr->items = item;
    }

    /* Insert the item structure */

    item = &descr->items[index];
    if (index < descr->nb_items)
        RtlMoveMemory( item + 1, item,
                       (descr->nb_items - index) * sizeof(LB_ITEMDATA) );
    item->str      = str;
    item->data     = data;
    item->height   = 0;
    item->selected = FALSE;
    descr->nb_items++;

    /* Get item height */

    if (descr->style & LBS_OWNERDRAWVARIABLE)
    {
        MEASUREITEMSTRUCT mis;
        UINT id = GetWindowLongA( hwnd, GWL_ID );

        mis.CtlType    = ODT_LISTBOX;
        mis.CtlID      = id;
        mis.itemID     = index;
        mis.itemData   = descr->items[index].data;
        mis.itemHeight = descr->item_height;
        SendMessageW( descr->owner, WM_MEASUREITEM, id, (LPARAM)&mis );
        item->height = mis.itemHeight ? mis.itemHeight : 1;
        TRACE("[%04x]: measure item %d (%s) = %d\n",
              hwnd, index, str ? debugstr_w(str) : "", item->height );
    }

    /* Repaint the items */

    LISTBOX_UpdateScroll( hwnd, descr );
    LISTBOX_InvalidateItems( hwnd, descr, index );

    /* Move selection and focused item */
    /* If listbox was empty, set focus to the first item */
    if (descr->nb_items == 1)
         LISTBOX_SetCaretIndex( hwnd, descr, 0, FALSE );
    /* single select don't change selection index in win31 */
    else if ((ISWIN31) && !(IS_MULTISELECT(descr)))
    {
        descr->selected_item++;
        LISTBOX_SetSelection( hwnd, descr, descr->selected_item-1, TRUE, FALSE );
    }
    else
    {
        if (index <= descr->selected_item)
        {
           descr->selected_item++;
           descr->focus_item = oldfocus; /* focus not changed */
        }
    }
    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_InsertString
 */
static LRESULT LISTBOX_InsertString( HWND hwnd, LB_DESCR *descr, INT index,
                                     LPCWSTR str )
{
    LPWSTR new_str = NULL;
    DWORD data = 0;
    LRESULT ret;

    if (HAS_STRINGS(descr))
    {
        static const WCHAR empty_stringW[] = { 0 };
        if (!str) str = empty_stringW;
        if (!(new_str = HeapAlloc( GetProcessHeap(), 0, (strlenW(str) + 1) * sizeof(WCHAR) )))
        {
            SEND_NOTIFICATION( hwnd, descr, LBN_ERRSPACE );
            return LB_ERRSPACE;
        }
        strcpyW(new_str, str);
    }
    else data = (DWORD)str;

    if (index == -1) index = descr->nb_items;
    if ((ret = LISTBOX_InsertItem( hwnd, descr, index, new_str, data )) != 0)
    {
        if (new_str) HeapFree( GetProcessHeap(), 0, new_str );
        return ret;
    }

    TRACE("[%04x]: added item %d %s\n",
          hwnd, index, HAS_STRINGS(descr) ? debugstr_w(new_str) : "" );
    return index;
}


/***********************************************************************
 *           LISTBOX_DeleteItem
 *
 * Delete the content of an item. 'index' must be a valid index.
 */
static void LISTBOX_DeleteItem( HWND hwnd, LB_DESCR *descr, INT index )
{
    /* Note: Win 3.1 only sends DELETEITEM on owner-draw items,
     *       while Win95 sends it for all items with user data.
     *       It's probably better to send it too often than not
     *       often enough, so this is what we do here.
     */
    if (IS_OWNERDRAW(descr) || descr->items[index].data)
    {
        DELETEITEMSTRUCT dis;
        UINT id = GetWindowLongA( hwnd, GWL_ID );

        dis.CtlType  = ODT_LISTBOX;
        dis.CtlID    = id;
        dis.itemID   = index;
        dis.hwndItem = hwnd;
        dis.itemData = descr->items[index].data;
        SendMessageW( descr->owner, WM_DELETEITEM, id, (LPARAM)&dis );
    }
    if (HAS_STRINGS(descr) && descr->items[index].str)
        HeapFree( GetProcessHeap(), 0, descr->items[index].str );
}


/***********************************************************************
 *           LISTBOX_RemoveItem
 *
 * Remove an item from the listbox and delete its content.
 */
static LRESULT LISTBOX_RemoveItem( HWND hwnd, LB_DESCR *descr, INT index )
{
    LB_ITEMDATA *item;
    INT max_items;

    if ((index == -1) && (descr->nb_items > 0)) index = descr->nb_items - 1;
    else if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;

    /* We need to invalidate the original rect instead of the updated one. */
    LISTBOX_InvalidateItems( hwnd, descr, index );

    LISTBOX_DeleteItem( hwnd, descr, index );

    /* Remove the item */

    item = &descr->items[index];
    if (index < descr->nb_items-1)
        RtlMoveMemory( item, item + 1,
                       (descr->nb_items - index - 1) * sizeof(LB_ITEMDATA) );
    descr->nb_items--;
    if (descr->anchor_item == descr->nb_items) descr->anchor_item--;

    /* Shrink the item array if possible */

    max_items = HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(LB_ITEMDATA);
    if (descr->nb_items < max_items - 2*LB_ARRAY_GRANULARITY)
    {
        max_items -= LB_ARRAY_GRANULARITY;
        item = HeapReAlloc( GetProcessHeap(), 0, descr->items,
                            max_items * sizeof(LB_ITEMDATA) );
        if (item) descr->items = item;
    }
    /* Repaint the items */

    LISTBOX_UpdateScroll( hwnd, descr );
    /* if we removed the scrollbar, reset the top of the list
      (correct for owner-drawn ???) */
    if (descr->nb_items == descr->page_size)
        LISTBOX_SetTopItem( hwnd, descr, 0, TRUE );

    /* Move selection and focused item */
    if (!IS_MULTISELECT(descr))
    {
        if (index == descr->selected_item)
            descr->selected_item = -1;
        else if (index < descr->selected_item)
    {
            descr->selected_item--;
            if (ISWIN31) /* win 31 do not change the selected item number */
               LISTBOX_SetSelection( hwnd, descr, descr->selected_item + 1, TRUE, FALSE);
    }
    }

    if (descr->focus_item >= descr->nb_items)
    {
          descr->focus_item = descr->nb_items - 1;
          if (descr->focus_item < 0) descr->focus_item = 0;
    }
    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_ResetContent
 */
static void LISTBOX_ResetContent( HWND hwnd, LB_DESCR *descr )
{
    INT i;

    for (i = 0; i < descr->nb_items; i++) LISTBOX_DeleteItem( hwnd, descr, i );
    if (descr->items) HeapFree( GetProcessHeap(), 0, descr->items );
    descr->nb_items      = 0;
    descr->top_item      = 0;
    descr->selected_item = -1;
    descr->focus_item    = 0;
    descr->anchor_item   = -1;
    descr->items         = NULL;
}


/***********************************************************************
 *           LISTBOX_SetCount
 */
static LRESULT LISTBOX_SetCount( HWND hwnd, LB_DESCR *descr, INT count )
{
    LRESULT ret;

    if (HAS_STRINGS(descr)) return LB_ERR;
    /* FIXME: this is far from optimal... */
    if (count > descr->nb_items)
    {
        while (count > descr->nb_items)
            if ((ret = LISTBOX_InsertString( hwnd, descr, -1, 0 )) < 0)
                return ret;
    }
    else if (count < descr->nb_items)
    {
        while (count < descr->nb_items)
            if ((ret = LISTBOX_RemoveItem( hwnd, descr, -1 )) < 0)
                return ret;
    }
    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_Directory
 */
static LRESULT LISTBOX_Directory( HWND hwnd, LB_DESCR *descr, UINT attrib,
                                  LPCWSTR filespec, BOOL long_names )
{
    HANDLE handle;
    LRESULT ret = LB_OKAY;
    WIN32_FIND_DATAW entry;
    int pos;

    /* don't scan directory if we just want drives exclusively */
    if (attrib != (DDL_DRIVES | DDL_EXCLUSIVE)) {
        /* scan directory */
        if ((handle = FindFirstFileW(filespec, &entry)) == INVALID_HANDLE_VALUE)
        {
            if (GetLastError() != ERROR_NO_MORE_FILES) return LB_ERR;
        }
        else
        {
            do
            {
                WCHAR buffer[270];
                if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {
                    static const WCHAR bracketW[]  = { ']',0 };
                    static const WCHAR dotW[] = { '.',0 };
                    if (!(attrib & DDL_DIRECTORY) ||
                        !strcmpW( entry.cAlternateFileName, dotW )) continue;
                    buffer[0] = '[';
                    if (long_names) strcpyW( buffer + 1, entry.cFileName );
                    else strcpyW( buffer + 1, entry.cAlternateFileName );
                    strcatW(buffer, bracketW);
                }
                else  /* not a directory */
                {
#define ATTRIBS (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE)

                    if ((attrib & DDL_EXCLUSIVE) &&
                        ((attrib & ATTRIBS) != (entry.dwFileAttributes & ATTRIBS)))
                        continue;
#undef ATTRIBS
                    if (long_names) strcpyW( buffer, entry.cFileName );
                    else strcpyW( buffer, entry.cAlternateFileName );
                }
                if (!long_names) CharLowerW( buffer );
                pos = LISTBOX_FindFileStrPos( hwnd, descr, buffer );
                if ((ret = LISTBOX_InsertString( hwnd, descr, pos, buffer )) < 0)
                    break;
            } while (FindNextFileW( handle, &entry ));
            FindClose( handle );
        }
    }

    /* scan drives */
    if ((ret >= 0) && (attrib & DDL_DRIVES))
    {
        WCHAR buffer[] = {'[','-','a','-',']',0};
        WCHAR root[] = {'A',':','\\',0};
        int drive;
        for (drive = 0; drive < 26; drive++, buffer[2]++, root[0]++)
        {
            if (GetDriveTypeW(root) <= DRIVE_NO_ROOT_DIR) continue;
            if ((ret = LISTBOX_InsertString( hwnd, descr, -1, buffer )) < 0)
                break;
        }
    }
    return ret;
}


/***********************************************************************
 *           LISTBOX_HandleVScroll
 */
static LRESULT LISTBOX_HandleVScroll( HWND hwnd, LB_DESCR *descr, WPARAM wParam )
{
    SCROLLINFO info;

    if (descr->style & LBS_MULTICOLUMN) return 0;
    switch(LOWORD(wParam))
    {
    case SB_LINEUP:
        LISTBOX_SetTopItem( hwnd, descr, descr->top_item - 1, TRUE );
        break;
    case SB_LINEDOWN:
        LISTBOX_SetTopItem( hwnd, descr, descr->top_item + 1, TRUE );
        break;
    case SB_PAGEUP:
        LISTBOX_SetTopItem( hwnd, descr, descr->top_item -
                            LISTBOX_GetCurrentPageSize( descr ), TRUE );
        break;
    case SB_PAGEDOWN:
        LISTBOX_SetTopItem( hwnd, descr, descr->top_item +
                            LISTBOX_GetCurrentPageSize( descr ), TRUE );
        break;
    case SB_THUMBPOSITION:
        LISTBOX_SetTopItem( hwnd, descr, HIWORD(wParam), TRUE );
        break;
    case SB_THUMBTRACK:
        info.cbSize = sizeof(info);
        info.fMask = SIF_TRACKPOS;
        GetScrollInfo( hwnd, SB_VERT, &info );
        LISTBOX_SetTopItem( hwnd, descr, info.nTrackPos, TRUE );
        break;
    case SB_TOP:
        LISTBOX_SetTopItem( hwnd, descr, 0, TRUE );
        break;
    case SB_BOTTOM:
        LISTBOX_SetTopItem( hwnd, descr, descr->nb_items, TRUE );
        break;
    }
    return 0;
}


/***********************************************************************
 *           LISTBOX_HandleHScroll
 */
static LRESULT LISTBOX_HandleHScroll( HWND hwnd, LB_DESCR *descr, WPARAM wParam )
{
    SCROLLINFO info;
    INT page;

    if (descr->style & LBS_MULTICOLUMN)
    {
        switch(LOWORD(wParam))
        {
        case SB_LINELEFT:
            LISTBOX_SetTopItem( hwnd, descr, descr->top_item-descr->page_size,
                                TRUE );
            break;
        case SB_LINERIGHT:
            LISTBOX_SetTopItem( hwnd, descr, descr->top_item+descr->page_size,
                                TRUE );
            break;
        case SB_PAGELEFT:
            page = descr->width / descr->column_width;
            if (page < 1) page = 1;
            LISTBOX_SetTopItem( hwnd, descr,
                             descr->top_item - page * descr->page_size, TRUE );
            break;
        case SB_PAGERIGHT:
            page = descr->width / descr->column_width;
            if (page < 1) page = 1;
            LISTBOX_SetTopItem( hwnd, descr,
                             descr->top_item + page * descr->page_size, TRUE );
            break;
        case SB_THUMBPOSITION:
            LISTBOX_SetTopItem( hwnd, descr, HIWORD(wParam)*descr->page_size,
                                TRUE );
            break;
        case SB_THUMBTRACK:
            info.cbSize = sizeof(info);
            info.fMask  = SIF_TRACKPOS;
            GetScrollInfo( hwnd, SB_VERT, &info );
            LISTBOX_SetTopItem( hwnd, descr, info.nTrackPos*descr->page_size,
                                TRUE );
            break;
        case SB_LEFT:
            LISTBOX_SetTopItem( hwnd, descr, 0, TRUE );
            break;
        case SB_RIGHT:
            LISTBOX_SetTopItem( hwnd, descr, descr->nb_items, TRUE );
            break;
        }
    }
    else if (descr->horz_extent)
    {
        switch(LOWORD(wParam))
        {
        case SB_LINELEFT:
            LISTBOX_SetHorizontalPos( hwnd, descr, descr->horz_pos - 1 );
            break;
        case SB_LINERIGHT:
            LISTBOX_SetHorizontalPos( hwnd, descr, descr->horz_pos + 1 );
            break;
        case SB_PAGELEFT:
            LISTBOX_SetHorizontalPos( hwnd, descr,
                                      descr->horz_pos - descr->width );
            break;
        case SB_PAGERIGHT:
            LISTBOX_SetHorizontalPos( hwnd, descr,
                                      descr->horz_pos + descr->width );
            break;
        case SB_THUMBPOSITION:
            LISTBOX_SetHorizontalPos( hwnd, descr, HIWORD(wParam) );
            break;
        case SB_THUMBTRACK:
            info.cbSize = sizeof(info);
            info.fMask = SIF_TRACKPOS;
            GetScrollInfo( hwnd, SB_HORZ, &info );
            LISTBOX_SetHorizontalPos( hwnd, descr, info.nTrackPos );
            break;
        case SB_LEFT:
            LISTBOX_SetHorizontalPos( hwnd, descr, 0 );
            break;
        case SB_RIGHT:
            LISTBOX_SetHorizontalPos( hwnd, descr,
                                      descr->horz_extent - descr->width );
            break;
        }
    }
    return 0;
}

static LRESULT LISTBOX_HandleMouseWheel(HWND hwnd, LB_DESCR *descr, WPARAM wParam )
{
    short gcWheelDelta = 0;
    UINT pulScrollLines = 3;

    SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);

    gcWheelDelta -= (short) HIWORD(wParam);

    if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines)
    {
        int cLineScroll = (int) min((UINT) descr->page_size, pulScrollLines);
        cLineScroll *= (gcWheelDelta / WHEEL_DELTA);
        LISTBOX_SetTopItem( hwnd, descr, descr->top_item + cLineScroll, TRUE );
    }
    return 0;
}

/***********************************************************************
 *           LISTBOX_HandleLButtonDown
 */
static LRESULT LISTBOX_HandleLButtonDown( HWND hwnd, LB_DESCR *descr,
                                          WPARAM wParam, INT x, INT y )
{
    INT index = LISTBOX_GetItemFromPoint( descr, x, y );
    TRACE("[%04x]: lbuttondown %d,%d item %d\n", hwnd, x, y, index );
    if (!descr->caret_on && (descr->in_focus)) return 0;

    if (!descr->in_focus)
    {
        if( !descr->lphc ) SetFocus( hwnd );
        else SetFocus( (descr->lphc->hWndEdit) ? descr->lphc->hWndEdit : descr->lphc->self );
    }

    if (index == -1) return 0;

    if (descr->style & LBS_EXTENDEDSEL)
    {
        /* we should perhaps make sure that all items are deselected
           FIXME: needed for !LBS_EXTENDEDSEL, too ?
           if (!(wParam & (MK_SHIFT|MK_CONTROL)))
           LISTBOX_SetSelection( hwnd, descr, -1, FALSE, FALSE);
        */

        if (!(wParam & MK_SHIFT)) descr->anchor_item = index;
        if (wParam & MK_CONTROL)
        {
            LISTBOX_SetCaretIndex( hwnd, descr, index, FALSE );
            LISTBOX_SetSelection( hwnd, descr, index,
                                  !descr->items[index].selected,
                                  (descr->style & LBS_NOTIFY) != 0);
        }
        else LISTBOX_MoveCaret( hwnd, descr, index, FALSE );
    }
    else
    {
        LISTBOX_MoveCaret( hwnd, descr, index, FALSE );
        LISTBOX_SetSelection( hwnd, descr, index,
                              (!(descr->style & LBS_MULTIPLESEL) ||
                               !descr->items[index].selected),
                              (descr->style & LBS_NOTIFY) != 0 );
    }

    descr->captured = TRUE;
    SetCapture( hwnd );

    if (!descr->lphc)
    {
        if (descr->style & LBS_NOTIFY )
            SendMessageW( descr->owner, WM_LBTRACKPOINT, index,
                            MAKELPARAM( x, y ) );
        if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_DRAGDETECT)
        {
            POINT pt;

	    pt.x = x;
	    pt.y = y;

            if (DragDetect( hwnd, pt ))
                SendMessageW( descr->owner, WM_BEGINDRAG, 0, 0 );
        }
    }
    return 0;
}


/*************************************************************************
 * LISTBOX_HandleLButtonDownCombo [Internal]
 *
 * Process LButtonDown message for the ComboListBox
 *
nn * PARAMS
 *     pWnd       [I] The windows internal structure
 *     pDescr     [I] The ListBox internal structure
 *     wParam     [I] Key Flag (WM_LBUTTONDOWN doc for more info)
 *     x          [I] X Mouse Coordinate
 *     y          [I] Y Mouse Coordinate
 *
 * RETURNS
 *     0 since we are processing the WM_LBUTTONDOWN Message
 *
 * NOTES
 *  This function is only to be used when a ListBox is a ComboListBox
 */

static LRESULT LISTBOX_HandleLButtonDownCombo( HWND hwnd, LB_DESCR *pDescr,
                                               UINT msg, WPARAM wParam, INT x, INT y)
{
    RECT clientRect, screenRect;
    POINT mousePos;

    mousePos.x = x;
    mousePos.y = y;

    GetClientRect(hwnd, &clientRect);

    if(PtInRect(&clientRect, mousePos))
    {
       /* MousePos is in client, resume normal processing */
        if (msg == WM_LBUTTONDOWN)
        {
           pDescr->lphc->droppedIndex = pDescr->nb_items ? pDescr->selected_item : -1;
           return LISTBOX_HandleLButtonDown( hwnd, pDescr, wParam, x, y);
        }
        else if (pDescr->style & LBS_NOTIFY)
            SEND_NOTIFICATION( hwnd, pDescr, LBN_DBLCLK );
        return 0;
    }
    else
    {
        POINT screenMousePos;
        HWND hWndOldCapture;

        /* Check the Non-Client Area */
        screenMousePos = mousePos;
        hWndOldCapture = GetCapture();
        ReleaseCapture();
        GetWindowRect(hwnd, &screenRect);
        ClientToScreen(hwnd, &screenMousePos);

        if(!PtInRect(&screenRect, screenMousePos))
        {
            LISTBOX_SetCaretIndex( hwnd, pDescr, pDescr->lphc->droppedIndex, FALSE );
            LISTBOX_SetSelection( hwnd, pDescr, pDescr->lphc->droppedIndex, FALSE, FALSE );
            COMBO_FlipListbox( pDescr->lphc, FALSE, FALSE );
            return 0;
        }
        else
        {
            /* Check to see the NC is a scrollbar */
            INT nHitTestType=0;
            LONG style = GetWindowLongA( hwnd, GWL_STYLE );
            /* Check Vertical scroll bar */
            if (style & WS_VSCROLL)
            {
                clientRect.right += GetSystemMetrics(SM_CXVSCROLL);
                if (PtInRect( &clientRect, mousePos ))
                {
                    nHitTestType = HTVSCROLL;
                }
            }
              /* Check horizontal scroll bar */
            if (style & WS_HSCROLL)
            {
                clientRect.bottom += GetSystemMetrics(SM_CYHSCROLL);
                if (PtInRect( &clientRect, mousePos ))
                {
                    nHitTestType = HTHSCROLL;
                }
            }
            /* Windows sends this message when a scrollbar is clicked 
             */

            if(nHitTestType != 0)
            {
                SendMessageW(hwnd, WM_NCLBUTTONDOWN, nHitTestType,
                    MAKELONG(screenMousePos.x, screenMousePos.y));
            }
            /* Resume the Capture after scrolling is complete 
             */
            if(hWndOldCapture != 0)
            {
                SetCapture(hWndOldCapture);
            }
        }
    }
    return 0;
}

/***********************************************************************
 *           LISTBOX_HandleLButtonUp
 */
static LRESULT LISTBOX_HandleLButtonUp( HWND hwnd, LB_DESCR *descr )
{
    if (LISTBOX_Timer != LB_TIMER_NONE)
        KillSystemTimer( hwnd, LB_TIMER_ID );
    LISTBOX_Timer = LB_TIMER_NONE;
    if (descr->captured)
    {
        descr->captured = FALSE;
        if (GetCapture() == hwnd) ReleaseCapture();
        if ((descr->style & LBS_NOTIFY) && descr->nb_items)
            SEND_NOTIFICATION( hwnd, descr, LBN_SELCHANGE );
    }
    return 0;
}


/***********************************************************************
 *           LISTBOX_HandleTimer
 *
 * Handle scrolling upon a timer event.
 * Return TRUE if scrolling should continue.
 */
static LRESULT LISTBOX_HandleTimer( HWND hwnd, LB_DESCR *descr,
                                    INT index, TIMER_DIRECTION dir )
{
    switch(dir)
    {
    case LB_TIMER_UP:
        if (descr->top_item) index = descr->top_item - 1;
        else index = 0;
        break;
    case LB_TIMER_LEFT:
        if (descr->top_item) index -= descr->page_size;
        break;
    case LB_TIMER_DOWN:
        index = descr->top_item + LISTBOX_GetCurrentPageSize( descr );
        if (index == descr->focus_item) index++;
        if (index >= descr->nb_items) index = descr->nb_items - 1;
        break;
    case LB_TIMER_RIGHT:
        if (index + descr->page_size < descr->nb_items)
            index += descr->page_size;
        break;
    case LB_TIMER_NONE:
        break;
    }
    if (index == descr->focus_item) return FALSE;
    LISTBOX_MoveCaret( hwnd, descr, index, FALSE );
    return TRUE;
}


/***********************************************************************
 *           LISTBOX_HandleSystemTimer
 *
 * WM_SYSTIMER handler.
 */
static LRESULT LISTBOX_HandleSystemTimer( HWND hwnd, LB_DESCR *descr )
{
    if (!LISTBOX_HandleTimer( hwnd, descr, descr->focus_item, LISTBOX_Timer ))
    {
        KillSystemTimer( hwnd, LB_TIMER_ID );
        LISTBOX_Timer = LB_TIMER_NONE;
    }
    return 0;
}


/***********************************************************************
 *           LISTBOX_HandleMouseMove
 *
 * WM_MOUSEMOVE handler.
 */
static void LISTBOX_HandleMouseMove( HWND hwnd, LB_DESCR *descr,
                                     INT x, INT y )
{
    INT index;
    TIMER_DIRECTION dir = LB_TIMER_NONE;

    if (!descr->captured) return;

    if (descr->style & LBS_MULTICOLUMN)
    {
        if (y < 0) y = 0;
        else if (y >= descr->item_height * descr->page_size)
            y = descr->item_height * descr->page_size - 1;

        if (x < 0)
        {
            dir = LB_TIMER_LEFT;
            x = 0;
        }
        else if (x >= descr->width)
        {
            dir = LB_TIMER_RIGHT;
            x = descr->width - 1;
        }
    }
    else
    {
        if (y < 0) dir = LB_TIMER_UP;  /* above */
        else if (y >= descr->height) dir = LB_TIMER_DOWN;  /* below */
    }

    index = LISTBOX_GetItemFromPoint( descr, x, y );
    if (index == -1) index = descr->focus_item;
    if (!LISTBOX_HandleTimer( hwnd, descr, index, dir )) dir = LB_TIMER_NONE;

    /* Start/stop the system timer */

    if (dir != LB_TIMER_NONE)
        SetSystemTimer( hwnd, LB_TIMER_ID, LB_SCROLL_TIMEOUT, NULL);
    else if (LISTBOX_Timer != LB_TIMER_NONE)
        KillSystemTimer( hwnd, LB_TIMER_ID );
    LISTBOX_Timer = dir;
}


/***********************************************************************
 *           LISTBOX_HandleKeyDown
 */
static LRESULT LISTBOX_HandleKeyDown( HWND hwnd, LB_DESCR *descr, WPARAM wParam )
{
    INT caret = -1;
    BOOL bForceSelection = TRUE; /* select item pointed to by focus_item */
    if ((IS_MULTISELECT(descr)) || (descr->selected_item == descr->focus_item))
       bForceSelection = FALSE; /* only for single select list */

    if (descr->style & LBS_WANTKEYBOARDINPUT)
    {
        caret = SendMessageW( descr->owner, WM_VKEYTOITEM,
                                MAKEWPARAM(LOWORD(wParam), descr->focus_item),
                                hwnd );
        if (caret == -2) return 0;
    }
    if (caret == -1) switch(wParam)
    {
    case VK_LEFT:
        if (descr->style & LBS_MULTICOLUMN)
        {
            bForceSelection = FALSE;
            if (descr->focus_item >= descr->page_size)
                caret = descr->focus_item - descr->page_size;
            break;
        }
        /* fall through */
    case VK_UP:
        caret = descr->focus_item - 1;
        if (caret < 0) caret = 0;
        break;
    case VK_RIGHT:
        if (descr->style & LBS_MULTICOLUMN)
        {
            bForceSelection = FALSE;
            if (descr->focus_item + descr->page_size < descr->nb_items)
                caret = descr->focus_item + descr->page_size;
            break;
        }
        /* fall through */
    case VK_DOWN:
        caret = descr->focus_item + 1;
        if (caret >= descr->nb_items) caret = descr->nb_items - 1;
        break;

    case VK_PRIOR:
        if (descr->style & LBS_MULTICOLUMN)
        {
            INT page = descr->width / descr->column_width;
            if (page < 1) page = 1;
            caret = descr->focus_item - (page * descr->page_size) + 1;
        }
        else caret = descr->focus_item-LISTBOX_GetCurrentPageSize(descr) + 1;
        if (caret < 0) caret = 0;
        break;
    case VK_NEXT:
        if (descr->style & LBS_MULTICOLUMN)
        {
            INT page = descr->width / descr->column_width;
            if (page < 1) page = 1;
            caret = descr->focus_item + (page * descr->page_size) - 1;
        }
        else caret = descr->focus_item + LISTBOX_GetCurrentPageSize(descr) - 1;
        if (caret >= descr->nb_items) caret = descr->nb_items - 1;
        break;
    case VK_HOME:
        caret = 0;
        break;
    case VK_END:
        caret = descr->nb_items - 1;
        break;
    case VK_SPACE:
        if (descr->style & LBS_EXTENDEDSEL) caret = descr->focus_item;
        else if (descr->style & LBS_MULTIPLESEL)
        {
            LISTBOX_SetSelection( hwnd, descr, descr->focus_item,
                                  !descr->items[descr->focus_item].selected,
                                  (descr->style & LBS_NOTIFY) != 0 );
        }
        break;
    default:
        bForceSelection = FALSE;
    }
    if (bForceSelection) /* focused item is used instead of key */
        caret = descr->focus_item;
    if (caret >= 0)
    {
        if ((descr->style & LBS_EXTENDEDSEL) &&
            !(GetKeyState( VK_SHIFT ) & 0x8000))
            descr->anchor_item = caret;
        LISTBOX_MoveCaret( hwnd, descr, caret, TRUE );
        LISTBOX_SetSelection( hwnd, descr, caret, TRUE, FALSE);
        if (descr->style & LBS_NOTIFY)
        {
	    if( descr->lphc )
            {
		/* make sure that combo parent doesn't hide us */
		descr->lphc->wState |= CBF_NOROLLUP;
	    }
            if (descr->nb_items) SEND_NOTIFICATION( hwnd, descr, LBN_SELCHANGE );
        }
    }
    return 0;
}


/***********************************************************************
 *           LISTBOX_HandleChar
 */
static LRESULT LISTBOX_HandleChar( HWND hwnd, LB_DESCR *descr, WCHAR charW )
{
    INT caret = -1;
    WCHAR str[2];

    str[0] = charW;
    str[1] = '\0';

    if (descr->style & LBS_WANTKEYBOARDINPUT)
    {
        caret = SendMessageW( descr->owner, WM_CHARTOITEM,
                                MAKEWPARAM(charW, descr->focus_item),
                                hwnd );
        if (caret == -2) return 0;
    }
    if (caret == -1)
        caret = LISTBOX_FindString( hwnd, descr, descr->focus_item, str, FALSE);
    if (caret != -1)
    {
        if ((!IS_MULTISELECT(descr)) && descr->selected_item == -1)
           LISTBOX_SetSelection( hwnd, descr, caret, TRUE, FALSE);
        LISTBOX_MoveCaret( hwnd, descr, caret, TRUE );
        if ((descr->style & LBS_NOTIFY) && descr->nb_items)
            SEND_NOTIFICATION( hwnd, descr, LBN_SELCHANGE );
    }
    return 0;
}


/***********************************************************************
 *           LISTBOX_Create
 */
static BOOL LISTBOX_Create( HWND hwnd, LPHEADCOMBO lphc )
{
    LB_DESCR *descr;
    MEASUREITEMSTRUCT mis;
    RECT rect;

    if (!(descr = HeapAlloc( GetProcessHeap(), 0, sizeof(*descr) )))
        return FALSE;

    GetClientRect( hwnd, &rect );
    descr->owner         = GetParent( hwnd );
    descr->style         = GetWindowLongA( hwnd, GWL_STYLE );
    descr->width         = rect.right - rect.left;
    descr->height        = rect.bottom - rect.top;
    descr->items         = NULL;
    descr->nb_items      = 0;
    descr->top_item      = 0;
    descr->selected_item = -1;
    descr->focus_item    = 0;
    descr->anchor_item   = -1;
    descr->item_height   = 1;
    descr->page_size     = 1;
    descr->column_width  = 150;
    descr->horz_extent   = (descr->style & WS_HSCROLL) ? 1 : 0;
    descr->horz_pos      = 0;
    descr->nb_tabs       = 0;
    descr->tabs          = NULL;
    descr->caret_on      = lphc ? FALSE : TRUE;
    if (descr->style & LBS_NOSEL) descr->caret_on = FALSE;
    descr->in_focus 	 = FALSE;
    descr->captured      = FALSE;
    descr->font          = 0;
    descr->locale        = 0;  /* FIXME */
    descr->lphc		 = lphc;

    if (is_old_app(hwnd) && ( descr->style & ( WS_VSCROLL | WS_HSCROLL ) ) )
    {
	/* Win95 document "List Box Differences" from MSDN:
	   If a list box in a version 3.x application has either the
	   WS_HSCROLL or WS_VSCROLL style, the list box receives both
	   horizontal and vertical scroll bars.
	*/
	descr->style |= WS_VSCROLL | WS_HSCROLL;
    }

    if( lphc )
    {
	TRACE_(combo)("[%04x]: resetting owner %04x -> %04x\n",
                      hwnd, descr->owner, lphc->self );
        descr->owner = lphc->self;
    }

    SetWindowLongA( hwnd, 0, (LONG)descr );

/*    if (wnd->dwExStyle & WS_EX_NOPARENTNOTIFY) descr->style &= ~LBS_NOTIFY;
 */
    if (descr->style & LBS_EXTENDEDSEL) descr->style |= LBS_MULTIPLESEL;
    if (descr->style & LBS_MULTICOLUMN) descr->style &= ~LBS_OWNERDRAWVARIABLE;
    if (descr->style & LBS_OWNERDRAWVARIABLE) descr->style |= LBS_NOINTEGRALHEIGHT;
    descr->item_height = LISTBOX_SetFont( hwnd, descr, 0 );

    if (descr->style & LBS_OWNERDRAWFIXED)
    {
	if( descr->lphc && (descr->lphc->dwStyle & CBS_DROPDOWN))
	{
	    /* WinWord gets VERY unhappy if we send WM_MEASUREITEM from here */
	  descr->item_height = lphc->fixedOwnerDrawHeight;
	}
	else
	{
            UINT id = GetWindowLongA( hwnd, GWL_ID );
            mis.CtlType    = ODT_LISTBOX;
            mis.CtlID      = id;
            mis.itemID     = -1;
            mis.itemWidth  =  0;
            mis.itemData   =  0;
            mis.itemHeight = descr->item_height;
            SendMessageW( descr->owner, WM_MEASUREITEM, id, (LPARAM)&mis );
            descr->item_height = mis.itemHeight ? mis.itemHeight : 1;
	}
    }

    TRACE("owner: %04x, style: %08x, width: %d, height: %d\n", descr->owner, descr->style, descr->width, descr->height);
    return TRUE;
}


/***********************************************************************
 *           LISTBOX_Destroy
 */
static BOOL LISTBOX_Destroy( HWND hwnd, LB_DESCR *descr )
{
    LISTBOX_ResetContent( hwnd, descr );
    SetWindowLongA( hwnd, 0, 0 );
    HeapFree( GetProcessHeap(), 0, descr );
    return TRUE;
}


/***********************************************************************
 *           ListBoxWndProc_common
 */
static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
                                             WPARAM wParam, LPARAM lParam, BOOL unicode )
{
    LRESULT ret;
    LB_DESCR *descr;

    if (!(descr = (LB_DESCR *)GetWindowLongA( hwnd, 0 )))
    {
        if (msg == WM_CREATE)
        {
            if (!LISTBOX_Create( hwnd, NULL ))
                return -1;
            TRACE("creating wnd=%04x descr=%lx\n", hwnd, GetWindowLongA( hwnd, 0 ) );
            return 0;
        }
        /* Ignore all other messages before we get a WM_CREATE */
        return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) :
                         DefWindowProcA( hwnd, msg, wParam, lParam );
    }

    TRACE("[%04x]: msg %s wp %08x lp %08lx\n",
          hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam );
    switch(msg)
    {
    case LB_RESETCONTENT16:
    case LB_RESETCONTENT:
        LISTBOX_ResetContent( hwnd, descr );
        LISTBOX_UpdateScroll( hwnd, descr );
        InvalidateRect( hwnd, NULL, TRUE );
        return 0;

    case LB_ADDSTRING16:
        if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam);
        /* fall through */
    case LB_ADDSTRING:
    {
        INT ret;
        LPWSTR textW;
        if(unicode || !HAS_STRINGS(descr))
            textW = (LPWSTR)lParam;
        else
        {
            LPSTR textA = (LPSTR)lParam;
            INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
            if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
                MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
        }
        wParam = LISTBOX_FindStringPos( hwnd, descr, textW, FALSE );
        ret = LISTBOX_InsertString( hwnd, descr, wParam, textW );
        if (!unicode && HAS_STRINGS(descr))
            HeapFree(GetProcessHeap(), 0, textW);
        return ret;
    }

    case LB_INSERTSTRING16:
        if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam);
        wParam = (INT)(INT16)wParam;
        /* fall through */
    case LB_INSERTSTRING:
    {
        INT ret;
        LPWSTR textW;
        if(unicode || !HAS_STRINGS(descr))
            textW = (LPWSTR)lParam;
        else
        {
            LPSTR textA = (LPSTR)lParam;
            INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
            if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
                MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
        }
        ret = LISTBOX_InsertString( hwnd, descr, wParam, textW );
        if(!unicode && HAS_STRINGS(descr))
            HeapFree(GetProcessHeap(), 0, textW);
        return ret;
    }

    case LB_ADDFILE16:
        if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam);
        /* fall through */
    case LB_ADDFILE:
    {
        INT ret;
        LPWSTR textW;
        if(unicode || !HAS_STRINGS(descr))
            textW = (LPWSTR)lParam;
        else
        {
            LPSTR textA = (LPSTR)lParam;
            INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
            if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
                MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
        }
        wParam = LISTBOX_FindFileStrPos( hwnd, descr, textW );
        ret = LISTBOX_InsertString( hwnd, descr, wParam, textW );
        if(!unicode && HAS_STRINGS(descr))
            HeapFree(GetProcessHeap(), 0, textW);
        return ret;
    }

    case LB_DELETESTRING16:
    case LB_DELETESTRING:
        if (LISTBOX_RemoveItem( hwnd, descr, wParam) != LB_ERR)
           return descr->nb_items;
        else
           return LB_ERR;

    case LB_GETITEMDATA16:
    case LB_GETITEMDATA:
        if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
            return LB_ERR;
        return descr->items[wParam].data;

    case LB_SETITEMDATA16:
    case LB_SETITEMDATA:
        if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
            return LB_ERR;
        descr->items[wParam].data = (DWORD)lParam;
        return LB_OKAY;

    case LB_GETCOUNT16:
    case LB_GETCOUNT:
        return descr->nb_items;

    case LB_GETTEXT16:
        lParam = (LPARAM)MapSL(lParam);
        /* fall through */
    case LB_GETTEXT:
        return LISTBOX_GetText( descr, wParam, lParam, unicode );

    case LB_GETTEXTLEN16:
        /* fall through */
    case LB_GETTEXTLEN:
        if ((INT)wParam >= descr->nb_items || (INT)wParam < 0)
            return LB_ERR;
        return (HAS_STRINGS(descr) ? strlenW(descr->items[wParam].str)
                                   : sizeof(DWORD));

    case LB_GETCURSEL16:
    case LB_GETCURSEL:
        if (descr->nb_items==0)
	  return LB_ERR;
        if (!IS_MULTISELECT(descr))
          return descr->selected_item;
	/* else */
	if (descr->selected_item!=-1)
	  return descr->selected_item;
	/* else */
	return descr->focus_item;
        /* otherwise, if the user tries to move the selection with the    */
        /* arrow keys, we will give the application something to choke on */
    case LB_GETTOPINDEX16:
    case LB_GETTOPINDEX:
        return descr->top_item;

    case LB_GETITEMHEIGHT16:
    case LB_GETITEMHEIGHT:
        return LISTBOX_GetItemHeight( descr, wParam );

    case LB_SETITEMHEIGHT16:
        lParam = LOWORD(lParam);
        /* fall through */
    case LB_SETITEMHEIGHT:
        return LISTBOX_SetItemHeight( hwnd, descr, wParam, lParam, TRUE );

    case LB_ITEMFROMPOINT:
        {
            POINT pt;
            RECT rect;

	    pt.x = LOWORD(lParam);
	    pt.y = HIWORD(lParam);
	    rect.left = 0;
	    rect.top = 0;
	    rect.right = descr->width;
	    rect.bottom = descr->height;

            return MAKELONG( LISTBOX_GetItemFromPoint(descr, pt.x, pt.y),
                             !PtInRect( &rect, pt ) );
        }

    case LB_SETCARETINDEX16:
    case LB_SETCARETINDEX:
        if ((!IS_MULTISELECT(descr)) && (descr->selected_item != -1)) return LB_ERR;
        if (LISTBOX_SetCaretIndex( hwnd, descr, wParam, !lParam ) == LB_ERR)
            return LB_ERR;
        else if (ISWIN31)
             return wParam;
        else
             return LB_OKAY;

    case LB_GETCARETINDEX16:
    case LB_GETCARETINDEX:
        return descr->focus_item;

    case LB_SETTOPINDEX16:
    case LB_SETTOPINDEX:
        return LISTBOX_SetTopItem( hwnd, descr, wParam, TRUE );

    case LB_SETCOLUMNWIDTH16:
    case LB_SETCOLUMNWIDTH:
        return LISTBOX_SetColumnWidth( hwnd, descr, wParam );

    case LB_GETITEMRECT16:
        {
            RECT rect;
            ret = LISTBOX_GetItemRect( descr, (INT16)wParam, &rect );
            CONV_RECT32TO16( &rect, MapSL(lParam) );
        }
	return ret;

    case LB_GETITEMRECT:
        return LISTBOX_GetItemRect( descr, wParam, (RECT *)lParam );

    case LB_FINDSTRING16:
        wParam = (INT)(INT16)wParam;
        if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam);
        /* fall through */
    case LB_FINDSTRING:
    {
        INT ret;
        LPWSTR textW;
        if(unicode || !HAS_STRINGS(descr))
            textW = (LPWSTR)lParam;
        else
        {
            LPSTR textA = (LPSTR)lParam;
            INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
            if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
                MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
        }
        ret = LISTBOX_FindString( hwnd, descr, wParam, textW, FALSE );
        if(!unicode && HAS_STRINGS(descr))
            HeapFree(GetProcessHeap(), 0, textW);
        return ret;
    }

    case LB_FINDSTRINGEXACT16:
        wParam = (INT)(INT16)wParam;
        if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam);
        /* fall through */
    case LB_FINDSTRINGEXACT:
    {
        INT ret;
        LPWSTR textW;
        if(unicode || !HAS_STRINGS(descr))
            textW = (LPWSTR)lParam;
        else
        {
            LPSTR textA = (LPSTR)lParam;
            INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
            if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
                MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
        }
        ret = LISTBOX_FindString( hwnd, descr, wParam, textW, TRUE );
        if(!unicode && HAS_STRINGS(descr))
            HeapFree(GetProcessHeap(), 0, textW);
        return ret;
    }

    case LB_SELECTSTRING16:
        wParam = (INT)(INT16)wParam;
        if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam);
        /* fall through */
    case LB_SELECTSTRING:
    {
        INT index;
        LPWSTR textW;

	if(HAS_STRINGS(descr))
	    TRACE("LB_SELECTSTRING: %s\n", unicode ? debugstr_w((LPWSTR)lParam) :
						     debugstr_a((LPSTR)lParam));
        if(unicode || !HAS_STRINGS(descr))
            textW = (LPWSTR)lParam;
        else
        {
            LPSTR textA = (LPSTR)lParam;
            INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
            if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
                MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
        }
        index = LISTBOX_FindString( hwnd, descr, wParam, textW, FALSE );
        if(!unicode && HAS_STRINGS(descr))
            HeapFree(GetProcessHeap(), 0, textW);
        if (index != LB_ERR)
	{
            LISTBOX_SetCaretIndex( hwnd, descr, index, TRUE );
            LISTBOX_SetSelection( hwnd, descr, index, TRUE, FALSE );
	}
        return index;
    }

    case LB_GETSEL16:
        wParam = (INT)(INT16)wParam;
        /* fall through */
    case LB_GETSEL:
        if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
            return LB_ERR;
        return descr->items[wParam].selected;

    case LB_SETSEL16:
        lParam = (INT)(INT16)lParam;
        /* fall through */
    case LB_SETSEL:
        return LISTBOX_SetSelection( hwnd, descr, lParam, wParam, FALSE );

    case LB_SETCURSEL16:
        wParam = (INT)(INT16)wParam;
        /* fall through */
    case LB_SETCURSEL:
        if (IS_MULTISELECT(descr)) return LB_ERR;
        LISTBOX_SetCaretIndex( hwnd, descr, wParam, TRUE );
        return LISTBOX_SetSelection( hwnd, descr, wParam, TRUE, FALSE );

    case LB_GETSELCOUNT16:
    case LB_GETSELCOUNT:
        return LISTBOX_GetSelCount( descr );

    case LB_GETSELITEMS16:
        return LISTBOX_GetSelItems16( descr, wParam, (LPINT16)MapSL(lParam) );

    case LB_GETSELITEMS:
        return LISTBOX_GetSelItems( descr, wParam, (LPINT)lParam );

    case LB_SELITEMRANGE16:
    case LB_SELITEMRANGE:
        if (LOWORD(lParam) <= HIWORD(lParam))
            return LISTBOX_SelectItemRange( hwnd, descr, LOWORD(lParam),
                                            HIWORD(lParam), wParam );
        else
            return LISTBOX_SelectItemRange( hwnd, descr, HIWORD(lParam),
                                            LOWORD(lParam), wParam );

    case LB_SELITEMRANGEEX16:
    case LB_SELITEMRANGEEX:
        if ((INT)lParam >= (INT)wParam)
            return LISTBOX_SelectItemRange( hwnd, descr, wParam, lParam, TRUE );
        else
            return LISTBOX_SelectItemRange( hwnd, descr, lParam, wParam, FALSE);

    case LB_GETHORIZONTALEXTENT16:
    case LB_GETHORIZONTALEXTENT:
        return descr->horz_extent;

    case LB_SETHORIZONTALEXTENT16:
    case LB_SETHORIZONTALEXTENT:
        return LISTBOX_SetHorizontalExtent( hwnd, descr, wParam );

    case LB_GETANCHORINDEX16:
    case LB_GETANCHORINDEX:
        return descr->anchor_item;

    case LB_SETANCHORINDEX16:
        wParam = (INT)(INT16)wParam;
        /* fall through */
    case LB_SETANCHORINDEX:
        if (((INT)wParam < -1) || ((INT)wParam >= descr->nb_items))
            return LB_ERR;
        descr->anchor_item = (INT)wParam;
        return LB_OKAY;

    case LB_DIR16:
        /* according to Win16 docs, DDL_DRIVES should make DDL_EXCLUSIVE
         * be set automatically (this is different in Win32) */
        if (wParam & DDL_DRIVES) wParam |= DDL_EXCLUSIVE;
	lParam = (LPARAM)MapSL(lParam);
        /* fall through */
    case LB_DIR:
    {
        INT ret;
        LPWSTR textW;
        if(unicode)
            textW = (LPWSTR)lParam;
        else
        {
            LPSTR textA = (LPSTR)lParam;
            INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
            if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
                MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
        }
        ret = LISTBOX_Directory( hwnd, descr, wParam, textW, msg == LB_DIR );
        if(!unicode)
            HeapFree(GetProcessHeap(), 0, textW);
        return ret;
    }

    case LB_GETLOCALE:
        return descr->locale;

    case LB_SETLOCALE:
        descr->locale = (LCID)wParam;  /* FIXME: should check for valid lcid */
        return LB_OKAY;

    case LB_INITSTORAGE:
        return LISTBOX_InitStorage( hwnd, descr, wParam );

    case LB_SETCOUNT:
        return LISTBOX_SetCount( hwnd, descr, (INT)wParam );

    case LB_SETTABSTOPS16:
        return LISTBOX_SetTabStops( hwnd, descr, (INT)(INT16)wParam, MapSL(lParam), TRUE );

    case LB_SETTABSTOPS:
        return LISTBOX_SetTabStops( hwnd, descr, wParam, (LPINT)lParam, FALSE );

    case LB_CARETON16:
    case LB_CARETON:
        if (descr->caret_on)
            return LB_OKAY;
        descr->caret_on = TRUE;
        if ((descr->focus_item != -1) && (descr->in_focus))
            LISTBOX_RepaintItem( hwnd, descr, descr->focus_item, ODA_FOCUS );
        return LB_OKAY;

    case LB_CARETOFF16:
    case LB_CARETOFF:
        if (!descr->caret_on)
            return LB_OKAY;
        descr->caret_on = FALSE;
        if ((descr->focus_item != -1) && (descr->in_focus))
            LISTBOX_RepaintItem( hwnd, descr, descr->focus_item, ODA_FOCUS );
        return LB_OKAY;

    case WM_DESTROY:
        return LISTBOX_Destroy( hwnd, descr );

    case WM_ENABLE:
        InvalidateRect( hwnd, NULL, TRUE );
        return 0;

    case WM_SETREDRAW:
        LISTBOX_SetRedraw( hwnd, descr, wParam != 0 );
        return 0;

    case WM_GETDLGCODE:
        return DLGC_WANTARROWS | DLGC_WANTCHARS;

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = ( wParam ) ? ((HDC)wParam) :  BeginPaint( hwnd, &ps );
            ret = LISTBOX_Paint( hwnd, descr, hdc );
            if( !wParam ) EndPaint( hwnd, &ps );
        }
        return ret;
    case WM_SIZE:
        LISTBOX_UpdateSize( hwnd, descr );
        return 0;
    case WM_GETFONT:
        return descr->font;
    case WM_SETFONT:
        LISTBOX_SetFont( hwnd, descr, (HFONT)wParam );
        if (lParam) InvalidateRect( hwnd, 0, TRUE );
        return 0;
    case WM_SETFOCUS:
        descr->in_focus = TRUE;
        descr->caret_on = TRUE;
        if (descr->focus_item != -1)
            LISTBOX_RepaintItem( hwnd, descr, descr->focus_item, ODA_FOCUS );
        SEND_NOTIFICATION( hwnd, descr, LBN_SETFOCUS );
        return 0;
    case WM_KILLFOCUS:
        descr->in_focus = FALSE;
        if ((descr->focus_item != -1) && descr->caret_on)
            LISTBOX_RepaintItem( hwnd, descr, descr->focus_item, ODA_FOCUS );
        SEND_NOTIFICATION( hwnd, descr, LBN_KILLFOCUS );
        return 0;
    case WM_HSCROLL:
        return LISTBOX_HandleHScroll( hwnd, descr, wParam );
    case WM_VSCROLL:
        return LISTBOX_HandleVScroll( hwnd, descr, wParam );
    case WM_MOUSEWHEEL:
        if (wParam & (MK_SHIFT | MK_CONTROL))
            return DefWindowProcW( hwnd, msg, wParam, lParam );
        return LISTBOX_HandleMouseWheel( hwnd, descr, wParam );
    case WM_LBUTTONDOWN:
        return LISTBOX_HandleLButtonDown( hwnd, descr, wParam,
                                          (INT16)LOWORD(lParam),
                                          (INT16)HIWORD(lParam) );
    case WM_LBUTTONDBLCLK:
        if (descr->style & LBS_NOTIFY)
            SEND_NOTIFICATION( hwnd, descr, LBN_DBLCLK );
        return 0;
    case WM_MOUSEMOVE:
        if (GetCapture() == hwnd)
            LISTBOX_HandleMouseMove( hwnd, descr, (INT16)LOWORD(lParam),
                                     (INT16)HIWORD(lParam) );
        return 0;
    case WM_LBUTTONUP:
        return LISTBOX_HandleLButtonUp( hwnd, descr );
    case WM_KEYDOWN:
        return LISTBOX_HandleKeyDown( hwnd, descr, wParam );
    case WM_CHAR:
    {
        WCHAR charW;
        if(unicode)
            charW = (WCHAR)wParam;
        else
        {
            CHAR charA = (CHAR)wParam;
            MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1);
        }
        return LISTBOX_HandleChar( hwnd, descr, charW );
    }
    case WM_SYSTIMER:
        return LISTBOX_HandleSystemTimer( hwnd, descr );
    case WM_ERASEBKGND:
        if ((IS_OWNERDRAW(descr)) && !(descr->style & LBS_DISPLAYCHANGED))
        {
            RECT rect;
            HBRUSH hbrush = SendMessageW( descr->owner, WM_CTLCOLORLISTBOX,
                                              wParam, (LPARAM)hwnd );
	    TRACE("hbrush = %04x\n", hbrush);
	    if(!hbrush)
		hbrush = GetSysColorBrush(COLOR_WINDOW);
	    if(hbrush)
	    {
		GetClientRect(hwnd, &rect);
		FillRect((HDC)wParam, &rect, hbrush);
	    }
        }
        return 1;
    case WM_DROPFILES:
        if( !descr->lphc )
            return unicode ? SendMessageW( descr->owner, msg, wParam, lParam ) :
                             SendMessageA( descr->owner, msg, wParam, lParam );
        break;

    case WM_DROPOBJECT:
    case WM_QUERYDROPOBJECT:
    case WM_DRAGSELECT:
    case WM_DRAGMOVE:
	if( !descr->lphc )
        {
            LPDRAGINFO16 dragInfo = MapSL( lParam );
            dragInfo->l = LISTBOX_GetItemFromPoint( descr, dragInfo->pt.x,
                                                dragInfo->pt.y );
            return SendMessage16( descr->owner, msg, wParam, lParam );
        }
	break;

    default:
        if ((msg >= WM_USER) && (msg < 0xc000))
            WARN("[%04x]: unknown msg %04x wp %08x lp %08lx\n",
                 hwnd, msg, wParam, lParam );
        return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) :
                         DefWindowProcA( hwnd, msg, wParam, lParam );
    }
    return 0;
}

/***********************************************************************
 *           ListBoxWndProcA
 *
 * This is just a wrapper for the real wndproc, it only does window locking
 * and unlocking.
 */
static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    if (!IsWindow(hwnd)) return 0;
    return ListBoxWndProc_common( hwnd, msg, wParam, lParam, FALSE );
}

/***********************************************************************
 *           ListBoxWndProcW
 */
static LRESULT WINAPI ListBoxWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    if (!IsWindow(hwnd)) return 0;
    return ListBoxWndProc_common( hwnd, msg, wParam, lParam, TRUE );
}

/***********************************************************************
 *           ComboLBWndProc_common
 *
 * The real combo listbox wndproc
 */
static LRESULT WINAPI ComboLBWndProc_common( HWND hwnd, UINT msg,
                                             WPARAM wParam, LPARAM lParam, BOOL unicode )
{
    LRESULT lRet = 0;
    LB_DESCR *descr = (LB_DESCR *)GetWindowLongA( hwnd, 0 );

    TRACE_(combo)("[%04x]: msg %s wp %08x lp %08lx\n",
                  hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam );

    if( descr || msg == WM_CREATE )
    {
        LPHEADCOMBO lphc = (descr) ? descr->lphc : NULL;

        switch( msg )
        {
        case WM_CREATE:
            {
                CREATESTRUCTA *lpcs = (CREATESTRUCTA *)lParam;
                TRACE_(combo)("\tpassed parent handle = %p\n",lpcs->lpCreateParams);
                lphc = (LPHEADCOMBO)(lpcs->lpCreateParams);
                return LISTBOX_Create( hwnd, lphc );
            }
        case WM_MOUSEMOVE:
            if ( (TWEAK_WineLook > WIN31_LOOK) &&
                 (CB_GETTYPE(lphc) != CBS_SIMPLE) )
            {
                POINT   mousePos;
                BOOL    captured;
                RECT    clientRect;

                mousePos.x = (INT16)LOWORD(lParam);
                mousePos.y = (INT16)HIWORD(lParam);

                /*
                 * If we are in a dropdown combobox, we simulate that
                 * the mouse is captured to show the tracking of the item.
                 */
                GetClientRect(hwnd, &clientRect);

                if (PtInRect( &clientRect, mousePos ))
                {
                    captured = descr->captured;
                    descr->captured = TRUE;

                    LISTBOX_HandleMouseMove( hwnd, descr,
                                             mousePos.x, mousePos.y);

                    descr->captured = captured;

                }
                else
                {
                    LISTBOX_HandleMouseMove( hwnd, descr,
                                             mousePos.x, mousePos.y);
                }

                return 0;

            }
            else
            {
                /*
                 * If we are in Win3.1 look, go with the default behavior.
                 */
                return unicode ? ListBoxWndProcW( hwnd, msg, wParam, lParam ) :
                    ListBoxWndProcA( hwnd, msg, wParam, lParam );
            }
        case WM_LBUTTONUP:
            if (TWEAK_WineLook > WIN31_LOOK)
            {
                POINT mousePos;
                RECT  clientRect;

                /*
                 * If the mouse button "up" is not in the listbox,
                 * we make sure there is no selection by re-selecting the
                 * item that was selected when the listbox was made visible.
                 */
                mousePos.x = (INT16)LOWORD(lParam);
                mousePos.y = (INT16)HIWORD(lParam);

                GetClientRect(hwnd, &clientRect);

                /*
                 * When the user clicks outside the combobox and the focus
                 * is lost, the owning combobox will send a fake buttonup with
                 * 0xFFFFFFF as the mouse location, we must also revert the
                 * selection to the original selection.
                 */
                if ( (lParam == (LPARAM)-1) ||
                     (!PtInRect( &clientRect, mousePos )) )
                {
                    LISTBOX_MoveCaret( hwnd, descr, lphc->droppedIndex, FALSE );
                }
            }
            return LISTBOX_HandleLButtonUp( hwnd, descr );
        case WM_LBUTTONDBLCLK:
        case WM_LBUTTONDOWN:
            return LISTBOX_HandleLButtonDownCombo(hwnd, descr, msg, wParam,
                                                  (INT16)LOWORD(lParam),
                                                  (INT16)HIWORD(lParam) );
        case WM_NCACTIVATE:
            return FALSE;
        case WM_KEYDOWN:
            if( CB_GETTYPE(lphc) != CBS_SIMPLE )
            {
                /* for some reason(?) Windows makes it possible to
                 * show/hide ComboLBox by sending it WM_KEYDOWNs */

                if( (!(lphc->wState & CBF_EUI) && wParam == VK_F4) ||
                    ( (lphc->wState & CBF_EUI) && !(lphc->wState & CBF_DROPPED)
                      && (wParam == VK_DOWN || wParam == VK_UP)) )
                {
                    COMBO_FlipListbox( lphc, FALSE, FALSE );
                    return 0;
                }
            }
            return LISTBOX_HandleKeyDown( hwnd, descr, wParam );

        case LB_SETCURSEL16:
        case LB_SETCURSEL:
            lRet = unicode ? ListBoxWndProcW( hwnd, msg, wParam, lParam ) :
                ListBoxWndProcA( hwnd, msg, wParam, lParam );
            lRet =(lRet == LB_ERR) ? lRet : descr->selected_item;
            return lRet;
        case WM_NCDESTROY:
            if( CB_GETTYPE(lphc) != CBS_SIMPLE )
                lphc->hWndLBox = 0;
            /* fall through */

        default:
            return unicode ? ListBoxWndProcW( hwnd, msg, wParam, lParam ) :
                ListBoxWndProcA( hwnd, msg, wParam, lParam );
        }
    }
    lRet = unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) :
        DefWindowProcA( hwnd, msg, wParam, lParam );

    TRACE_(combo)("\t default on msg [%04x]\n", (UINT16)msg );

    return lRet;
}

/***********************************************************************
 *           ComboLBWndProcA
 *
 *  NOTE: in Windows, winproc address of the ComboLBox is the same 
 *	  as that of the Listbox.
 */
LRESULT WINAPI ComboLBWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    if (!IsWindow(hwnd)) return 0;
    return ComboLBWndProc_common( hwnd, msg, wParam, lParam, FALSE );
}

/***********************************************************************
 *           ComboLBWndProcW
 */
LRESULT WINAPI ComboLBWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    if (!IsWindow(hwnd)) return 0;
    return ComboLBWndProc_common( hwnd, msg, wParam, lParam, TRUE );
}
