/*
 * Listbox controls
 *
 * Copyright 1996 Alexandre Julliard
 */

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "windef.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "wine/winbase16.h"
#include "winuser.h"
#include "winerror.h"
#include "drive.h"
#include "heap.h"
#include "spy.h"
#include "selectors.h"
#include "win.h"
#include "combo.h"
#include "debugtools.h"
#include "tweak.h"

DEFAULT_DEBUG_CHANNEL(listbox);
DECLARE_DEBUG_CHANNEL(combo);

/* Unimplemented yet:
 * - LBS_NOSEL
 * - LBS_USETABSTOPS
 * - Unicode
 * - Locale handling
 */

/* 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
{
    LPSTR     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
{
    HANDLE      heap;           /* Heap for this listbox */
    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(wnd,descr,code) \
    (SendMessageA( (descr)->owner, WM_COMMAND, \
     MAKEWPARAM((wnd)->wIDmenu, (code)), (wnd)->hwndSelf ))

#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;


/***********************************************************************
 *           LISTBOX_Dump
 */
void LISTBOX_Dump( WND *wnd )
{
    INT i;
    LB_ITEMDATA *item;
    LB_DESCR *descr = *(LB_DESCR **)wnd->wExtra;

    TRACE( "Listbox:\n" );
    TRACE( "hwnd=%04x descr=%08x heap=%08x items=%d top=%d\n",
                     wnd->hwndSelf, (UINT)descr, descr->heap, 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, item->str, item->selected, item->data, item->height );
    }
}


/***********************************************************************
 *           LISTBOX_GetCurrentPageSize
 *
 * Return the current page size
 */
static INT LISTBOX_GetCurrentPageSize( WND *wnd, 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( WND *wnd, 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( WND *wnd, 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( wnd->hwndSelf, SB_HORZ, &info, TRUE );
        info.nMax = 0;
        info.fMask = SIF_RANGE;
        if (descr->style & WS_VSCROLL)
            SetScrollInfo( wnd->hwndSelf, SB_VERT, &info, TRUE );
    }
    else
    {
        info.nMin  = 0;
        info.nMax  = descr->nb_items - 1;
        info.nPos  = descr->top_item;
        info.nPage = LISTBOX_GetCurrentPageSize( wnd, descr );
        info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
        if (descr->style & LBS_DISABLENOSCROLL)
            info.fMask |= SIF_DISABLENOSCROLL;
        if (descr->style & WS_VSCROLL)
            SetScrollInfo( wnd->hwndSelf, 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( wnd->hwndSelf, SB_HORZ, &info, TRUE );
            
        }
    }
}


/***********************************************************************
 *           LISTBOX_SetTopItem
 *
 * Set the top item of the listbox, scrolling up or down if necessary.
 */
static LRESULT LISTBOX_SetTopItem( WND *wnd, LB_DESCR *descr, INT index,
                                   BOOL scroll )
{
    INT max = LISTBOX_GetMaxTopIndex( wnd, 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( wnd->hwndSelf, 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( wnd->hwndSelf, 0, diff, NULL, NULL, 0, NULL,
                              SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
        else
            scroll = FALSE;
    }
    if (!scroll) InvalidateRect( wnd->hwndSelf, NULL, TRUE );
    descr->top_item = index;
    LISTBOX_UpdateScroll( wnd, 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( WND *wnd, 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( wnd->hwndSelf, NULL, TRUE );
    LISTBOX_SetTopItem( wnd, 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( WND *wnd, LB_DESCR *descr )
{
    RECT rect;

    GetClientRect( wnd->hwndSelf, &rect );
    descr->width  = rect.right - rect.left;
    descr->height = rect.bottom - rect.top;
    if (!(descr->style & LBS_NOINTEGRALHEIGHT) && !(descr->style & LBS_OWNERDRAWVARIABLE))
    {
        UINT remaining = descr->height % descr->item_height;
        if ((descr->height > descr->item_height) && remaining)
        {
            if (!(wnd->flags & WIN_ISWIN32))
            { /* 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 = wnd->rectWindow.bottom - wnd->rectWindow.top - descr->height;
                if ((descr->item_height - remaining) <= ncheight)
                    remaining = remaining - descr->item_height;
            }
            TRACE("[%04x]: changing height %d -> %d\n",
			 wnd->hwndSelf, descr->height,
			 descr->height - remaining );
            SetWindowPos( wnd->hwndSelf, 0, 0, 0,
                            wnd->rectWindow.right - wnd->rectWindow.left,
                            wnd->rectWindow.bottom - wnd->rectWindow.top - remaining,
                            SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE );
            return;
        }
    }
    TRACE("[%04x]: new size = %d,%d\n",
		 wnd->hwndSelf, descr->width, descr->height );
    LISTBOX_UpdatePage( wnd, descr );
    LISTBOX_UpdateScroll( wnd, descr );
}


/***********************************************************************
 *           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( WND *wnd, 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( WND *wnd, 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( WND *wnd, LB_DESCR *descr, HDC hdc,
                               const RECT *rect, INT index, UINT action )
{
    LB_ITEMDATA *item = NULL;
    if (index < descr->nb_items) item = &descr->items[index];

    if (IS_OWNERDRAW(descr))
    {
        DRAWITEMSTRUCT dis;
        RECT r;
        HRGN hrgn;

	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(wnd->hwndSelf, &r);
        hrgn = CreateRectRgnIndirect(&r);
        SelectClipRgn( hdc, hrgn);
        DeleteObject( hrgn );

        dis.CtlType      = ODT_LISTBOX;
        dis.CtlID        = wnd->wIDmenu;
        dis.hwndItem     = wnd->hwndSelf;
        dis.itemAction   = action;
        dis.hDC          = hdc;
        dis.itemID       = index;
        dis.itemState    = 0;
        if (item && item->selected) dis.itemState |= ODS_SELECTED;
        if ((descr->focus_item == index) &&
            (descr->caret_on) &&
            (descr->in_focus)) dis.itemState |= ODS_FOCUS;
        if (wnd->dwStyle & WS_DISABLED) 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",
		     wnd->hwndSelf, index, item ? item->str : "", action,
		     dis.itemState, rect->left, rect->top,
		     rect->right, rect->bottom );
        SendMessageA(descr->owner, WM_DRAWITEM, wnd->wIDmenu, (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",
		     wnd->hwndSelf, index, item ? item->str : "", action,
		     rect->left, rect->top, rect->right, rect->bottom );
        if (!item)
            ExtTextOutA( hdc, rect->left + 1, rect->top,
                           ETO_OPAQUE | ETO_CLIPPED, rect, NULL, 0, NULL );
        else if (!(descr->style & LBS_USETABSTOPS)) 
	    ExtTextOutA( hdc, rect->left + 1, rect->top,
			   ETO_OPAQUE | ETO_CLIPPED, rect, item->str,
			   strlen(item->str), NULL );
        else
	{
	    /* Output empty string to paint background in the full width. */
	    ExtTextOutA( hdc, rect->left + 1, rect->top,
                           ETO_OPAQUE | ETO_CLIPPED, rect, NULL, 0, NULL );
	    TabbedTextOutA( hdc, rect->left + 1 , rect->top,
			      item->str, strlen(item->str), 
			      descr->nb_tabs, descr->tabs, 0);
	}
        if (item && item->selected)
        {
            SetBkColor( hdc, oldBk );
            SetTextColor( hdc, oldText );
        }
        if ((descr->focus_item == index) &&
            (descr->caret_on) &&
            (descr->in_focus)) DrawFocusRect( hdc, rect );
    }
}


/***********************************************************************
 *           LISTBOX_SetRedraw
 *
 * Change the redraw flag.
 */
static void LISTBOX_SetRedraw( WND *wnd, 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(wnd->hwndSelf, 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( wnd, descr );
    }
    else descr->style |= LBS_NOREDRAW;
}


/***********************************************************************
 *           LISTBOX_RepaintItem
 *
 * Repaint a single item synchronously.
 */
static void LISTBOX_RepaintItem( WND *wnd, 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(wnd->hwndSelf)) return;
    if (descr->style & LBS_NOREDRAW)
       {
       descr->style |= LBS_DISPLAYCHANGED;
       return;
       }
    if (LISTBOX_GetItemRect( wnd, descr, index, &rect ) != 1) return;
    if (!(hdc = GetDCEx( wnd->hwndSelf, 0, DCX_CACHE ))) return;
    if (descr->font) oldFont = SelectObject( hdc, descr->font );
    hbrush = SendMessageA( descr->owner, WM_CTLCOLORLISTBOX,
                             hdc, (LPARAM)wnd->hwndSelf );
    if (hbrush) oldBrush = SelectObject( hdc, hbrush );
    if (wnd->dwStyle & WS_DISABLED)
        SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) );
    SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
    LISTBOX_PaintItem( wnd, descr, hdc, &rect, index, action );
    if (oldFont) SelectObject( hdc, oldFont );
    if (oldBrush) SelectObject( hdc, oldBrush );
    ReleaseDC( wnd->hwndSelf, hdc );
}


/***********************************************************************
 *           LISTBOX_InitStorage
 */
static LRESULT LISTBOX_InitStorage( WND *wnd, LB_DESCR *descr, INT nb_items,
                                    DWORD bytes )
{
    LB_ITEMDATA *item;

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


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

        TRACE("[%04x]: settabstops ", wnd->hwndSelf );
        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( WND *wnd, LB_DESCR *descr, INT index,
                                LPSTR buffer )
{
    if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
    if (HAS_STRINGS(descr))
    {
        if (!buffer)
		return strlen(descr->items[index].str);
        lstrcpyA( buffer, descr->items[index].str );
        return strlen(buffer);
    } else {
    	if (buffer)
        	*((LPDWORD)buffer)=*(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( WND *wnd, LB_DESCR *descr, LPCSTR 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 = lstrcmpiA( descr->items[index].str, str );
        else
        {
            COMPAREITEMSTRUCT cis;

            cis.CtlType    = ODT_LISTBOX;
            cis.CtlID      = wnd->wIDmenu;
            cis.hwndItem   = wnd->hwndSelf;
            cis.itemID1    = index;
            cis.itemData1  = descr->items[index].data;
            cis.itemID2    = -1;
            cis.itemData2  = (DWORD)str;
            cis.dwLocaleId = descr->locale;
            res = SendMessageA( descr->owner, WM_COMPAREITEM,
                                  wnd->wIDmenu, (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( WND *wnd, LB_DESCR *descr, LPCSTR str )
{
    INT min, max, res = -1;

    if (!HAS_STRINGS(descr))
        return LISTBOX_FindStringPos( wnd, descr, str, FALSE );
    min = 0;
    max = descr->nb_items;
    while (min != max)
    {
        INT index = (min + max) / 2;
        const char *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 = lstrcmpiA( str, p );
            }
        }
        else  /* filename */
        {
            if (*str == '[') res = 1;
            else res = lstrcmpiA( 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( WND *wnd, LB_DESCR *descr, INT start,
                                 LPCSTR 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 (!lstrcmpiA( str, item->str )) return i;
            for (i = 0, item = descr->items; i <= start; i++, item++)
                if (!lstrcmpiA( str, item->str )) return i;
        }
        else
        {
 /* Special case for drives and directories: ignore prefix */
#define CHECK_DRIVE(item) \
    if ((item)->str[0] == '[') \
    { \
        if (!lstrncmpiA( str, (item)->str+1, len )) return i; \
        if (((item)->str[1] == '-') && !lstrncmpiA(str,(item)->str+2,len)) \
        return i; \
    }

            INT len = strlen(str);
            for (i = start + 1; i < descr->nb_items; i++, item++)
            {
               if (!lstrncmpiA( str, item->str, len )) return i;
               CHECK_DRIVE(item);
            }
            for (i = 0, item = descr->items; i <= start; i++, item++)
            {
               if (!lstrncmpiA( 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( wnd, 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( WND *wnd, 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( WND *wnd, 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_GetSelItems32
 */
static LRESULT LISTBOX_GetSelItems( WND *wnd, 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( WND *wnd, 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;
    INT focusItem;

    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 = SendMessageA( descr->owner, WM_CTLCOLORLISTBOX,
                             hdc, (LPARAM)wnd->hwndSelf );
    if (hbrush) oldBrush = SelectObject( hdc, hbrush );
    if (wnd->dwStyle & WS_DISABLED)
        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( wnd, descr, hdc, &rect, descr->focus_item,
                           ODA_FOCUS );
        rect.top = rect.bottom;
    }

    /* Paint all the item, regarding the selection
       Focus state will be painted after  */
    focusItem = descr->focus_item;
    descr->focus_item = -1;

    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 == focusItem)
        {
	    /* 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( wnd, descr, hdc, &rect, i, ODA_DRAWENTIRE );
        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;
                    ExtTextOutA( 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 */
    descr->focus_item = focusItem;
    if (focusRect.top != focusRect.bottom && descr->caret_on)
        LISTBOX_PaintItem( wnd, descr, hdc, &focusRect, descr->focus_item, ODA_FOCUS );

    if (!IS_OWNERDRAW(descr))
    {
        /* Clear the remainder of the client area */
        if (rect.top < descr->height)
        {
            rect.bottom = descr->height;
            ExtTextOutA( 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;
            ExtTextOutA( 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( WND *wnd, LB_DESCR *descr, INT index )
{
    RECT rect;

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


/***********************************************************************
 *           LISTBOX_GetItemHeight
 */
static LRESULT LISTBOX_GetItemHeight( WND *wnd, 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( WND *wnd, LB_DESCR *descr, INT index,
                                      UINT height )
{
    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",
		     wnd->hwndSelf, index, height );
        descr->items[index].height = height;
        LISTBOX_UpdateScroll( wnd, descr );
        LISTBOX_InvalidateItems( wnd, descr, index );
    }
    else if (height != descr->item_height)
    {
        TRACE("[%04x]: new height = %d\n",
		     wnd->hwndSelf, height );
        descr->item_height = height;
        LISTBOX_UpdatePage( wnd, descr );
        LISTBOX_UpdateScroll( wnd, descr );
        InvalidateRect( wnd->hwndSelf, 0, TRUE );
    }
    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_SetHorizontalPos
 */
static void LISTBOX_SetHorizontalPos( WND *wnd, 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",
		 wnd->hwndSelf, pos );
    descr->horz_pos = pos;
    LISTBOX_UpdateScroll( wnd, descr );
    if (abs(diff) < descr->width)
        ScrollWindowEx( wnd->hwndSelf, diff, 0, NULL, NULL, 0, NULL,
                          SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
    else
        InvalidateRect( wnd->hwndSelf, NULL, TRUE );
}


/***********************************************************************
 *           LISTBOX_SetHorizontalExtent
 */
static LRESULT LISTBOX_SetHorizontalExtent( WND *wnd, LB_DESCR *descr,
                                            UINT 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",
		 wnd->hwndSelf, extent );
    descr->horz_extent = extent;
    if (descr->horz_pos > extent - descr->width)
        LISTBOX_SetHorizontalPos( wnd, descr, extent - descr->width );
    else
        LISTBOX_UpdateScroll( wnd, descr );
    return LB_OKAY;
}


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


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

    descr->font = font;

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


/***********************************************************************
 *           LISTBOX_MakeItemVisible
 *
 * Make sure that a given item is partially or fully visible.
 */
static void LISTBOX_MakeItemVisible( WND *wnd, 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( wnd, 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( WND *wnd, LB_DESCR *descr, INT index,
                                      BOOL fully_visible )
{
    INT oldfocus = descr->focus_item;          

    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( wnd, descr, oldfocus, ODA_FOCUS );

    LISTBOX_MakeItemVisible( wnd, descr, index, fully_visible );
    if (descr->caret_on && (descr->in_focus))
        LISTBOX_RepaintItem( wnd, 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( WND *wnd, LB_DESCR *descr, INT first,
                                        INT last, BOOL on )
{
    INT i;

    /* A few sanity checks */

    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( wnd, descr, i, ODA_SELECT );
        }
        LISTBOX_SetCaretIndex( wnd, 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( wnd, descr, i, ODA_SELECT );
        }
    }
    return LB_OKAY;
}

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

    if ((index < -1) || (index >= descr->nb_items)) return LB_ERR;
    if (descr->style & LBS_MULTIPLESEL)
    {
        if (index == -1)  /* Select all items */
            return LISTBOX_SelectItemRange( wnd, descr, 0, -1, on );
        else  /* Only one item */
            return LISTBOX_SelectItemRange( wnd, 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( wnd, descr, oldsel, ODA_SELECT );
        if (index != -1) LISTBOX_RepaintItem( wnd, descr, index, ODA_SELECT );
        if (send_notify && descr->nb_items) SEND_NOTIFICATION( wnd, 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( WND *wnd, 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( wnd, 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( wnd, descr, 0, first - 1, FALSE );
            LISTBOX_SelectItemRange( wnd, descr, last + 1, -1, FALSE );
            LISTBOX_SelectItemRange( wnd, descr, first, last, TRUE );
        }
    }
    else if (!(descr->style & LBS_MULTIPLESEL))
    {
        /* Set selection to new caret item */
        LISTBOX_SetSelection( wnd, descr, index, TRUE, FALSE );
    }
   
    /* 4. repaint the new item with the focus */
    descr->focus_item = index;
    LISTBOX_MakeItemVisible( wnd, descr, index, fully_visible );
    if (descr->caret_on && (descr->in_focus))
        LISTBOX_RepaintItem( wnd, descr, index, ODA_FOCUS );
}


/***********************************************************************
 *           LISTBOX_InsertItem
 */
static LRESULT LISTBOX_InsertItem( WND *wnd, LB_DESCR *descr, INT index,
                                   LPSTR 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( descr->heap, 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( descr->heap, 0, descr->items,
                                  max_items * sizeof(LB_ITEMDATA) )))
        {
            SEND_NOTIFICATION( wnd, 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;

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

    /* Repaint the items */

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

    /* Move selection and focused item */
    /* If listbox was empty, set focus to the first item */
    if (descr->nb_items == 1)
         LISTBOX_SetCaretIndex( wnd, descr, 0, FALSE );
    /* single select don't change selection index in win31 */
    else if ((ISWIN31) && !(IS_MULTISELECT(descr)))
    {
        descr->selected_item++;
        LISTBOX_SetSelection( wnd, 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( WND *wnd, LB_DESCR *descr, INT index,
                                     LPCSTR str )
{
    LPSTR new_str = NULL;
    DWORD data = 0;
    LRESULT ret;

    if (HAS_STRINGS(descr))
    {
        if (!str) str="";
        if (!(new_str = HEAP_strdupA( descr->heap, 0, str )))
        {
            SEND_NOTIFICATION( wnd, descr, LBN_ERRSPACE );
            return LB_ERRSPACE;
        }
    }
    else data = (DWORD)str;

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

    TRACE("[%04x]: added item %d '%s'\n",
		 wnd->hwndSelf, index, HAS_STRINGS(descr) ? new_str : "" );
    return index;
}


/***********************************************************************
 *           LISTBOX_DeleteItem
 *
 * Delete the content of an item. 'index' must be a valid index.
 */
static void LISTBOX_DeleteItem( WND *wnd, 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;

        dis.CtlType  = ODT_LISTBOX;
        dis.CtlID    = wnd->wIDmenu;
        dis.itemID   = index;
        dis.hwndItem = wnd->hwndSelf;
        dis.itemData = descr->items[index].data;
        SendMessageA( descr->owner, WM_DELETEITEM, wnd->wIDmenu, (LPARAM)&dis );
    }
    if (HAS_STRINGS(descr) && descr->items[index].str)
        HeapFree( descr->heap, 0, descr->items[index].str );
}


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

    if (index == -1) 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( wnd, descr, index );

    LISTBOX_DeleteItem( wnd, 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( descr->heap, 0, descr->items ) / sizeof(LB_ITEMDATA);
    if (descr->nb_items < max_items - 2*LB_ARRAY_GRANULARITY)
    {
        max_items -= LB_ARRAY_GRANULARITY;
        item = HeapReAlloc( descr->heap, 0, descr->items,
                            max_items * sizeof(LB_ITEMDATA) );
        if (item) descr->items = item;
    }
    /* Repaint the items */

    LISTBOX_UpdateScroll( wnd, 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( wnd, 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( wnd, 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( WND *wnd, LB_DESCR *descr )
{
    INT i;

    for (i = 0; i < descr->nb_items; i++) LISTBOX_DeleteItem( wnd, descr, i );
    if (descr->items) HeapFree( descr->heap, 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_UpdateScroll( wnd, descr );
    InvalidateRect( wnd->hwndSelf, NULL, TRUE );
}


/***********************************************************************
 *           LISTBOX_SetCount
 */
static LRESULT LISTBOX_SetCount( WND *wnd, 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( wnd, descr, -1, 0 )) < 0)
                return ret;
    }
    else if (count < descr->nb_items)
    {
        while (count < descr->nb_items)
            if ((ret = LISTBOX_RemoveItem( wnd, descr, -1 )) < 0)
                return ret;
    }
    return LB_OKAY;
}


/***********************************************************************
 *           LISTBOX_Directory
 */
static LRESULT LISTBOX_Directory( WND *wnd, LB_DESCR *descr, UINT attrib,
                                  LPCSTR filespec, BOOL long_names )
{
    HANDLE handle;
    LRESULT ret = LB_OKAY;
    WIN32_FIND_DATAA entry;
    int pos;

    if ((handle = FindFirstFileA(filespec,&entry)) == INVALID_HANDLE_VALUE)
    {
        if (GetLastError() != ERROR_NO_MORE_FILES) return LB_ERR;
    }
    else
    {
        do
        {
            char buffer[270];
            if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if (!(attrib & DDL_DIRECTORY) ||
                    !strcmp( entry.cAlternateFileName, "." )) continue;
                if (long_names) sprintf( buffer, "[%s]", entry.cFileName );
                else sprintf( buffer, "[%s]", entry.cAlternateFileName );
            }
            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) strcpy( buffer, entry.cFileName );
                else strcpy( buffer, entry.cAlternateFileName );
            }
            if (!long_names) CharLowerA( buffer );
            pos = LISTBOX_FindFileStrPos( wnd, descr, buffer );
            if ((ret = LISTBOX_InsertString( wnd, descr, pos, buffer )) < 0)
                break;
        } while (FindNextFileA( handle, &entry ));
        FindClose( handle );
    }

    if ((ret >= 0) && (attrib & DDL_DRIVES))
    {
        char buffer[] = "[-a-]";
        int drive;
        for (drive = 0; drive < MAX_DOS_DRIVES; drive++, buffer[2]++)
        {
            if (!DRIVE_IsValid(drive)) continue;
            if ((ret = LISTBOX_InsertString( wnd, descr, -1, buffer )) < 0)
                break;
        }
    }
    return ret;
}


/***********************************************************************
 *           LISTBOX_HandleVScroll
 */
static LRESULT LISTBOX_HandleVScroll( WND *wnd, LB_DESCR *descr,
                                      WPARAM wParam, LPARAM lParam )
{
    SCROLLINFO info;

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


/***********************************************************************
 *           LISTBOX_HandleHScroll
 */
static LRESULT LISTBOX_HandleHScroll( WND *wnd, LB_DESCR *descr,
                                      WPARAM wParam, LPARAM lParam )
{
    SCROLLINFO info;
    INT page;

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

static LRESULT LISTBOX_HandleMouseWheel(WND *wnd, LB_DESCR *descr,WPARAM wParam, LPARAM lParam )
{
    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( wnd, descr, descr->top_item + cLineScroll, TRUE );
    }
    return 0;
}

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

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

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

    descr->captured = TRUE;
    SetCapture( wnd->hwndSelf );
    if (index != -1 && !descr->lphc)
    {
        if (descr->style & LBS_NOTIFY )
            SendMessageA( descr->owner, WM_LBTRACKPOINT, index,
                            MAKELPARAM( x, y ) );
        if (wnd->dwExStyle & WS_EX_DRAGDETECT)
        {
            POINT pt;
	    
	    pt.x = x;
	    pt.y = y;

            if (DragDetect( wnd->hwndSelf, pt ))
                SendMessageA( descr->owner, WM_BEGINDRAG, 0, 0 );
        }
    }
    return 0;
}


/*************************************************************************
 * LISTBOX_HandleLButtonDownCombo [Internal] 
 *
 * Process LButtonDown message for the ComboListBox
 *
 * 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( WND *pWnd, LB_DESCR *pDescr,
                                               UINT msg, WPARAM wParam, INT x, INT y)
{
    RECT clientRect, screenRect;
    POINT mousePos;

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

    GetClientRect(pWnd->hwndSelf, &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( pWnd, pDescr, wParam, x, y);
        }
        else if (pDescr->style & LBS_NOTIFY)
            SEND_NOTIFICATION( pWnd, pDescr, LBN_DBLCLK );
        return 0;
    }
    else
    {
        POINT screenMousePos;
        HWND hWndOldCapture;

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

        if(!PtInRect(&screenRect, screenMousePos))
        { 
            LISTBOX_SetSelection( pWnd, 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;
            /* Check Vertical scroll bar */
            if (pWnd->dwStyle & WS_VSCROLL)
            {
                clientRect.right += GetSystemMetrics(SM_CXVSCROLL);
                if (PtInRect( &clientRect, mousePos )) 
                {
                    nHitTestType = HTVSCROLL;
                }
            }
              /* Check horizontal scroll bar */
            if (pWnd->dwStyle & 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)
            {
                SendMessageA(pWnd->hwndSelf, 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( WND *wnd, LB_DESCR *descr )
{
    if (LISTBOX_Timer != LB_TIMER_NONE)
        KillSystemTimer( wnd->hwndSelf, LB_TIMER_ID );
    LISTBOX_Timer = LB_TIMER_NONE;
    if (descr->captured)
    {
        descr->captured = FALSE;
        if (GetCapture() == wnd->hwndSelf) ReleaseCapture();
        if ((descr->style & LBS_NOTIFY) && descr->nb_items)
            SEND_NOTIFICATION( wnd, descr, LBN_SELCHANGE );
    }
    return 0;
}


/***********************************************************************
 *           LISTBOX_HandleTimer
 *
 * Handle scrolling upon a timer event.
 * Return TRUE if scrolling should continue.
 */
static LRESULT LISTBOX_HandleTimer( WND *wnd, 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( wnd, 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( wnd, descr, index, FALSE );
    return TRUE;
}


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


/***********************************************************************
 *           LISTBOX_HandleMouseMove
 *
 * WM_MOUSEMOVE handler.
 */
static void LISTBOX_HandleMouseMove( WND *wnd, 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( wnd, descr, x, y );
    if (index == -1) index = descr->focus_item;
    if (!LISTBOX_HandleTimer( wnd, descr, index, dir )) dir = LB_TIMER_NONE;

    /* Start/stop the system timer */

    if (dir != LB_TIMER_NONE)
        SetSystemTimer( wnd->hwndSelf, LB_TIMER_ID, LB_SCROLL_TIMEOUT, NULL);
    else if (LISTBOX_Timer != LB_TIMER_NONE)
        KillSystemTimer( wnd->hwndSelf, LB_TIMER_ID );
    LISTBOX_Timer = dir;
}


/***********************************************************************
 *           LISTBOX_HandleKeyDown
 */
static LRESULT LISTBOX_HandleKeyDown( WND *wnd, 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 = SendMessageA( descr->owner, WM_VKEYTOITEM,
                                MAKEWPARAM(LOWORD(wParam), descr->focus_item),
                                wnd->hwndSelf );
        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(wnd,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(wnd,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( wnd, 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( wnd, descr, caret, TRUE );
        LISTBOX_SetSelection( wnd, descr, caret, TRUE, FALSE);
        if (descr->style & LBS_NOTIFY)
        {
	    if( descr->lphc && CB_GETTYPE(descr->lphc) != CBS_SIMPLE )
            {
		/* make sure that combo parent doesn't hide us */
		descr->lphc->wState |= CBF_NOROLLUP;
	    }
            if (descr->nb_items) SEND_NOTIFICATION( wnd, descr, LBN_SELCHANGE );
        }
    }
    return 0;
}


/***********************************************************************
 *           LISTBOX_HandleChar
 */
static LRESULT LISTBOX_HandleChar( WND *wnd, LB_DESCR *descr,
                                   WPARAM wParam )
{
    INT caret = -1;
    char str[2];
    
    str[0] = wParam & 0xff; 
    str[1] = '\0';

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


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

    if (!(descr = HeapAlloc( GetProcessHeap(), 0, sizeof(*descr) )))
        return FALSE;
    if (!(descr->heap = HeapCreate( 0, 0x10000, 0 )))
    {
        HeapFree( GetProcessHeap(), 0, descr );
        return FALSE;
    }
    GetClientRect( wnd->hwndSelf, &rect );
    descr->owner         = GetParent( wnd->hwndSelf );
    descr->style         = wnd->dwStyle;
    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   = (wnd->dwStyle & WS_HSCROLL) ? 1 : 0;
    descr->horz_pos      = 0;
    descr->nb_tabs       = 0;
    descr->tabs          = NULL;
    descr->caret_on      = lphc ? FALSE : TRUE;
    descr->in_focus 	 = FALSE;
    descr->captured      = FALSE;
    descr->font          = 0;
    descr->locale        = 0;  /* FIXME */
    descr->lphc		 = lphc;

    if( ( GetExpWinVer16( wnd->hInstance ) & 0xFF00 ) == 0x0300
	&& ( 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",
		     wnd->hwndSelf, descr->owner, lphc->self->hwndSelf );
	descr->owner = lphc->self->hwndSelf;
    }

    *(LB_DESCR **)wnd->wExtra = 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( wnd, 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
	{
            mis.CtlType    = ODT_LISTBOX;
            mis.CtlID      = wnd->wIDmenu;
            mis.itemID     = -1;
            mis.itemWidth  =  0;
            mis.itemData   =  0;
            mis.itemHeight = descr->item_height;
            SendMessageA( descr->owner, WM_MEASUREITEM, wnd->wIDmenu, (LPARAM)&mis );
            descr->item_height = mis.itemHeight ? mis.itemHeight : 1;
	}
    }

    return TRUE;
}


/***********************************************************************
 *           LISTBOX_Destroy
 */
static BOOL LISTBOX_Destroy( WND *wnd, LB_DESCR *descr )
{
    LISTBOX_ResetContent( wnd, descr );
    HeapDestroy( descr->heap );
    HeapFree( GetProcessHeap(), 0, descr );
    wnd->wExtra[0] = 0;
    return TRUE;
}


/***********************************************************************
 *           ListBoxWndProc
 */
static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg,
                               	      WPARAM wParam, LPARAM lParam )
{
    LRESULT ret;
    LB_DESCR *descr;
    HWND	hwnd = wnd->hwndSelf;

    if (!wnd) return 0;
    if (!(descr = *(LB_DESCR **)wnd->wExtra))
    {
        switch (msg)
	{
	    case WM_CREATE:
	    {
                if (!LISTBOX_Create( wnd, NULL ))
		     return -1;
		TRACE("creating wnd=%04x descr=%p\n",
		      hwnd, *(LB_DESCR **)wnd->wExtra );
		return 0;
	    }
	    case WM_NCCREATE:
	    {
	        /*
		 * When a listbox is not in a combobox and the look
		 * is win95,  the WS_BORDER style is replaced with 
		 * the WS_EX_CLIENTEDGE style.
		 */
	        if ( (TWEAK_WineLook > WIN31_LOOK) &&
		     (wnd->dwStyle & WS_BORDER) )
		{
	            wnd->dwExStyle |= WS_EX_CLIENTEDGE;
		    wnd->dwStyle     &= ~ WS_BORDER;
		}
	    }
	}

        /* Ignore all other messages before we get a WM_CREATE */
        return DefWindowProcA( hwnd, msg, wParam, lParam );
    }

    TRACE("[%04x]: msg %s wp %08x lp %08lx\n",
		 wnd->hwndSelf, SPY_GetMsgName(msg), wParam, lParam );
    switch(msg)
    {
    case LB_RESETCONTENT16:
    case LB_RESETCONTENT:
        LISTBOX_ResetContent( wnd, descr );
        return 0;

    case LB_ADDSTRING16:
        if (HAS_STRINGS(descr)) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
        /* fall through */
    case LB_ADDSTRING:
        wParam = LISTBOX_FindStringPos( wnd, descr, (LPCSTR)lParam, FALSE );
        return LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam );

    case LB_INSERTSTRING16:
        if (HAS_STRINGS(descr)) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
        wParam = (INT)(INT16)wParam;
        /* fall through */
    case LB_INSERTSTRING:
        return LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam );

    case LB_ADDFILE16:
        if (HAS_STRINGS(descr)) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
        /* fall through */
    case LB_ADDFILE:
        wParam = LISTBOX_FindFileStrPos( wnd, descr, (LPCSTR)lParam );
        return LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam );

    case LB_DELETESTRING16:
    case LB_DELETESTRING:
        if (LISTBOX_RemoveItem( wnd, 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)PTR_SEG_TO_LIN(lParam);
        /* fall through */
    case LB_GETTEXT:
        return LISTBOX_GetText( wnd, descr, wParam, (LPSTR)lParam );

    case LB_GETTEXTLEN16:
        /* fall through */
    case LB_GETTEXTLEN:
        if (wParam >= descr->nb_items)
            return LB_ERR;
        return (HAS_STRINGS(descr) ? strlen(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( wnd, descr, wParam );

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

    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(wnd, 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( wnd, 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( wnd, descr, wParam, TRUE );

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

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

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

    case LB_FINDSTRING16:
        wParam = (INT)(INT16)wParam;
        if (HAS_STRINGS(descr)) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
        /* fall through */
    case LB_FINDSTRING:
        return LISTBOX_FindString( wnd, descr, wParam, (LPCSTR)lParam, FALSE );

    case LB_FINDSTRINGEXACT16:
        wParam = (INT)(INT16)wParam;
        if (HAS_STRINGS(descr)) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
        /* fall through */
    case LB_FINDSTRINGEXACT:
        return LISTBOX_FindString( wnd, descr, wParam, (LPCSTR)lParam, TRUE );

    case LB_SELECTSTRING16:
        wParam = (INT)(INT16)wParam;
        if (HAS_STRINGS(descr)) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
        /* fall through */
    case LB_SELECTSTRING:
        {
            INT index = LISTBOX_FindString( wnd, descr, wParam,
                                              (LPCSTR)lParam, FALSE );
            if (index == LB_ERR)
                return LB_ERR;
            LISTBOX_SetSelection( wnd, 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( wnd, 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( wnd, descr, wParam, TRUE );  
        return LISTBOX_SetSelection( wnd, descr, wParam, TRUE, FALSE );

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

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

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

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

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

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

    case LB_SETHORIZONTALEXTENT16:
    case LB_SETHORIZONTALEXTENT:
        return LISTBOX_SetHorizontalExtent( wnd, 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:
        return LISTBOX_Directory( wnd, descr, wParam,
                                  (LPCSTR)PTR_SEG_TO_LIN(lParam), FALSE );

    case LB_DIR:
        return LISTBOX_Directory( wnd, descr, wParam, (LPCSTR)lParam, TRUE );

    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( wnd, descr, wParam, (DWORD)lParam );

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

    case LB_SETTABSTOPS16:
        return LISTBOX_SetTabStops( wnd, descr, (INT)(INT16)wParam,
                                    (LPINT)PTR_SEG_TO_LIN(lParam), TRUE );

    case LB_SETTABSTOPS:
        return LISTBOX_SetTabStops( wnd, 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( wnd, 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( wnd, descr, descr->focus_item, ODA_FOCUS );
        return LB_OKAY;
	
    case WM_DESTROY:
        return LISTBOX_Destroy( wnd, descr );

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

    case WM_SETREDRAW:
        LISTBOX_SetRedraw( wnd, 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( wnd, descr, hdc );
            if( !wParam ) EndPaint( hwnd, &ps );
        }
        return ret;
    case WM_SIZE:
        LISTBOX_UpdateSize( wnd, descr );
        return 0;
    case WM_GETFONT:
        return descr->font;
    case WM_SETFONT:
        LISTBOX_SetFont( wnd, descr, (HFONT)wParam );
        if (lParam) InvalidateRect( wnd->hwndSelf, 0, TRUE );
        return 0;
    case WM_SETFOCUS:
        descr->in_focus = TRUE;
        descr->caret_on = TRUE;
        if (descr->focus_item != -1)
            LISTBOX_RepaintItem( wnd, descr, descr->focus_item, ODA_FOCUS );
        SEND_NOTIFICATION( wnd, descr, LBN_SETFOCUS );
        return 0;
    case WM_KILLFOCUS:
        descr->in_focus = FALSE;
        if ((descr->focus_item != -1) && descr->caret_on)
            LISTBOX_RepaintItem( wnd, descr, descr->focus_item, ODA_FOCUS );
        SEND_NOTIFICATION( wnd, descr, LBN_KILLFOCUS );
        return 0;
    case WM_HSCROLL:
        return LISTBOX_HandleHScroll( wnd, descr, wParam, lParam );
    case WM_VSCROLL:
        return LISTBOX_HandleVScroll( wnd, descr, wParam, lParam );
    case WM_MOUSEACTIVATE:
        return MA_NOACTIVATE;
    case WM_MOUSEWHEEL:
        if (wParam & (MK_SHIFT | MK_CONTROL))
            return DefWindowProcA( hwnd, msg, wParam, lParam );
        return LISTBOX_HandleMouseWheel( wnd, descr, wParam, lParam );
    case WM_LBUTTONDOWN:
        return LISTBOX_HandleLButtonDown( wnd, descr, wParam,
                                          (INT16)LOWORD(lParam),
                                          (INT16)HIWORD(lParam) );
    case WM_LBUTTONDBLCLK:
        if (descr->style & LBS_NOTIFY)
            SEND_NOTIFICATION( wnd, descr, LBN_DBLCLK );
        return 0;
    case WM_MOUSEMOVE:
        if (GetCapture() == hwnd)
            LISTBOX_HandleMouseMove( wnd, descr, (INT16)LOWORD(lParam),
                                     (INT16)HIWORD(lParam) );
        return 0;
    case WM_LBUTTONUP:
        return LISTBOX_HandleLButtonUp( wnd, descr );
    case WM_KEYDOWN:
        return LISTBOX_HandleKeyDown( wnd, descr, wParam );
    case WM_CHAR:
        return LISTBOX_HandleChar( wnd, descr, wParam );
    case WM_SYSTIMER:
        return LISTBOX_HandleSystemTimer( wnd, descr );
    case WM_ERASEBKGND:
        if ((IS_OWNERDRAW(descr)) && !(descr->style & LBS_DISPLAYCHANGED))
        {
            RECT rect;
            HBRUSH hbrush = SendMessageA( descr->owner, WM_CTLCOLORLISTBOX,
                                              wParam, (LPARAM)wnd->hwndSelf );
            GetClientRect(hwnd, &rect);
            if (hbrush) FillRect( (HDC)wParam, &rect, hbrush );
        }
        return 1;
    case WM_DROPFILES:
        if( !descr->lphc ) 
            return SendMessageA( descr->owner, msg, wParam, lParam );
	break;

    case WM_DROPOBJECT:
    case WM_QUERYDROPOBJECT:
    case WM_DRAGSELECT:
    case WM_DRAGMOVE:
	if( !descr->lphc )
        {
            LPDRAGINFO dragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN( (SEGPTR)lParam );
            dragInfo->l = LISTBOX_GetItemFromPoint( wnd, descr, dragInfo->pt.x,
                                                dragInfo->pt.y );
            return SendMessageA( 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 DefWindowProcA( hwnd, msg, wParam, lParam );
    }
    return 0;
}

/***********************************************************************
 *           ListBoxWndProc
 *
 * This is just a wrapper for the real wndproc, it only does window locking
 * and unlocking.
 */
LRESULT WINAPI ListBoxWndProc( HWND hwnd, UINT msg,
                               WPARAM wParam, LPARAM lParam )
{
    WND*	wndPtr = WIN_FindWndPtr( hwnd );
    LRESULT	res = ListBoxWndProc_locked(wndPtr,msg,wParam,lParam);

    WIN_ReleaseWndPtr(wndPtr);
    return res;
}

/***********************************************************************
 *           COMBO_Directory
 */
LRESULT COMBO_Directory( LPHEADCOMBO lphc, UINT attrib, LPSTR dir, BOOL bLong)
{
    WND *wnd = WIN_FindWndPtr( lphc->hWndLBox );

    if( wnd )
    {
        LB_DESCR *descr = *(LB_DESCR **)wnd->wExtra;
	if( descr )
	{
	    LRESULT	lRet = LISTBOX_Directory( wnd, descr, attrib, dir, bLong );

	    RedrawWindow( lphc->self->hwndSelf, NULL, 0, 
			    RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW );
            WIN_ReleaseWndPtr(wnd);
	    return lRet;
	}
        WIN_ReleaseWndPtr(wnd);
    }
    return CB_ERR;
}

/***********************************************************************
 *           ComboLBWndProc_locked
 *
 * The real combo listbox wndproc, but called with locked WND struct.
 */
static inline LRESULT WINAPI ComboLBWndProc_locked( WND* wnd, UINT msg,
                               WPARAM wParam, LPARAM lParam )
{
    LRESULT lRet = 0;
    HWND hwnd = wnd->hwndSelf;

    if (wnd)
    {
	LB_DESCR *descr = *(LB_DESCR **)wnd->wExtra;

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

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

	    switch( msg )
	    {
		case WM_CREATE:
#define lpcs	((LPCREATESTRUCTA)lParam)
		     TRACE_(combo)("\tpassed parent handle = 0x%08x\n", 
				  (UINT)lpcs->lpCreateParams);

		     lphc = (LPHEADCOMBO)(lpcs->lpCreateParams);
#undef  lpcs
		     return LISTBOX_Create( wnd, 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( wnd, descr, 
						    mousePos.x, mousePos.y);

                           descr->captured = captured;

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

		       return 0;

		     }
		     else
		     {
		       /*
			* If we are in Win3.1 look, go with the default behavior.
			*/
		       return ListBoxWndProc( 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 == 0xFFFFFFFF) ||
			    (!PtInRect( &clientRect, mousePos )) )
		       {
			 LISTBOX_MoveCaret( wnd,
					    descr, 
					    lphc->droppedIndex, 
					    FALSE );
		       }
		     }
		     return LISTBOX_HandleLButtonUp( wnd, descr );
		case WM_LBUTTONDBLCLK:
		case WM_LBUTTONDOWN:
                     return LISTBOX_HandleLButtonDownCombo(wnd, descr, msg, wParam, 
                                          (INT16)LOWORD(lParam),
                                          (INT16)HIWORD(lParam) );
		case WM_MOUSEACTIVATE:
		     return MA_NOACTIVATE;
                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( wnd, descr, wParam );

		case LB_SETCURSEL16:
		case LB_SETCURSEL:
		     lRet = ListBoxWndProc( 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 ListBoxWndProc( hwnd, msg, wParam, lParam );
	    }
        }
        lRet = DefWindowProcA( hwnd, msg, wParam, lParam );

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

/***********************************************************************
 *           ComboLBWndProc
 *
 *  NOTE: in Windows, winproc address of the ComboLBox is the same 
 *	  as that of the Listbox.
 * 
 * This is just a wrapper for the real wndproc, it only does window locking
 * and unlocking.
 */
LRESULT WINAPI ComboLBWndProc( HWND hwnd, UINT msg,
                               WPARAM wParam, LPARAM lParam )
{
    WND *wnd = WIN_FindWndPtr( hwnd );
    LRESULT res = ComboLBWndProc_locked(wnd,msg,wParam,lParam);

    WIN_ReleaseWndPtr(wnd);
    return res;
}
