/*
 * Listview control
 *
 * Copyright 1998, 1999 Eric Kohl
 * Copyright 1999 Luc Tourangeau
 * Copyright 2000 Jason Mawdsley
 * Copyright 2001 Codeweavers Inc.
 * Copyright 2002 Dimitrie O. Paun
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTES
 * Listview control implementation.
 *
 * TODO:
 *   -- Hot item handling.
 *   -- Expand large item in ICON mode when the cursor is flying over the icon or text.
 *   -- Support CustonDraw options for _WIN32_IE >= 0x560 (see NMLVCUSTOMDRAW docs)
 *
 * Notifications:
 *   LISTVIEW_Notify : most notifications from children (editbox and header)
 *
 * Data structure:
 *   LISTVIEW_SetItemCount : not completed for non OWNERDATA
 *
 * Advanced functionality:
 *   LISTVIEW_GetNumberOfWorkAreas : not implemented
 *   LISTVIEW_GetISearchString : not implemented
 *   LISTVIEW_GetBkImage : not implemented
 *   LISTVIEW_SetBkImage : not implemented
 *   LISTVIEW_GetColumnOrderArray : simple hack only
 *   LISTVIEW_SetColumnOrderArray : simple hack only
 *   LISTVIEW_Arrange : empty stub
 *   LISTVIEW_ApproximateViewRect : incomplete
 *   LISTVIEW_Update : not completed
 *
 * Known differences in message stream from native control (not known if
 * these differences cause problems):
 *   LVM_INSERTITEM issues LVM_SETITEMSTATE and LVM_SETITEM in certain cases.
 *   LVM_SETITEM does not always issue LVN_ITEMCHANGING/LVN_ITEMCHANGED.
 *   WM_CREATE does not issue WM_QUERYUISTATE and associated registry
 *     processing for "USEDOUBLECLICKTIME".
 */


#include "config.h"
#include "wine/port.h"

#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "winbase.h"
#include "winnt.h"
#include "heap.h"
#include "commctrl.h"
#include "comctl32.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(listview);

/* make sure you set this to 0 for production use! */
#define DEBUG_RANGES 1

typedef struct tagCOLUMN_INFO
{
  RECT rcHeader;	/* tracks the header's rectangle */
  UINT align;		/* one of DT_{LEFT,CENTER,RIGHT} */
  BOOL hasImage;        /* on/off switch for column images */
} COLUMN_INFO;

typedef struct tagITEMHDR
{
  LPWSTR pszText;
  INT iImage;
} ITEMHDR, *LPITEMHDR;

typedef struct tagLISTVIEW_SUBITEM
{
  ITEMHDR hdr;
  INT iSubItem;
} LISTVIEW_SUBITEM;

typedef struct tagLISTVIEW_ITEM
{
  ITEMHDR hdr;
  UINT state;
  LPARAM lParam;
  INT iIndent;
} LISTVIEW_ITEM;

typedef struct tagRANGE
{
  INT lower;
  INT upper;
} RANGE;

typedef struct tagRANGES
{
  HDPA hdpa;
} *RANGES;

typedef struct tagITERATOR
{
  INT nItem;
  INT nSpecial;
  RANGE range;
  RANGES ranges;
  INT index;
} ITERATOR;

typedef struct tagLISTVIEW_INFO
{
  HWND hwndSelf;
  HBRUSH hBkBrush;
  COLORREF clrBk;
  COLORREF clrText;
  COLORREF clrTextBk;
  COLORREF clrTextBkDefault;
  HIMAGELIST himlNormal;
  HIMAGELIST himlSmall;
  HIMAGELIST himlState;
  BOOL bLButtonDown;
  BOOL bRButtonDown;
  INT nItemHeight;
  INT nItemWidth;
  RANGES selectionRanges;
  INT nSelectionMark;
  INT nHotItem;
  SHORT notifyFormat;
  RECT rcList;                 /* This rectangle is really the window
				* client rectangle possibly reduced by the 
				* horizontal scroll bar and/or header - see 
				* LISTVIEW_UpdateSize. This rectangle offset
				* by the LISTVIEW_GetOrigin value is in
				* client coordinates   */
  RECT rcView;                 /* This rectangle contains all items - 
				* contructed in LISTVIEW_AlignTop and
				* LISTVIEW_AlignLeft   */
  SIZE iconSize;
  SIZE iconSpacing;
  SIZE iconStateSize;
  UINT uCallbackMask;
  HWND hwndHeader;
  HFONT hDefaultFont;
  HCURSOR hHotCursor;
  HFONT hFont;
  INT ntmHeight;		/*  from GetTextMetrics from above font */
  BOOL bRedraw;
  BOOL bFocus;
  INT nFocusedItem;
  RECT rcFocus;
  DWORD dwStyle;		/* the cached window GWL_STYLE */
  DWORD dwLvExStyle;		/* extended listview style */
  INT nItemCount;		/* the number of items in the list */
  HDPA hdpaItems;               /* array ITEM_INFO pointers */
  HDPA hdpaPosX;		/* maintains the (X, Y) coordinates of the */
  HDPA hdpaPosY;		/* items in LVS_ICON, and LVS_SMALLICON modes */
  HDPA hdpaColumns;		/* array of COLUMN_INFO pointers */
  PFNLVCOMPARE pfnCompare;
  LPARAM lParamSort;
  HWND hwndEdit;
  WNDPROC EditWndProc;
  INT nEditLabelItem;
  DWORD dwHoverTime;

  DWORD lastKeyPressTimestamp;
  WPARAM charCode;
  INT nSearchParamLength;
  WCHAR szSearchParam[ MAX_PATH ];
  BOOL bIsDrawing;
} LISTVIEW_INFO;

/*
 * constants
 */
/* How many we debug buffer to allocate */
#define DEBUG_BUFFERS 20
/* The size of a single debug bbuffer */
#define DEBUG_BUFFER_SIZE 256

/* Internal interface to LISTVIEW_HScroll and LISTVIEW_VScroll */
#define SB_INTERNAL      -1

/* maximum size of a label */
#define DISP_TEXT_SIZE 512

/* padding for items in list and small icon display modes */
#define WIDTH_PADDING 12

/* padding for items in list, report and small icon display modes */
#define HEIGHT_PADDING 1

/* offset of items in report display mode */
#define REPORT_MARGINX 2

/* padding for icon in large icon display mode
 *   ICON_TOP_PADDING_NOTHITABLE - space between top of box and area
 *                                 that HITTEST will see.
 *   ICON_TOP_PADDING_HITABLE - spacing between above and icon.
 *   ICON_TOP_PADDING - sum of the two above.
 *   ICON_BOTTOM_PADDING - between bottom of icon and top of text
 *   LABEL_VERT_PADDING - between bottom of text and end of box
 *
 *   ICON_LR_PADDING - additional width above icon size.
 *   ICON_LR_HALF - half of the above value
 */
#define ICON_TOP_PADDING_NOTHITABLE  2
#define ICON_TOP_PADDING_HITABLE     2
#define ICON_TOP_PADDING (ICON_TOP_PADDING_NOTHITABLE + ICON_TOP_PADDING_HITABLE)
#define ICON_BOTTOM_PADDING          4
#define LABEL_VERT_PADDING           7
#define ICON_LR_PADDING              16
#define ICON_LR_HALF                 (ICON_LR_PADDING/2)

/* default label width for items in list and small icon display modes */
#define DEFAULT_LABEL_WIDTH 40

/* default column width for items in list display mode */
#define DEFAULT_COLUMN_WIDTH 128

/* Size of "line" scroll for V & H scrolls */
#define LISTVIEW_SCROLL_ICON_LINE_SIZE 37

/* Padding betwen image and label */
#define IMAGE_PADDING  2

/* Padding behind the label */
#define TRAILING_PADDING  5

/* Border for the icon caption */
#define CAPTION_BORDER  2

/* Standard DrawText flags */
#define LV_ML_DT_FLAGS  (DT_TOP | DT_NOPREFIX | DT_EDITCONTROL | DT_CENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS)
#define LV_FL_DT_FLAGS  (DT_TOP | DT_NOPREFIX | DT_EDITCONTROL | DT_CENTER | DT_WORDBREAK | DT_NOCLIP)
#define LV_SL_DT_FLAGS  (DT_TOP | DT_EDITCONTROL | DT_SINGLELINE | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS)

/* The time in milisecods to reset the search in the list */
#define KEY_DELAY       450

/* Dump the LISTVIEW_INFO structure to the debug channel */
#define LISTVIEW_DUMP(iP) do { \
  TRACE("hwndSelf=%08x, clrBk=0x%06lx, clrText=0x%06lx, clrTextBk=0x%06lx, ItemHeight=%d, ItemWidth=%d, Style=0x%08lx\n", \
        iP->hwndSelf, iP->clrBk, iP->clrText, iP->clrTextBk, \
        iP->nItemHeight, iP->nItemWidth, infoPtr->dwStyle); \
  TRACE("hwndSelf=%08x, himlNor=%p, himlSml=%p, himlState=%p, Focused=%d, Hot=%d, exStyle=0x%08lx, Focus=%s\n", \
        iP->hwndSelf, iP->himlNormal, iP->himlSmall, iP->himlState, \
        iP->nFocusedItem, iP->nHotItem, iP->dwLvExStyle, \
        (iP->bFocus) ? "true" : "false"); \
  TRACE("hwndSelf=%08x, ntmH=%d, icSz.cx=%ld, icSz.cy=%ld, icSp.cx=%ld, icSp.cy=%ld, notifyFmt=%d\n", \
        iP->hwndSelf, iP->ntmHeight, iP->iconSize.cx, iP->iconSize.cy, \
        iP->iconSpacing.cx, iP->iconSpacing.cy, iP->notifyFormat); \
  TRACE("hwndSelf=%08x, rcList=(%d,%d)-(%d,%d), rcView=(%d,%d)-(%d,%d)\n", \
        iP->hwndSelf, \
	iP->rcList.left, iP->rcList.top, iP->rcList.right, iP->rcList.bottom, \
	iP->rcView.left, iP->rcView.top, iP->rcView.right, iP->rcView.bottom); \
} while(0)


/*
 * forward declarations
 */
static BOOL LISTVIEW_GetItemT(LISTVIEW_INFO *, LPLVITEMW, BOOL);
static BOOL LISTVIEW_GetItemBox(LISTVIEW_INFO *, INT, LPRECT);
static void LISTVIEW_AlignLeft(LISTVIEW_INFO *);
static void LISTVIEW_AlignTop(LISTVIEW_INFO *);
static void LISTVIEW_AddGroupSelection(LISTVIEW_INFO *, INT);
static INT LISTVIEW_CalculateMaxHeight(LISTVIEW_INFO *);
static BOOL LISTVIEW_GetItemOrigin(LISTVIEW_INFO *, INT, LPPOINT);
static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *, INT, LPPOINT);
static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *, INT, LPRECT);
static INT LISTVIEW_CalculateMaxWidth(LISTVIEW_INFO *);
static INT LISTVIEW_GetLabelWidth(LISTVIEW_INFO *, INT);
static INT LISTVIEW_GetColumnWidth(LISTVIEW_INFO *, INT);
static BOOL LISTVIEW_GetOrigin(LISTVIEW_INFO *, LPPOINT);
static BOOL LISTVIEW_GetViewRect(LISTVIEW_INFO *, LPRECT);
static void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *, INT);
static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *, LPLVITEMW, BOOL);
static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *, INT, POINT);
static void LISTVIEW_UpdateScroll(LISTVIEW_INFO *);
static void LISTVIEW_SetSelection(LISTVIEW_INFO *, INT);
static BOOL LISTVIEW_UpdateSize(LISTVIEW_INFO *);
static void LISTVIEW_UnsupportedStyles(LONG);
static HWND LISTVIEW_EditLabelT(LISTVIEW_INFO *, INT, BOOL);
static LRESULT LISTVIEW_Command(LISTVIEW_INFO *, WPARAM, LPARAM);
static LRESULT LISTVIEW_SortItems(LISTVIEW_INFO *, PFNLVCOMPARE, LPARAM);
static LRESULT LISTVIEW_GetStringWidthT(LISTVIEW_INFO *, LPCWSTR, BOOL);
static BOOL LISTVIEW_KeySelection(LISTVIEW_INFO *, INT);
static LRESULT LISTVIEW_GetItemState(LISTVIEW_INFO *, INT, UINT);
static LRESULT LISTVIEW_SetItemState(LISTVIEW_INFO *, INT, LPLVITEMW);
static LRESULT LISTVIEW_GetColumnT(LISTVIEW_INFO *, INT, LPLVCOLUMNW, BOOL);
static LRESULT LISTVIEW_VScroll(LISTVIEW_INFO *, INT, INT, HWND);
static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *, INT, INT, HWND);
static INT LISTVIEW_GetTopIndex(LISTVIEW_INFO *);
static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *, INT, BOOL);
static HWND CreateEditLabelT(LISTVIEW_INFO *, LPCWSTR, DWORD, INT, INT, INT, INT, BOOL);

/******** Text handling functions *************************************/

/* A text pointer is either NULL, LPSTR_TEXTCALLBACK, or points to a
 * text string. The string may be ANSI or Unicode, in which case
 * the boolean isW tells us the type of the string.
 *
 * The name of the function tell what type of strings it expects:
 *   W: Unicode, T: ANSI/Unicode - function of isW
 */

static inline BOOL is_textW(LPCWSTR text)
{
    return text != NULL && text != LPSTR_TEXTCALLBACKW;
}

static inline BOOL is_textT(LPCWSTR text, BOOL isW)
{
    /* we can ignore isW since LPSTR_TEXTCALLBACKW == LPSTR_TEXTCALLBACKA */
    return is_textW(text);
}

static inline int textlenT(LPCWSTR text, BOOL isW)
{
    return !is_textT(text, isW) ? 0 :
	   isW ? lstrlenW(text) : lstrlenA((LPCSTR)text);
}

static inline void textcpynT(LPWSTR dest, BOOL isDestW, LPCWSTR src, BOOL isSrcW, INT max)
{
    if (isDestW)
	if (isSrcW) lstrcpynW(dest, src, max);
	else MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, dest, max);
    else
	if (isSrcW) WideCharToMultiByte(CP_ACP, 0, src, -1, (LPSTR)dest, max, NULL, NULL);
	else lstrcpynA((LPSTR)dest, (LPCSTR)src, max);
}

static inline LPWSTR textdupTtoW(LPCWSTR text, BOOL isW)
{
    LPWSTR wstr = (LPWSTR)text;

    if (!isW && is_textT(text, isW))
    {
	INT len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)text, -1, NULL, 0);
	wstr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
	if (wstr) MultiByteToWideChar(CP_ACP, 0, (LPCSTR)text, -1, wstr, len);
    }
    TRACE("   wstr=%s\n", text == LPSTR_TEXTCALLBACKW ?  "(callback)" : debugstr_w(wstr));
    return wstr;
}

static inline void textfreeT(LPWSTR wstr, BOOL isW)
{
    if (!isW && is_textT(wstr, isW)) HeapFree(GetProcessHeap(), 0, wstr);
}

/*
 * dest is a pointer to a Unicode string
 * src is a pointer to a string (Unicode if isW, ANSI if !isW)
 */
static BOOL textsetptrT(LPWSTR *dest, LPWSTR src, BOOL isW)
{
    BOOL bResult = TRUE;
    
    if (src == LPSTR_TEXTCALLBACKW)
    {
	if (is_textW(*dest)) COMCTL32_Free(*dest);
	*dest = LPSTR_TEXTCALLBACKW;
    }
    else
    {
	LPWSTR pszText = textdupTtoW(src, isW);
	if (*dest == LPSTR_TEXTCALLBACKW) *dest = NULL;
	bResult = Str_SetPtrW(dest, pszText);
	textfreeT(pszText, isW);
    }
    return bResult;
}

/*
 * compares a Unicode to a Unicode/ANSI text string
 */
static inline int textcmpWT(LPWSTR aw, LPWSTR bt, BOOL isW)
{
    if (!aw) return bt ? -1 : 0;
    if (!bt) return aw ? 1 : 0;
    if (aw == LPSTR_TEXTCALLBACKW)
	return bt == LPSTR_TEXTCALLBACKW ? 0 : -1;
    if (bt != LPSTR_TEXTCALLBACKW)
    {
	LPWSTR bw = textdupTtoW(bt, isW);
	int r = bw ? lstrcmpW(aw, bw) : 1;
	textfreeT(bw, isW);
	return r;
    }	    
	    
    return 1;
}
    
static inline int lstrncmpiW(LPCWSTR s1, LPCWSTR s2, int n)
{
    int res;

    n = min(min(n, strlenW(s1)), strlenW(s2));
    res = CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, s1, n, s2, n);
    return res ? res - sizeof(WCHAR) : res;
}

/******** Debugging functions *****************************************/

static inline LPCSTR debugtext_t(LPCWSTR text, BOOL isW)
{
    if (text == LPSTR_TEXTCALLBACKW) return "(callback)";
    return isW ? debugstr_w(text) : debugstr_a((LPCSTR)text);
}

static inline LPCSTR debugtext_tn(LPCWSTR text, BOOL isW, INT n)
{
    if (text == LPSTR_TEXTCALLBACKW) return "(callback)";
    n = min(textlenT(text, isW), n);
    return isW ? debugstr_wn(text, n) : debugstr_an((LPCSTR)text, n);
}

static char* debug_getbuf()
{
    static int index = 0;
    static char buffers[DEBUG_BUFFERS][DEBUG_BUFFER_SIZE];
    return buffers[index++ % DEBUG_BUFFERS];
}

static inline char* debugrange(const RANGE* lprng)
{
    if (lprng) 
    {
	char* buf = debug_getbuf();
	snprintf(buf, DEBUG_BUFFER_SIZE, "[%d, %d)", lprng->lower, lprng->upper);
    	return buf;
    } else return "(null)";
}

static inline char* debugpoint(const POINT* lppt)
{
    if (lppt) 
    {
	char* buf = debug_getbuf();
	snprintf(buf, DEBUG_BUFFER_SIZE, "(%ld, %ld)", lppt->x, lppt->y);
    	return buf;
    } else return "(null)";
}

static inline char* debugrect(const RECT* rect)
{
    if (rect) 
    {
	char* buf = debug_getbuf();
	snprintf(buf, DEBUG_BUFFER_SIZE, "[(%d, %d);(%d, %d)]", 
		 rect->left, rect->top, rect->right, rect->bottom);
    	return buf;
    } else return "(null)";
}

static char* debugnmlistview(LPNMLISTVIEW plvnm)
{
    if (plvnm)
    {
	char* buf = debug_getbuf();
        snprintf(buf, DEBUG_BUFFER_SIZE, "iItem=%d, iSubItem=%d, uNewState=0x%x,"
	         " uOldState=0x%x, uChanged=0x%x, ptAction=%s, lParam=%ld\n",
	         plvnm->iItem, plvnm->iSubItem, plvnm->uNewState, plvnm->uOldState,
		 plvnm->uChanged, debugpoint(&plvnm->ptAction), plvnm->lParam);
	return buf;
    } else return "(null)";
}

static char* debuglvitem_t(LPLVITEMW lpLVItem, BOOL isW)
{
    char* buf = debug_getbuf(), *text = buf;
    int len, size = DEBUG_BUFFER_SIZE;
    
    if (lpLVItem == NULL) return "(null)";
    len = snprintf(buf, size, "{iItem=%d, iSubItem=%d, ", lpLVItem->iItem, lpLVItem->iSubItem);
    if (len == -1) goto end; buf += len; size -= len;
    if (lpLVItem->mask & LVIF_STATE)
	len = snprintf(buf, size, "state=%x, stateMask=%x, ", lpLVItem->state, lpLVItem->stateMask);
    else len = 0;
    if (len == -1) goto end; buf += len; size -= len;
    if (lpLVItem->mask & LVIF_TEXT)
	len = snprintf(buf, size, "pszText=%s, cchTextMax=%d, ", debugtext_tn(lpLVItem->pszText, isW, 80), lpLVItem->cchTextMax);
    else len = 0;
    if (len == -1) goto end; buf += len; size -= len;
    if (lpLVItem->mask & LVIF_IMAGE)
	len = snprintf(buf, size, "iImage=%d, ", lpLVItem->iImage);
    else len = 0;
    if (len == -1) goto end; buf += len; size -= len;
    if (lpLVItem->mask & LVIF_PARAM)
	len = snprintf(buf, size, "lParam=%lx, ", lpLVItem->lParam);
    else len = 0;
    if (len == -1) goto end; buf += len; size -= len;
    if (lpLVItem->mask & LVIF_INDENT)
	len = snprintf(buf, size, "iIndent=%d, ", lpLVItem->iIndent);
    else len = 0;
    if (len == -1) goto end; buf += len; size -= len;
    goto undo;
end:
    buf = text + strlen(text);
undo:
    if (buf - text > 2) buf[-2] = '}'; buf[-1] = 0;
    return text;
}

static char* debuglvcolumn_t(LPLVCOLUMNW lpColumn, BOOL isW)
{
    char* buf = debug_getbuf(), *text = buf;
    int len, size = DEBUG_BUFFER_SIZE;
    
    if (lpColumn == NULL) return "(null)";
    len = snprintf(buf, size, "{");
    if (len == -1) goto end; buf += len; size -= len;
    if (lpColumn->mask & LVCF_SUBITEM)
	len = snprintf(buf, size, "iSubItem=%d, ",  lpColumn->iSubItem);
    else len = 0;
    if (len == -1) goto end; buf += len; size -= len;
    if (lpColumn->mask & LVCF_FMT)
	len = snprintf(buf, size, "fmt=%x, ", lpColumn->fmt);
    else len = 0;
    if (len == -1) goto end; buf += len; size -= len;
    if (lpColumn->mask & LVCF_WIDTH)
	len = snprintf(buf, size, "cx=%d, ", lpColumn->cx);
    else len = 0;
    if (len == -1) goto end; buf += len; size -= len;
    if (lpColumn->mask & LVCF_TEXT)
	len = snprintf(buf, size, "pszText=%s, cchTextMax=%d, ", debugtext_tn(lpColumn->pszText, isW, 80), lpColumn->cchTextMax);
    else len = 0;
    if (len == -1) goto end; buf += len; size -= len;
    if (lpColumn->mask & LVCF_IMAGE)
	len = snprintf(buf, size, "iImage=%d, ", lpColumn->iImage);
    else len = 0;
    if (len == -1) goto end; buf += len; size -= len;
    if (lpColumn->mask & LVCF_ORDER)
	len = snprintf(buf, size, "iOrder=%d, ", lpColumn->iOrder);
    else len = 0;
    if (len == -1) goto end; buf += len; size -= len;
    goto undo;
end:
    buf = text + strlen(text);
undo:
    if (buf - text > 2) buf[-2] = '}'; buf[-1] = 0;
    return text;
}


/******** Notification functions i************************************/

static LRESULT notify_hdr(LISTVIEW_INFO *infoPtr, INT code, LPNMHDR pnmh)
{
    LRESULT result;
    
    TRACE("(code=%d)\n", code);

    pnmh->hwndFrom = infoPtr->hwndSelf;
    pnmh->idFrom = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
    pnmh->code = code;
    result = SendMessageW(GetParent(infoPtr->hwndSelf), WM_NOTIFY,
			  (WPARAM)pnmh->idFrom, (LPARAM)pnmh);

    TRACE("  <= %ld\n", result);

    return result;
}

static inline LRESULT notify(LISTVIEW_INFO *infoPtr, INT code)
{
    NMHDR nmh;
    return notify_hdr(infoPtr, code, &nmh);
}

static inline void notify_itemactivate(LISTVIEW_INFO *infoPtr)
{
    notify(infoPtr, LVN_ITEMACTIVATE);
}

static inline LRESULT notify_listview(LISTVIEW_INFO *infoPtr, INT code, LPNMLISTVIEW plvnm)
{
    TRACE("(code=%d, plvnm=%s)\n", code, debugnmlistview(plvnm));
    return notify_hdr(infoPtr, code, (LPNMHDR)plvnm);
}

static LRESULT notify_click(LISTVIEW_INFO *infoPtr,  INT code, LVHITTESTINFO *lvht)
{
    NMLISTVIEW nmlv;
    
    ZeroMemory(&nmlv, sizeof(nmlv));
    nmlv.iItem = lvht->iItem;
    nmlv.iSubItem = lvht->iSubItem;
    nmlv.ptAction = lvht->pt;
    return notify_listview(infoPtr, code, &nmlv);
}

static int get_ansi_notification(INT unicodeNotificationCode)
{
    switch (unicodeNotificationCode)
    {
    case LVN_BEGINLABELEDITW: return LVN_BEGINLABELEDITA;
    case LVN_ENDLABELEDITW: return LVN_ENDLABELEDITA;
    case LVN_GETDISPINFOW: return LVN_GETDISPINFOA;
    case LVN_SETDISPINFOW: return LVN_SETDISPINFOA;
    case LVN_ODFINDITEMW: return LVN_ODFINDITEMA;
    case LVN_GETINFOTIPW: return LVN_GETINFOTIPA;
    }
    ERR("unknown notification %x\n", unicodeNotificationCode);
    assert(FALSE);
}

/*
  Send notification. depends on dispinfoW having same
  structure as dispinfoA.
  infoPtr : listview struct
  notificationCode : *Unicode* notification code
  pdi : dispinfo structure (can be unicode or ansi)
  isW : TRUE if dispinfo is Unicode
*/
static BOOL notify_dispinfoT(LISTVIEW_INFO *infoPtr, INT notificationCode, LPNMLVDISPINFOW pdi, BOOL isW)
{
    BOOL bResult = FALSE;
    BOOL convertToAnsi = FALSE, convertToUnicode = FALSE;
    INT realNotifCode;
    INT cchTempBufMax = 0, savCchTextMax = 0;
    LPWSTR pszTempBuf = NULL, savPszText = NULL;

    if ((pdi->item.mask & LVIF_TEXT) && is_textT(pdi->item.pszText, isW))
    {
	convertToAnsi = (isW && infoPtr->notifyFormat == NFR_ANSI);
        convertToUnicode = (!isW && infoPtr->notifyFormat == NFR_UNICODE);
    }

    if (convertToAnsi || convertToUnicode)
    {
	if (notificationCode != LVN_GETDISPINFOW)
	{
	    cchTempBufMax = convertToUnicode ?
      		MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pdi->item.pszText, -1, NULL, 0):
      		WideCharToMultiByte(CP_ACP, 0, pdi->item.pszText, -1, NULL, 0, NULL, NULL);
        }
	else
	{
	    cchTempBufMax = pdi->item.cchTextMax;
	    *pdi->item.pszText = 0; /* make sure we don't process garbage */
	}

        pszTempBuf = HeapAlloc(GetProcessHeap(), 0,
            (convertToUnicode ? sizeof(WCHAR) : sizeof(CHAR)) * cchTempBufMax);
        if (!pszTempBuf) return FALSE;
        if (convertToUnicode)
	    MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pdi->item.pszText, -1,
                                pszTempBuf, cchTempBufMax);
        else
            WideCharToMultiByte(CP_ACP, 0, pdi->item.pszText, -1, (LPSTR) pszTempBuf,
                                cchTempBufMax, NULL, NULL);
        savCchTextMax = pdi->item.cchTextMax;
        savPszText = pdi->item.pszText;
        pdi->item.pszText = pszTempBuf;
        pdi->item.cchTextMax = cchTempBufMax;
    }

    if (infoPtr->notifyFormat == NFR_ANSI)
	realNotifCode = get_ansi_notification(notificationCode);
    else
	realNotifCode = notificationCode;
    TRACE(" pdi->item=%s\n", debuglvitem_t(&pdi->item, infoPtr->notifyFormat != NFR_ANSI));
    bResult = notify_hdr(infoPtr, realNotifCode, (LPNMHDR)pdi);

    if (convertToUnicode || convertToAnsi)
    {
	if (convertToUnicode) /* note : pointer can be changed by app ! */
	    WideCharToMultiByte(CP_ACP, 0, pdi->item.pszText, -1, (LPSTR) savPszText,
                                savCchTextMax, NULL, NULL);
        else
            MultiByteToWideChar(CP_ACP, 0, (LPSTR) pdi->item.pszText, -1,
                                savPszText, savCchTextMax);
        pdi->item.pszText = savPszText; /* restores our buffer */
        pdi->item.cchTextMax = savCchTextMax;
        HeapFree(GetProcessHeap(), 0, pszTempBuf);
    }
    return bResult;
}

static void customdraw_fill(NMLVCUSTOMDRAW *lpnmlvcd, LISTVIEW_INFO *infoPtr, HDC hdc, LPRECT rcBounds)
{
    ZeroMemory(lpnmlvcd, sizeof(NMLVCUSTOMDRAW));
    lpnmlvcd->nmcd.hdc = hdc;
    lpnmlvcd->nmcd.rc = *rcBounds;
    lpnmlvcd->clrTextBk = infoPtr->clrTextBk;
    lpnmlvcd->clrText   = infoPtr->clrText;
}

static inline DWORD notify_customdraw (LISTVIEW_INFO *infoPtr, DWORD dwDrawStage, NMLVCUSTOMDRAW *lpnmlvcd)
{
    lpnmlvcd->nmcd.dwDrawStage = dwDrawStage;
    return notify_hdr(infoPtr, NM_CUSTOMDRAW, &lpnmlvcd->nmcd.hdr);
}

/******** Item iterator functions **********************************/

static RANGES ranges_create(int count);
static void ranges_destroy(RANGES ranges);
static BOOL ranges_add(RANGES ranges, RANGE range);
static BOOL ranges_del(RANGES ranges, RANGE range);
static void ranges_dump(RANGES ranges);

static inline BOOL ranges_additem(RANGES ranges, INT nItem)
{
    RANGE range = { nItem, nItem + 1 };

    return ranges_add(ranges, range);
}

static inline BOOL ranges_delitem(RANGES ranges, INT nItem)
{
    RANGE range = { nItem, nItem + 1 };

    return ranges_del(ranges, range);
}

/***
 * ITERATOR DOCUMENTATION
 *
 * The iterator functions allow for easy, and convenient iteration
 * over items of iterest in the list. Typically, you create a
 * iterator, use it, and destroy it, as such:
 *   ITERATOR i;
 *
 *   iterator_xxxitems(&i, ...);
 *   while (iterator_{prev,next}(&i)
 *   {
 *       //code which uses i.nItem
 *   }
 *   iterator_destroy(&i);
 *
 *   where xxx is either: framed, or visible.
 * Note that it is important that the code destroys the iterator
 * after it's done with it, as the creation of the iterator may
 * allocate memory, which thus needs to be freed.
 * 
 * You can iterate both forwards, and backwards through the list,
 * by using iterator_next or iterator_prev respectively.
 * 
 * Lower numbered items are draw on top of higher number items in
 * LVS_ICON, and LVS_SMALLICON (which are the only modes where
 * items may overlap). So, to test items, you should use
 *    iterator_next
 * which lists the items top to bottom (in Z-order).
 * For drawing items, you should use
 *    iterator_prev
 * which lists the items bottom to top (in Z-order).
 * If you keep iterating over the items after the end-of-items
 * marker (-1) is returned, the iterator will start from the
 * beginning. Typically, you don't need to test for -1,
 * because iterator_{next,prev} will return TRUE if more items
 * are to be iterated over, or FALSE otherwise.
 *
 * Note: the iterator is defined to be bidirectional. That is,
 *       any number of prev followed by any number of next, or
 *       five versa, should leave the iterator at the same item:
 *           prev * n, next * n = next * n, prev * n
 *
 * The iterator has a notion of a out-of-order, special item,
 * which sits at the start of the list. This is used in
 * LVS_ICON, and LVS_SMALLICON mode to handle the focused item,
 * which needs to be first, as it may overlap other items.
 *           
 * The code is a bit messy because we have:
 *   - a special item to deal with
 *   - simple range, or composite range
 *   - empty range.
 * If find bugs, or want to add features, please make sure you
 * always check/modify *both* iterator_prev, and iterator_next.
 */

/****
 * This function iterates through the items in increasing order,
 * but prefixed by the special item, then -1. That is:
 *    special, 1, 2, 3, ..., n, -1.
 * Each item is listed only once.
 */
static inline BOOL iterator_next(ITERATOR* i)
{
    if (i->nItem == -1)
    {
	i->nItem = i->nSpecial;
	if (i->nItem != -1) return TRUE;
    }
    if (i->nItem == i->nSpecial)
    {
	if (i->ranges) i->index = 0;
	goto pickarange;
    }

    i->nItem++;
testitem:
    if (i->nItem == i->nSpecial) i->nItem++;
    if (i->nItem < i->range.upper) return TRUE;

pickarange:
    if (i->ranges)
    {
	if (i->index < i->ranges->hdpa->nItemCount)
	    i->range = *(RANGE*)DPA_GetPtr(i->ranges->hdpa, i->index++);
	else goto end;
    }
    else if (i->nItem >= i->range.upper) goto end;

    i->nItem = i->range.lower;
    if (i->nItem >= 0) goto testitem;
end:
    i->nItem = -1;
    return FALSE;
}

/****
 * This function iterates through the items in decreasing order,
 * followed by the special item, then -1. That is:
 *    n, n-1, ..., 3, 2, 1, special, -1.
 * Each item is listed only once.
 */
static inline BOOL iterator_prev(ITERATOR* i)
{
    BOOL start = FALSE;

    if (i->nItem == -1)
    {
	start = TRUE;
	if (i->ranges) i->index = i->ranges->hdpa->nItemCount;
	goto pickarange;
    }
    if (i->nItem == i->nSpecial)
    {
	i->nItem = -1;
	return FALSE;
    }

testitem:
    i->nItem--;
    if (i->nItem == i->nSpecial) i->nItem--;
    if (i->nItem >= i->range.lower) return TRUE;

pickarange:
    if (i->ranges)
    {
	if (i->index > 0)
	    i->range = *(RANGE*)DPA_GetPtr(i->ranges->hdpa, --i->index);
	else goto end;
    }
    else if (!start && i->nItem < i->range.lower) goto end;

    i->nItem = i->range.upper;
    if (i->nItem > 0) goto testitem;
end:
    return (i->nItem = i->nSpecial) != -1;
}

static RANGE iterator_range(ITERATOR* i)
{
    RANGE range;

    if (!i->ranges) return i->range;

    range.lower = (*(RANGE*)DPA_GetPtr(i->ranges->hdpa, 0)).lower;
    range.upper = (*(RANGE*)DPA_GetPtr(i->ranges->hdpa, i->ranges->hdpa->nItemCount - 1)).upper;
    return range;
}

/***
 * Releases resources associated with this ierator.
 */
static inline void iterator_destroy(ITERATOR* i)
{
    if (i->ranges) ranges_destroy(i->ranges);
}

/***
 * Create an empty iterator.
 */
static inline BOOL iterator_empty(ITERATOR* i)
{
    ZeroMemory(i, sizeof(*i));
    i->nItem = i->nSpecial = i->range.lower = i->range.upper = -1;
    return TRUE;
}


/***
 * Create an iterator over a bunch of ranges.
 * Please note that the iterator will take ownership of the ranges,
 * and will free them upon destruction.
 */
static inline BOOL iterator_ranges(ITERATOR* i, RANGES ranges)
{
    iterator_empty(i);
    i->ranges = ranges;
    return TRUE;
}

/***
 * Creates an iterator over the items which intersect lprc.
 */
static BOOL iterator_frameditems(ITERATOR* i, LISTVIEW_INFO* infoPtr, const RECT* lprc)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    RECT frame = *lprc, rcItem, rcTemp;
    POINT Origin;
    
    /* in case we fail, we want to return an empty iterator */
    if (!iterator_empty(i)) return FALSE;

    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE;

    TRACE("(lprc=%s)\n", debugrect(lprc));
    OffsetRect(&frame, -Origin.x, -Origin.y);

    if (uView == LVS_ICON || uView == LVS_SMALLICON)
    {
	INT nItem;
	
	if (uView == LVS_ICON)
	{
	    if (LISTVIEW_GetItemBox(infoPtr, infoPtr->nFocusedItem, &rcItem) && IntersectRect(&rcTemp, &rcItem, lprc))
		i->nSpecial = infoPtr->nFocusedItem;
	}
	if (!(i->ranges = ranges_create(50))) return FALSE;
	/* to do better here, we need to have PosX, and PosY sorted */
	TRACE("building icon ranges:\n");
	for (nItem = 0; nItem < infoPtr->nItemCount; nItem++)
	{
            rcItem.left = (LONG)DPA_GetPtr(infoPtr->hdpaPosX, nItem);
	    rcItem.top = (LONG)DPA_GetPtr(infoPtr->hdpaPosY, nItem);
	    rcItem.right = rcItem.left + infoPtr->nItemWidth;
	    rcItem.bottom = rcItem.top + infoPtr->nItemHeight;
	    if (IntersectRect(&rcTemp, &rcItem, &frame))
		ranges_additem(i->ranges, nItem);
	}
	if (TRACE_ON(listview))
	{
	    TRACE("    icon items:\n");
	    ranges_dump(i->ranges);
	}
	return TRUE;
    }
    else if (uView == LVS_REPORT)
    {
	INT lower, upper;
	
	if (frame.left >= infoPtr->nItemWidth) return TRUE;
	if (frame.top >= infoPtr->nItemHeight * infoPtr->nItemCount) return TRUE;
	
	lower = max(frame.top / infoPtr->nItemHeight, 0);
	upper = min((frame.bottom - 1) / infoPtr->nItemHeight, infoPtr->nItemCount - 1);
	if (upper < lower) return TRUE;
	i->range.lower = lower;
	i->range.upper = upper + 1;
	TRACE("    report=%s\n", debugrange(&i->range));
    }
    else
    {
	INT nPerCol = max((infoPtr->rcList.bottom - infoPtr->rcList.top) / infoPtr->nItemHeight, 1);
	INT nFirstRow = max(frame.top / infoPtr->nItemHeight, 0);
	INT nLastRow = min((frame.bottom - 1) / infoPtr->nItemHeight, nPerCol - 1);
	INT nFirstCol = max(frame.left / infoPtr->nItemWidth, 0);
	INT nLastCol = min((frame.right - 1) / infoPtr->nItemWidth, (infoPtr->nItemCount + nPerCol - 1) / nPerCol);
	INT lower = nFirstCol * nPerCol + nFirstRow;
	RANGE item_range;
	INT nCol;

	TRACE("nPerCol=%d, nFirstRow=%d, nLastRow=%d, nFirstCol=%d, nLastCol=%d, lower=%d\n",
	      nPerCol, nFirstRow, nLastRow, nFirstCol, nLastCol, lower);
	
	if (nLastCol < nFirstCol || nLastRow < nFirstRow) return TRUE;

	if (!(i->ranges = ranges_create(nLastCol - nFirstCol + 1))) return FALSE;
	TRACE("building list ranges:\n");
	for (nCol = nFirstCol; nCol <= nLastCol; nCol++)
	{
	    item_range.lower = nCol * nPerCol + nFirstRow;
	    if(item_range.lower >= infoPtr->nItemCount) break;
	    item_range.upper = min(nCol * nPerCol + nLastRow + 1, infoPtr->nItemCount);
	    TRACE("   list=%s\n", debugrange(&item_range));
	    ranges_add(i->ranges, item_range);
	}
    }

    return TRUE;
}

/***
 * Creates an iterator over the items which intersect the visible region of hdc.
 */
static BOOL iterator_visibleitems(ITERATOR* i, LISTVIEW_INFO *infoPtr, HDC  hdc)
{
    POINT Origin, Position;
    RECT rcItem, rcClip;
    INT rgntype;
    
    rgntype = GetClipBox(hdc, &rcClip);
    if (rgntype == NULLREGION) return iterator_empty(i);
    if (!iterator_frameditems(i, infoPtr, &rcClip)) return FALSE;
    if (rgntype == SIMPLEREGION) return TRUE;
 
    /* first deal with the special item */
    if (LISTVIEW_GetItemBox(infoPtr, i->nSpecial, &rcItem) && !RectVisible(hdc, &rcItem))
	i->nSpecial = -1;
    
    /* if we can't deal with the region, we'll just go with the simple range */
    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return TRUE;
    TRACE("building visible range:\n");
    if (!i->ranges)
    {
	if (!(i->ranges = ranges_create(50))) return TRUE;
	if (!ranges_add(i->ranges, i->range))
        {
	    ranges_destroy(i->ranges);
	    i->ranges = 0;
	    return TRUE;
        }
    }

    /* now delete the invisible items from the list */
    while(iterator_next(i))
    {
	if (!LISTVIEW_GetItemOrigin(infoPtr, i->nItem, &Position)) continue;
	rcItem.left = Position.x + Origin.x;
	rcItem.top = Position.y + Origin.y;
	rcItem.right = rcItem.left + infoPtr->nItemWidth;
	rcItem.bottom = rcItem.top + infoPtr->nItemHeight;
	if (!RectVisible(hdc, &rcItem))
	    ranges_delitem(i->ranges, i->nItem);
    }
    /* the iterator should restart on the next iterator_next */
    TRACE("done\n");
    
    return TRUE;
}

/******** Misc helper functions ************************************/

static inline LRESULT CallWindowProcT(WNDPROC proc, HWND hwnd, UINT uMsg,
		                      WPARAM wParam, LPARAM lParam, BOOL isW)
{
    if (isW) return CallWindowProcW(proc, hwnd, uMsg, wParam, lParam);
    else return CallWindowProcA(proc, hwnd, uMsg, wParam, lParam);
}

/******** Internal API functions ************************************/

/* The Invalidate* are macros, so we preserve the caller location */
#define LISTVIEW_InvalidateRect(infoPtr, rect) while(infoPtr->bRedraw) { \
    TRACE(" invalidating rect=%s\n", debugrect(rect)); \
    InvalidateRect(infoPtr->hwndSelf, rect, TRUE); \
    break;\
}

#define LISTVIEW_InvalidateItem(infoPtr, nItem) do { \
    RECT rcBox; \
    if(LISTVIEW_GetItemBox(infoPtr, nItem, &rcBox)) \
	LISTVIEW_InvalidateRect(infoPtr, &rcBox); \
} while (0)

#define LISTVIEW_InvalidateSubItem(infoPtr, nItem, nSubItem) do { \
    POINT Origin, Position; \
    RECT rcBox; \
    if (LISTVIEW_GetOrigin(infoPtr, &Origin) && \
	LISTVIEW_GetItemOrigin(infoPtr, nItem, &Position) && \
	LISTVIEW_GetHeaderRect(infoPtr, nSubItem, &rcBox)) { \
	OffsetRect(&rcBox, Origin.x + Position.x, Origin.y + Position.y); \
	LISTVIEW_InvalidateRect(infoPtr, &rcBox); \
    }\
} while (0)

#define LISTVIEW_InvalidateList(infoPtr)\
    LISTVIEW_InvalidateRect(infoPtr, NULL)


static inline BOOL LISTVIEW_GetHeaderRect(LISTVIEW_INFO *infoPtr, INT nSubItem, RECT *lprc)
{
    COLUMN_INFO *columnInfo;
    
    columnInfo = (COLUMN_INFO *)DPA_GetPtr(infoPtr->hdpaColumns, nSubItem);
    if (!columnInfo) return FALSE;
    *lprc = columnInfo->rcHeader;
    return TRUE;
}
	
static inline BOOL LISTVIEW_GetItemW(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem)
{
    return LISTVIEW_GetItemT(infoPtr, lpLVItem, TRUE);
}

/***
 * DESCRIPTION:
 * Retrieves the number of items that can fit vertically in the client area.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * Number of items per row.
 */
static inline INT LISTVIEW_GetCountPerRow(LISTVIEW_INFO *infoPtr)
{
    INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;

    return max(nListWidth/infoPtr->nItemWidth, 1);
}

/***
 * DESCRIPTION:
 * Retrieves the number of items that can fit horizontally in the client
 * area.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * Number of items per column.
 */
static inline INT LISTVIEW_GetCountPerColumn(LISTVIEW_INFO *infoPtr)
{
    INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;

    return max(nListHeight / infoPtr->nItemHeight, 1);
}


/*************************************************************************
 *		LISTVIEW_ProcessLetterKeys
 *
 *  Processes keyboard messages generated by pressing the letter keys
 *  on the keyboard.
 *  What this does is perform a case insensitive search from the
 *  current position with the following quirks:
 *  - If two chars or more are pressed in quick succession we search
 *    for the corresponding string (e.g. 'abc').
 *  - If there is a delay we wipe away the current search string and
 *    restart with just that char.
 *  - If the user keeps pressing the same character, whether slowly or
 *    fast, so that the search string is entirely composed of this
 *    character ('aaaaa' for instance), then we search for first item
 *    that starting with that character.
 *  - If the user types the above character in quick succession, then
 *    we must also search for the corresponding string ('aaaaa'), and
 *    go to that string if there is a match.
 *
 * PARAMETERS
 *   [I] hwnd : handle to the window
 *   [I] charCode : the character code, the actual character
 *   [I] keyData : key data
 *
 * RETURNS
 *
 *  Zero.
 *
 * BUGS
 *
 *  - The current implementation has a list of characters it will
 *    accept and it ignores averything else. In particular it will
 *    ignore accentuated characters which seems to match what
 *    Windows does. But I'm not sure it makes sense to follow
 *    Windows there.
 *  - We don't sound a beep when the search fails.
 *
 * SEE ALSO
 *
 *  TREEVIEW_ProcessLetterKeys
 */
static INT LISTVIEW_ProcessLetterKeys(LISTVIEW_INFO *infoPtr, WPARAM charCode, LPARAM keyData)
{
    INT nItem;
    INT endidx,idx;
    LVITEMW item;
    WCHAR buffer[MAX_PATH];
    DWORD lastKeyPressTimestamp = infoPtr->lastKeyPressTimestamp;

    /* simple parameter checking */
    if (!charCode || !keyData) return 0;

    /* only allow the valid WM_CHARs through */
    if (!isalnum(charCode) &&
        charCode != '.' && charCode != '`' && charCode != '!' &&
        charCode != '@' && charCode != '#' && charCode != '$' &&
        charCode != '%' && charCode != '^' && charCode != '&' &&
        charCode != '*' && charCode != '(' && charCode != ')' &&
        charCode != '-' && charCode != '_' && charCode != '+' &&
        charCode != '=' && charCode != '\\'&& charCode != ']' &&
        charCode != '}' && charCode != '[' && charCode != '{' &&
        charCode != '/' && charCode != '?' && charCode != '>' &&
        charCode != '<' && charCode != ',' && charCode != '~')
        return 0;

    /* if there's one item or less, there is no where to go */
    if (infoPtr->nItemCount <= 1) return 0;

    /* update the search parameters */
    infoPtr->lastKeyPressTimestamp = GetTickCount();
    if (infoPtr->lastKeyPressTimestamp - lastKeyPressTimestamp < KEY_DELAY) {
        if (infoPtr->nSearchParamLength < MAX_PATH)
            infoPtr->szSearchParam[infoPtr->nSearchParamLength++]=charCode;
        if (infoPtr->charCode != charCode)
            infoPtr->charCode = charCode = 0;
    } else {
        infoPtr->charCode=charCode;
        infoPtr->szSearchParam[0]=charCode;
        infoPtr->nSearchParamLength=1;
        /* Redundant with the 1 char string */
        charCode=0;
    }

    /* and search from the current position */
    nItem=-1;
    if (infoPtr->nFocusedItem >= 0) {
        endidx=infoPtr->nFocusedItem;
        idx=endidx;
        /* if looking for single character match,
         * then we must always move forward
         */
        if (infoPtr->nSearchParamLength == 1)
            idx++;
    } else {
        endidx=infoPtr->nItemCount;
        idx=0;
    }
    do {
        if (idx == infoPtr->nItemCount) {
            if (endidx == infoPtr->nItemCount || endidx == 0)
                break;
            idx=0;
        }

        /* get item */
        item.mask = LVIF_TEXT;
        item.iItem = idx;
        item.iSubItem = 0;
        item.pszText = buffer;
        item.cchTextMax = MAX_PATH;
        if (!LISTVIEW_GetItemW(infoPtr, &item)) return 0;

        /* check for a match */
        if (lstrncmpiW(item.pszText,infoPtr->szSearchParam,infoPtr->nSearchParamLength) == 0) {
            nItem=idx;
            break;
        } else if ( (charCode != 0) && (nItem == -1) && (nItem != infoPtr->nFocusedItem) &&
                    (lstrncmpiW(item.pszText,infoPtr->szSearchParam,1) == 0) ) {
            /* This would work but we must keep looking for a longer match */
            nItem=idx;
        }
        idx++;
    } while (idx != endidx);

    if (nItem != -1)
        LISTVIEW_KeySelection(infoPtr, nItem);

    return 0;
}

/*************************************************************************
 * LISTVIEW_UpdateHeaderSize [Internal]
 *
 * Function to resize the header control
 *
 * PARAMS
 *     hwnd             [I] handle to a window
 *     nNewScrollPos    [I] Scroll Pos to Set
 *
 * RETURNS
 *     nothing
 *
 * NOTES
 */
static void LISTVIEW_UpdateHeaderSize(LISTVIEW_INFO *infoPtr, INT nNewScrollPos)
{
    RECT winRect;
    POINT point[2];

    TRACE("nNewScrollPos=%d\n", nNewScrollPos);

    GetWindowRect(infoPtr->hwndHeader, &winRect);
    point[0].x = winRect.left;
    point[0].y = winRect.top;
    point[1].x = winRect.right;
    point[1].y = winRect.bottom;

    MapWindowPoints(HWND_DESKTOP, infoPtr->hwndSelf, point, 2);
    point[0].x = -nNewScrollPos;
    point[1].x += nNewScrollPos;

    SetWindowPos(infoPtr->hwndHeader,0,
        point[0].x,point[0].y,point[1].x,point[1].y,
        SWP_NOZORDER | SWP_NOACTIVATE);
}

/***
 * DESCRIPTION:
 * Update the scrollbars. This functions should be called whenever
 * the content, size or view changes.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * None
 */
static void LISTVIEW_UpdateScroll(LISTVIEW_INFO *infoPtr)
{
  LONG lStyle = infoPtr->dwStyle;
  UINT uView =  lStyle & LVS_TYPEMASK;
  INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
  INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
  SCROLLINFO scrollInfo;

  if (lStyle & LVS_NOSCROLL) return;

  scrollInfo.cbSize = sizeof(SCROLLINFO);

  if (uView == LVS_LIST)
  {
    /* update horizontal scrollbar */
    INT nCountPerColumn = LISTVIEW_GetCountPerColumn(infoPtr);
    INT nCountPerRow = LISTVIEW_GetCountPerRow(infoPtr);

    TRACE("items=%d, perColumn=%d, perRow=%d\n",
	  infoPtr->nItemCount, nCountPerColumn, nCountPerRow);
   
    scrollInfo.nMin = 0; 
    scrollInfo.nMax = infoPtr->nItemCount / nCountPerColumn;
    if((infoPtr->nItemCount % nCountPerColumn) == 0)
        scrollInfo.nMax--;
    if (scrollInfo.nMax < 0) scrollInfo.nMax = 0;
    scrollInfo.nPos = ListView_GetTopIndex(infoPtr->hwndSelf) / nCountPerColumn;
    scrollInfo.nPage = nCountPerRow;
    scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
    SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE);
    ShowScrollBar(infoPtr->hwndSelf, SB_VERT, FALSE);
  }
  else if (uView == LVS_REPORT)
  {
    BOOL test;

    /* update vertical scrollbar */
    scrollInfo.nMin = 0;
    scrollInfo.nMax = infoPtr->nItemCount - 1;
    scrollInfo.nPos = ListView_GetTopIndex(infoPtr->hwndSelf);
    scrollInfo.nPage = LISTVIEW_GetCountPerColumn(infoPtr);
    scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
    test = (scrollInfo.nMin >= scrollInfo.nMax - max((INT)scrollInfo.nPage - 1, 0));
    TRACE("LVS_REPORT Vert. nMax=%d, nPage=%d, test=%d\n",
	  scrollInfo.nMax, scrollInfo.nPage, test);
    SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo, TRUE);
    ShowScrollBar(infoPtr->hwndSelf, SB_VERT, (test) ? FALSE : TRUE);

    /* update horizontal scrollbar */
    nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
    scrollInfo.fMask = SIF_POS;
    if (!GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo)
       || infoPtr->nItemCount == 0)
    {
      scrollInfo.nPos = 0;
    }
    scrollInfo.nMin = 0;
    scrollInfo.nMax = max(infoPtr->nItemWidth, 0)-1;
    scrollInfo.nPage = nListWidth;
    scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE  ;
    test = (scrollInfo.nMin >= scrollInfo.nMax - max((INT)scrollInfo.nPage - 1, 0));
    TRACE("LVS_REPORT Horz. nMax=%d, nPage=%d, test=%d\n",
	  scrollInfo.nMax, scrollInfo.nPage, test);
    SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE);
    ShowScrollBar(infoPtr->hwndSelf, SB_HORZ, (test) ? FALSE : TRUE);

    /* Update the Header Control */
    scrollInfo.fMask = SIF_POS;
    GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo);
    LISTVIEW_UpdateHeaderSize(infoPtr, scrollInfo.nPos);

  }
  else
  {
    RECT rcView;

    if (LISTVIEW_GetViewRect(infoPtr, &rcView))
    {
      INT nViewWidth = rcView.right - rcView.left;
      INT nViewHeight = rcView.bottom - rcView.top;

      /* Update Horizontal Scrollbar */
      scrollInfo.fMask = SIF_POS;
      if (!GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo)
        || infoPtr->nItemCount == 0)
      {
        scrollInfo.nPos = 0;
      }
      scrollInfo.nMin = 0;
      scrollInfo.nMax = max(nViewWidth, 0)-1;
      scrollInfo.nPage = nListWidth;
      scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
      TRACE("LVS_ICON/SMALLICON Horz.\n");
      SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE);

      /* Update Vertical Scrollbar */
      nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
      scrollInfo.fMask = SIF_POS;
      if (!GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo)
        || infoPtr->nItemCount == 0)
      {
        scrollInfo.nPos = 0;
      }
      scrollInfo.nMin = 0;
      scrollInfo.nMax = max(nViewHeight,0)-1;
      scrollInfo.nPage = nListHeight;
      scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
      TRACE("LVS_ICON/SMALLICON Vert.\n");
      SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo, TRUE);
    }
  }
}


/***
 * DESCRIPTION:
 * Shows/hides the focus rectangle. 
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] fShow : TRUE to show the focus, FALSE to hide it.
 *
 * RETURN:
 * None
 */
static void LISTVIEW_ShowFocusRect(LISTVIEW_INFO *infoPtr, BOOL fShow)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    HDC hdc;

    TRACE("fShow=%d, nItem=%d\n", fShow, infoPtr->nFocusedItem);

    if (infoPtr->nFocusedItem < 0) return;

    /* we need some gymnastics in ICON mode to handle large items */
    if ( (infoPtr->dwStyle & LVS_TYPEMASK) == LVS_ICON )
    {
	RECT rcBox;

	if (!LISTVIEW_GetItemBox(infoPtr, infoPtr->nFocusedItem, &rcBox)) 
	    return;
	if ((rcBox.bottom - rcBox.top) > infoPtr->nItemHeight)
	{
	    LISTVIEW_InvalidateRect(infoPtr, &rcBox);
	    return;
	}
    }

    if (!(hdc = GetDC(infoPtr->hwndSelf))) return;

    /* for some reason, owner draw should work only in report mode */
    if ((infoPtr->dwStyle & LVS_OWNERDRAWFIXED) && (uView == LVS_REPORT))
    {
	DRAWITEMSTRUCT dis;
	LVITEMW item;

        item.iItem = infoPtr->nFocusedItem;
	item.iSubItem = 0;
        item.mask = LVIF_PARAM;
	if (!LISTVIEW_GetItemW(infoPtr, &item)) goto done;
	   
	ZeroMemory(&dis, sizeof(dis)); 
	dis.CtlType = ODT_LISTVIEW;
	dis.CtlID = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
	dis.itemID = item.iItem;
	dis.itemAction = ODA_FOCUS;
	if (fShow) dis.itemState |= ODS_FOCUS;
	dis.hwndItem = infoPtr->hwndSelf;
	dis.hDC = hdc;
	if (!LISTVIEW_GetItemBox(infoPtr, dis.itemID, &dis.rcItem)) goto done;
	dis.itemData = item.lParam;

	SendMessageW(GetParent(infoPtr->hwndSelf), WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
    }
    else
    {
	DrawFocusRect(hdc, &infoPtr->rcFocus);
    }
done:
    ReleaseDC(infoPtr->hwndSelf, hdc);
}

/***
 * Invalidates all visible selected items.
 */
static void LISTVIEW_InvalidateSelectedItems(LISTVIEW_INFO *infoPtr)
{
    ITERATOR i; 
   
    iterator_frameditems(&i, infoPtr, &infoPtr->rcList); 
    while(iterator_next(&i))
    {
	if (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED))
	    LISTVIEW_InvalidateItem(infoPtr, i.nItem);
    }
    iterator_destroy(&i);
}

	    
/***
 * DESCRIPTION:
 * Prints a message for unsupported window styles.
 * A kind of TODO list for window styles.
 *
 * PARAMETER(S):
 * [I] LONG : window style
 *
 * RETURN:
 * None
 */
static void LISTVIEW_UnsupportedStyles(LONG lStyle)
{
  if ((LVS_TYPESTYLEMASK & lStyle) == LVS_NOSCROLL)
    FIXME("  LVS_NOSCROLL\n");

  if (lStyle & LVS_NOLABELWRAP)
    FIXME("  LVS_NOLABELWRAP\n");

  if (lStyle & LVS_SORTASCENDING)
    FIXME("  LVS_SORTASCENDING\n");

  if (lStyle & LVS_SORTDESCENDING)
    FIXME("  LVS_SORTDESCENDING\n");
}


/***
 * DESCRIPTION:            [INTERNAL]
 * Computes an item's (left,top) corner, relative to rcView.
 * That is, the position has NOT been made relative to the Origin.
 * This is deliberate, to avoid computing the Origin over, and
 * over again, when this function is call in a loop. Instead,
 * one ca factor the computation of the Origin before the loop,
 * and offset the value retured by this function, on every iteration.
 * 
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nItem  : item number
 * [O] lpptOrig : item top, left corner
 *
 * RETURN:
 *   TRUE if computations OK
 *   FALSE otherwise
 */
static BOOL LISTVIEW_GetItemOrigin(LISTVIEW_INFO *infoPtr, INT nItem, LPPOINT lpptPosition)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;

    if (nItem < 0 || nItem >= infoPtr->nItemCount) return FALSE;

    if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
    {
	lpptPosition->x = (LONG)DPA_GetPtr(infoPtr->hdpaPosX, nItem);
	lpptPosition->y = (LONG)DPA_GetPtr(infoPtr->hdpaPosY, nItem);
    }
    else if (uView == LVS_LIST)
    {
        INT nCountPerColumn = LISTVIEW_GetCountPerColumn(infoPtr);
	lpptPosition->x = nItem / nCountPerColumn * infoPtr->nItemWidth;
	lpptPosition->y = nItem % nCountPerColumn * infoPtr->nItemHeight;
    }
    else /* LVS_REPORT */
    {
	lpptPosition->x = REPORT_MARGINX;
	lpptPosition->y = nItem * infoPtr->nItemHeight;
    }

    return TRUE;
}
    
/***
 * DESCRIPTION:            [INTERNAL]
 * Compute the rectangles of an item.  This is to localize all
 * the computations in one place. If you are not interested in some
 * of these values, simply pass in a NULL -- the fucntion is smart
 * enough to compute only what's necessary. The function computes
 * the standard rectangles (BOUNDS, ICON, LABEL) plus a non-standard
 * one, the BOX rectangle. This rectangle is very cheap to compute,
 * and is guaranteed to contain all the other rectangles. Computing
 * the ICON rect is also cheap, but all the others are potentaily
 * expensive. This gives an easy and effective optimization when
 * searching (like point inclusion, or rectangle intersection):
 * first test against the BOX, and if TRUE, test agains the desired
 * rectangle.
 * If the function does not have all the necessary information
 * to computed the requested rectangles, will crash with a
 * failed assertion. This is done so we catch all programming
 * errors, given that the function is called only from our code.
 *
 * We have the following 'special' meanings for a few fields:
 *   * If LVIS_FOCUSED is set, we assume the item has the focus
 *     This is important in ICON mode, where it might get a larger
 *     then usual rectange
 *
 * Please note that subitem support works only in REPORT mode.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] lpLVItem : item to compute the measures for
 * [O] lprcBox : ptr to Box rectangle
 *                The internal LVIR_BOX rectangle
 * [0] lprcState : ptr to State icon rectangle
 *  		  The internal LVIR_STATE rectangle
 * [O] lprcIcon : ptr to Icon rectangle
 *                Same as LVM_GETITEMRECT with LVIR_ICON
 * [O] lprcLabel : ptr to Label rectangle
 *                Same as LVM_GETITEMRECT with LVIR_LABEL
 *
 * RETURN:
 *   TRUE if computations OK
 *   FALSE otherwise
 */
static BOOL LISTVIEW_GetItemMetrics(LISTVIEW_INFO *infoPtr, LVITEMW *lpLVItem,
				    LPRECT lprcBox, LPRECT lprcState, 
				    LPRECT lprcIcon, LPRECT lprcLabel)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    BOOL doState = FALSE, doIcon = FALSE, doLabel = FALSE, oversizedBox = FALSE;
    RECT Box, State, Icon, Label;

    TRACE("(lpLVItem=%s)\n", debuglvitem_t(lpLVItem, TRUE));
	
    /* Be smart and try to figure out the minimum we have to do */
    if (lpLVItem->iSubItem) assert(uView == LVS_REPORT);
    if (uView == LVS_ICON && (lprcBox || lprcLabel))
    {
	assert((lpLVItem->mask & LVIF_STATE) && (lpLVItem->stateMask & LVIS_FOCUSED));
	if (lpLVItem->state & LVIS_FOCUSED) oversizedBox = doLabel = TRUE;
    }
    if (lprcLabel) doLabel = TRUE;
    if (doLabel || lprcIcon) doIcon = TRUE;
    if (doIcon || lprcState) doState = TRUE;
    
    /************************************************************/
    /* compute the box rectangle (it should be cheap to do)     */
    /************************************************************/
    if (lpLVItem->iSubItem)
    {
        if (!LISTVIEW_GetHeaderRect(infoPtr, lpLVItem->iSubItem, &Box)) return FALSE;
    }
    else
    {
	Box.left = 0;
	Box.right = infoPtr->nItemWidth;
    }
    Box.top = 0;
    Box.bottom = infoPtr->nItemHeight;
		
    /************************************************************/
    /* compute STATEICON bounding box                           */
    /************************************************************/
    if (doState)
    {
	if (uView == LVS_ICON)
	{
     	    State.left = Box.left - infoPtr->iconStateSize.cx - 2;
	    if (infoPtr->himlNormal) 
		State.left += (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2;
	    State.top  = Box.top + infoPtr->iconSize.cy - infoPtr->iconStateSize.cy + 4;
	}
	else
	{
	    /* we need the ident in report mode, if we don't have it, we fail */
	    State.left = Box.left;
	    if (uView == LVS_REPORT) 
	    {
		State.left += REPORT_MARGINX;
		if (lpLVItem->iSubItem == 0)
		{
		    assert(lpLVItem->mask & LVIF_INDENT);
		    State.left += infoPtr->iconSize.cx * lpLVItem->iIndent;
		}
	    }
	    State.top  = Box.top;
	}	
	State.right    = State.left;
	State.bottom   = State.top;
	if (infoPtr->himlState && lpLVItem->iSubItem == 0)
	{
	    State.right  += infoPtr->iconStateSize.cx;
	    State.bottom += infoPtr->iconStateSize.cy;
	}
	if (lprcState) *lprcState = State;
	TRACE("    - state=%s\n", debugrect(&State));
    }

    /************************************************************/
    /* compute ICON bounding box (ala LVM_GETITEMRECT)          */
    /************************************************************/
    if (doIcon)
    {
	if (uView == LVS_ICON)
	{
	    Icon.left   = Box.left;
	    if (infoPtr->himlNormal) 
		Icon.left += (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2;
	    Icon.top    = Box.top + ICON_TOP_PADDING;
	    Icon.right  = Icon.left;
	    Icon.bottom = Icon.top;
	    if (infoPtr->himlNormal)
	    {
		Icon.right  += infoPtr->iconSize.cx;
		Icon.bottom += infoPtr->iconSize.cy;
	    }
	}
	else /* LVS_SMALLICON, LVS_LIST or LVS_REPORT */
	{
	    Icon.left = State.right;
	    if (!IsRectEmpty(&State)) Icon.left += IMAGE_PADDING;
	    Icon.top    = Box.top;
	    Icon.right  = Icon.left;
	    /* FIXME: add suport for icons for subitems */
	    if (infoPtr->himlSmall && lpLVItem->iSubItem == 0) Icon.right += infoPtr->iconSize.cx;
	    Icon.bottom = Icon.top + infoPtr->nItemHeight;
	}
	if(lprcIcon) *lprcIcon = Icon;
	TRACE("    - icon=%s\n", debugrect(&Icon));
     }

    /************************************************************/
    /* compute LABEL bounding box (ala LVM_GETITEMRECT)         */
    /************************************************************/
    if (doLabel)
    {
	SIZE labelSize = { 0, 0 };

	/* calculate how far to the right can the label strech */
	Label.right = Box.right;
	if (uView == LVS_REPORT)
	{
	    if (lpLVItem->iSubItem == 0 && !LISTVIEW_GetHeaderRect(infoPtr, 0, &Label)) return FALSE;
	    Label.right -= REPORT_MARGINX;
	}

	if (lpLVItem->iSubItem || ((infoPtr->dwStyle & LVS_OWNERDRAWFIXED) && uView == LVS_REPORT))
	{
	   labelSize.cx = infoPtr->nItemWidth;
	   labelSize.cy = infoPtr->nItemHeight;
	   goto calc_label;
	}
	
	/* we need the text in non owner draw mode */
	assert(lpLVItem->mask & LVIF_TEXT);
	if (is_textT(lpLVItem->pszText, TRUE))
        {
    	    HFONT hFont = infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont;
    	    HDC hdc = GetDC(infoPtr->hwndSelf);
    	    HFONT hOldFont = SelectObject(hdc, hFont);
	    UINT uFormat;
	    RECT rcText;

	    /* compute rough rectangle where the label will go */
	    SetRectEmpty(&rcText);
	    rcText.right = infoPtr->nItemWidth - TRAILING_PADDING;
	    rcText.bottom = infoPtr->nItemHeight;
	    if (uView == LVS_ICON) 
		rcText.bottom -= ICON_TOP_PADDING + infoPtr->iconSize.cy + ICON_BOTTOM_PADDING;

	    /* now figure out the flags */
	    if (uView == LVS_ICON)
		uFormat = oversizedBox ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS;
	    else
		uFormat = LV_SL_DT_FLAGS;
	    
    	    DrawTextW (hdc, lpLVItem->pszText, -1, &rcText, uFormat | DT_CALCRECT);

	    labelSize.cx = min(rcText.right - rcText.left + TRAILING_PADDING, infoPtr->nItemWidth);
	    labelSize.cy = rcText.bottom - rcText.top;

    	    SelectObject(hdc, hOldFont);
    	    ReleaseDC(infoPtr->hwndSelf, hdc);
	}

calc_label:
	if (uView == LVS_ICON)
	{
	    Label.left = Box.left + (infoPtr->nItemWidth - labelSize.cx) / 2;
	    Label.top  = Box.top + ICON_TOP_PADDING_HITABLE +
		         infoPtr->iconSize.cy + ICON_BOTTOM_PADDING;
	    Label.right = Label.left + labelSize.cx;
	    Label.bottom = Label.top + infoPtr->nItemHeight;
	    if (!oversizedBox && labelSize.cy > infoPtr->ntmHeight)
	    {
		labelSize.cy = min(Box.bottom - Label.top, labelSize.cy);
		labelSize.cy /= infoPtr->ntmHeight;
		labelSize.cy = max(labelSize.cy, 1);
		labelSize.cy *= infoPtr->ntmHeight;
	     }
	     Label.bottom = Label.top + labelSize.cy + HEIGHT_PADDING;
	}
	else /* LVS_SMALLICON, LVS_LIST or LVS_REPORT */
	{
	    Label.left = Icon.right;
	    if (!IsRectEmpty(&Icon) || !IsRectEmpty(&State)) Label.left += IMAGE_PADDING;
	    Label.top = Box.top;
	    Label.right = min(Label.left + labelSize.cx, Label.right);
	    Label.bottom = Label.top + infoPtr->nItemHeight;
	}
  
	if (lprcLabel) *lprcLabel = Label;
	TRACE("    - label=%s\n", debugrect(&Label));
    }

    /* Fix the Box if necessary */
    if (lprcBox)
    {
	if (oversizedBox) UnionRect(lprcBox, &Box, &Label);
	else *lprcBox = Box;
    }
    TRACE("    - box=%s\n", debugrect(&Box));

    return TRUE;
}

/***
 * DESCRIPTION:            [INTERNAL]
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nItem : item number
 * [O] lprcBox : ptr to Box rectangle
 *
 * RETURN:
 *   TRUE if computations OK
 *   FALSE otherwise
 */
static BOOL LISTVIEW_GetItemBox(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprcBox)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
    POINT Position, Origin;
    LVITEMW lvItem;

    if (!LISTVIEW_GetItemOrigin(infoPtr, nItem, &Position)) return FALSE;
    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE;

    /* Be smart and try to figure out the minimum we have to do */
    lvItem.mask = 0;
    if (uView == LVS_ICON && infoPtr->bFocus && LISTVIEW_GetItemState(infoPtr, nItem, LVIS_FOCUSED))
	lvItem.mask |= LVIF_TEXT;
    lvItem.iItem = nItem;
    lvItem.iSubItem = 0;
    lvItem.pszText = szDispText;
    lvItem.cchTextMax = DISP_TEXT_SIZE;
    if (lvItem.mask && !LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE;
    if (uView == LVS_ICON)
    {
	lvItem.mask |= LVIF_STATE;
	lvItem.stateMask = LVIS_FOCUSED;
	lvItem.state = (lvItem.mask & LVIF_TEXT ? LVIS_FOCUSED : 0);
    }
    if (!LISTVIEW_GetItemMetrics(infoPtr, &lvItem, lprcBox, 0, 0, 0)) return FALSE;

    OffsetRect(lprcBox, Position.x + Origin.x, Position.y + Origin.y);

    return TRUE;
}

/***
 * DESCRIPTION:
 * Aligns the items with the top edge of the window.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * None
 */
static void LISTVIEW_AlignTop(LISTVIEW_INFO *infoPtr)
{
  UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
  INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
  POINT ptItem;
  RECT rcView;
  INT i, off_x=0, off_y=0;

  if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
  {
    /* Since SetItemPosition uses upper-left of icon, and for
       style=LVS_ICON the icon is not left adjusted, get the offset */
    if (uView == LVS_ICON)
    {
      off_y = ICON_TOP_PADDING;
      off_x = (infoPtr->iconSpacing.cx - infoPtr->iconSize.cx) / 2;
    }
    ptItem.x = off_x;
    ptItem.y = off_y;
    ZeroMemory(&rcView, sizeof(RECT));
    TRACE("Icon  off.x=%d, off.y=%d, left=%d, right=%d\n",
	  off_x, off_y,
	  infoPtr->rcList.left, infoPtr->rcList.right);

    if (nListWidth > infoPtr->nItemWidth)
    {
      for (i = 0; i < infoPtr->nItemCount; i++)
      {
        if ((ptItem.x-off_x) + infoPtr->nItemWidth > nListWidth)
        {
          ptItem.x = off_x;
          ptItem.y += infoPtr->nItemHeight;
        }

        LISTVIEW_SetItemPosition(infoPtr, i, ptItem);
        ptItem.x += infoPtr->nItemWidth;
        rcView.right = max(rcView.right, ptItem.x);
      }

      rcView.right -= off_x;
      rcView.bottom = (ptItem.y-off_y) + infoPtr->nItemHeight;
    }
    else
    {
      for (i = 0; i < infoPtr->nItemCount; i++)
      {
        LISTVIEW_SetItemPosition(infoPtr, i, ptItem);
        ptItem.y += infoPtr->nItemHeight;
      }

      rcView.right = infoPtr->nItemWidth;
      rcView.bottom = ptItem.y-off_y;
    }

    infoPtr->rcView = rcView;
  }
}

/***
 * DESCRIPTION:
 * Aligns the items with the left edge of the window.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * None
 */
static void LISTVIEW_AlignLeft(LISTVIEW_INFO *infoPtr)
{
  UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
  INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
  POINT ptItem;
  RECT rcView;
  INT i, off_x=0, off_y=0;

  if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
  {
    /* Since SetItemPosition uses upper-left of icon, and for
       style=LVS_ICON the icon is not left adjusted, get the offset */
    if (uView == LVS_ICON)
    {
      off_y = ICON_TOP_PADDING;
      off_x = (infoPtr->iconSpacing.cx - infoPtr->iconSize.cx) / 2;
    }
    ptItem.x = off_x;
    ptItem.y = off_y;
    ZeroMemory(&rcView, sizeof(RECT));
    TRACE("Icon  off.x=%d, off.y=%d\n", off_x, off_y);

    if (nListHeight > infoPtr->nItemHeight)
    {
      for (i = 0; i < infoPtr->nItemCount; i++)
      {
        if (ptItem.y + infoPtr->nItemHeight > nListHeight)
        {
          ptItem.y = off_y;
          ptItem.x += infoPtr->nItemWidth;
        }

        LISTVIEW_SetItemPosition(infoPtr, i, ptItem);
        ptItem.y += infoPtr->nItemHeight;
        rcView.bottom = max(rcView.bottom, ptItem.y);
      }

      rcView.right = ptItem.x + infoPtr->nItemWidth;
    }
    else
    {
      for (i = 0; i < infoPtr->nItemCount; i++)
      {
        LISTVIEW_SetItemPosition(infoPtr, i, ptItem);
        ptItem.x += infoPtr->nItemWidth;
      }

      rcView.bottom = infoPtr->nItemHeight;
      rcView.right = ptItem.x;
    }

    infoPtr->rcView = rcView;
  }
}


/***
 * DESCRIPTION:
 * Retrieves the bounding rectangle of all the items.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [O] lprcView : bounding rectangle
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_GetViewRect(LISTVIEW_INFO *infoPtr, LPRECT lprcView)
{
    POINT ptOrigin;

    TRACE("(lprcView=%p)\n", lprcView);

    if (!lprcView) return FALSE;
  
    if (!LISTVIEW_GetOrigin(infoPtr, &ptOrigin)) return FALSE;
   
    *lprcView = infoPtr->rcView;
    OffsetRect(lprcView, ptOrigin.x, ptOrigin.y); 

    TRACE("lprcView=%s\n", debugrect(lprcView));

    return TRUE;
}

/***
 * DESCRIPTION:
 * Retrieves the subitem pointer associated with the subitem index.
 *
 * PARAMETER(S):
 * [I] HDPA : DPA handle for a specific item
 * [I] INT : index of subitem
 *
 * RETURN:
 *   SUCCESS : subitem pointer
 *   FAILURE : NULL
 */
static LISTVIEW_SUBITEM* LISTVIEW_GetSubItemPtr(HDPA hdpaSubItems, INT nSubItem)
{
    LISTVIEW_SUBITEM *lpSubItem;
    INT i;

    /* we should binary search here if need be */
    for (i = 1; i < hdpaSubItems->nItemCount; i++)
    {
	lpSubItem = (LISTVIEW_SUBITEM *) DPA_GetPtr(hdpaSubItems, i);
	if (lpSubItem && (lpSubItem->iSubItem == nSubItem))
	    return lpSubItem;
    }

    return NULL;
}


/***
 * DESCRIPTION:
 * Calculates the width of a specific item.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nItem : item to calculate width, or -1 for max of all
 *
 * RETURN:
 * Returns the width of an item width an item.
 */
static INT LISTVIEW_CalculateItemWidth(LISTVIEW_INFO *infoPtr, INT nItem)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    INT nItemWidth = 0, i;

    if (uView == LVS_ICON) 
	nItemWidth = infoPtr->iconSpacing.cx;
    else if (uView == LVS_REPORT)
    {
	RECT rcHeaderItem;
	
	/* calculate width of header */
	for (i = 0; i < infoPtr->hdpaColumns->nItemCount; i++)
	    if (LISTVIEW_GetHeaderRect(infoPtr, i, &rcHeaderItem))
		nItemWidth += (rcHeaderItem.right - rcHeaderItem.left);
    }
    else
    {
	INT nLabelWidth;
	
	if (infoPtr->nItemCount == 0) return DEFAULT_COLUMN_WIDTH;
    
        /* get width of string */
	if (nItem == -1) 
	{
	    for (i = 0; i < infoPtr->nItemCount; i++)
	    {
		nLabelWidth = LISTVIEW_GetLabelWidth(infoPtr, i);
		nItemWidth = max(nItemWidth, nLabelWidth);
	    }
	}
	else
            nItemWidth = LISTVIEW_GetLabelWidth(infoPtr, nItem);
        if (!nItemWidth)  return DEFAULT_COLUMN_WIDTH;
        nItemWidth += WIDTH_PADDING;
        if (infoPtr->himlSmall) nItemWidth += infoPtr->iconSize.cx; 
        if (infoPtr->himlState) nItemWidth += infoPtr->iconStateSize.cx;
	if (nItem == -1) nItemWidth = max(DEFAULT_COLUMN_WIDTH, nItemWidth);
    }

    return max(nItemWidth, 1);
}

/***
 * DESCRIPTION:
 * Calculates the max width of any item in the list.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] LONG : window style
 *
 * RETURN:
 * Returns item width.
 */
static inline INT LISTVIEW_CalculateMaxWidth(LISTVIEW_INFO *infoPtr)
{
    return LISTVIEW_CalculateItemWidth(infoPtr, -1);
}

/***
 * DESCRIPTION:
 * Retrieves and saves important text metrics info for the current
 * Listview font.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 */
static void LISTVIEW_SaveTextMetrics(LISTVIEW_INFO *infoPtr)
{
    HDC hdc = GetDC(infoPtr->hwndSelf);
    HFONT hFont = infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont;
    HFONT hOldFont = SelectObject(hdc, hFont);
    TEXTMETRICW tm;

    if (GetTextMetricsW(hdc, &tm))
	infoPtr->ntmHeight = tm.tmHeight;
    SelectObject(hdc, hOldFont);
    ReleaseDC(infoPtr->hwndSelf, hdc);
    
    TRACE("tmHeight=%d\n", infoPtr->ntmHeight);
}


/***
 * DESCRIPTION:
 * Calculates the height of an item.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * Returns item height.
 */
static INT LISTVIEW_CalculateMaxHeight(LISTVIEW_INFO *infoPtr)
{
    INT nItemHeight;

    if ((infoPtr->dwStyle & LVS_TYPEMASK) == LVS_ICON)
	nItemHeight = infoPtr->iconSpacing.cy;
    else
    {
	nItemHeight = infoPtr->ntmHeight; 
	if (infoPtr->himlState)
	    nItemHeight = max(nItemHeight, infoPtr->iconStateSize.cy);
	if (infoPtr->himlSmall)
	    nItemHeight = max(nItemHeight, infoPtr->iconSize.cy);
	if (infoPtr->himlState || infoPtr->himlSmall)
	    nItemHeight += HEIGHT_PADDING;
    }
    return nItemHeight;
}

/***
 * DESCRIPTION:
 * A compare function for ranges
 *
 * PARAMETER(S)
 * [I] range1 : pointer to range 1;
 * [I] range2 : pointer to range 2;
 * [I] flags : flags
 *
 * RETURNS:
 * > 0 : if range 1 > range 2
 * < 0 : if range 2 > range 1
 * = 0 : if range intersects range 2
 */
static INT CALLBACK ranges_cmp(LPVOID range1, LPVOID range2, LPARAM flags)
{
    INT cmp;
    
    if (((RANGE*)range1)->upper <= ((RANGE*)range2)->lower) 
	cmp = -1;
    else if (((RANGE*)range2)->upper <= ((RANGE*)range1)->lower) 
	cmp = 1;
    else 
	cmp = 0;
    
    TRACE("range1=%s, range2=%s, cmp=%d\n", debugrange((RANGE*)range1), debugrange((RANGE*)range2), cmp);

    return cmp;
}

#if DEBUG_RANGES
#define ranges_check ranges_assert
#else
#define ranges_check(ranges, desc) do { } while(0)
#endif

static void ranges_assert(RANGES ranges, LPCSTR desc)
{
    INT i;
    RANGE *prev, *curr;
    
    assert (ranges);
    assert (ranges->hdpa->nItemCount >= 0);
    if (ranges->hdpa->nItemCount == 0) return;
    TRACE("*** Checking %s ***\n", desc);
    ranges_dump(ranges);
    assert ((prev = (RANGE *)DPA_GetPtr(ranges->hdpa, 0))->lower >= 0);
    /* assert (((RANGE *)DPA_GetPtr(ranges->hdpa, ranges->hdpa->nItemCount - 1))->upper <= nUpper); */
    for (i = 1; i < ranges->hdpa->nItemCount; i++)
    {
	curr = (RANGE *)DPA_GetPtr(ranges->hdpa, i);
	assert (prev->upper <= curr->lower);
	prev = curr;
    }
    TRACE("--- Done checking---\n");
}

static RANGES ranges_create(int count)
{
    RANGES ranges = (RANGES)COMCTL32_Alloc(sizeof(struct tagRANGES));
    if (!ranges) return NULL;
    ranges->hdpa = DPA_Create(count);
    if (ranges->hdpa) return ranges;
    COMCTL32_Free(ranges);
    return NULL;
}

static void ranges_destroy(RANGES ranges)
{
    if (!ranges) return;
    if (ranges->hdpa)
    {
	INT i;
	
	for(i = 0; i < ranges->hdpa->nItemCount; i++)
	    COMCTL32_Free(DPA_GetPtr(ranges->hdpa, i));
	DPA_Destroy(ranges->hdpa);
    	ranges->hdpa = NULL;
    }
    COMCTL32_Free(ranges);
}

static RANGES ranges_clone(RANGES ranges)
{
    RANGES clone;
    INT i;
	   
    if (!ranges) return NULL; 
    clone = ranges_create(ranges->hdpa->nItemCount);
    if (!clone) return NULL;
    
    for (i = 0; i < ranges->hdpa->nItemCount; i++)
    {
        RANGE *newrng = (RANGE *)COMCTL32_Alloc(sizeof(RANGE));
	if (!newrng)
	{
	    ranges_destroy(clone);
	    return NULL;
	}
	*newrng = *((RANGE*)DPA_GetPtr(ranges->hdpa, i));
	DPA_InsertPtr(clone->hdpa, i, newrng);
    }
    return clone;
}

static RANGES ranges_diff(RANGES ranges, RANGES sub)
{
    INT i;

    if (!ranges || !sub) return ranges;
    
    for (i = 0; i < sub->hdpa->nItemCount; i++)
	ranges_del(ranges, *((RANGE *)DPA_GetPtr(sub->hdpa, i)));

    return ranges;
}

static void ranges_dump(RANGES ranges)
{
    INT i;

    if (!ranges) return;
    for (i = 0; i < ranges->hdpa->nItemCount; i++)
    	TRACE("   %s\n", debugrange(DPA_GetPtr(ranges->hdpa, i)));
}

static inline BOOL ranges_contain(RANGES ranges, INT nItem)
{
    RANGE srchrng = { nItem, nItem + 1 };

    TRACE("(nItem=%d)\n", nItem);
    if (!ranges) return FALSE;
    if (TRACE_ON(listview)) ranges_dump(ranges);
    ranges_check(ranges, "before contain");
    return DPA_Search(ranges->hdpa, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED) != -1;
}

static INT ranges_itemcount(RANGES ranges)
{
    INT i, count = 0;
    
    if (!ranges) return 0;
    for (i = 0; i < ranges->hdpa->nItemCount; i++)
    {
	RANGE *sel = DPA_GetPtr(ranges->hdpa, i);
	count += sel->upper - sel->lower;
    }

    return count;
}

static BOOL ranges_shift(RANGES ranges, INT nItem, INT delta, INT nUpper)
{
    RANGE srchrng = { nItem, nItem + 1 }, *chkrng;
    INT index;

    if (!ranges) return FALSE;
    index = DPA_Search(ranges->hdpa, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED | DPAS_INSERTAFTER);
    if (index == -1) return TRUE;

    for (;index < ranges->hdpa->nItemCount; index++)
    {
	chkrng = DPA_GetPtr(ranges->hdpa, index);
    	if (chkrng->lower >= nItem)
	    chkrng->lower = max(min(chkrng->lower + delta, nUpper - 1), 0);
        if (chkrng->upper > nItem)
	    chkrng->upper = max(min(chkrng->upper + delta, nUpper), 0);
    }
    return TRUE;
}

static BOOL ranges_add(RANGES ranges, RANGE range)
{
    RANGE srchrgn;
    INT index;

    TRACE("(%s)\n", debugrange(&range));
    ranges_check(ranges, "before add");
    if (!ranges) goto fail;

    /* try find overlapping regions first */
    srchrgn.lower = range.lower - 1;
    srchrgn.upper = range.upper + 1;
    index = DPA_Search(ranges->hdpa, &srchrgn, 0, ranges_cmp, 0, DPAS_SORTED);
   
    if (index == -1)
    {
	RANGE *newrgn;

	TRACE("Adding new range\n");

	/* create the brand new range to insert */	
        newrgn = (RANGE *)COMCTL32_Alloc(sizeof(RANGE));
	if(!newrgn) goto fail;
	*newrgn = range;
	
	/* figure out where to insert it */
	index = DPA_Search(ranges->hdpa, newrgn, 0, ranges_cmp, 0, DPAS_SORTED | DPAS_INSERTAFTER);
	TRACE("index=%d\n", index);
	if (index == -1) index = 0;
	
	/* and get it over with */
	DPA_InsertPtr(ranges->hdpa, index, newrgn);
    }
    else
    {
	RANGE *chkrgn, *mrgrgn;
	INT fromindex, mergeindex;

	chkrgn = DPA_GetPtr(ranges->hdpa, index);
	if (!chkrgn) goto fail;
	TRACE("Merge with %s @%d\n", debugrange(chkrgn), index);

	chkrgn->lower = min(range.lower, chkrgn->lower);
	chkrgn->upper = max(range.upper, chkrgn->upper);
	
	TRACE("New range %s @%d\n", debugrange(chkrgn), index);

        /* merge now common anges */
	fromindex = 0;
	srchrgn.lower = chkrgn->lower - 1;
	srchrgn.upper = chkrgn->upper + 1;
	    
	do
	{
	    mergeindex = DPA_Search(ranges->hdpa, &srchrgn, fromindex, ranges_cmp, 0, 0);
	    if (mergeindex == -1) break;
	    if (mergeindex == index) 
	    {
		fromindex = index + 1;
		continue;
	    }
	  
	    TRACE("Merge with index %i\n", mergeindex);
	    
	    mrgrgn = DPA_GetPtr(ranges->hdpa, mergeindex);
	    if (!mrgrgn) goto fail;
	    
	    chkrgn->lower = min(chkrgn->lower, mrgrgn->lower);
	    chkrgn->upper = max(chkrgn->upper, mrgrgn->upper);
	    COMCTL32_Free(mrgrgn);
	    DPA_DeletePtr(ranges->hdpa, mergeindex);
	    if (mergeindex < index) index --;
	} while(1);
    }

    ranges_check(ranges, "after add");
    if (TRACE_ON(listview)) ranges_dump(ranges);
    return TRUE;
    
fail:
    ranges_check(ranges, "failed add");
    return FALSE;
}

static BOOL ranges_del(RANGES ranges, RANGE range)
{
    RANGE *chkrgn;
    INT index;

    TRACE("(%s)\n", debugrange(&range));
    ranges_check(ranges, "before del");
    if (!ranges) goto fail;
    
    /* we don't use DPAS_SORTED here, since we need *
     * to find the first overlapping range          */
    index = DPA_Search(ranges->hdpa, &range, 0, ranges_cmp, 0, 0);
    while(index != -1) 
    {
	chkrgn = DPA_GetPtr(ranges->hdpa, index);
	if (!chkrgn) goto fail;
	
        TRACE("Matches range %s @%d\n", debugrange(chkrgn), index); 

	/* case 1: Same range */
	if ( (chkrgn->upper == range.upper) &&
	     (chkrgn->lower == range.lower) )
	{
	    DPA_DeletePtr(ranges->hdpa, index);
	    break;
	}
	/* case 2: engulf */
	else if ( (chkrgn->upper <= range.upper) &&
		  (chkrgn->lower >= range.lower) ) 
	{
	    DPA_DeletePtr(ranges->hdpa, index);
	}
	/* case 3: overlap upper */
	else if ( (chkrgn->upper <= range.upper) &&
		  (chkrgn->lower < range.lower) )
	{
	    chkrgn->upper = range.lower;
	}
	/* case 4: overlap lower */
	else if ( (chkrgn->upper > range.upper) &&
		  (chkrgn->lower >= range.lower) )
	{
	    chkrgn->lower = range.upper;
	    break;
	}
	/* case 5: fully internal */
	else
	{
	    RANGE tmprgn = *chkrgn, *newrgn;

	    if (!(newrgn = (RANGE *)COMCTL32_Alloc(sizeof(RANGE)))) goto fail;
	    newrgn->lower = chkrgn->lower;
	    newrgn->upper = range.lower;
	    chkrgn->lower = range.upper;
	    DPA_InsertPtr(ranges->hdpa, index, newrgn);
	    chkrgn = &tmprgn;
	    break;
	}

	index = DPA_Search(ranges->hdpa, &range, index, ranges_cmp, 0, 0);
    }

    ranges_check(ranges, "after del");
    return TRUE;

fail:
    ranges_check(ranges, "failed del");
    return FALSE;
}

/***
* DESCRIPTION:
* Removes all selection ranges
*
* Parameters(s):
* [I] infoPtr : valid pointer to the listview structure
* [I] toSkip : item range to skip removing the selection
*
* RETURNS:
*   SUCCESS : TRUE
*   FAILURE : TRUE
*/
static BOOL LISTVIEW_DeselectAllSkipItems(LISTVIEW_INFO *infoPtr, RANGES toSkip)
{
    LVITEMW lvItem;
    ITERATOR i;

    TRACE("()\n");
    if (TRACE_ON(listview)) ranges_dump(toSkip);

    lvItem.state = 0;
    lvItem.stateMask = LVIS_SELECTED;
    
    /* need to clone the DPA because callbacks can change it */
    iterator_ranges(&i, ranges_diff(ranges_clone(infoPtr->selectionRanges), toSkip));
    while(iterator_next(&i))
	LISTVIEW_SetItemState(infoPtr, i.nItem, &lvItem);
    /* note that the iterator destructor will free the cloned range */
    iterator_destroy(&i);

    return TRUE;
}

static inline BOOL LISTVIEW_DeselectAllSkipItem(LISTVIEW_INFO *infoPtr, INT nItem)
{
    RANGES toSkip = ranges_create(1);
   
    if (!toSkip) return FALSE;
    if (nItem != -1) ranges_additem(toSkip, nItem);
    LISTVIEW_DeselectAllSkipItems(infoPtr, toSkip);
    ranges_destroy(toSkip);
    return TRUE;
}

static inline BOOL LISTVIEW_DeselectAll(LISTVIEW_INFO *infoPtr)
{
    return LISTVIEW_DeselectAllSkipItem(infoPtr, -1);
}

/***
 * DESCRIPTION:
 * Retrieves the number of items that are marked as selected.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * Number of items selected.
 */
static INT LISTVIEW_GetSelectedCount(LISTVIEW_INFO *infoPtr)
{
    INT nSelectedCount = 0;

    if (infoPtr->uCallbackMask & LVIS_SELECTED)
    {
        INT i;
	for (i = 0; i < infoPtr->nItemCount; i++)
  	{
	    if (LISTVIEW_GetItemState(infoPtr, i, LVIS_SELECTED))
		nSelectedCount++;
	}
    }
    else
	nSelectedCount = ranges_itemcount(infoPtr->selectionRanges);

    TRACE("nSelectedCount=%d\n", nSelectedCount);
    return nSelectedCount;
}

/***
 * DESCRIPTION:
 * Manages the item focus.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : item index
 *
 * RETURN:
 *   TRUE : focused item changed
 *   FALSE : focused item has NOT changed
 */
static inline BOOL LISTVIEW_SetItemFocus(LISTVIEW_INFO *infoPtr, INT nItem)
{
    INT oldFocus = infoPtr->nFocusedItem;
    LVITEMW lvItem;

    if (nItem == infoPtr->nFocusedItem) return FALSE;
    
    lvItem.state =  nItem == -1 ? 0 : LVIS_FOCUSED;
    lvItem.stateMask = LVIS_FOCUSED;
    LISTVIEW_SetItemState(infoPtr, nItem, &lvItem);

    return oldFocus != infoPtr->nFocusedItem;
}

/* Helper function for LISTVIEW_ShiftIndices *only* */
static INT shift_item(LISTVIEW_INFO *infoPtr, INT nShiftItem, INT nItem, INT direction)
{
    if (nShiftItem < nItem) return nShiftItem;

    if (nShiftItem > nItem) return nShiftItem + direction;

    if (direction > 0) return nShiftItem + direction;

    return min(nShiftItem, infoPtr->nItemCount - 1);
}

/**
* DESCRIPTION:
* Updates the various indices after an item has been inserted or deleted.
*
* PARAMETER(S):
* [I] infoPtr : valid pointer to the listview structure
* [I] nItem : item index
* [I] direction : Direction of shift, +1 or -1.
*
* RETURN:
* None
*/
static void LISTVIEW_ShiftIndices(LISTVIEW_INFO *infoPtr, INT nItem, INT direction)
{
    INT nNewFocus;
    
    TRACE("Shifting %iu, %i steps\n", nItem, direction);

    ranges_shift(infoPtr->selectionRanges, nItem, direction, infoPtr->nItemCount);

    assert(abs(direction) == 1);

    infoPtr->nSelectionMark = shift_item(infoPtr, infoPtr->nSelectionMark, nItem, direction);

    nNewFocus = shift_item(infoPtr, infoPtr->nFocusedItem, nItem, direction);
    if (nNewFocus != infoPtr->nFocusedItem)
        LISTVIEW_SetItemFocus(infoPtr, nNewFocus);
    
    /* But we are not supposed to modify nHotItem! */
}


/**
 * DESCRIPTION:
 * Adds a block of selections.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : item index
 *
 * RETURN:
 * None
 */
static void LISTVIEW_AddGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
{
  INT nFirst = min(infoPtr->nSelectionMark, nItem);
  INT nLast = max(infoPtr->nSelectionMark, nItem);
  INT i;
  LVITEMW item;

  if (nFirst == -1)
    nFirst = nItem;

  item.state = LVIS_SELECTED;
  item.stateMask = LVIS_SELECTED;

  /* FIXME: this is not correct LVS_OWNERDATA
   * See docu for LVN_ITEMCHANGED. Is there something similar for
   * RemoveGroupSelection (is there such a thing?)?
   */
  for (i = nFirst; i <= nLast; i++)
    LISTVIEW_SetItemState(infoPtr,i,&item);

  LISTVIEW_SetItemFocus(infoPtr, nItem);
  infoPtr->nSelectionMark = nItem;
}


/***
 * DESCRIPTION:
 * Sets a single group selection.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : item index
 *
 * RETURN:
 * None
 */
static void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    RANGES selection;
    LVITEMW item;
    ITERATOR i;

    if (!(selection = ranges_create(100))) return;

    item.state = LVIS_SELECTED; 
    item.stateMask = LVIS_SELECTED;

    if ((uView == LVS_LIST) || (uView == LVS_REPORT))
    {
	if (infoPtr->nSelectionMark == -1)
	{
	    infoPtr->nSelectionMark = nItem;
	    ranges_additem(selection, nItem);
	}
	else
	{
	    RANGE sel;
	    
	    sel.lower = min(infoPtr->nSelectionMark, nItem);
	    sel.upper = max(infoPtr->nSelectionMark, nItem) + 1;
	    ranges_add(selection, sel);
	}
    }
    else
    {
	RECT rcItem, rcSel, rcSelMark;
	POINT ptItem;
	
	rcItem.left = LVIR_BOUNDS;
	if (!LISTVIEW_GetItemRect(infoPtr, nItem, &rcItem)) return;
	rcSelMark.left = LVIR_BOUNDS;
	if (!LISTVIEW_GetItemRect(infoPtr, infoPtr->nSelectionMark, &rcSelMark)) return;
	UnionRect(&rcSel, &rcItem, &rcSelMark);
	iterator_frameditems(&i, infoPtr, &rcSel);
	while(iterator_next(&i))
	{
	    LISTVIEW_GetItemPosition(infoPtr, i.nItem, &ptItem);
	    if (PtInRect(&rcSel, ptItem)) ranges_additem(selection, i.nItem);
	}
	iterator_destroy(&i);
    }

    LISTVIEW_DeselectAllSkipItems(infoPtr, selection);
    iterator_ranges(&i, selection);
    while(iterator_next(&i))
	LISTVIEW_SetItemState(infoPtr, i.nItem, &item);
    /* this will also destroy the selection */
    iterator_destroy(&i);
    
    LISTVIEW_SetItemFocus(infoPtr, nItem);
}

/***
 * DESCRIPTION:
 * Sets a single selection.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : item index
 *
 * RETURN:
 * None
 */
static void LISTVIEW_SetSelection(LISTVIEW_INFO *infoPtr, INT nItem)
{
    LVITEMW lvItem;

    TRACE("nItem=%d\n", nItem);
    
    LISTVIEW_DeselectAllSkipItem(infoPtr, nItem);

    lvItem.state = LVIS_FOCUSED | LVIS_SELECTED;
    lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
    LISTVIEW_SetItemState(infoPtr, nItem, &lvItem);

    infoPtr->nSelectionMark = nItem;
}

/***
 * DESCRIPTION:
 * Set selection(s) with keyboard.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : item index
 *
 * RETURN:
 *   SUCCESS : TRUE (needs to be repainted)
 *   FAILURE : FALSE (nothing has changed)
 */
static BOOL LISTVIEW_KeySelection(LISTVIEW_INFO *infoPtr, INT nItem)
{
  /* FIXME: pass in the state */
  LONG lStyle = infoPtr->dwStyle;
  WORD wShift = HIWORD(GetKeyState(VK_SHIFT));
  WORD wCtrl = HIWORD(GetKeyState(VK_CONTROL));
  BOOL bResult = FALSE;

  if ((nItem >= 0) && (nItem < infoPtr->nItemCount))
  {
    if (lStyle & LVS_SINGLESEL)
    {
      bResult = TRUE;
      LISTVIEW_SetSelection(infoPtr, nItem);
    }
    else
    {
      if (wShift)
      {
        bResult = TRUE;
        LISTVIEW_SetGroupSelection(infoPtr, nItem);
      }
      else if (wCtrl)
      {
        bResult = LISTVIEW_SetItemFocus(infoPtr, nItem);
      }
      else
      {
        bResult = TRUE;
        LISTVIEW_SetSelection(infoPtr, nItem);
      }
    }
    ListView_EnsureVisible(infoPtr->hwndSelf, nItem, FALSE);
  }

  UpdateWindow(infoPtr->hwndSelf); /* update client area */
  return bResult;
}


/***
 * DESCRIPTION:
 * Called when the mouse is being actively tracked and has hovered for a specified
 * amount of time
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] fwKeys : key indicator
 * [I] pts : mouse position
 *
 * RETURN:
 *   0 if the message was processed, non-zero if there was an error
 *
 * INFO:
 * LVS_EX_TRACKSELECT: An item is automatically selected when the cursor remains
 * over the item for a certain period of time.
 *
 */
static LRESULT LISTVIEW_MouseHover(LISTVIEW_INFO *infoPtr, WORD fwKyes, POINTS pts)
{
    if(infoPtr->dwLvExStyle & LVS_EX_TRACKSELECT)
	/* FIXME: select the item!!! */
	/*LISTVIEW_GetItemAtPt(infoPtr, pt)*/;

    return 0;
}

/***
 * DESCRIPTION:
 * Called whenever WM_MOUSEMOVE is received.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] fwKeys : key indicator
 * [I] pts : mouse position
 *
 * RETURN:
 *   0 if the message is processed, non-zero if there was an error
 */
static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, POINTS pts)
{
  TRACKMOUSEEVENT trackinfo;

  /* see if we are supposed to be tracking mouse hovering */
  if(infoPtr->dwLvExStyle & LVS_EX_TRACKSELECT) {
     /* fill in the trackinfo struct */
     trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
     trackinfo.dwFlags = TME_QUERY;
     trackinfo.hwndTrack = infoPtr->hwndSelf;
     trackinfo.dwHoverTime = infoPtr->dwHoverTime;

     /* see if we are already tracking this hwnd */
     _TrackMouseEvent(&trackinfo);

     if(!(trackinfo.dwFlags & TME_HOVER)) {
       trackinfo.dwFlags = TME_HOVER;

       /* call TRACKMOUSEEVENT so we receive WM_MOUSEHOVER messages */
       _TrackMouseEvent(&trackinfo);
    }
  }

  return 0;
}


/***
 * Tests wheather the item is assignable to a list with style lStyle 
 */
static inline BOOL is_assignable_item(LPLVITEMW lpLVItem, LONG lStyle)
{
    if ( (lpLVItem->mask & LVIF_TEXT) && 
	(lpLVItem->pszText == LPSTR_TEXTCALLBACKW) &&
	(lStyle & (LVS_SORTASCENDING | LVS_SORTDESCENDING)) ) return FALSE;
    
    return TRUE;
}


/***
 * DESCRIPTION:
 * Helper for LISTVIEW_SetItemT *only*: sets item attributes.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] lpLVItem : valid pointer to new item atttributes
 * [I] isNew : the item being set is being inserted
 * [I] isW : TRUE if lpLVItem is Unicode, FALSE if it's ANSI
 * [O] bChanged : will be set to TRUE if the item really changed
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL set_main_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isNew, BOOL isW, BOOL *bChanged)
{
    LISTVIEW_ITEM *lpItem;
    NMLISTVIEW nmlv;
    UINT uChanged = 0;
    LVITEMW item;

    TRACE("()\n");

    assert(lpLVItem->iItem >= 0 && lpLVItem->iItem < infoPtr->nItemCount);
    
    if (lpLVItem->mask == 0) return TRUE;   

    if (infoPtr->dwStyle & LVS_OWNERDATA)
    {
	/* a virtual listview we stores only selection and focus */
	if ((lpLVItem->mask & ~LVIF_STATE) || (lpLVItem->stateMask & ~(LVIS_FOCUSED | LVIS_SELECTED)))
	    return FALSE;
	lpItem = NULL;
    }
    else
    {
	HDPA hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
	if (!hdpaSubItems) return FALSE;
	if (!(lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0))) return FALSE;
    }

    /* we need to get the lParam and state of the item */
    item.iItem = lpLVItem->iItem;
    item.iSubItem = lpLVItem->iSubItem;
    item.mask = LVIF_STATE | LVIF_PARAM;
    item.stateMask = ~0;
    item.state = 0;
    item.lParam = 0;
    if (!isNew && !LISTVIEW_GetItemT(infoPtr, &item, TRUE)) return FALSE;

    TRACE("oldState=%x, newState=%x\n", item.state, lpLVItem->state);
    /* determine what fields will change */    
    if ((lpLVItem->mask & LVIF_STATE) && ((item.state ^ lpLVItem->state) & lpLVItem->stateMask & ~infoPtr->uCallbackMask))
	uChanged |= LVIF_STATE;

    if ((lpLVItem->mask & LVIF_IMAGE) && (lpItem->hdr.iImage != lpLVItem->iImage))
	uChanged |= LVIF_IMAGE;

    if ((lpLVItem->mask & LVIF_PARAM) && (lpItem->lParam != lpLVItem->lParam))
	uChanged |= LVIF_PARAM;

    if ((lpLVItem->mask & LVIF_INDENT) && (lpItem->iIndent != lpLVItem->iIndent))
	uChanged |= LVIF_INDENT;

    if ((lpLVItem->mask & LVIF_TEXT) && textcmpWT(lpItem->hdr.pszText, lpLVItem->pszText, isW))
	uChanged |= LVIF_TEXT;
   
    TRACE("uChanged=0x%x\n", uChanged); 
    if (!uChanged) return TRUE;
    *bChanged = TRUE;
    
    ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
    nmlv.iItem = lpLVItem->iItem;
    nmlv.uNewState = (item.state & ~lpLVItem->stateMask) | (lpLVItem->state & lpLVItem->stateMask);
    nmlv.uOldState = item.state;
    nmlv.uChanged = uChanged;
    nmlv.lParam = item.lParam;
    
    /* send LVN_ITEMCHANGING notification, if the item is not being inserted */
    /* and we are _NOT_ virtual (LVS_OWERNDATA) */
    if(lpItem && !isNew && notify_listview(infoPtr, LVN_ITEMCHANGING, &nmlv))
	return FALSE;

    /* copy information */
    if (lpLVItem->mask & LVIF_TEXT)
        textsetptrT(&lpItem->hdr.pszText, lpLVItem->pszText, isW);

    if (lpLVItem->mask & LVIF_IMAGE)
	lpItem->hdr.iImage = lpLVItem->iImage;

    if (lpLVItem->mask & LVIF_PARAM)
	lpItem->lParam = lpLVItem->lParam;

    if (lpLVItem->mask & LVIF_INDENT)
	lpItem->iIndent = lpLVItem->iIndent;

    if (uChanged & LVIF_STATE)
    {
	if (lpLVItem->stateMask & ~infoPtr->uCallbackMask & ~(LVIS_FOCUSED | LVIS_SELECTED))
	{
	    lpItem->state &= ~lpLVItem->stateMask;
	    lpItem->state |= (lpLVItem->state & lpLVItem->stateMask);
	}
	if (lpLVItem->state & lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED)
	{
	    if (infoPtr->dwStyle & LVS_SINGLESEL) LISTVIEW_DeselectAllSkipItem(infoPtr, lpLVItem->iItem);
	    ranges_additem(infoPtr->selectionRanges, lpLVItem->iItem);
	}
	else if (lpLVItem->stateMask & LVIS_SELECTED)
	    ranges_delitem(infoPtr->selectionRanges, lpLVItem->iItem);
	
	/* if we are asked to change focus, and we manage it, do it */
	if (lpLVItem->state & lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED)
	{
	    if (lpLVItem->state & LVIS_FOCUSED)
	    {
		LISTVIEW_SetItemFocus(infoPtr, -1);
		infoPtr->nFocusedItem = lpLVItem->iItem;
    	        LISTVIEW_EnsureVisible(infoPtr, lpLVItem->iItem, FALSE);
	    }
	    else if (infoPtr->nFocusedItem == lpLVItem->iItem)
		infoPtr->nFocusedItem = -1;
	}
    }

    /* if we're inserting the item, we're done */
    if (isNew) return TRUE;
    
    /* send LVN_ITEMCHANGED notification */
    if (lpLVItem->mask & LVIF_PARAM) nmlv.lParam = lpLVItem->lParam;
    notify_listview(infoPtr, LVN_ITEMCHANGED, &nmlv);

    return TRUE;
}

/***
 * DESCRIPTION:
 * Helper for LISTVIEW_{Set,Insert}ItemT *only*: sets subitem attributes.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] lpLVItem : valid pointer to new subitem atttributes
 * [I] isW : TRUE if lpLVItem is Unicode, FALSE if it's ANSI
 * [O] bChanged : will be set to TRUE if the item really changed
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL set_sub_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW, BOOL *bChanged)
{
    HDPA hdpaSubItems;
    LISTVIEW_SUBITEM *lpSubItem;

    /* we do not support subitems for virtual listviews */
    if (infoPtr->dwStyle & LVS_OWNERDATA) return FALSE;
    
    /* set subitem only if column is present */
    if (lpLVItem->iSubItem >= infoPtr->hdpaColumns->nItemCount) return FALSE;
   
    /* First do some sanity checks */
    if (lpLVItem->mask & ~(LVIF_TEXT | LVIF_IMAGE)) return FALSE;
    if (!(lpLVItem->mask & (LVIF_TEXT | LVIF_IMAGE))) return TRUE;
   
    /* get the subitem structure, and create it if not there */
    hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
    if (!hdpaSubItems) return FALSE;
    
    lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, lpLVItem->iSubItem);
    if (!lpSubItem)
    {
	LISTVIEW_SUBITEM *tmpSubItem;
	INT i;

	lpSubItem = (LISTVIEW_SUBITEM *)COMCTL32_Alloc(sizeof(LISTVIEW_SUBITEM));
	if (!lpSubItem) return FALSE;
	/* we could binary search here, if need be...*/
  	for (i = 1; i < hdpaSubItems->nItemCount; i++)
  	{
	    tmpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
	    if (tmpSubItem && tmpSubItem->iSubItem > lpLVItem->iSubItem) break;
  	}
	if (DPA_InsertPtr(hdpaSubItems, i, lpSubItem) == -1)
	{
	    COMCTL32_Free(lpSubItem);
	    return FALSE;
	}
        lpSubItem->iSubItem = lpLVItem->iSubItem;
	*bChanged = TRUE;
    }
    
    if (lpLVItem->mask & LVIF_IMAGE)
	if (lpSubItem->hdr.iImage != lpLVItem->iImage)
	{
	    lpSubItem->hdr.iImage = lpLVItem->iImage;
	    *bChanged = TRUE;
	}

    if (lpLVItem->mask & LVIF_TEXT)
	if (lpSubItem->hdr.pszText != lpLVItem->pszText)
	{
	    textsetptrT(&lpSubItem->hdr.pszText, lpLVItem->pszText, isW);
	    *bChanged = TRUE;
	}

    return TRUE;
}

/***
 * DESCRIPTION:
 * Sets item attributes.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] LPLVITEM : new item atttributes
 * [I] isW : TRUE if lpLVItem is Unicode, FALSE if it's ANSI
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    LPWSTR pszText = NULL;
    BOOL bResult, bChanged = FALSE;
    
    TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW);

    if (!lpLVItem || lpLVItem->iItem < 0 || lpLVItem->iItem >= infoPtr->nItemCount)
	return FALSE;

    /* For efficiency, we transform the lpLVItem->pszText to Unicode here */
    if ((lpLVItem->mask & LVIF_TEXT) && is_textW(lpLVItem->pszText))
    {
	pszText = lpLVItem->pszText;
	lpLVItem->pszText = textdupTtoW(lpLVItem->pszText, isW);
    }
    
    /* actually set the fields */
    if (!is_assignable_item(lpLVItem, infoPtr->dwStyle)) return FALSE;
    
    if (lpLVItem->iSubItem)
	bResult = set_sub_item(infoPtr, lpLVItem, TRUE, &bChanged);
    else
	bResult = set_main_item(infoPtr, lpLVItem, FALSE, TRUE, &bChanged);

    /* redraw item, if necessary */
    if (bChanged && !infoPtr->bIsDrawing)
    {
	/* this little optimization eliminates some nasty flicker */
	if ( uView == LVS_REPORT && !(infoPtr->dwStyle & LVS_OWNERDRAWFIXED) &&
	     (!(infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT) || lpLVItem->iSubItem) )
	    LISTVIEW_InvalidateSubItem(infoPtr, lpLVItem->iItem, lpLVItem->iSubItem);
	else
	    LISTVIEW_InvalidateItem(infoPtr, lpLVItem->iItem);
    }
    /* restore text */
    if (pszText)
    {
	textfreeT(lpLVItem->pszText, isW);
	lpLVItem->pszText = pszText;
    }

    return bResult;
}

/***
 * DESCRIPTION:
 * Retrieves the index of the item at coordinate (0, 0) of the client area.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * item index
 */
static INT LISTVIEW_GetTopIndex(LISTVIEW_INFO *infoPtr)
{
    LONG lStyle = infoPtr->dwStyle;
    UINT uView = lStyle & LVS_TYPEMASK;
    INT nItem = 0;
    SCROLLINFO scrollInfo;

    scrollInfo.cbSize = sizeof(SCROLLINFO);
    scrollInfo.fMask = SIF_POS;

    if (uView == LVS_LIST)
    {
	if ((lStyle & WS_HSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo))
	    nItem = scrollInfo.nPos * LISTVIEW_GetCountPerColumn(infoPtr);
    }
    else if (uView == LVS_REPORT)
    {
	if ((lStyle & WS_VSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo))
	    nItem = scrollInfo.nPos;
    } 
    else
    {
	if ((lStyle & WS_VSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo))
	    nItem = LISTVIEW_GetCountPerRow(infoPtr) * (scrollInfo.nPos / infoPtr->nItemHeight);
    }

    TRACE("nItem=%d\n", nItem);
    
    return nItem;
}


/***
 * DESCRIPTION:
 * Erases the background of the given rectangle
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] hdc : device context handle
 * [I] lprcBox : clipping rectangle
 *
 * RETURN:
 *   Success: TRUE
 *   Failure: FALSE
 */
static inline BOOL LISTVIEW_FillBkgnd(LISTVIEW_INFO *infoPtr, HDC hdc, const RECT* lprcBox)
{
    if (!infoPtr->hBkBrush) return FALSE;

    TRACE("(hdc=%x, lprcBox=%s, hBkBrush=%x)\n", hdc, debugrect(lprcBox), infoPtr->hBkBrush);

    return FillRect(hdc, lprcBox, infoPtr->hBkBrush);
}

/***
 * DESCRIPTION:
 * Draws an item.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] hdc : device context handle
 * [I] nItem : item index
 * [I] nSubItem : subitem index
 * [I] pos : item position in client coordinates
 * [I] cdmode : custom draw mode
 *
 * RETURN:
 *   Success: TRUE
 *   Failure: FALSE
 */
static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nSubItem, POINT pos, DWORD cdmode)
{
    UINT uFormat, uView = infoPtr->dwStyle & LVS_TYPEMASK;
    WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
    DWORD cditemmode = CDRF_DODEFAULT;
    RECT* lprcFocus, rcSelect, rcBox, rcState, rcIcon, rcLabel;
    NMLVCUSTOMDRAW nmlvcd;
    HIMAGELIST himl;
    LVITEMW lvItem;

    TRACE("(hdc=%x, nItem=%d, nSubItem=%d, pos=%s)\n", hdc, nItem, nSubItem, debugpoint(&pos));

    /* get information needed for drawing the item */
    lvItem.mask = LVIF_TEXT | LVIF_IMAGE;
    if (nSubItem == 0) lvItem.mask |= LVIF_STATE;
    if (uView == LVS_REPORT) lvItem.mask |= LVIF_INDENT;
    lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK;
    lvItem.iItem = nItem;
    lvItem.iSubItem = nSubItem;
    lvItem.cchTextMax = DISP_TEXT_SIZE;
    lvItem.pszText = szDispText;
    if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE;
    TRACE("   lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));

    /* now check if we need to update the focus rectangle */
    lprcFocus = infoPtr->bFocus && (lvItem.state & LVIS_FOCUSED) ? &infoPtr->rcFocus : 0;
    
    if (!lprcFocus) lvItem.state &= ~LVIS_FOCUSED;
    if (!LISTVIEW_GetItemMetrics(infoPtr, &lvItem, &rcBox, &rcState, &rcIcon, &rcLabel)) return FALSE;
    OffsetRect(&rcBox, pos.x, pos.y);
    OffsetRect(&rcState, pos.x, pos.y);
    OffsetRect(&rcIcon, pos.x, pos.y);
    OffsetRect(&rcLabel, pos.x, pos.y);
    TRACE("    rcBox=%s, rcState=%s, rcIcon=%s. rcLabel=%s\n", 
	debugrect(&rcBox), debugrect(&rcState), debugrect(&rcIcon), debugrect(&rcLabel));

    /* fill in the custom draw structure */
    customdraw_fill(&nmlvcd, infoPtr, hdc, &rcBox);
    nmlvcd.nmcd.dwItemSpec = lvItem.iItem;
    nmlvcd.iSubItem = lvItem.iSubItem;
    if (lvItem.state & LVIS_SELECTED) nmlvcd.nmcd.uItemState |= CDIS_SELECTED;
    if (lvItem.state & LVIS_FOCUSED) nmlvcd.nmcd.uItemState |= CDIS_FOCUS;
    if (lvItem.iItem == infoPtr->nHotItem) nmlvcd.nmcd.uItemState |= CDIS_HOT;
    nmlvcd.nmcd.lItemlParam = lvItem.lParam;
    if ((lvItem.state & LVIS_SELECTED) && 
	(lvItem.iSubItem == 0 || 
	 (uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))))
    {
	if (infoPtr->bFocus)
	{
	    nmlvcd.clrTextBk = comctl32_color.clrHighlight;
	    nmlvcd.clrText   = comctl32_color.clrHighlightText;
        }
	else if (infoPtr->dwStyle & LVS_SHOWSELALWAYS)
	{
	    nmlvcd.clrTextBk = comctl32_color.clr3dFace;
	    nmlvcd.clrText   = comctl32_color.clrBtnText;
	}
    }
    
    if (cdmode & CDRF_NOTIFYITEMDRAW)
        cditemmode = notify_customdraw (infoPtr, CDDS_ITEMPREPAINT, &nmlvcd);
    if (cditemmode & CDRF_SKIPDEFAULT) goto postpaint;

    /* state icons */
    if (infoPtr->himlState && !IsRectEmpty(&rcState))
    {
        UINT uStateImage = (lvItem.state & LVIS_STATEIMAGEMASK) >> 12;
        if (uStateImage)
	     ImageList_Draw(infoPtr->himlState, uStateImage - 1, hdc, rcState.left, rcState.top, ILD_NORMAL);
    }

    /* small icons */
    himl = (uView == LVS_ICON ? infoPtr->himlNormal : infoPtr->himlSmall);
    if (himl && lvItem.iImage >= 0 && !IsRectEmpty(&rcIcon))
	ImageList_Draw(himl, lvItem.iImage, hdc, rcIcon.left, rcIcon.top,
			(lvItem.state & LVIS_SELECTED) && (infoPtr->bFocus) ? ILD_SELECTED : ILD_NORMAL);

    /* Don't bother painting item being edited */
    if (infoPtr->hwndEdit && lprcFocus && nSubItem == 0) goto postpaint;

    /* Set the text attributes */
    SetBkMode(hdc, nmlvcd.clrTextBk == CLR_NONE ? TRANSPARENT : OPAQUE);
    if (nmlvcd.clrTextBk != CLR_NONE)
	SetBkColor(hdc, nmlvcd.clrTextBk == CLR_DEFAULT ? infoPtr->clrTextBkDefault : nmlvcd.clrTextBk);
    SetTextColor(hdc, nmlvcd.clrText);

    /* draw the selection background, if we're drawing the main item */
    if (nSubItem == 0)
    {
	rcSelect = rcLabel;
    	if (uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
	    rcSelect.right = rcBox.right;
   
    	if (lvItem.state & LVIS_SELECTED) 
            ExtTextOutW(hdc, rcSelect.left, rcSelect.top, ETO_OPAQUE, &rcSelect, 0, 0, 0);
    	if(lprcFocus) *lprcFocus = rcSelect;
    }
   
    /* figure out the text drawing flags */
    uFormat = (uView == LVS_ICON ? (lprcFocus ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS) : LV_SL_DT_FLAGS);
    if (uView == LVS_ICON)
	uFormat = (lprcFocus ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS);
    else 
    {
	INT align = DT_LEFT;
	
	if (nSubItem)
	{
    	    LVCOLUMNW lvColumn;
	    lvColumn.mask = LVCF_FMT;
	    LISTVIEW_GetColumnT(infoPtr, nSubItem, &lvColumn, TRUE);
	    TRACE("lvColumn=%s\n", debuglvcolumn_t(&lvColumn, TRUE));
	    if (lvColumn.fmt & LVCFMT_RIGHT) align = DT_RIGHT;
	    else if (lvColumn.fmt & LVCFMT_CENTER) align = DT_CENTER;
	}
	uFormat |= align;
    }
    if (!(uFormat & (DT_RIGHT | DT_CENTER))) rcLabel.left += 2;
    DrawTextW(hdc, lvItem.pszText, -1, &rcLabel, uFormat);

postpaint:
    if (cditemmode & CDRF_NOTIFYPOSTPAINT)
        notify_customdraw(infoPtr, CDDS_ITEMPOSTPAINT, &nmlvcd);
    return TRUE;
}

/***
 * DESCRIPTION:
 * Draws listview items when in owner draw mode.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] hdc : device context handle
 *
 * RETURN:
 * None
 */
static void LISTVIEW_RefreshOwnerDraw(LISTVIEW_INFO *infoPtr, HDC hdc)
{
    UINT uID = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
    HWND hwndParent = GetParent(infoPtr->hwndSelf);
    POINT Origin, Position;
    DRAWITEMSTRUCT dis;
    LVITEMW item;
    ITERATOR i;
    
    TRACE("()\n");

    ZeroMemory(&dis, sizeof(dis));
    
    /* Get scroll info once before loop */
    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return;

    /* figure out what we need to draw */
    iterator_visibleitems(&i, infoPtr, hdc);
    
    /* send cache hint notification */
    if (infoPtr->dwStyle & LVS_OWNERDATA)
    {
	RANGE range = iterator_range(&i);
        NMLVCACHEHINT nmlv;

	ZeroMemory(&nmlv, sizeof(NMLVCACHEHINT));
        nmlv.iFrom = range.lower;
        nmlv.iTo   = range.upper - 1;
        notify_hdr(infoPtr, LVN_ODCACHEHINT, &nmlv.hdr);
    }

    /* iterate through the invalidated rows */
    while(iterator_prev(&i))
    {
	item.iItem = i.nItem;
	item.iSubItem = 0;
	item.mask = LVIF_PARAM | LVIF_STATE;
	item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
	if (!LISTVIEW_GetItemW(infoPtr, &item)) continue;
	   
	dis.CtlType = ODT_LISTVIEW;
	dis.CtlID = uID;
	dis.itemID = item.iItem;
	dis.itemAction = ODA_DRAWENTIRE;
	dis.itemState = 0;
	if (item.state & LVIS_SELECTED) dis.itemState |= ODS_SELECTED;
	if (infoPtr->bFocus && (item.state & LVIS_FOCUSED)) dis.itemState |= ODS_FOCUS;
	dis.hwndItem = infoPtr->hwndSelf;
	dis.hDC = hdc;
	if (!LISTVIEW_GetItemOrigin(infoPtr, dis.itemID, &Position)) continue;
	dis.rcItem.left = Position.x + Origin.x;
	dis.rcItem.right = dis.rcItem.left + infoPtr->nItemWidth;
	dis.rcItem.top = Position.y + Origin.y;
	dis.rcItem.bottom = dis.rcItem.top + infoPtr->nItemHeight;
	dis.itemData = item.lParam;

	TRACE("item=%s, rcItem=%s\n", debuglvitem_t(&item, TRUE), debugrect(&dis.rcItem));
	SendMessageW(hwndParent, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
    }
    iterator_destroy(&i);
}

/***
 * DESCRIPTION:
 * Draws listview items when in report display mode.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] hdc : device context handle
 * [I] cdmode : custom draw mode
 *
 * RETURN:
 * None
 */
static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode)
{
    INT rgntype, nFirstCol, nLastCol, nCol;
    RECT rcClip, rcItem;
    POINT Origin, Position;
    ITERATOR i;

    TRACE("()\n");

    /* figure out what to draw */
    rgntype = GetClipBox(hdc, &rcClip);
    if (rgntype == NULLREGION) return;
    
    /* Get scroll info once before loop */
    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return;
    
    /* narrow down the columns we need to paint */
    for(nFirstCol = 0; nFirstCol < infoPtr->hdpaColumns->nItemCount; nFirstCol++)
	if (LISTVIEW_GetHeaderRect(infoPtr, nFirstCol, &rcItem) &&
	    rcItem.right + Origin.x >= rcClip.left) break;
    for(nLastCol = infoPtr->hdpaColumns->nItemCount - 1; nLastCol >= 0; nLastCol--)
	if (LISTVIEW_GetHeaderRect(infoPtr, nLastCol, &rcItem) &&
	    rcItem.left + Origin.x < rcClip.right) break;

    /* figure out what we need to draw */
    iterator_visibleitems(&i, infoPtr, hdc);
    
    /* a last few bits before we start drawing */
    TRACE("Colums=(%di - %d)\n", nFirstCol, nLastCol);

    /* iterate through the invalidated rows */
    while(iterator_prev(&i))
    {
	/* iterate through the invalidated columns */
	for (nCol = nFirstCol; nCol <= nLastCol; nCol++)
	{
	    if (!LISTVIEW_GetItemOrigin(infoPtr, i.nItem, &Position)) continue;
	    Position.x += Origin.x;
	    Position.y += Origin.y;

	    if (rgntype == COMPLEXREGION && LISTVIEW_GetHeaderRect(infoPtr, nCol, &rcItem))
	    {
		rcItem.top = 0;
	        rcItem.bottom = infoPtr->nItemHeight;
		OffsetRect(&rcItem, Position.x, Position.y);
		if (!RectVisible(hdc, &rcItem)) continue;
	    }

	    LISTVIEW_DrawItem(infoPtr, hdc, i.nItem, nCol, Position, cdmode);
	}
    }
    iterator_destroy(&i);
}

/***
 * DESCRIPTION:
 * Draws listview items when in list display mode.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] hdc : device context handle
 * [I] cdmode : custom draw mode
 *
 * RETURN:
 * None
 */
static void LISTVIEW_RefreshList(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode)
{
    POINT Origin, Position;
    ITERATOR i;

    /* Get scroll info once before loop */
    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return;
    
    /* figure out what we need to draw */
    iterator_visibleitems(&i, infoPtr, hdc);
    
    while(iterator_prev(&i))
    {
	if (!LISTVIEW_GetItemOrigin(infoPtr, i.nItem, &Position)) continue;
	Position.x += Origin.x;
	Position.y += Origin.y;

        LISTVIEW_DrawItem(infoPtr, hdc, i.nItem, 0, Position, cdmode);
    }
    iterator_destroy(&i);
}


/***
 * DESCRIPTION:
 * Draws listview items.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] HDC : device context handle
 *
 * RETURN:
 * NoneX
 */
static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    COLORREF oldTextColor, oldClrTextBk, oldClrText;
    NMLVCUSTOMDRAW nmlvcd;
    HFONT hOldFont;
    DWORD cdmode;
    INT oldBkMode;
    RECT rcClient;

    LISTVIEW_DUMP(infoPtr);
  
    infoPtr->bIsDrawing = TRUE;

    /* save dc values we're gonna trash while drawing */
    hOldFont = SelectObject(hdc, infoPtr->hFont);
    oldBkMode = GetBkMode(hdc);
    infoPtr->clrTextBkDefault = GetBkColor(hdc);
    oldTextColor = GetTextColor(hdc);

    oldClrTextBk = infoPtr->clrTextBk;
    oldClrText   = infoPtr->clrText;
   
    GetClientRect(infoPtr->hwndSelf, &rcClient);
    customdraw_fill(&nmlvcd, infoPtr, hdc, &rcClient);
    cdmode = notify_customdraw(infoPtr, CDDS_PREPAINT, &nmlvcd);
    if (cdmode & CDRF_SKIPDEFAULT) goto enddraw;

    /* Use these colors to draw the items */
    infoPtr->clrTextBk = nmlvcd.clrTextBk;
    infoPtr->clrText = nmlvcd.clrText;

    /* nothing to draw */
    if(infoPtr->nItemCount == 0) goto enddraw;

    if ((infoPtr->dwStyle & LVS_OWNERDRAWFIXED) && (uView == LVS_REPORT))
	LISTVIEW_RefreshOwnerDraw(infoPtr, hdc);
    else
    {
    	if (uView == LVS_REPORT)
            LISTVIEW_RefreshReport(infoPtr, hdc, cdmode);
	else /* LVS_LIST, LVS_ICON or LVS_SMALLICON */
	    LISTVIEW_RefreshList(infoPtr, hdc, cdmode);

	/* if we have a focus rect, draw it */
	if (infoPtr->bFocus)
	    DrawFocusRect(hdc, &infoPtr->rcFocus);
    }
    
enddraw:
    if (cdmode & CDRF_NOTIFYPOSTPAINT)
	notify_customdraw(infoPtr, CDDS_POSTPAINT, &nmlvcd);

    infoPtr->clrTextBk = oldClrTextBk;
    infoPtr->clrText = oldClrText;

    SelectObject(hdc, hOldFont);
    SetBkMode(hdc, oldBkMode);
    SetBkColor(hdc, infoPtr->clrTextBkDefault);
    SetTextColor(hdc, oldTextColor);
    infoPtr->bIsDrawing = FALSE;
}


/***
 * DESCRIPTION:
 * Calculates the approximate width and height of a given number of items.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : number of items
 * [I] INT : width
 * [I] INT : height
 *
 * RETURN:
 * Returns a DWORD. The width in the low word and the height in high word.
 */
static LRESULT LISTVIEW_ApproximateViewRect(LISTVIEW_INFO *infoPtr, INT nItemCount,
                                            WORD wWidth, WORD wHeight)
{
  UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
  INT nItemCountPerColumn = 1;
  INT nColumnCount = 0;
  DWORD dwViewRect = 0;

  if (nItemCount == -1)
    nItemCount = infoPtr->nItemCount;

  if (uView == LVS_LIST)
  {
    if (wHeight == 0xFFFF)
    {
      /* use current height */
      wHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
    }

    if (wHeight < infoPtr->nItemHeight)
      wHeight = infoPtr->nItemHeight;

    if (nItemCount > 0)
    {
      if (infoPtr->nItemHeight > 0)
      {
        nItemCountPerColumn = wHeight / infoPtr->nItemHeight;
        if (nItemCountPerColumn == 0)
          nItemCountPerColumn = 1;

        if (nItemCount % nItemCountPerColumn != 0)
          nColumnCount = nItemCount / nItemCountPerColumn;
        else
          nColumnCount = nItemCount / nItemCountPerColumn + 1;
      }
    }

    /* Microsoft padding magic */
    wHeight = nItemCountPerColumn * infoPtr->nItemHeight + 2;
    wWidth = nColumnCount * infoPtr->nItemWidth + 2;

    dwViewRect = MAKELONG(wWidth, wHeight);
  }
  else if (uView == LVS_REPORT)
    FIXME("uView == LVS_REPORT: not implemented\n");
  else if (uView == LVS_SMALLICON)
    FIXME("uView == LVS_SMALLICON: not implemented\n");
  else if (uView == LVS_ICON)
    FIXME("uView == LVS_ICON: not implemented\n");

  return dwViewRect;
}

/***
 * DESCRIPTION:
 * Arranges listview items in icon display mode.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : alignment code
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_Arrange(LISTVIEW_INFO *infoPtr, INT nAlignCode)
{
  UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
  BOOL bResult = FALSE;

  if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
  {
    switch (nAlignCode)
    {
    case LVA_ALIGNLEFT:
      FIXME("nAlignCode=LVA_ALIGNLEFT: not implemented\n");
      break;
    case LVA_ALIGNTOP:
      FIXME("nAlignCode=LVA_ALIGNTOP: not implemented\n");
      break;
    case LVA_DEFAULT:
      FIXME("nAlignCode=LVA_DEFAULT: not implemented\n");
      break;
    case LVA_SNAPTOGRID:
      FIXME("nAlignCode=LVA_SNAPTOGRID: not implemented\n");
      break;
    }
  }

  return bResult;
}

/* << LISTVIEW_CreateDragImage >> */


/***
 * DESCRIPTION:
 * Removes all listview items and subitems.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_DeleteAllItems(LISTVIEW_INFO *infoPtr)
{
  LONG lStyle = infoPtr->dwStyle;
  UINT uView = lStyle & LVS_TYPEMASK;
  LISTVIEW_ITEM *lpItem;
  LISTVIEW_SUBITEM *lpSubItem;
  NMLISTVIEW nmlv;
  BOOL bSuppress;
  BOOL bResult = FALSE;
  HDPA hdpaSubItems;

  TRACE("()\n");

  LISTVIEW_DeselectAll(infoPtr);
  infoPtr->nSelectionMark=-1;
  infoPtr->nFocusedItem=-1;
  SetRectEmpty(&infoPtr->rcFocus);
  /* But we are supposed to leave nHotItem as is! */

  if (lStyle & LVS_OWNERDATA)
  {
    infoPtr->nItemCount = 0;
    LISTVIEW_InvalidateList(infoPtr);
    return TRUE;
  }

  if (infoPtr->nItemCount > 0)
  {
    INT i, j;

    /* send LVN_DELETEALLITEMS notification */
    /* verify if subsequent LVN_DELETEITEM notifications should be
       suppressed */
    ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
    nmlv.iItem = -1;
    bSuppress = notify_listview(infoPtr, LVN_DELETEALLITEMS, &nmlv);

    for (i = 0; i < infoPtr->nItemCount; i++)
    {
      hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, i);
      if (hdpaSubItems != NULL)
      {
        for (j = 1; j < hdpaSubItems->nItemCount; j++)
        {
          lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, j);
          if (lpSubItem != NULL)
          {
            /* free subitem string */
            if (is_textW(lpSubItem->hdr.pszText))
              COMCTL32_Free(lpSubItem->hdr.pszText);

            /* free subitem */
            COMCTL32_Free(lpSubItem);
          }
        }

        lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
        if (lpItem != NULL)
        {
          if (!bSuppress)
          {
            /* send LVN_DELETEITEM notification */
            nmlv.iItem = i;
            nmlv.lParam = lpItem->lParam;
            notify_listview(infoPtr, LVN_DELETEITEM, &nmlv);
          }

          /* free item string */
          if (is_textW(lpItem->hdr.pszText))
            COMCTL32_Free(lpItem->hdr.pszText);

          /* free item */
          COMCTL32_Free(lpItem);
        }

        DPA_Destroy(hdpaSubItems);
      }
    }

    /* reinitialize listview memory */
    bResult = DPA_DeleteAllPtrs(infoPtr->hdpaItems);
    infoPtr->nItemCount = 0;
    DPA_DeleteAllPtrs(infoPtr->hdpaPosX);
    DPA_DeleteAllPtrs(infoPtr->hdpaPosY);

    /* align items (set position of each item) */
    if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
    {
      if (lStyle & LVS_ALIGNLEFT)
      {
        LISTVIEW_AlignLeft(infoPtr);
      }
      else
      {
        LISTVIEW_AlignTop(infoPtr);
      }
    }

    LISTVIEW_UpdateScroll(infoPtr);

    LISTVIEW_InvalidateList(infoPtr);
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Scrolls, and updates the columns, when a column is changing width.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nColumn : column to scroll
 * [I] dx : amount of scroll, in pixels
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_ScrollColumns(LISTVIEW_INFO *infoPtr, INT nColumn, INT dx)
{
    COLUMN_INFO *lpColumnInfo;
    RECT rcOld, rcCol;
    INT nCol;
    
    if ((lpColumnInfo = DPA_GetPtr(infoPtr->hdpaColumns, nColumn)))
	rcCol = lpColumnInfo->rcHeader;
    
    /* ajust the other columns */
    for (nCol = nColumn; (lpColumnInfo = DPA_GetPtr(infoPtr->hdpaColumns, nCol)); nCol++)
    {
        lpColumnInfo->rcHeader.left += dx;
        lpColumnInfo->rcHeader.right += dx;
    }

    /* do not update screen if not in report mode */
    if ((infoPtr->dwStyle & LVS_TYPEMASK) != LVS_REPORT) return TRUE;
    
    /* if we have a focus, must first erase the focus rect */
    if (infoPtr->bFocus) LISTVIEW_ShowFocusRect(infoPtr, FALSE);
    
    /* Need to reset the item width when inserting a new column */
    infoPtr->nItemWidth += dx;

    LISTVIEW_UpdateScroll(infoPtr);

    /* scroll to cover the deleted column, and invalidate for redraw */
    rcOld = infoPtr->rcList;
    rcOld.left = rcCol.left;
    ScrollWindowEx(infoPtr->hwndSelf, dx, 0, &rcOld, &rcOld, 0, 0, SW_ERASE | SW_INVALIDATE);
    
    /* we can restore focus now */
    if (infoPtr->bFocus) LISTVIEW_ShowFocusRect(infoPtr, TRUE);

    return TRUE;
}

/***
 * DESCRIPTION:
 * Removes a column from the listview control.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : column index
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_DeleteColumn(LISTVIEW_INFO *infoPtr, INT nColumn)
{
    RECT rcCol;
    
    TRACE("nColumn=%d\n", nColumn);

    if (nColumn <= 0) return FALSE;

    if (!LISTVIEW_GetHeaderRect(infoPtr, nColumn, &rcCol))
	return FALSE;
    
    if (!Header_DeleteItem(infoPtr->hwndHeader, nColumn))
	return FALSE;

    COMCTL32_Free(DPA_GetPtr(infoPtr->hdpaColumns, nColumn));
    DPA_DeletePtr(infoPtr->hdpaColumns, nColumn);
  
    if (!(infoPtr->dwStyle & LVS_OWNERDATA))
    {
	LISTVIEW_SUBITEM *lpSubItem, *lpDelItem;
	HDPA hdpaSubItems;
	INT nItem, nSubItem, i;
	
	for (nItem = 0; nItem < infoPtr->nItemCount; nItem++)
	{
	    hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
	    if (!hdpaSubItems) continue;
	    nSubItem = 0;
	    lpDelItem = 0;
	    for (i = 1; i < hdpaSubItems->nItemCount; i++)
	    {
		lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
		if (!lpSubItem) break;
		if (lpSubItem->iSubItem == nColumn)
		{
		    nSubItem = i;
		    lpDelItem = lpSubItem;
		}
		else if (lpSubItem->iSubItem > nColumn) 
		{
		    lpSubItem->iSubItem--;
		}
	    }

	    /* if we found our subitem, zapp it */	
	    if (nSubItem > 0)
	    {
		/* free string */
		if (is_textW(lpDelItem->hdr.pszText))
		    COMCTL32_Free(lpDelItem->hdr.pszText);

		/* free item */
		COMCTL32_Free(lpDelItem);

		/* free dpa memory */
		DPA_DeletePtr(hdpaSubItems, nSubItem);
    	    }
	}
    }

    /* update the other column info */
    LISTVIEW_ScrollColumns(infoPtr, nColumn, -(rcCol.right - rcCol.left));

    return TRUE;
}

/***
 * DESCRIPTION:
 * Removes an item from the listview control.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : item index
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_DeleteItem(LISTVIEW_INFO *infoPtr, INT nItem)
{
  LONG lStyle = infoPtr->dwStyle;
  UINT uView = lStyle & LVS_TYPEMASK;
  NMLISTVIEW nmlv;
  BOOL bResult = FALSE;
  HDPA hdpaSubItems;
  LISTVIEW_ITEM *lpItem;
  LISTVIEW_SUBITEM *lpSubItem;
  LVITEMW item;
  INT i;

  TRACE("(nItem=%d)\n", nItem);

  /* remove selection, and focus */
  item.state = 0;
  item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  LISTVIEW_SetItemState(infoPtr, nItem, &item);

  /* send LVN_DELETEITEM notification. */
  ZeroMemory(&nmlv, sizeof (NMLISTVIEW));
  nmlv.iItem = nItem;
  notify_listview(infoPtr, LVN_DELETEITEM, &nmlv);

  if (lStyle & LVS_OWNERDATA)
  {
    infoPtr->nItemCount--;
    LISTVIEW_InvalidateList(infoPtr); /*FIXME: optimize */
    return TRUE;
  }

  if ((nItem >= 0) && (nItem < infoPtr->nItemCount))
  {
    /* initialize memory */
    ZeroMemory(&nmlv, sizeof(NMLISTVIEW));

    hdpaSubItems = (HDPA)DPA_DeletePtr(infoPtr->hdpaItems, nItem);
    if (hdpaSubItems != NULL)
    {
      infoPtr->nItemCount--;
      for (i = 1; i < hdpaSubItems->nItemCount; i++)
      {
        lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
        if (lpSubItem != NULL)
        {
          /* free item string */
          if (is_textW(lpSubItem->hdr.pszText))
            COMCTL32_Free(lpSubItem->hdr.pszText);

          /* free item */
          COMCTL32_Free(lpSubItem);
        }
      }

      lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
      if (lpItem != NULL)
      {
        /* free item string */
        if (is_textW(lpItem->hdr.pszText))
          COMCTL32_Free(lpItem->hdr.pszText);

        /* free item */
        COMCTL32_Free(lpItem);
      }

      bResult = DPA_Destroy(hdpaSubItems);
      DPA_DeletePtr(infoPtr->hdpaPosX, nItem);
      DPA_DeletePtr(infoPtr->hdpaPosY, nItem);
    }

    LISTVIEW_ShiftIndices(infoPtr, nItem, -1);

    /* align items (set position of each item) */
    if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
    {
      if (lStyle & LVS_ALIGNLEFT)
        LISTVIEW_AlignLeft(infoPtr);
      else
        LISTVIEW_AlignTop(infoPtr);
    }

    LISTVIEW_UpdateScroll(infoPtr);

    LISTVIEW_InvalidateList(infoPtr); /* FIXME: optimize */
  }

  return bResult;
}


/***
 * DESCRIPTION:
 * Callback implementation for editlabel control
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] pszText : modified text
 * [I] isW : TRUE if psxText is Unicode, FALSE if it's ANSI
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, LPWSTR pszText, BOOL isW)
{
    NMLVDISPINFOW dispInfo;

    TRACE("(pszText=%s, isW=%d)\n", debugtext_t(pszText, isW), isW);

    ZeroMemory(&dispInfo, sizeof(dispInfo));
    dispInfo.item.mask = LVIF_PARAM | LVIF_STATE;
    dispInfo.item.iItem = infoPtr->nEditLabelItem;
    dispInfo.item.iSubItem = 0;
    dispInfo.item.stateMask = ~0;
    if (!LISTVIEW_GetItemW(infoPtr, &dispInfo.item)) return FALSE;
    /* add the text from the edit in */
    dispInfo.item.mask |= LVIF_TEXT;
    dispInfo.item.pszText = pszText;
    dispInfo.item.cchTextMax = textlenT(pszText, isW);

    /* Do we need to update the Item Text */
    if (!notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW)) return FALSE;
    if (!pszText) return TRUE;

    ZeroMemory(&dispInfo, sizeof(dispInfo));
    dispInfo.item.mask = LVIF_TEXT;
    dispInfo.item.iItem = infoPtr->nEditLabelItem;
    dispInfo.item.iSubItem = 0;
    dispInfo.item.pszText = pszText;
    dispInfo.item.cchTextMax = textlenT(pszText, isW);
    return LISTVIEW_SetItemT(infoPtr, &dispInfo.item, isW);
}

/***
 * DESCRIPTION:
 * Begin in place editing of specified list view item
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : item index
 * [I] isW : TRUE if it's a Unicode req, FALSE if ASCII
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static HWND LISTVIEW_EditLabelT(LISTVIEW_INFO *infoPtr, INT nItem, BOOL isW)
{
    WCHAR szDispText[DISP_TEXT_SIZE] = { 0 };
    NMLVDISPINFOW dispInfo;
    RECT rect;

    TRACE("(nItem=%d, isW=%d)\n", nItem, isW);

    if (~infoPtr->dwStyle & LVS_EDITLABELS) return 0;
    if (nItem < 0 || nItem >= infoPtr->nItemCount) return 0;

    infoPtr->nEditLabelItem = nItem;

    /* Is the EditBox still there, if so remove it */
    if(infoPtr->hwndEdit != 0)
    {
        SetFocus(infoPtr->hwndSelf);
        infoPtr->hwndEdit = 0;
    }

    LISTVIEW_SetSelection(infoPtr, nItem);
    LISTVIEW_SetItemFocus(infoPtr, nItem);

    rect.left = LVIR_LABEL;
    if (!LISTVIEW_GetItemRect(infoPtr, nItem, &rect)) return 0;
    
    ZeroMemory(&dispInfo, sizeof(dispInfo));
    dispInfo.item.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT;
    dispInfo.item.iItem = nItem;
    dispInfo.item.iSubItem = 0;
    dispInfo.item.stateMask = ~0;
    dispInfo.item.pszText = szDispText;
    dispInfo.item.cchTextMax = DISP_TEXT_SIZE;
    if (!LISTVIEW_GetItemT(infoPtr, &dispInfo.item, isW)) return 0;

    infoPtr->hwndEdit = CreateEditLabelT(infoPtr, dispInfo.item.pszText, WS_VISIBLE,
		    rect.left-2, rect.top-1, 0, rect.bottom - rect.top+2, isW);
    if (!infoPtr->hwndEdit) return 0;
    
    if (notify_dispinfoT(infoPtr, LVN_BEGINLABELEDITW, &dispInfo, isW))
    {
	SendMessageW(infoPtr->hwndEdit, WM_CLOSE, 0, 0);
	infoPtr->hwndEdit = 0;
	return 0;
    }

    ShowWindow(infoPtr->hwndEdit, SW_NORMAL);
    SetFocus(infoPtr->hwndEdit);
    SendMessageW(infoPtr->hwndEdit, EM_SETSEL, 0, -1);
    return infoPtr->hwndEdit;
}


/***
 * DESCRIPTION:
 * Ensures the specified item is visible, scrolling into view if necessary.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nItem : item index
 * [I] bPartial : partially or entirely visible
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *infoPtr, INT nItem, BOOL bPartial)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    INT nScrollPosHeight = 0;
    INT nScrollPosWidth = 0;
    INT nHorzAdjust = 0;
    INT nVertAdjust = 0;
    INT nHorzDiff = 0;
    INT nVertDiff = 0;
    RECT rcItem, rcTemp;

    rcItem.left = LVIR_BOUNDS;
    if (!LISTVIEW_GetItemRect(infoPtr, nItem, &rcItem)) return FALSE;

    if (bPartial && IntersectRect(&rcTemp, &infoPtr->rcList, &rcItem)) return TRUE;
    
    if (rcItem.left < infoPtr->rcList.left || rcItem.right > infoPtr->rcList.right)
    {
        /* scroll left/right, but in LVS_REPORT mode */
        if (uView == LVS_LIST)
            nScrollPosWidth = infoPtr->nItemWidth;
        else if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
            nScrollPosWidth = 1;

	if (rcItem.left < infoPtr->rcList.left)
	{
	    nHorzAdjust = -1;
	    if (uView != LVS_REPORT) nHorzDiff = rcItem.left - infoPtr->rcList.left;
	}
	else
	{
	    nHorzAdjust = 1;
	    if (uView != LVS_REPORT) nHorzDiff = rcItem.right - infoPtr->rcList.right;
	}
    }

    if (rcItem.top < infoPtr->rcList.top || rcItem.bottom > infoPtr->rcList.bottom)
    {
	/* scroll up/down, but not in LVS_LIST mode */
        if (uView == LVS_REPORT)
            nScrollPosHeight = infoPtr->nItemHeight;
        else if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
            nScrollPosHeight = 1;

	if (rcItem.top < infoPtr->rcList.top)
	{
	    nVertAdjust = -1;
	    if (uView != LVS_LIST) nVertDiff = rcItem.top - infoPtr->rcList.top;
	}
	else
	{
	    nVertAdjust = 1;
	    if (uView != LVS_LIST) nVertDiff = rcItem.bottom - infoPtr->rcList.bottom;
	}
    }

    if (!nScrollPosWidth && !nScrollPosHeight) return TRUE;

    if (nScrollPosWidth)
    {
	INT diff = nHorzDiff / nScrollPosWidth;
	if (nHorzDiff % nScrollPosWidth) diff += nHorzAdjust;
	LISTVIEW_HScroll(infoPtr, SB_INTERNAL, diff, 0);
    }

    if (nScrollPosHeight)
    {
	INT diff = nVertDiff / nScrollPosHeight;
	if (nVertDiff % nScrollPosHeight) diff += nVertAdjust;
	LISTVIEW_VScroll(infoPtr, SB_INTERNAL, diff, 0);
    }

    return TRUE;
}

/***
 * DESCRIPTION:
 * Searches for an item with specific characteristics.
 *
 * PARAMETER(S):
 * [I] hwnd : window handle
 * [I] nStart : base item index
 * [I] lpFindInfo : item information to look for
 *
 * RETURN:
 *   SUCCESS : index of item
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_FindItemW(LISTVIEW_INFO *infoPtr, INT nStart,
                                  LPLVFINDINFOW lpFindInfo)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
    BOOL bWrap = FALSE, bNearest = FALSE;
    INT nItem = nStart + 1, nLast = infoPtr->nItemCount, nNearestItem = -1;
    ULONG xdist, ydist, dist, mindist = 0x7fffffff;
    POINT Position, Destination;
    LVITEMW lvItem;

    if (!lpFindInfo || nItem < 0) return -1;
    
    lvItem.mask = 0;
    if (lpFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL))
    {
        lvItem.mask |= LVIF_TEXT;
        lvItem.pszText = szDispText;
        lvItem.cchTextMax = DISP_TEXT_SIZE;
    }

    if (lpFindInfo->flags & LVFI_WRAP)
        bWrap = TRUE;

    if ((lpFindInfo->flags & LVFI_NEARESTXY) && 
	(uView == LVS_ICON || uView ==LVS_SMALLICON))
    {
	POINT Origin;
	
	FIXME("LVFI_NEARESTXY is slow.\n");
        if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return -1;
	Destination.x = lpFindInfo->pt.x - Origin.x;
	Destination.y = lpFindInfo->pt.y - Origin.y;
	switch(lpFindInfo->vkDirection)
	{
	case VK_DOWN:  Destination.y += infoPtr->nItemHeight; break;
	case VK_UP:    Destination.y -= infoPtr->nItemHeight; break;
	case VK_RIGHT: Destination.x += infoPtr->nItemWidth; break;
	case VK_LEFT:  Destination.x -= infoPtr->nItemWidth; break;
	case VK_HOME:  Destination.x = Destination.y = 0; break;
	case VK_END:   Destination.x = infoPtr->rcView.right; Destination.y = infoPtr->rcView.bottom; break;
	case VK_NEXT:  Destination.y += infoPtr->rcList.bottom - infoPtr->rcList.top; break;
	case VK_PRIOR: Destination.y -= infoPtr->rcList.bottom - infoPtr->rcList.top; break;
	default: FIXME("Unknown vkDirection=%d\n", lpFindInfo->vkDirection);
	}
	bNearest = TRUE;
    }

    /* if LVFI_PARAM is specified, all other flags are ignored */
    if (lpFindInfo->flags & LVFI_PARAM)
    {
        lvItem.mask |= LVIF_PARAM;
	bNearest = FALSE;
	lvItem.mask &= ~LVIF_TEXT;
    }

again:
    for (; nItem < nLast; nItem++)
    {
        lvItem.iItem = nItem;
        lvItem.iSubItem = 0;
        if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) continue;

	if (lvItem.mask & LVIF_PARAM && lpFindInfo->lParam == lvItem.lParam)
	    return nItem;
	
        if (lvItem.mask & LVIF_TEXT)
	{
            if (lpFindInfo->flags & LVFI_PARTIAL)
            {
            	if (strstrW(lvItem.pszText, lpFindInfo->psz) == NULL) continue;
            }
            else
            {
            	if (lstrcmpW(lvItem.pszText, lpFindInfo->psz) != 0) continue;
            }
	}

        if (!bNearest) return nItem;
	
	/* This is very inefficient. To do a good job here,
	 * we need a sorted array of (x,y) item positions */
	if (!LISTVIEW_GetItemOrigin(infoPtr, nItem, &Position)) continue;

	/* compute the distance^2 to the destination */
	xdist = Destination.x - Position.x;
	ydist = Destination.y - Position.y;
	dist = xdist * xdist + ydist * ydist;

	/* remember the distance, and item if it's closer */
	if (dist < mindist)
	{
	    mindist = dist;
	    nNearestItem = nItem;
	}
    }

    if (bWrap)
    {
        nItem = 0;
        nLast = min(nStart + 1, infoPtr->nItemCount);
        bWrap = FALSE;
	goto again;
    }

    return nNearestItem;
}

/***
 * DESCRIPTION:
 * Searches for an item with specific characteristics.
 *
 * PARAMETER(S):
 * [I] hwnd : window handle
 * [I] nStart : base item index
 * [I] lpFindInfo : item information to look for
 *
 * RETURN:
 *   SUCCESS : index of item
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_FindItemA(LISTVIEW_INFO *infoPtr, INT nStart,
                                  LPLVFINDINFOA lpFindInfo)
{
  BOOL hasText = lpFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL);
  LVFINDINFOW fiw;
  LRESULT res;

  memcpy(&fiw, lpFindInfo, sizeof(fiw));
  if (hasText) fiw.psz = textdupTtoW((LPCWSTR)lpFindInfo->psz, FALSE);
  res = LISTVIEW_FindItemW(infoPtr, nStart, &fiw);
  if (hasText) textfreeT((LPWSTR)fiw.psz, FALSE);
  return res;
}

/***
 * DESCRIPTION:
 * Retrieves the background image of the listview control.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [O] LPLVMKBIMAGE : background image attributes
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
/* static LRESULT LISTVIEW_GetBkImage(LISTVIEW_INFO *infoPtr, LPLVBKIMAGE lpBkImage)   */
/* {   */
/*   FIXME (listview, "empty stub!\n"); */
/*   return FALSE;   */
/* }   */

/***
 * DESCRIPTION:
 * Retrieves column attributes.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT :  column index
 * [IO] LPLVCOLUMNW : column information
 * [I] isW : if TRUE, then lpColumn is a LPLVCOLUMNW
 *           otherwise it is in fact a LPLVCOLUMNA
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_GetColumnT(LISTVIEW_INFO *infoPtr, INT nItem, LPLVCOLUMNW lpColumn, BOOL isW)
{
  HDITEMW hdi;
  BOOL bResult = FALSE;

  if (lpColumn != NULL)
  {

    /* initialize memory */
    ZeroMemory(&hdi, sizeof(hdi));

    if (lpColumn->mask & LVCF_FMT)
      hdi.mask |= HDI_FORMAT;

    if (lpColumn->mask & LVCF_WIDTH)
      hdi.mask |= HDI_WIDTH;

    if (lpColumn->mask & LVCF_TEXT)
    {
      hdi.mask |= HDI_TEXT;
      hdi.cchTextMax = lpColumn->cchTextMax;
      hdi.pszText    = lpColumn->pszText;
    }

    if (lpColumn->mask & LVCF_IMAGE)
      hdi.mask |= HDI_IMAGE;

    if (lpColumn->mask & LVCF_ORDER)
      hdi.mask |= HDI_ORDER;

    if (isW)
      bResult = Header_GetItemW(infoPtr->hwndHeader, nItem, &hdi);
    else
      bResult = Header_GetItemA(infoPtr->hwndHeader, nItem, &hdi);

    if (bResult)
    {
      if (lpColumn->mask & LVCF_FMT)
      {
        lpColumn->fmt = 0;

        if (hdi.fmt & HDF_LEFT)
          lpColumn->fmt |= LVCFMT_LEFT;
        else if (hdi.fmt & HDF_RIGHT)
          lpColumn->fmt |= LVCFMT_RIGHT;
        else if (hdi.fmt & HDF_CENTER)
          lpColumn->fmt |= LVCFMT_CENTER;

        if (hdi.fmt & HDF_IMAGE)
          lpColumn->fmt |= LVCFMT_COL_HAS_IMAGES;

	if (hdi.fmt & HDF_BITMAP_ON_RIGHT)
	  lpColumn->fmt |= LVCFMT_BITMAP_ON_RIGHT;
      }

      if (lpColumn->mask & LVCF_WIDTH)
        lpColumn->cx = hdi.cxy;

      if (lpColumn->mask & LVCF_IMAGE)
        lpColumn->iImage = hdi.iImage;

      if (lpColumn->mask & LVCF_ORDER)
        lpColumn->iOrder = hdi.iOrder;

      TRACE("(col=%d, lpColumn=%s, isW=%d)\n",
	    nItem, debuglvcolumn_t(lpColumn, isW), isW);

    }
  }

  return bResult;
}


static LRESULT LISTVIEW_GetColumnOrderArray(LISTVIEW_INFO *infoPtr, INT iCount, LPINT lpiArray)
{
    INT i;

    if (!lpiArray)
	return FALSE;

    /* FIXME: little hack */
    for (i = 0; i < iCount; i++)
	lpiArray[i] = i;

    return TRUE;
}

/***
 * DESCRIPTION:
 * Retrieves the column width.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] int : column index
 *
 * RETURN:
 *   SUCCESS : column width
 *   FAILURE : zero
 */
static INT LISTVIEW_GetColumnWidth(LISTVIEW_INFO *infoPtr, INT nColumn)
{
    INT nColumnWidth = 0;
    RECT rcHeader;

    TRACE("nColumn=%d\n", nColumn);

    /* we have a 'column' in LIST and REPORT mode only */
    switch(infoPtr->dwStyle & LVS_TYPEMASK)
    {
    case LVS_LIST:
	nColumnWidth = infoPtr->nItemWidth;
	break;
    case LVS_REPORT:
	if (LISTVIEW_GetHeaderRect(infoPtr, nColumn, &rcHeader))
	    nColumnWidth = rcHeader.right - rcHeader.left;
	break;
    }

    TRACE("nColumnWidth=%d\n", nColumnWidth);
    return nColumnWidth;
}

/***
 * DESCRIPTION:
 * In list or report display mode, retrieves the number of items that can fit
 * vertically in the visible area. In icon or small icon display mode,
 * retrieves the total number of visible items.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * Number of fully visible items.
 */
static LRESULT LISTVIEW_GetCountPerPage(LISTVIEW_INFO *infoPtr)
{
  UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
  INT nItemCount = 0;

  if (uView == LVS_LIST)
  {
    if (infoPtr->rcList.right > infoPtr->nItemWidth)
    {
      nItemCount = LISTVIEW_GetCountPerRow(infoPtr) *
                   LISTVIEW_GetCountPerColumn(infoPtr);
    }
  }
  else if (uView == LVS_REPORT)
  {
    nItemCount = LISTVIEW_GetCountPerColumn(infoPtr);
  }
  else
  {
    nItemCount = infoPtr->nItemCount;
  }

  return nItemCount;
}


/***
 * DESCRIPTION:
 * Retrieves an image list handle.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nImageList : image list identifier
 *
 * RETURN:
 *   SUCCESS : image list handle
 *   FAILURE : NULL
 */
static LRESULT LISTVIEW_GetImageList(LISTVIEW_INFO *infoPtr, INT nImageList)
{
  HIMAGELIST himl = NULL;

  switch (nImageList)
  {
  case LVSIL_NORMAL:
    himl = infoPtr->himlNormal;
    break;
  case LVSIL_SMALL:
    himl = infoPtr->himlSmall;
    break;
  case LVSIL_STATE:
    himl = infoPtr->himlState;
    break;
  }

  return (LRESULT)himl;
}

/* LISTVIEW_GetISearchString */

/***
 * DESCRIPTION:
 * Retrieves item attributes.
 *
 * PARAMETER(S):
 * [I] hwnd : window handle
 * [IO] lpLVItem : item info
 * [I] isW : if TRUE, then lpLVItem is a LPLVITEMW,
 *           if FALSE, the lpLVItem is a LPLVITEMA.
 *
 * NOTE:
 *   This is the internal 'GetItem' interface -- it tries to
 *   be smart, and avoids text copies, if possible, by modifing
 *   lpLVItem->pszText to point to the text string. Please note
 *   that this is not always possible (e.g. OWNERDATA), so on
 *   entry you *must* supply valid values for pszText, and cchTextMax.
 *   The only difference to the documented interface is that upon
 *   return, you should use *only* the lpLVItem->pszText, rather than
 *   the buffer pointer you provided on input. Most code already does
 *   that, so it's not a problem.
 *   For the two cases when the text must be copied (that is,
 *   for LVM_GETITEM, and LVMGETITEMTEXT), use LISTVIEW_GetItemExtT.
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_GetItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW)
{
    NMLVDISPINFOW dispInfo;
    LISTVIEW_ITEM *lpItem;
    ITEMHDR* pItemHdr;
    HDPA hdpaSubItems;

    TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW);

    if (!lpLVItem || lpLVItem->iItem < 0 || lpLVItem->iItem >= infoPtr->nItemCount)
	return FALSE;

    if (lpLVItem->mask == 0) return TRUE;

    /* a quick optimization if all we're asked is the focus state
     * these queries are worth optimising since they are common,
     * and can be answered in constant time, without the heavy accesses */
    if ( (lpLVItem->mask == LVIF_STATE) && (lpLVItem->stateMask == LVIS_FOCUSED) &&
	 !(infoPtr->uCallbackMask & LVIS_FOCUSED) )
    {
	lpLVItem->state = 0;
	if (infoPtr->nFocusedItem == lpLVItem->iItem)
	    lpLVItem->state |= LVIS_FOCUSED;
	return TRUE;
    }

    ZeroMemory(&dispInfo, sizeof(dispInfo));

    /* if the app stores all the data, handle it separately */
    if (infoPtr->dwStyle & LVS_OWNERDATA)
    {
	dispInfo.item.state = 0;

	/* if we need to callback, do it now */
	if ((lpLVItem->mask & ~LVIF_STATE) || infoPtr->uCallbackMask)
	{
	    /* NOTE: copy only fields which we _know_ are initialized, some apps
	     *       depend on the uninitialized fields being 0 */
	    dispInfo.item.mask = lpLVItem->mask;
	    dispInfo.item.iItem = lpLVItem->iItem;
	    dispInfo.item.iSubItem = lpLVItem->iSubItem;
	    if (lpLVItem->mask & LVIF_TEXT)
	    {
		dispInfo.item.pszText = lpLVItem->pszText;
		dispInfo.item.cchTextMax = lpLVItem->cchTextMax;		
	    }
	    if (lpLVItem->mask & LVIF_STATE)
	        dispInfo.item.stateMask = lpLVItem->stateMask & infoPtr->uCallbackMask;
	    notify_dispinfoT(infoPtr, LVN_GETDISPINFOW, &dispInfo, isW);
	    dispInfo.item.stateMask = lpLVItem->stateMask;
	    *lpLVItem = dispInfo.item;
	    TRACE("   getdispinfo(1):lpLVItem=%s\n", debuglvitem_t(lpLVItem, isW));
	}

	/* we store only a little state, so if we're not asked, we're done */
	if (!(lpLVItem->mask & LVIF_STATE) || lpLVItem->iSubItem) return TRUE;

	/* if focus is handled by us, report it */
	if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED ) 
	{
	    lpLVItem->state &= ~LVIS_FOCUSED;
	    if (infoPtr->nFocusedItem == lpLVItem->iItem)
	        lpLVItem->state |= LVIS_FOCUSED;
        }

	/* and do the same for selection, if we handle it */
	if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED ) 
	{
	    lpLVItem->state &= ~LVIS_SELECTED;
	    if (ranges_contain(infoPtr->selectionRanges, lpLVItem->iItem))
		lpLVItem->state |= LVIS_SELECTED;
	}
	
	return TRUE;
    }

    /* find the item and subitem structures before we proceed */
    hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
    if (hdpaSubItems == NULL) return FALSE;

    if ( !(lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0)) )
        return FALSE;

    if (lpLVItem->iSubItem)
    {
	LISTVIEW_SUBITEM *lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, lpLVItem->iSubItem);
        if(!lpSubItem) return FALSE;
	pItemHdr = &lpSubItem->hdr;
    }
    else
	pItemHdr = &lpItem->hdr;

    /* Do we need to query the state from the app? */
    if ((lpLVItem->mask & LVIF_STATE) && infoPtr->uCallbackMask && lpLVItem->iSubItem == 0)
    {
	dispInfo.item.mask |= LVIF_STATE;
	dispInfo.item.stateMask = infoPtr->uCallbackMask;
    }
  
    /* Do we need to enquire about the image? */
    if ((lpLVItem->mask & LVIF_IMAGE) && pItemHdr->iImage == I_IMAGECALLBACK)
	dispInfo.item.mask |= LVIF_IMAGE;

    /* Apps depend on calling back for text if it is NULL or LPSTR_TEXTCALLBACKW */
    if ((lpLVItem->mask & LVIF_TEXT) && !is_textW(pItemHdr->pszText))
    {
	dispInfo.item.mask |= LVIF_TEXT;
	dispInfo.item.pszText = lpLVItem->pszText;
	dispInfo.item.cchTextMax = lpLVItem->cchTextMax;
	if (dispInfo.item.pszText && dispInfo.item.cchTextMax > 0)
	    *dispInfo.item.pszText = '\0';
    }

    /* If we don't have all the requested info, query the application */
    if (dispInfo.item.mask != 0)
    {
	dispInfo.item.iItem = lpLVItem->iItem;
	dispInfo.item.iSubItem = lpLVItem->iSubItem;
	dispInfo.item.lParam = lpItem->lParam;
	notify_dispinfoT(infoPtr, LVN_GETDISPINFOW, &dispInfo, isW);
	TRACE("   getdispinfo(2):item=%s\n", debuglvitem_t(&dispInfo.item, isW));
    }

    /* Now, handle the iImage field */
    if (dispInfo.item.mask & LVIF_IMAGE)
    {
	lpLVItem->iImage = dispInfo.item.iImage;
	if ((dispInfo.item.mask & LVIF_DI_SETITEM) && pItemHdr->iImage == I_IMAGECALLBACK)
	    pItemHdr->iImage = dispInfo.item.iImage;
    }
    else if (lpLVItem->mask & LVIF_IMAGE)
	lpLVItem->iImage = pItemHdr->iImage;

    /* The pszText field */
    if (dispInfo.item.mask & LVIF_TEXT)
    {
	if ((dispInfo.item.mask & LVIF_DI_SETITEM) && pItemHdr->pszText)
	    textsetptrT(&pItemHdr->pszText, dispInfo.item.pszText, isW);

	lpLVItem->pszText = dispInfo.item.pszText;
    }
    else if (lpLVItem->mask & LVIF_TEXT)
    {
	if (isW) lpLVItem->pszText = pItemHdr->pszText;
	else textcpynT(lpLVItem->pszText, isW, pItemHdr->pszText, TRUE, lpLVItem->cchTextMax);
    }

    /* if this is a subitem, we're done */
    if (lpLVItem->iSubItem) return TRUE;
  
    /* Next is the lParam field */
    if (dispInfo.item.mask & LVIF_PARAM)
    {
	lpLVItem->lParam = dispInfo.item.lParam;
	if ((dispInfo.item.mask & LVIF_DI_SETITEM))
	    lpItem->lParam = dispInfo.item.lParam;
    }
    else if (lpLVItem->mask & LVIF_PARAM)
	lpLVItem->lParam = lpItem->lParam;

    /* ... the state field (this one is different due to uCallbackmask) */
    if (lpLVItem->mask & LVIF_STATE) 
    {
	lpLVItem->state = lpItem->state;
	if (dispInfo.item.mask & LVIF_STATE)
	{
	    lpLVItem->state &= ~dispInfo.item.stateMask;
	    lpLVItem->state |= (dispInfo.item.state & dispInfo.item.stateMask);
	}
	if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED ) 
	{
	    lpLVItem->state &= ~LVIS_FOCUSED;
	    if (infoPtr->nFocusedItem == lpLVItem->iItem)
	        lpLVItem->state |= LVIS_FOCUSED;
        }
	if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED ) 
	{
	    lpLVItem->state &= ~LVIS_SELECTED;
	    if (ranges_contain(infoPtr->selectionRanges, lpLVItem->iItem))
		lpLVItem->state |= LVIS_SELECTED;
	}	    
    }

    /* and last, but not least, the indent field */
    if (lpLVItem->mask & LVIF_INDENT)
	lpLVItem->iIndent = lpItem->iIndent;

    return TRUE;
}

/***
 * DESCRIPTION:
 * Retrieves item attributes.
 *
 * PARAMETER(S):
 * [I] hwnd : window handle
 * [IO] lpLVItem : item info
 * [I] isW : if TRUE, then lpLVItem is a LPLVITEMW,
 *           if FALSE, the lpLVItem is a LPLVITEMA.
 *
 * NOTE:
 *   This is the external 'GetItem' interface -- it properly copies
 *   the text in the provided buffer.
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_GetItemExtT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW)
{
    LPWSTR pszText;
    BOOL bResult;

    if (!lpLVItem || lpLVItem->iItem < 0 || lpLVItem->iItem >= infoPtr->nItemCount)
	return FALSE;

    pszText = lpLVItem->pszText;
    bResult = LISTVIEW_GetItemT(infoPtr, lpLVItem, isW);
    if (bResult && lpLVItem->pszText != pszText)
	textcpynT(pszText, isW, lpLVItem->pszText, isW, lpLVItem->cchTextMax);
    lpLVItem->pszText = pszText;

    return bResult;
}


/***
 * DESCRIPTION:
 * Retrieves the position (upper-left) of the listview control item.
 * Note that for LVS_ICON style, the upper-left is that of the icon
 * and not the bounding box.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nItem : item index
 * [O] lpptPosition : coordinate information
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, LPPOINT lpptPosition)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    POINT Origin;

    TRACE("(nItem=%d, lpptPosition=%p)\n", nItem, lpptPosition);

    if (!lpptPosition || nItem < 0 || nItem >= infoPtr->nItemCount) return FALSE;
    if (!LISTVIEW_GetItemOrigin(infoPtr, nItem, lpptPosition)) return FALSE;
    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE;

    if (uView == LVS_ICON)
    {
        lpptPosition->x += (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2;
        lpptPosition->y += ICON_TOP_PADDING;
    }
    lpptPosition->x += Origin.x;
    lpptPosition->y += Origin.y;
    
    TRACE ("  lpptPosition=%s\n", debugpoint(lpptPosition));
    return TRUE;
}


/***
 * DESCRIPTION:
 * Retrieves the bounding rectangle for a listview control item.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nItem : item index
 * [IO] lprc : bounding rectangle coordinates
 *     lprc->left specifies the portion of the item for which the bounding
 *     rectangle will be retrieved.
 *
 *     LVIR_BOUNDS Returns the bounding rectangle of the entire item,
 *        including the icon and label.
 *         *
 *         * For LVS_ICON
 *         * Experiment shows that native control returns:
 *         *  width = min (48, length of text line)
 *         *    .left = position.x - (width - iconsize.cx)/2
 *         *    .right = .left + width
 *         *  height = #lines of text * ntmHeight + icon height + 8
 *         *    .top = position.y - 2
 *         *    .bottom = .top + height
 *         *  separation between items .y = itemSpacing.cy - height
 *         *                           .x = itemSpacing.cx - width
 *     LVIR_ICON Returns the bounding rectangle of the icon or small icon.
 *         *
 *         * For LVS_ICON
 *         * Experiment shows that native control returns:
 *         *  width = iconSize.cx + 16
 *         *    .left = position.x - (width - iconsize.cx)/2
 *         *    .right = .left + width
 *         *  height = iconSize.cy + 4
 *         *    .top = position.y - 2
 *         *    .bottom = .top + height
 *         *  separation between items .y = itemSpacing.cy - height
 *         *                           .x = itemSpacing.cx - width
 *     LVIR_LABEL Returns the bounding rectangle of the item text.
 *         *
 *         * For LVS_ICON
 *         * Experiment shows that native control returns:
 *         *  width = text length
 *         *    .left = position.x - width/2
 *         *    .right = .left + width
 *         *  height = ntmH * linecount + 2
 *         *    .top = position.y + iconSize.cy + 6
 *         *    .bottom = .top + height
 *         *  separation between items .y = itemSpacing.cy - height
 *         *                           .x = itemSpacing.cx - width
 *     LVIR_SELECTBOUNDS Returns the union of the LVIR_ICON and LVIR_LABEL
 *	rectangles, but excludes columns in report view.
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 *
 * NOTES
 *   Note that the bounding rectangle of the label in the LVS_ICON view depends
 *   upon whether the window has the focus currently and on whether the item
 *   is the one with the focus.  Ensure that the control's record of which
 *   item has the focus agrees with the items' records.
 */
static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
    BOOL doLabel = TRUE, oversizedBox = FALSE;
    POINT Position, Origin;
    LVITEMW lvItem;
    RECT label_rect;

    TRACE("(hwnd=%x, nItem=%d, lprc=%p)\n", infoPtr->hwndSelf, nItem, lprc);

    if (!lprc || nItem < 0 || nItem >= infoPtr->nItemCount) return FALSE;
    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE;
    if (!LISTVIEW_GetItemOrigin(infoPtr, nItem, &Position)) return FALSE;

    /* Be smart and try to figure out the minimum we have to do */
    if (lprc->left == LVIR_ICON) doLabel = FALSE;
    if (uView == LVS_REPORT && lprc->left == LVIR_BOUNDS) doLabel = FALSE;
    if (uView == LVS_ICON && lprc->left != LVIR_ICON &&
	infoPtr->bFocus && LISTVIEW_GetItemState(infoPtr, nItem, LVIS_FOCUSED))
	oversizedBox = TRUE;

    /* get what we need from the item before hand, so we make
     * only one request. This can speed up things, if data
     * is stored on the app side */
    lvItem.mask = 0;
    if (uView == LVS_REPORT) lvItem.mask |= LVIF_INDENT;
    if (doLabel) lvItem.mask |= LVIF_TEXT;
    lvItem.iItem = nItem;
    lvItem.iSubItem = 0;
    lvItem.pszText = szDispText;
    lvItem.cchTextMax = DISP_TEXT_SIZE;
    if (lvItem.mask && !LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE;
    /* we got the state already up, simulate it here, to avoid a reget */
    if (uView == LVS_ICON && (lprc->left != LVIR_ICON))
    {
	lvItem.mask |= LVIF_STATE;
	lvItem.stateMask = LVIS_FOCUSED;
	lvItem.state = (oversizedBox ? LVIS_FOCUSED : 0);
    }

    if (uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT) && lprc->left == LVIR_SELECTBOUNDS)
	lprc->left = LVIR_BOUNDS;
    switch(lprc->left)
    {
    case LVIR_ICON:
	if (!LISTVIEW_GetItemMetrics(infoPtr, &lvItem, NULL, NULL, lprc, NULL)) return FALSE;
        break;

    case LVIR_LABEL:
	if (!LISTVIEW_GetItemMetrics(infoPtr, &lvItem, NULL, NULL, NULL, lprc)) return FALSE;
        break;

    case LVIR_BOUNDS:
	if (!LISTVIEW_GetItemMetrics(infoPtr, &lvItem, lprc, NULL, NULL, NULL)) return FALSE;
        break;

    case LVIR_SELECTBOUNDS:
	if (!LISTVIEW_GetItemMetrics(infoPtr, &lvItem, NULL, NULL, lprc, &label_rect)) return FALSE;
	UnionRect(lprc, lprc, &label_rect);
        break;

    default:
	WARN("Unknown value: %d\n", lprc->left);
	return FALSE;
    }

    OffsetRect(lprc, Position.x + Origin.x, Position.y + Origin.y);

    TRACE(" rect=%s\n", debugrect(lprc));

    return TRUE;
}

/***
 * DESCRIPTION:
 * Retrieves the spacing between listview control items.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [IO] lprc : rectangle to receive the output
 *             on input, lprc->top = nSubItem
 *                       lprc->left = LVIR_ICON | LVIR_BOUNDS | LVIR_LABEL
 * 
 * NOTE: for subItem = 0, we should return the bounds of the _entire_ item,
 *       not only those of the first column.
 *       Fortunately, LISTVIEW_GetItemMetrics does the right thing.
 * 
 * RETURN:
 *     TRUE: success
 *     FALSE: failure
 */
static BOOL LISTVIEW_GetSubItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc)
{
    POINT Position, Origin;
    LVITEMW lvItem;
    
    if (!lprc || (infoPtr->dwStyle & LVS_TYPEMASK) != LVS_REPORT) return FALSE;
    
    TRACE("(nItem=%d, nSubItem=%d)\n", nItem, lprc->top);

    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE;
    if (!LISTVIEW_GetItemPosition(infoPtr, nItem, &Position)) return FALSE;

    lvItem.mask = lprc->top == 0 ? LVIF_INDENT : 0;
    lvItem.iItem = nItem;
    lvItem.iSubItem = lprc->top;
    
    if (lvItem.mask && !LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE;
    switch(lprc->left)
    {
    case LVIR_ICON:
	if (!LISTVIEW_GetItemMetrics(infoPtr, &lvItem, NULL, NULL, lprc, NULL)) return FALSE;
        break;

    case LVIR_LABEL:
    case LVIR_BOUNDS:
	if (!LISTVIEW_GetItemMetrics(infoPtr, &lvItem, lprc, NULL, NULL, NULL)) return FALSE;
        break;

    default:
	ERR("Unknown bounds=%d\n", lprc->left);
	return FALSE;
    }

    OffsetRect(lprc, Position.x + Origin.x, Position.y + Origin.y);
    return TRUE;
}


/***
 * DESCRIPTION:
 * Retrieves the width of a label.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 *   SUCCESS : string width (in pixels)
 *   FAILURE : zero
 */
static INT LISTVIEW_GetLabelWidth(LISTVIEW_INFO *infoPtr, INT nItem)
{
    WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
    LVITEMW lvItem;

    TRACE("(nItem=%d)\n", nItem);

    lvItem.mask = LVIF_TEXT;
    lvItem.iItem = nItem;
    lvItem.iSubItem = 0;
    lvItem.pszText = szDispText;
    lvItem.cchTextMax = DISP_TEXT_SIZE;
    if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return 0;
  
    return LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE);
}

/***
 * DESCRIPTION:
 * Retrieves the spacing between listview control items.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] BOOL : flag for small or large icon
 *
 * RETURN:
 * Horizontal + vertical spacing
 */
static LRESULT LISTVIEW_GetItemSpacing(LISTVIEW_INFO *infoPtr, BOOL bSmall)
{
  LONG lResult;

  if (!bSmall)
  {
    lResult = MAKELONG(infoPtr->iconSpacing.cx, infoPtr->iconSpacing.cy);
  }
  else
  {
    if ((infoPtr->dwStyle & LVS_TYPEMASK) == LVS_ICON)
      lResult = MAKELONG(DEFAULT_COLUMN_WIDTH, GetSystemMetrics(SM_CXSMICON)+HEIGHT_PADDING);
    else
      lResult = MAKELONG(infoPtr->nItemWidth, infoPtr->nItemHeight);
  }
  return lResult;
}

/***
 * DESCRIPTION:
 * Retrieves the state of a listview control item.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nItem : item index
 * [I] uMask : state mask
 *
 * RETURN:
 * State specified by the mask.
 */
static LRESULT LISTVIEW_GetItemState(LISTVIEW_INFO *infoPtr, INT nItem, UINT uMask)
{
    LVITEMW lvItem;

    if (nItem < 0 || nItem >= infoPtr->nItemCount) return 0;

    lvItem.iItem = nItem;
    lvItem.iSubItem = 0;
    lvItem.mask = LVIF_STATE;
    lvItem.stateMask = uMask;
    if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return 0;

    return lvItem.state & uMask;
}

/***
 * DESCRIPTION:
 * Retrieves the text of a listview control item or subitem.
 *
 * PARAMETER(S):
 * [I] hwnd : window handle
 * [I] nItem : item index
 * [IO] lpLVItem : item information
 * [I] isW :  TRUE if lpLVItem is Unicode
 *
 * RETURN:
 *   SUCCESS : string length
 *   FAILURE : 0
 */
static LRESULT LISTVIEW_GetItemTextT(LISTVIEW_INFO *infoPtr, INT nItem, LPLVITEMW lpLVItem, BOOL isW)
{
    if (!lpLVItem || nItem < 0 || nItem >= infoPtr->nItemCount) return 0;

    lpLVItem->mask = LVIF_TEXT;
    lpLVItem->iItem = nItem;
    if (!LISTVIEW_GetItemExtT(infoPtr, lpLVItem, isW)) return 0;

    return textlenT(lpLVItem->pszText, isW);
}

/***
 * DESCRIPTION:
 * Searches for an item based on properties + relationships.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nItem : item index
 * [I] uFlags : relationship flag
 *
 * FIXME:
 *   This function is very, very inefficient! Needs work.
 * 
 * RETURN:
 *   SUCCESS : item index
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_GetNextItem(LISTVIEW_INFO *infoPtr, INT nItem, UINT uFlags)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    UINT uMask = 0;
    LVFINDINFOW lvFindInfo;
    INT nCountPerColumn;
    INT i;

    TRACE("nItem=%d, uFlags=%x, nItemCount=%d\n", nItem, uFlags, infoPtr->nItemCount);
    if (nItem < -1 || nItem >= infoPtr->nItemCount) return -1;

    ZeroMemory(&lvFindInfo, sizeof(lvFindInfo));

    if (uFlags & LVNI_CUT)
      uMask |= LVIS_CUT;

    if (uFlags & LVNI_DROPHILITED)
      uMask |= LVIS_DROPHILITED;

    if (uFlags & LVNI_FOCUSED)
      uMask |= LVIS_FOCUSED;

    if (uFlags & LVNI_SELECTED)
      uMask |= LVIS_SELECTED;

    /* if we're asked for the focused item, that's only one, 
     * so it's worth optimizing */
    if (uFlags & LVNI_FOCUSED)
    {
	if (!(LISTVIEW_GetItemState(infoPtr, infoPtr->nFocusedItem, uMask) & uMask) == uMask) return -1;
	return (infoPtr->nFocusedItem == nItem) ? -1 : infoPtr->nFocusedItem;
    }
    
    if (uFlags & LVNI_ABOVE)
    {
      if ((uView == LVS_LIST) || (uView == LVS_REPORT))
      {
        while (nItem >= 0)
        {
          nItem--;
          if ((ListView_GetItemState(infoPtr->hwndSelf, nItem, uMask) & uMask) == uMask)
            return nItem;
        }
      }
      else
      {
        lvFindInfo.flags = LVFI_NEARESTXY;
        lvFindInfo.vkDirection = VK_UP;
        ListView_GetItemPosition(infoPtr->hwndSelf, nItem, &lvFindInfo.pt);
        while ((nItem = ListView_FindItemW(infoPtr->hwndSelf, nItem, &lvFindInfo)) != -1)
        {
          if ((ListView_GetItemState(infoPtr->hwndSelf, nItem, uMask) & uMask) == uMask)
            return nItem;
        }
      }
    }
    else if (uFlags & LVNI_BELOW)
    {
      if ((uView == LVS_LIST) || (uView == LVS_REPORT))
      {
        while (nItem < infoPtr->nItemCount)
        {
          nItem++;
          if ((LISTVIEW_GetItemState(infoPtr, nItem, uMask) & uMask) == uMask)
            return nItem;
        }
      }
      else
      {
        lvFindInfo.flags = LVFI_NEARESTXY;
        lvFindInfo.vkDirection = VK_DOWN;
        ListView_GetItemPosition(infoPtr->hwndSelf, nItem, &lvFindInfo.pt);
        while ((nItem = ListView_FindItemW(infoPtr->hwndSelf, nItem, &lvFindInfo)) != -1)
        {
          if ((LISTVIEW_GetItemState(infoPtr, nItem, uMask) & uMask) == uMask)
            return nItem;
        }
      }
    }
    else if (uFlags & LVNI_TOLEFT)
    {
      if (uView == LVS_LIST)
      {
        nCountPerColumn = LISTVIEW_GetCountPerColumn(infoPtr);
        while (nItem - nCountPerColumn >= 0)
        {
          nItem -= nCountPerColumn;
          if ((LISTVIEW_GetItemState(infoPtr, nItem, uMask) & uMask) == uMask)
            return nItem;
        }
      }
      else if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
      {
        lvFindInfo.flags = LVFI_NEARESTXY;
        lvFindInfo.vkDirection = VK_LEFT;
        ListView_GetItemPosition(infoPtr->hwndSelf, nItem, &lvFindInfo.pt);
        while ((nItem = ListView_FindItemW(infoPtr->hwndSelf, nItem, &lvFindInfo)) != -1)
        {
          if ((ListView_GetItemState(infoPtr->hwndSelf, nItem, uMask) & uMask) == uMask)
            return nItem;
        }
      }
    }
    else if (uFlags & LVNI_TORIGHT)
    {
      if (uView == LVS_LIST)
      {
        nCountPerColumn = LISTVIEW_GetCountPerColumn(infoPtr);
        while (nItem + nCountPerColumn < infoPtr->nItemCount)
        {
          nItem += nCountPerColumn;
          if ((ListView_GetItemState(infoPtr->hwndSelf, nItem, uMask) & uMask) == uMask)
            return nItem;
        }
      }
      else if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
      {
        lvFindInfo.flags = LVFI_NEARESTXY;
        lvFindInfo.vkDirection = VK_RIGHT;
        ListView_GetItemPosition(infoPtr->hwndSelf, nItem, &lvFindInfo.pt);
        while ((nItem = ListView_FindItemW(infoPtr->hwndSelf, nItem, &lvFindInfo)) != -1)
        {
          if ((LISTVIEW_GetItemState(infoPtr, nItem, uMask) & uMask) == uMask)
            return nItem;
        }
      }
    }
    else
    {
      nItem++;

      /* search by index */
      for (i = nItem; i < infoPtr->nItemCount; i++)
      {
        if ((LISTVIEW_GetItemState(infoPtr, i, uMask) & uMask) == uMask)
          return i;
      }
    }

    return -1;
}

/* LISTVIEW_GetNumberOfWorkAreas */

/***
 * DESCRIPTION:
 * Retrieves the origin coordinates when in icon or small icon display mode.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [O] lpptOrigin : coordinate information
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_GetOrigin(LISTVIEW_INFO *infoPtr, LPPOINT lpptOrigin)
{
    DWORD lStyle = infoPtr->dwStyle;
    UINT uView = lStyle & LVS_TYPEMASK;
    INT nHorzPos = 0, nVertPos = 0;
    SCROLLINFO scrollInfo;

    if (!lpptOrigin) return FALSE;

    scrollInfo.cbSize = sizeof(SCROLLINFO);    
    scrollInfo.fMask = SIF_POS;
    
    if ((lStyle & WS_HSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo))
	nHorzPos = scrollInfo.nPos;
    if ((lStyle & WS_VSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo))
	nVertPos = scrollInfo.nPos;

    TRACE("nHorzPos=%d, nVertPos=%d\n", nHorzPos, nVertPos);

    lpptOrigin->x = infoPtr->rcList.left;
    lpptOrigin->y = infoPtr->rcList.top;
    if (uView == LVS_LIST)
	nHorzPos *= infoPtr->nItemWidth;
    else if (uView == LVS_REPORT)
	nVertPos *= infoPtr->nItemHeight;
    
    lpptOrigin->x -= nHorzPos;
    lpptOrigin->y -= nVertPos;

    TRACE(" origin=%s\n", debugpoint(lpptOrigin));

    return TRUE;
}

/***
 * DESCRIPTION:
 * Retrieves the width of a string.
 *
 * PARAMETER(S):
 * [I] hwnd : window handle
 * [I] lpszText : text string to process
 * [I] isW : TRUE if lpszText is Unicode, FALSE otherwise
 *
 * RETURN:
 *   SUCCESS : string width (in pixels)
 *   FAILURE : zero
 */
static LRESULT LISTVIEW_GetStringWidthT(LISTVIEW_INFO *infoPtr, LPCWSTR lpszText, BOOL isW)
{
    SIZE stringSize;
    
    stringSize.cx = 0;    
    if (is_textT(lpszText, isW))
    {
    	HFONT hFont = infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont;
    	HDC hdc = GetDC(infoPtr->hwndSelf);
    	HFONT hOldFont = SelectObject(hdc, hFont);

    	if (isW)
  	    GetTextExtentPointW(hdc, lpszText, lstrlenW(lpszText), &stringSize);
    	else
  	    GetTextExtentPointA(hdc, (LPCSTR)lpszText, lstrlenA((LPCSTR)lpszText), &stringSize);
    	SelectObject(hdc, hOldFont);
    	ReleaseDC(infoPtr->hwndSelf, hdc);
    }
    return stringSize.cx;
}

/***
 * DESCRIPTION:
 * Determines which listview item is located at the specified position.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [IO] lpht : hit test information
 * [I] subitem : fill out iSubItem.
 * [I] select : return the index only if the hit selects the item
 *
 * NOTE:
 * (mm 20001022): We must not allow iSubItem to be touched, for
 * an app might pass only a structure with space up to iItem!
 * (MS Office 97 does that for instance in the file open dialog)
 * 
 * RETURN:
 *   SUCCESS : item index
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_HitTest(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpht, BOOL subitem, BOOL select)
{
    WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    RECT rcBox, rcBounds, rcState, rcIcon, rcLabel, rcSearch;
    POINT Origin, Position, opt;
    LVITEMW lvItem;
    ITERATOR i;
    
    TRACE("(pt=%s, subitem=%d, select=%d)\n", debugpoint(&lpht->pt), subitem, select);
    
    lpht->flags = 0;
    lpht->iItem = -1;
    if (subitem) lpht->iSubItem = 0;

    if (infoPtr->rcList.left > lpht->pt.x)
	lpht->flags |= LVHT_TOLEFT;
    else if (infoPtr->rcList.right < lpht->pt.x)
	lpht->flags |= LVHT_TORIGHT;
    
    if (infoPtr->rcList.top > lpht->pt.y)
	lpht->flags |= LVHT_ABOVE;
    else if (infoPtr->rcList.bottom < lpht->pt.y)
	lpht->flags |= LVHT_BELOW;

    TRACE("lpht->flags=0x%x\n", lpht->flags);
    if (lpht->flags) return -1;

    lpht->flags |= LVHT_NOWHERE;

    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return -1;
   
    /* first deal with the large items */
    rcSearch.left = lpht->pt.x;
    rcSearch.top = lpht->pt.y;
    rcSearch.right = rcSearch.left + 1;
    rcSearch.bottom = rcSearch.top + 1;
    
    iterator_frameditems(&i, infoPtr, &rcSearch);
    iterator_next(&i); /* go to first item in the sequence */
    lpht->iItem = i.nItem;
    iterator_destroy(&i);
   
    TRACE("lpht->iItem=%d\n", lpht->iItem); 
    if (lpht->iItem == -1) return -1;

    lvItem.mask = LVIF_STATE | LVIF_TEXT;
    if (uView == LVS_REPORT) lvItem.mask |= LVIF_INDENT;
    lvItem.stateMask = LVIS_STATEIMAGEMASK;
    if (uView == LVS_ICON) lvItem.stateMask |= LVIS_FOCUSED;
    lvItem.iItem = lpht->iItem;
    lvItem.iSubItem = 0;
    lvItem.pszText = szDispText;
    lvItem.cchTextMax = DISP_TEXT_SIZE;
    if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return -1;
    if (!infoPtr->bFocus) lvItem.state &= ~LVIS_FOCUSED; 
    
    if (!LISTVIEW_GetItemMetrics(infoPtr, &lvItem, &rcBox, &rcState, &rcIcon, &rcLabel)) return -1;
    if (!LISTVIEW_GetItemOrigin(infoPtr, lpht->iItem, &Position)) return -1;
    opt.x = lpht->pt.x - Position.x - Origin.x;
    opt.y = lpht->pt.y - Position.y - Origin.y;
    
    if (uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
	rcBounds = rcBox;
    else
	UnionRect(&rcBounds, &rcIcon, &rcLabel);
    TRACE("rcBounds=%s\n", debugrect(&rcBounds));
    if (!PtInRect(&rcBounds, opt)) return -1;

    if (PtInRect(&rcIcon, opt))
	lpht->flags |= LVHT_ONITEMICON;
    else if (PtInRect(&rcLabel, opt))
	lpht->flags |= LVHT_ONITEMLABEL;
    else if (infoPtr->himlState && ((lvItem.state & LVIS_STATEIMAGEMASK) >> 12) && PtInRect(&rcState, opt))
	lpht->flags |= LVHT_ONITEMSTATEICON;
    if (lpht->flags & LVHT_ONITEM)
	lpht->flags &= ~LVHT_NOWHERE;
   
    TRACE("lpht->flags=0x%x\n", lpht->flags); 
    if (uView == LVS_REPORT && lpht->iItem != -1 && subitem)
    {
  	INT j;

        rcBounds.right = rcBounds.left;
        for (j = 0; j < infoPtr->hdpaColumns->nItemCount; j++)
        {
	    rcBounds.left = rcBounds.right;
	    rcBounds.right += LISTVIEW_GetColumnWidth(infoPtr, j);
	    if (PtInRect(&rcBounds, opt))
	    {
		lpht->iSubItem = j;
		break;
	    }
	}
    }

    if (!select || lpht->iItem == -1) return lpht->iItem;

    if (uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) return lpht->iItem;
    
    if (uView == LVS_REPORT) UnionRect(&rcBounds, &rcIcon, &rcLabel);
    return PtInRect(&rcBounds, opt) ? lpht->iItem : -1;
}


/***
 * DESCRIPTION:
 * Inserts a new column.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : column index
 * [I] LPLVCOLUMNW : column information
 *
 * RETURN:
 *   SUCCESS : new column index
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
                                      LPLVCOLUMNW lpColumn, BOOL isW)
{
    COLUMN_INFO *lpColumnInfo = NULL;
    RECT rcCol;
    INT nNewColumn;
    HDITEMW hdi;

    TRACE("(nColumn=%d, lpColumn=%s, isW=%d)\n", nColumn, debuglvcolumn_t(lpColumn, isW), isW);

    if (!lpColumn) return -1;

    hdi.mask = hdi.fmt = 0;
    if (lpColumn->mask & LVCF_FMT)
    {
	/* format member is valid */
	hdi.mask |= HDI_FORMAT;

	/* set text alignment (leftmost column must be left-aligned) */
        if (nColumn == 0 || lpColumn->fmt & LVCFMT_LEFT)
            hdi.fmt |= HDF_LEFT;
        else if (lpColumn->fmt & LVCFMT_RIGHT)
            hdi.fmt |= HDF_RIGHT;
        else if (lpColumn->fmt & LVCFMT_CENTER)
            hdi.fmt |= HDF_CENTER;

        if (lpColumn->fmt & LVCFMT_BITMAP_ON_RIGHT)
            hdi.fmt |= HDF_BITMAP_ON_RIGHT;

        if (lpColumn->fmt & LVCFMT_COL_HAS_IMAGES)
        {
            hdi.fmt |= HDF_IMAGE;
            hdi.iImage = I_IMAGECALLBACK;
        }
    }

    if (lpColumn->mask & LVCF_WIDTH)
    {
        hdi.mask |= HDI_WIDTH;
        if(lpColumn->cx == LVSCW_AUTOSIZE_USEHEADER)
        {
            /* make it fill the remainder of the controls width */
            RECT rcHeader;
            INT item_index;

            for(item_index = 0; item_index < (nColumn - 1); item_index++)
            	if (LISTVIEW_GetHeaderRect(infoPtr, item_index, &rcHeader))
		    hdi.cxy += rcHeader.right - rcHeader.left;

            /* retrieve the layout of the header */
            GetClientRect(infoPtr->hwndSelf, &rcHeader);
            TRACE("start cxy=%d rcHeader=%s\n", hdi.cxy, debugrect(&rcHeader));

            hdi.cxy = (rcHeader.right - rcHeader.left) - hdi.cxy;
        }
        else
            hdi.cxy = lpColumn->cx;
    }

    if (lpColumn->mask & LVCF_TEXT)
    {
        hdi.mask |= HDI_TEXT | HDI_FORMAT;
        hdi.fmt |= HDF_STRING;
        hdi.pszText = lpColumn->pszText;
        hdi.cchTextMax = textlenT(lpColumn->pszText, isW);
    }

    if (lpColumn->mask & LVCF_IMAGE)
    {
        hdi.mask |= HDI_IMAGE;
        hdi.iImage = lpColumn->iImage;
    }

    if (lpColumn->mask & LVCF_ORDER)
    {
	hdi.mask |= HDI_ORDER;
	hdi.iOrder = lpColumn->iOrder;
    }

    /* insert item in header control */
    nNewColumn = SendMessageW(infoPtr->hwndHeader, 
		              isW ? HDM_INSERTITEMW : HDM_INSERTITEMA,
                              (WPARAM)nColumn, (LPARAM)&hdi);
    if (nNewColumn == -1) return -1;
   
    /* create our own column info */ 
    if (!(lpColumnInfo = COMCTL32_Alloc(sizeof(COLUMN_INFO)))) goto fail;
    if (DPA_InsertPtr(infoPtr->hdpaColumns, nNewColumn, lpColumnInfo) == -1) goto fail;
    if (!Header_GetItemRect(infoPtr->hwndHeader, nNewColumn, &rcCol)) goto fail;    
    lpColumnInfo->rcHeader = rcCol;
    if (lpColumn->mask & LVCF_FMT)
    {
        if (nColumn == 0 || lpColumn->fmt & LVCFMT_LEFT) lpColumnInfo->align = DT_LEFT;
        else if (lpColumn->fmt & LVCFMT_RIGHT) lpColumnInfo->align = DT_RIGHT;
        else if (lpColumn->fmt & LVCFMT_CENTER) lpColumnInfo->align = DT_CENTER;
	
        if (lpColumn->fmt & LVCFMT_IMAGE) lpColumnInfo->hasImage = TRUE;
    } 
    else
    {
	lpColumnInfo->align = DT_LEFT;
	lpColumnInfo->hasImage = (nColumn == 0);
    }
   
    /* now we have to actually adjust the data */
    if (!(infoPtr->dwStyle & LVS_OWNERDATA) && infoPtr->nItemCount > 0)
    {
	LISTVIEW_SUBITEM *lpSubItem, *lpMainItem, **lpNewItems = 0;
	HDPA hdpaSubItems;
	INT nItem, i;
	
	/* preallocate memory, so we can fail gracefully */
	if (nNewColumn == 0)
	{
	    lpNewItems = COMCTL32_Alloc(sizeof(LISTVIEW_SUBITEM *) * infoPtr->nItemCount);
	    if (!lpNewItems) goto fail;
	    for (i = 0; i < infoPtr->nItemCount; i++)
		if (!(lpNewItems[i] = COMCTL32_Alloc(sizeof(LISTVIEW_SUBITEM)))) break;
	    if (i != infoPtr->nItemCount)
	    {
		for(; i >=0; i--) COMCTL32_Free(lpNewItems[i]);
		COMCTL32_Free(lpNewItems);
		goto fail;
	    }
	}
	
	for (nItem = 0; nItem < infoPtr->nItemCount; nItem++)
	{
	    hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
	    if (!hdpaSubItems) continue;
	    for (i = 1; i < hdpaSubItems->nItemCount; i++)
	    {
		lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
		if (!lpSubItem) break;
		if (lpSubItem->iSubItem >= nNewColumn)
		    lpSubItem->iSubItem++;
	    }

	    /* if we found our subitem, zapp it */	
	    if (nNewColumn == 0)
	    {
		lpMainItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, 0);
		lpSubItem = lpNewItems[nItem];
		lpSubItem->hdr = lpMainItem->hdr;
		lpSubItem->iSubItem = 1;
		ZeroMemory(&lpMainItem->hdr, sizeof(lpMainItem->hdr));
		lpMainItem->iSubItem = 0;
		DPA_InsertPtr(hdpaSubItems, 1, lpSubItem);
    	    }
	}

	COMCTL32_Free(lpNewItems);
    }

    /* make space for the new column */
    LISTVIEW_ScrollColumns(infoPtr, nNewColumn + 1, rcCol.right - rcCol.left);
    
    return nNewColumn;

fail:
    if (nNewColumn != -1) SendMessageW(infoPtr->hwndHeader, HDM_DELETEITEM, nNewColumn, 0);
    if (lpColumnInfo)
    {
	DPA_DeletePtr(infoPtr->hdpaColumns, nNewColumn);
	COMCTL32_Free(lpColumnInfo);
    }
    return -1;
}

/* LISTVIEW_InsertCompare:  callback routine for comparing pszText members of the LV_ITEMS
   in a LISTVIEW on insert.  Passed to DPA_Sort in LISTVIEW_InsertItem.
   This function should only be used for inserting items into a sorted list (LVM_INSERTITEM)
   and not during the processing of a LVM_SORTITEMS message. Applications should provide
   their own sort proc. when sending LVM_SORTITEMS.
*/
/* Platform SDK:
    (remarks on LVITEM: LVM_INSERTITEM will insert the new item in the proper sort postion...
        if:
          LVS_SORTXXX must be specified,
          LVS_OWNERDRAW is not set,
          <item>.pszText is not LPSTR_TEXTCALLBACK.

    (LVS_SORT* flags): "For the LVS_SORTASCENDING... styles, item indices
    are sorted based on item text..."
*/
static INT WINAPI LISTVIEW_InsertCompare(  LPVOID first, LPVOID second,  LPARAM lParam)
{
    LISTVIEW_ITEM* lv_first = (LISTVIEW_ITEM*) DPA_GetPtr( (HDPA)first, 0 );
    LISTVIEW_ITEM* lv_second = (LISTVIEW_ITEM*) DPA_GetPtr( (HDPA)second, 0 );
    INT cmpv = textcmpWT(lv_first->hdr.pszText, lv_second->hdr.pszText, TRUE); 

    /* if we're sorting descending, negate the return value */
    return (((LISTVIEW_INFO *)lParam)->dwStyle & LVS_SORTDESCENDING) ? -cmpv : cmpv;
}

/***
 * nESCRIPTION:
 * Inserts a new item in the listview control.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] lpLVItem : item information
 * [I] isW : TRUE if lpLVItem is Unicode, FALSE if it's ANSI
 *
 * RETURN:
 *   SUCCESS : new item index
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW)
{
    LONG lStyle = infoPtr->dwStyle;
    UINT uView = lStyle & LVS_TYPEMASK;
    INT nItem = -1;
    HDPA hdpaSubItems;
    NMLISTVIEW nmlv;
    LISTVIEW_ITEM *lpItem;
    BOOL is_sorted, has_changed;

    TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW);

    if (lStyle & LVS_OWNERDATA)
    {
	nItem = infoPtr->nItemCount;
	infoPtr->nItemCount++;
	return nItem;
    }

    /* make sure it's an item, and not a subitem; cannot insert a subitem */
    if (!lpLVItem || lpLVItem->iItem < 0 || lpLVItem->iSubItem) return -1;

    if (!is_assignable_item(lpLVItem, lStyle)) return -1;

    if ( !(lpItem = (LISTVIEW_ITEM *)COMCTL32_Alloc(sizeof(LISTVIEW_ITEM))) )
	return -1;
    
    /* insert item in listview control data structure */
    if ( (hdpaSubItems = DPA_Create(8)) )
	nItem = DPA_InsertPtr(hdpaSubItems, 0, lpItem);
    if (nItem == -1) goto fail;

    /* FIXME: is the handling of this LVS_OWNERDRAWFIXED correct? */
    is_sorted = (lStyle & (LVS_SORTASCENDING | LVS_SORTDESCENDING)) &&
	        !(lStyle & LVS_OWNERDRAWFIXED) && (LPSTR_TEXTCALLBACKW != lpLVItem->pszText);

    nItem = DPA_InsertPtr( infoPtr->hdpaItems, 
		           is_sorted ? infoPtr->nItemCount + 1 : lpLVItem->iItem, 
			   hdpaSubItems );
    if (nItem == -1) goto fail;
    /* the array may be sparsly populated, we can't just increment the count here */
    infoPtr->nItemCount = infoPtr->hdpaItems->nItemCount;
  
    /* set the item attributes */ 
    if (!set_main_item(infoPtr, lpLVItem, TRUE, isW, &has_changed)) goto undo;

    /* if we're sorted, sort the list, and update the index */
    if (is_sorted)
    {
	DPA_Sort( infoPtr->hdpaItems, LISTVIEW_InsertCompare, (LPARAM)infoPtr );
	nItem = DPA_GetPtrIndex( infoPtr->hdpaItems, hdpaSubItems );
	assert(nItem != -1);
    }

    /* make room for the position, if we are in the right mode */
    if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
    {
        if (DPA_InsertPtr(infoPtr->hdpaPosX, nItem, 0) == -1)
	    goto undo;
        if (DPA_InsertPtr(infoPtr->hdpaPosY, nItem, 0) == -1)
	{
	    DPA_DeletePtr(infoPtr->hdpaPosX, nItem);
	    goto undo;
	}
    }
    
    /* Add the subitem list to the items array. Do this last in case we go to
     * fail during the above.
     */
    LISTVIEW_ShiftIndices(infoPtr, nItem, 1);
    
    /* send LVN_INSERTITEM notification */
    ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
    nmlv.iItem = nItem;
    nmlv.lParam = lpItem->lParam;
    notify_listview(infoPtr, LVN_INSERTITEM, &nmlv);

    /* align items (set position of each item) */
    if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
    {
	if (lStyle & LVS_ALIGNLEFT) LISTVIEW_AlignLeft(infoPtr);
        else LISTVIEW_AlignTop(infoPtr);
    }

    LISTVIEW_UpdateScroll(infoPtr);
    
    LISTVIEW_InvalidateList(infoPtr); /* FIXME: optimize */

    TRACE("    <- %d\n", nItem);
    return nItem;

undo:
    DPA_DeletePtr(infoPtr->hdpaItems, nItem);
    infoPtr->nItemCount--;
fail:
    DPA_DeletePtr(hdpaSubItems, 0);
    DPA_Destroy (hdpaSubItems);
    COMCTL32_Free (lpItem);
    return -1;
}

/***
 * DESCRIPTION:
 * Redraws a range of items.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : first item
 * [I] INT : last item
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_RedrawItems(LISTVIEW_INFO *infoPtr, INT nFirst, INT nLast)
{
    INT i;
 
    if (nLast < nFirst || min(nFirst, nLast) < 0 || 
	max(nFirst, nLast) >= infoPtr->nItemCount)
	return FALSE;
    
    for (i = nFirst; i <= nLast; i++)
	LISTVIEW_InvalidateItem(infoPtr, i);

    return TRUE;
}

/***
 * DESCRIPTION:
 * Scroll the content of a listview.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : horizontal scroll amount in pixels
 * [I] INT : vertical scroll amount in pixels
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 *
 * COMMENTS:
 *  If the control is in report mode (LVS_REPORT) the control can
 *  be scrolled only in line increments. "dy" will be rounded to the
 *  nearest number of pixels that are a whole line. Ex: if line height
 *  is 16 and an 8 is passed, the list will be scrolled by 16. If a 7
 *  is passed the the scroll will be 0.  (per MSDN 7/2002)
 *
 *  For:  (per experimentaion with native control and CSpy ListView)
 *     LVS_ICON       dy=1 = 1 pixel  (vertical only)
 *                    dx ignored
 *     LVS_SMALLICON  dy=1 = 1 pixel  (vertical only)
 *                    dx ignored
 *     LVS_LIST       dx=1 = 1 column (horizontal only)
 *                           but will only scroll 1 column per message
 *                           no matter what the value.
 *                    dy must be 0 or FALSE returned.
 *     LVS_REPORT     dx=1 = 1 pixel
 *                    dy=  see above
 *
 */
static LRESULT LISTVIEW_Scroll(LISTVIEW_INFO *infoPtr, INT dx, INT dy)
{
    switch(infoPtr->dwStyle & LVS_TYPEMASK) {
    case LVS_REPORT:
	dy += (dy < 0 ? -1 : 1) * infoPtr->nItemHeight/2;
        dy /= infoPtr->nItemHeight;
	break;
    case LVS_LIST:
    	if (dy != 0) return FALSE;
	break;
    default: /* icon */
	dx = 0;
	break;
    }	

    if (dx != 0) LISTVIEW_HScroll(infoPtr, SB_INTERNAL, dx, 0);
    if (dy != 0) LISTVIEW_VScroll(infoPtr, SB_INTERNAL, dy, 0);
  
    return TRUE;
}

/***
 * DESCRIPTION:
 * Sets the background color.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] COLORREF : background color
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetBkColor(LISTVIEW_INFO *infoPtr, COLORREF clrBk)
{
    TRACE("(clrBk=%lx)\n", clrBk);

    if(infoPtr->clrBk != clrBk) {
	if (infoPtr->clrBk != CLR_NONE) DeleteObject(infoPtr->hBkBrush);
	infoPtr->clrBk = clrBk;
	if (clrBk == CLR_NONE)
	    infoPtr->hBkBrush = GetClassLongW(infoPtr->hwndSelf, GCL_HBRBACKGROUND);
	else
	    infoPtr->hBkBrush = CreateSolidBrush(clrBk);
	LISTVIEW_InvalidateList(infoPtr);
    }

   return TRUE;
}

/* LISTVIEW_SetBkImage */

/***
 * DESCRIPTION:
 * Sets the attributes of a header item.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : column index
 * [I] LPLVCOLUMNW : column attributes
 * [I] isW: if TRUE, the lpColumn is a LPLVCOLUMNW,
 *          otherwise it is in fact a LPLVCOLUMNA
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
                                   LPLVCOLUMNW lpColumn, BOOL isW)
{
  BOOL bResult = FALSE;
  HDITEMW hdi, hdiget;

  if ((lpColumn != NULL) && (nColumn >= 0) && (nColumn < infoPtr->hdpaColumns->nItemCount))
  {
    /* initialize memory */
    ZeroMemory(&hdi, sizeof(hdi));

    if (lpColumn->mask & LVCF_FMT)
    {
      /* format member is valid */
      hdi.mask |= HDI_FORMAT;

      /* get current format first */
      hdiget.mask = HDI_FORMAT;
      if (Header_GetItemW(infoPtr->hwndHeader, nColumn, &hdiget))
	      /* preserve HDF_STRING if present */
	      hdi.fmt = hdiget.fmt & HDF_STRING;

      /* set text alignment (leftmost column must be left-aligned) */
      if (nColumn == 0)
      {
        hdi.fmt |= HDF_LEFT;
      }
      else
      {
        if (lpColumn->fmt & LVCFMT_LEFT)
          hdi.fmt |= HDF_LEFT;
        else if (lpColumn->fmt & LVCFMT_RIGHT)
          hdi.fmt |= HDF_RIGHT;
        else if (lpColumn->fmt & LVCFMT_CENTER)
          hdi.fmt |= HDF_CENTER;
      }

      if (lpColumn->fmt & LVCFMT_BITMAP_ON_RIGHT)
        hdi.fmt |= HDF_BITMAP_ON_RIGHT;

      if (lpColumn->fmt & LVCFMT_COL_HAS_IMAGES)
        hdi.fmt |= HDF_IMAGE;

      if (lpColumn->fmt & LVCFMT_IMAGE)
      {
        hdi.fmt |= HDF_IMAGE;
        hdi.iImage = I_IMAGECALLBACK;
      }
    }

    if (lpColumn->mask & LVCF_WIDTH)
    {
      hdi.mask |= HDI_WIDTH;
      hdi.cxy = lpColumn->cx;
    }

    if (lpColumn->mask & LVCF_TEXT)
    {
      hdi.mask |= HDI_TEXT | HDI_FORMAT;
      hdi.pszText = lpColumn->pszText;
      hdi.cchTextMax = textlenT(lpColumn->pszText, isW);
      hdi.fmt |= HDF_STRING;
    }

    if (lpColumn->mask & LVCF_IMAGE)
    {
      hdi.mask |= HDI_IMAGE;
      hdi.iImage = lpColumn->iImage;
    }

    if (lpColumn->mask & LVCF_ORDER)
    {
      hdi.mask |= HDI_ORDER;
      hdi.iOrder = lpColumn->iOrder;
    }

    /* set header item attributes */
    if (isW)
      bResult = Header_SetItemW(infoPtr->hwndHeader, nColumn, &hdi);
    else
      bResult = Header_SetItemA(infoPtr->hwndHeader, nColumn, &hdi);
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Sets the column order array
 *
 * PARAMETERS:
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : number of elements in column order array
 * [I] INT : pointer to column order array
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetColumnOrderArray(LISTVIEW_INFO *infoPtr, INT iCount, LPINT lpiArray)
{
  FIXME("iCount %d lpiArray %p\n", iCount, lpiArray);

  if (!lpiArray)
    return FALSE;

  return TRUE;
}


/***
 * DESCRIPTION:
 * Sets the width of a column
 *
 * PARAMETERS:
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : column index
 * [I] INT : column width
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetColumnWidth(LISTVIEW_INFO *infoPtr, INT iCol, INT cx)
{
    HDITEMW hdi;
    LRESULT lret;
    LONG lStyle = infoPtr->dwStyle;
    UINT uView = lStyle & LVS_TYPEMASK;
    HDC hdc;
    HFONT header_font;
    HFONT old_font;
    SIZE size;
    WCHAR text_buffer[DISP_TEXT_SIZE];
    INT header_item_count;
    INT item_index;
    INT nLabelWidth;
    RECT rcHeader;
    LVITEMW lvItem;
    WCHAR szDispText[DISP_TEXT_SIZE] = { 0 };

    TRACE("(iCol=%d, cx=%d\n", iCol, cx);

    /* set column width only if in report or list mode */
    if (uView != LVS_REPORT && uView != LVS_LIST) return FALSE;

    /* take care of invalid cx values */
    if(uView == LVS_REPORT && cx < -2) cx = LVSCW_AUTOSIZE;
    else if (uView == LVS_LIST && cx < 1) return FALSE;

    /* resize all columns if in LVS_LIST mode */
    if(uView == LVS_LIST) 
    {
	infoPtr->nItemWidth = cx;
	LISTVIEW_InvalidateList(infoPtr);
	return TRUE;
    }

    /* autosize based on listview items width */
    if(cx == LVSCW_AUTOSIZE)
    {
      /* set the width of the column to the width of the widest item */
      if (iCol == 0 || uView == LVS_LIST)
      {
        cx = 0;
        for(item_index = 0; item_index < infoPtr->nItemCount; item_index++)
        {
          nLabelWidth = LISTVIEW_GetLabelWidth(infoPtr, item_index);
          cx = (nLabelWidth>cx)?nLabelWidth:cx;
        }
        if (infoPtr->himlSmall)
          cx += infoPtr->iconSize.cx + IMAGE_PADDING;
      }
      else
      {
        lvItem.iSubItem = iCol;
        lvItem.mask = LVIF_TEXT;
        lvItem.pszText = szDispText;
        lvItem.cchTextMax = DISP_TEXT_SIZE;
        cx = 0;
        for(item_index = 0; item_index < infoPtr->nItemCount; item_index++)
        {
          lvItem.iItem = item_index;
          if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) continue;
          nLabelWidth = LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE);
          cx = (nLabelWidth>cx)?nLabelWidth:cx;
        }
      }
      cx += TRAILING_PADDING;
    } /* autosize based on listview header width */
    else if(cx == LVSCW_AUTOSIZE_USEHEADER)
    {
      header_item_count = infoPtr->hdpaColumns->nItemCount;

      /* if iCol is the last column make it fill the remainder of the controls width */
      if(iCol == (header_item_count - 1)) {
        cx = 0;

        for(item_index = 0; item_index < (header_item_count - 1); item_index++) 
	{
	  if (LISTVIEW_GetHeaderRect(infoPtr, item_index, &rcHeader))
	    cx += rcHeader.right - rcHeader.left;
        }

        /* retrieve the layout of the header */
        GetWindowRect(infoPtr->hwndHeader, &rcHeader);

        cx = (rcHeader.right - rcHeader.left) - cx;
      }
      else
      {
        /* Despite what the MS docs say, if this is not the last
           column, then MS resizes the column to the width of the
           largest text string in the column, including headers
           and items. This is different from LVSCW_AUTOSIZE in that
           LVSCW_AUTOSIZE ignores the header string length.
           */

        /* retrieve header font */
        header_font = SendMessageW(infoPtr->hwndHeader, WM_GETFONT, 0L, 0L);

        /* retrieve header text */
        hdi.mask = HDI_TEXT;
        hdi.cchTextMax = sizeof(text_buffer)/sizeof(text_buffer[0]);
        hdi.pszText = text_buffer;

        Header_GetItemW(infoPtr->hwndHeader, iCol, (LPARAM)(&hdi));

        /* determine the width of the text in the header */
        hdc = GetDC(infoPtr->hwndSelf);
        old_font = SelectObject(hdc, header_font); /* select the font into hdc */

        GetTextExtentPoint32W(hdc, text_buffer, lstrlenW(text_buffer), &size);

        SelectObject(hdc, old_font); /* restore the old font */
        ReleaseDC(infoPtr->hwndSelf, hdc);

        lvItem.iSubItem = iCol;
        lvItem.mask = LVIF_TEXT;
        lvItem.pszText = szDispText;
        lvItem.cchTextMax = DISP_TEXT_SIZE;
        cx = size.cx;
        for(item_index = 0; item_index < infoPtr->nItemCount; item_index++)
        {
          lvItem.iItem = item_index;
          if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) continue;
          nLabelWidth = LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE);
          nLabelWidth += TRAILING_PADDING;
          /* While it is possible for subitems to have icons, even MS messes
             up the positioning, so I suspect no applications actually use
             them. */
          if (item_index == 0 && infoPtr->himlSmall)
            nLabelWidth += infoPtr->iconSize.cx + IMAGE_PADDING;
          cx = (nLabelWidth>cx)?nLabelWidth:cx;
        }
      }
  }

  /* call header to update the column change */
  hdi.mask = HDI_WIDTH;

  hdi.cxy = cx;
  lret = Header_SetItemW(infoPtr->hwndHeader, (WPARAM)iCol, (LPARAM)&hdi);

  LISTVIEW_InvalidateList(infoPtr); /* FIXME: optimize */

  return lret;
}

/***
 * DESCRIPTION:
 * Sets the extended listview style.
 *
 * PARAMETERS:
 * [I] infoPtr : valid pointer to the listview structure
 * [I] DWORD : mask
 * [I] DWORD : style
 *
 * RETURN:
 *   SUCCESS : previous style
 *   FAILURE : 0
 */
static LRESULT LISTVIEW_SetExtendedListViewStyle(LISTVIEW_INFO *infoPtr, DWORD dwMask, DWORD dwStyle)
{
  DWORD dwOldStyle = infoPtr->dwLvExStyle;

  /* set new style */
  if (dwMask)
    infoPtr->dwLvExStyle = (dwOldStyle & ~dwMask) | (dwStyle & dwMask);
  else
    infoPtr->dwLvExStyle = dwStyle;

  return dwOldStyle;
}

/***
 * DESCRIPTION:
 * Sets the new hot cursor used during hot tracking and hover selection.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I} hCurosr : the new hot cursor handle
 *
 * RETURN:
 * Returns the previous hot cursor
 */
static HCURSOR LISTVIEW_SetHotCursor(LISTVIEW_INFO *infoPtr, HCURSOR hCursor)
{
    HCURSOR oldCursor = infoPtr->hHotCursor;
    infoPtr->hHotCursor = hCursor;
    return oldCursor;
}


/***
 * DESCRIPTION:
 * Sets the hot item index.
 *
 * PARAMETERS:
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT   : index
 *
 * RETURN:
 *   SUCCESS : previous hot item index
 *   FAILURE : -1 (no hot item)
 */
static LRESULT LISTVIEW_SetHotItem(LISTVIEW_INFO *infoPtr, INT iIndex)
{
    INT iOldIndex = infoPtr->nHotItem;
    infoPtr->nHotItem = iIndex;
    return iOldIndex;
}


/***
 * DESCRIPTION:
 * Sets the amount of time the cursor must hover over an item before it is selected.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] DWORD : dwHoverTime, if -1 the hover time is set to the default
 *
 * RETURN:
 * Returns the previous hover time
 */
static LRESULT LISTVIEW_SetHoverTime(LISTVIEW_INFO *infoPtr, DWORD dwHoverTime)
{
    DWORD oldHoverTime = infoPtr->dwHoverTime;
    infoPtr->dwHoverTime = dwHoverTime;
    return oldHoverTime;
}

/***
 * DESCRIPTION:
 * Sets spacing for icons of LVS_ICON style.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] DWORD : MAKELONG(cx, cy)
 *
 * RETURN:
 *   MAKELONG(oldcx, oldcy)
 */
static LRESULT LISTVIEW_SetIconSpacing(LISTVIEW_INFO *infoPtr, DWORD spacing)
{
    INT cy = HIWORD(spacing), cx = LOWORD(spacing);
    DWORD oldspacing = MAKELONG(infoPtr->iconSpacing.cx, infoPtr->iconSpacing.cy);
    LONG lStyle = infoPtr->dwStyle;
    UINT uView = lStyle & LVS_TYPEMASK;

    TRACE("requested=(%d,%d)\n", cx, cy);
    
    /* this is supported only for LVS_ICON style */
    if (uView != LVS_ICON) return oldspacing;
  
    /* set to defaults, if instructed to */
    if (cx == -1) cx = GetSystemMetrics(SM_CXICONSPACING);
    if (cy == -1) cy = GetSystemMetrics(SM_CYICONSPACING);

    /* if 0 then compute width
     * FIXME: Should scan each item and determine max width of
     *        icon or label, then make that the width */
    if (cx == 0)
	cx = infoPtr->iconSpacing.cx;

    /* if 0 then compute height */
    if (cy == 0) 
	cy = infoPtr->iconSize.cy + 2 * infoPtr->ntmHeight +
	     ICON_BOTTOM_PADDING + ICON_TOP_PADDING + LABEL_VERT_PADDING;
    

    infoPtr->iconSpacing.cx = cx;
    infoPtr->iconSpacing.cy = cy;

    TRACE("old=(%d,%d), new=(%d,%d), iconSize=(%ld,%ld), ntmH=%d\n",
	  LOWORD(oldspacing), HIWORD(oldspacing), cx, cy, 
	  infoPtr->iconSize.cx, infoPtr->iconSize.cy,
	  infoPtr->ntmHeight);

    /* these depend on the iconSpacing */
    infoPtr->nItemWidth = LISTVIEW_CalculateMaxWidth(infoPtr);
    infoPtr->nItemHeight = LISTVIEW_CalculateMaxHeight(infoPtr);

    return oldspacing;
}

inline void update_icon_size(HIMAGELIST himl, BOOL small, SIZE *size)
{
    INT cx, cy;
    
    if (himl && ImageList_GetIconSize(himl, &cx, &cy))
    {
	size->cx = cx;
	size->cy = cy;
    }
    else
    {
	size->cx = GetSystemMetrics(small ? SM_CXSMICON : SM_CXICON);
	size->cy = GetSystemMetrics(small ? SM_CYSMICON : SM_CYICON);
    }
}

/***
 * DESCRIPTION:
 * Sets image lists.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : image list type
 * [I] HIMAGELIST : image list handle
 *
 * RETURN:
 *   SUCCESS : old image list
 *   FAILURE : NULL
 */
static HIMAGELIST LISTVIEW_SetImageList(LISTVIEW_INFO *infoPtr, INT nType, HIMAGELIST himl)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    INT oldHeight = infoPtr->nItemHeight;
    HIMAGELIST himlOld = 0;

    switch (nType)
    {
    case LVSIL_NORMAL:
        himlOld = infoPtr->himlNormal;
        infoPtr->himlNormal = himl;
        if (uView == LVS_ICON) update_icon_size(himl, FALSE, &infoPtr->iconSize);
        LISTVIEW_SetIconSpacing(infoPtr, 0);
    break;

    case LVSIL_SMALL:
        himlOld = infoPtr->himlSmall;
        infoPtr->himlSmall = himl;
         if (uView != LVS_ICON) update_icon_size(himl, TRUE, &infoPtr->iconSize);
    break;

    case LVSIL_STATE:
        himlOld = infoPtr->himlState;
        infoPtr->himlState = himl;
        update_icon_size(himl, TRUE, &infoPtr->iconStateSize);
        ImageList_SetBkColor(infoPtr->himlState, CLR_NONE);
    break;

    default:
        ERR("Unknown icon type=%d\n", nType);
	return NULL;
    }

    infoPtr->nItemHeight = LISTVIEW_CalculateMaxHeight(infoPtr);
    if (infoPtr->nItemHeight != oldHeight)
        LISTVIEW_UpdateScroll(infoPtr);

    return himlOld;
}

/***
 * DESCRIPTION:
 * Preallocates memory (does *not* set the actual count of items !)
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT   : item count (projected number of items to allocate)
 * [I] DWORD : update flags
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_SetItemCount(LISTVIEW_INFO *infoPtr, INT nItems, DWORD dwFlags)
{
  TRACE("(nItems=%d, dwFlags=%lx)\n", nItems, dwFlags);

  if (infoPtr->dwStyle & LVS_OWNERDATA)
  {
      int precount,topvisible;

      TRACE("LVS_OWNERDATA is set!\n");
      if (dwFlags & (LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL))
        FIXME("flags %s %s not implemented\n",
              (dwFlags & LVSICF_NOINVALIDATEALL) ? "LVSICF_NOINVALIDATEALL"
              : "",
              (dwFlags & LVSICF_NOSCROLL) ? "LVSICF_NOSCROLL" : "");

      LISTVIEW_DeselectAll(infoPtr);

      precount = infoPtr->nItemCount;
      topvisible = LISTVIEW_GetTopIndex(infoPtr) +
                   LISTVIEW_GetCountPerColumn(infoPtr) + 1;

      infoPtr->nItemCount = nItems;
      infoPtr->nItemWidth = max(LISTVIEW_CalculateMaxWidth(infoPtr),
                                DEFAULT_COLUMN_WIDTH);

      LISTVIEW_UpdateSize(infoPtr);
      LISTVIEW_UpdateScroll(infoPtr);

      if (min(precount,infoPtr->nItemCount) < topvisible)
        LISTVIEW_InvalidateList(infoPtr); /* FIXME: optimize */
  }
  else
  {
    /* According to MSDN for non-LVS_OWNERDATA this is just
     * a performance issue. The control allocates its internal
     * data structures for the number of items specified. It
     * cuts down on the number of memory allocations. Therefore
     * we will just issue a WARN here
     */
     WARN("for non-ownerdata performance option not implemented.\n");
  }

  return TRUE;
}

/***
 * DESCRIPTION:
 * Sets the position of an item.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nItem : item index
 * [I] pt : coordinate
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, POINT pt)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    POINT old;

    TRACE("(nItem=%d, &pt=%s\n", nItem, debugpoint(&pt));

    if (nItem < 0 || nItem >= infoPtr->nItemCount ||
	!(uView == LVS_ICON || uView == LVS_SMALLICON)) return FALSE;

    /* This point value seems to be an undocumented feature.
     * The best guess is that it means either at the origin, 
     * or at true beginning of the list. I will assume the origin. */
    if ((pt.x == -1) && (pt.y == -1))
	LISTVIEW_GetOrigin(infoPtr, &pt);
    else if (uView == LVS_ICON)
    {
	pt.x -= (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2;
	pt.y -= ICON_TOP_PADDING;
    }

    /* save the old position */
    old.x = (LONG)DPA_GetPtr(infoPtr->hdpaPosX, nItem);
    old.y = (LONG)DPA_GetPtr(infoPtr->hdpaPosY, nItem);
    
    /* Is the position changing? */
    if (pt.x == old.x && pt.y == old.y) return TRUE;
   
    /* FIXME: shouldn't we invalidate, as the item moved? */
    
    /* Allocating a POINTER for every item is too resource intensive,
     * so we'll keep the (x,y) in different arrays */
    if (DPA_SetPtr(infoPtr->hdpaPosX, nItem, (void *)pt.x) &&
        DPA_SetPtr(infoPtr->hdpaPosY, nItem, (void *)pt.y) )
	return TRUE;
    
    ERR("We should never fail here (nItem=%d, pt=%s), please report.\n", 
	nItem, debugpoint(&pt));
    return FALSE;
}

/***
 * DESCRIPTION:
 * Sets the state of one or many items.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I]INT : item index
 * [I] LPLVITEM : item or subitem info
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetItemState(LISTVIEW_INFO *infoPtr, INT nItem, LPLVITEMW lpLVItem)
{
    BOOL bResult = TRUE;
    LVITEMW lvItem;

    lvItem.iItem = nItem;
    lvItem.iSubItem = 0;
    lvItem.mask = LVIF_STATE;
    lvItem.state = lpLVItem->state;
    lvItem.stateMask = lpLVItem->stateMask;
    TRACE("lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));

    if (nItem == -1)
    {
    	/* apply to all items */
    	for (lvItem.iItem = 0; lvItem.iItem < infoPtr->nItemCount; lvItem.iItem++)
	    if (!LISTVIEW_SetItemT(infoPtr, &lvItem, TRUE)) bResult = FALSE;
    }
    else
	bResult = LISTVIEW_SetItemT(infoPtr, &lvItem, TRUE);

    return bResult;
}

/***
 * DESCRIPTION:
 * Sets the text of an item or subitem.
 *
 * PARAMETER(S):
 * [I] hwnd : window handle
 * [I] nItem : item index
 * [I] lpLVItem : item or subitem info
 * [I] isW : TRUE if input is Unicode
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_SetItemTextT(LISTVIEW_INFO *infoPtr, INT nItem, LPLVITEMW lpLVItem, BOOL isW)
{
    LVITEMW lvItem;

    if (nItem < 0 && nItem >= infoPtr->nItemCount) return FALSE;
    
    lvItem.iItem = nItem;
    lvItem.iSubItem = lpLVItem->iSubItem;
    lvItem.mask = LVIF_TEXT;
    lvItem.pszText = lpLVItem->pszText;
    lvItem.cchTextMax = lpLVItem->cchTextMax;
    
    TRACE("(nItem=%d, lpLVItem=%s, isW=%d)\n", nItem, debuglvitem_t(&lvItem, isW), isW);

    return LISTVIEW_SetItemT(infoPtr, &lvItem, isW); 
}

/***
 * DESCRIPTION:
 * Set item index that marks the start of a multiple selection.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT  : index
 *
 * RETURN:
 * Index number or -1 if there is no selection mark.
 */
static LRESULT LISTVIEW_SetSelectionMark(LISTVIEW_INFO *infoPtr, INT nIndex)
{
  INT nOldIndex = infoPtr->nSelectionMark;

  TRACE("(nIndex=%d)\n", nIndex);

  infoPtr->nSelectionMark = nIndex;

  return nOldIndex;
}

/***
 * DESCRIPTION:
 * Sets the text background color.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] COLORREF : text background color
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetTextBkColor(LISTVIEW_INFO *infoPtr, COLORREF clrTextBk)
{
    TRACE("(clrTextBk=%lx)\n", clrTextBk);

    if (infoPtr->clrTextBk != clrTextBk)
    {
	infoPtr->clrTextBk = clrTextBk;
	LISTVIEW_InvalidateList(infoPtr);
    }
    
  return TRUE;
}

/***
 * DESCRIPTION:
 * Sets the text foreground color.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] COLORREF : text color
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetTextColor (LISTVIEW_INFO *infoPtr, COLORREF clrText)
{
    TRACE("(clrText=%lx)\n", clrText);

    if (infoPtr->clrText != clrText)
    {
	infoPtr->clrText = clrText;
	LISTVIEW_InvalidateList(infoPtr);
    }

    return TRUE;
}

/* LISTVIEW_SetToolTips */
/* LISTVIEW_SetUnicodeFormat */
/* LISTVIEW_SetWorkAreas */

/***
 * DESCRIPTION:
 * Callback internally used by LISTVIEW_SortItems()
 *
 * PARAMETER(S):
 * [I] LPVOID : first LISTVIEW_ITEM to compare
 * [I] LPVOID : second LISTVIEW_ITEM to compare
 * [I] LPARAM : HWND of control
 *
 * RETURN:
 *   if first comes before second : negative
 *   if first comes after second : positive
 *   if first and second are equivalent : zero
 */
static INT WINAPI LISTVIEW_CallBackCompare(LPVOID first, LPVOID second, LPARAM lParam)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongW((HWND)lParam, 0);
  LISTVIEW_ITEM* lv_first = (LISTVIEW_ITEM*) DPA_GetPtr( (HDPA)first, 0 );
  LISTVIEW_ITEM* lv_second = (LISTVIEW_ITEM*) DPA_GetPtr( (HDPA)second, 0 );

  /* Forward the call to the client defined callback */
  return (infoPtr->pfnCompare)( lv_first->lParam , lv_second->lParam, infoPtr->lParamSort );
}

/***
 * DESCRIPTION:
 * Sorts the listview items.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] WPARAM : application-defined value
 * [I] LPARAM : pointer to comparision callback
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SortItems(LISTVIEW_INFO *infoPtr, PFNLVCOMPARE pfnCompare, LPARAM lParamSort)
{
    UINT lStyle = infoPtr->dwStyle;
    HDPA hdpaSubItems;
    LISTVIEW_ITEM *lpItem;
    LPVOID selectionMarkItem;
    LVITEMW item;
    int i;

    TRACE("(pfnCompare=%p, lParamSort=%lx)\n", pfnCompare, lParamSort);

    if (lStyle & LVS_OWNERDATA) return FALSE;

    if (!infoPtr->hdpaItems) return FALSE;

    /* if there are 0 or 1 items, there is no need to sort */
    if (infoPtr->nItemCount < 2) return TRUE;

    if (infoPtr->nFocusedItem >= 0)
    {
	hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, infoPtr->nFocusedItem);
	lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
	if (lpItem) lpItem->state |= LVIS_FOCUSED;
    }
    /* FIXME: go thorugh selected items and mark them so in lpItem->state */
    /*        clear the lpItem->state for non-selected ones */
    /*        remove the selection ranges */
    
    infoPtr->pfnCompare = pfnCompare;
    infoPtr->lParamSort = lParamSort;
    DPA_Sort(infoPtr->hdpaItems, LISTVIEW_CallBackCompare, (LPARAM)infoPtr->hwndSelf);

    /* Adjust selections and indices so that they are the way they should
     * be after the sort (otherwise, the list items move around, but
     * whatever is at the item's previous original position will be
     * selected instead)
     */
    selectionMarkItem=(infoPtr->nSelectionMark>=0)?DPA_GetPtr(infoPtr->hdpaItems, infoPtr->nSelectionMark):NULL;
    for (i=0; i < infoPtr->nItemCount; i++)
    {
	hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, i);
	lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);

	if (lpItem->state & LVIS_SELECTED)
	{
	    item.state = LVIS_SELECTED;
	    item.stateMask = LVIS_SELECTED;
	    LISTVIEW_SetItemState(infoPtr, i, &item);
	}
	if (lpItem->state & LVIS_FOCUSED)
	{
            infoPtr->nFocusedItem = i;
	    lpItem->state &= ~LVIS_FOCUSED;
	}
    }
    if (selectionMarkItem != NULL)
	infoPtr->nSelectionMark = DPA_GetPtrIndex(infoPtr->hdpaItems, selectionMarkItem);
    /* I believe nHotItem should be left alone, see LISTVIEW_ShiftIndices */

    /* align the items */
    LISTVIEW_AlignTop(infoPtr);

    /* refresh the display */
    LISTVIEW_InvalidateList(infoPtr); /* FIXME: display should not change for [SMALL]ICON view */

    return TRUE;
}

/***
 * DESCRIPTION:
 * Updates an items or rearranges the listview control.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : item index
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_Update(LISTVIEW_INFO *infoPtr, INT nItem)
{
    LONG lStyle = infoPtr->dwStyle;
    UINT uView = lStyle & LVS_TYPEMASK;

    TRACE("(nItem=%d)\n", nItem);

    if (nItem < 0 && nItem >= infoPtr->nItemCount) return FALSE;

    /* rearrange with default alignment style */
    if ((lStyle & LVS_AUTOARRANGE) && ((uView == LVS_ICON) ||(uView == LVS_SMALLICON)))
	LISTVIEW_Arrange(infoPtr, 0);
    else
	LISTVIEW_InvalidateItem(infoPtr, nItem);

    return TRUE;
}

	
/***
 * DESCRIPTION:
 * Creates the listview control.
 *
 * PARAMETER(S):
 * [I] hwnd : window handle
 * [I] lpcs : the create parameters
 *
 * RETURN:
 *   Success: 0
 *   Failure: -1
 */
static LRESULT LISTVIEW_Create(HWND hwnd, LPCREATESTRUCTW lpcs)
{
  LISTVIEW_INFO *infoPtr;
  UINT uView = lpcs->style & LVS_TYPEMASK;
  LOGFONTW logFont;

  TRACE("(lpcs=%p)\n", lpcs);

  /* initialize info pointer */
  infoPtr = (LISTVIEW_INFO *)COMCTL32_Alloc(sizeof(LISTVIEW_INFO));
  if (!infoPtr) return -1;

  SetWindowLongW(hwnd, 0, (LONG)infoPtr);

  infoPtr->hwndSelf = hwnd;
  infoPtr->dwStyle = lpcs->style;
  /* determine the type of structures to use */
  infoPtr->notifyFormat = SendMessageW(GetParent(infoPtr->hwndSelf), WM_NOTIFYFORMAT,
                                       (WPARAM)infoPtr->hwndSelf, (LPARAM)NF_QUERY);

  /* initialize color information  */
  infoPtr->clrBk = CLR_NONE;
  infoPtr->clrText = comctl32_color.clrWindowText;
  infoPtr->clrTextBk = CLR_DEFAULT;
  LISTVIEW_SetBkColor(infoPtr, comctl32_color.clrWindow);

  /* set default values */
  infoPtr->nFocusedItem = -1;
  infoPtr->nSelectionMark = -1;
  infoPtr->nHotItem = -1;
  infoPtr->bRedraw = TRUE;
  infoPtr->iconSpacing.cx = GetSystemMetrics(SM_CXICONSPACING);
  infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING);
  infoPtr->nEditLabelItem = -1;

  /* get default font (icon title) */
  SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
  infoPtr->hDefaultFont = CreateFontIndirectW(&logFont);
  infoPtr->hFont = infoPtr->hDefaultFont;
  LISTVIEW_SaveTextMetrics(infoPtr);

  /* create header */
  infoPtr->hwndHeader =	CreateWindowW(WC_HEADERW, (LPCWSTR)NULL,
    WS_CHILD | HDS_HORZ | (DWORD)((LVS_NOSORTHEADER & lpcs->style)?0:HDS_BUTTONS),
    0, 0, 0, 0, hwnd, (HMENU)0,
    lpcs->hInstance, NULL);

  /* set header unicode format */
  SendMessageW(infoPtr->hwndHeader, HDM_SETUNICODEFORMAT, (WPARAM)TRUE, (LPARAM)NULL);

  /* set header font */
  SendMessageW(infoPtr->hwndHeader, WM_SETFONT, (WPARAM)infoPtr->hFont, (LPARAM)TRUE);

  infoPtr->hdpaColumns = DPA_Create(10);

  if (uView == LVS_ICON)
  {
    infoPtr->iconSize.cx = GetSystemMetrics(SM_CXICON);
    infoPtr->iconSize.cy = GetSystemMetrics(SM_CYICON);
  }
  else if (uView == LVS_REPORT)
  {
    if (!(LVS_NOCOLUMNHEADER & lpcs->style))
    {
      ShowWindow(infoPtr->hwndHeader, SW_SHOWNORMAL);
    }
    else
    {
      /* set HDS_HIDDEN flag to hide the header bar */
      SetWindowLongW(infoPtr->hwndHeader, GWL_STYLE,
                    GetWindowLongW(infoPtr->hwndHeader, GWL_STYLE) | HDS_HIDDEN);
    }


    infoPtr->iconSize.cx = GetSystemMetrics(SM_CXSMICON);
    infoPtr->iconSize.cy = GetSystemMetrics(SM_CYSMICON);
  }
  else
  {
    infoPtr->iconSize.cx = GetSystemMetrics(SM_CXSMICON);
    infoPtr->iconSize.cy = GetSystemMetrics(SM_CYSMICON);
  }

  infoPtr->iconStateSize.cx = GetSystemMetrics(SM_CXSMICON);
  infoPtr->iconStateSize.cy = GetSystemMetrics(SM_CYSMICON);

  /* display unsupported listview window styles */
  LISTVIEW_UnsupportedStyles(lpcs->style);

  /* allocate memory for the data structure */
  infoPtr->hdpaItems = DPA_Create(10);
  infoPtr->hdpaPosX  = DPA_Create(10);
  infoPtr->hdpaPosY  = DPA_Create(10);

  /* allocate memory for the selection ranges */
  infoPtr->selectionRanges = ranges_create(10);

  /* initialize size of items */
  infoPtr->nItemWidth = LISTVIEW_CalculateMaxWidth(infoPtr);
  infoPtr->nItemHeight = LISTVIEW_CalculateMaxHeight(infoPtr);

  /* initialize the hover time to -1(indicating the default system hover time) */
  infoPtr->dwHoverTime = -1;

  return 0;
}

/***
 * DESCRIPTION:
 * Erases the background of the listview control.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] hdc : device context handle
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static inline BOOL LISTVIEW_EraseBkgnd(LISTVIEW_INFO *infoPtr, HDC hdc)
{
    RECT rc;

    TRACE("(hdc=%x)\n", hdc);

    if (!GetClipBox(hdc, &rc)) return FALSE;

    return LISTVIEW_FillBkgnd(infoPtr, hdc, &rc);
}
	

/***
 * DESCRIPTION:
 * Helper function for LISTVIEW_[HV]Scroll *only*.
 * Performs vertical/horizontal scrolling by a give amount.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] dx : amount of horizontal scroll
 * [I] dy : amount of vertical scroll
 */
static void scroll_list(LISTVIEW_INFO *infoPtr, INT dx, INT dy)
{
    /* now we can scroll the list */
    ScrollWindowEx(infoPtr->hwndSelf, dx, dy, &infoPtr->rcList, 
		   &infoPtr->rcList, 0, 0, SW_ERASE | SW_INVALIDATE);
    /* if we have focus, adjust rect */
    OffsetRect(&infoPtr->rcFocus, dx, dy);
    UpdateWindow(infoPtr->hwndSelf);
}

/***
 * DESCRIPTION:
 * Performs vertical scrolling.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nScrollCode : scroll code
 * [I] nScrollDiff : units to scroll in SB_INTERNAL mode, 0 otherwise
 * [I] hScrollWnd  : scrollbar control window handle
 *
 * RETURN:
 * Zero
 *
 * NOTES:
 *   SB_LINEUP/SB_LINEDOWN:
 *        for LVS_ICON, LVS_SMALLICON is 37 by experiment
 *        for LVS_REPORT is 1 line
 *        for LVS_LIST cannot occur
 *
 */
static LRESULT LISTVIEW_VScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode, 
				INT nScrollDiff, HWND hScrollWnd)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    INT nOldScrollPos, nNewScrollPos;
    SCROLLINFO scrollInfo;
    BOOL is_an_icon;

    TRACE("(nScrollCode=%d, nScrollDiff=%d)\n", nScrollCode, nScrollDiff);

    if (infoPtr->hwndEdit) SendMessageW(infoPtr->hwndEdit, WM_KILLFOCUS, 0, 0);

    scrollInfo.cbSize = sizeof(SCROLLINFO);
    scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;

    is_an_icon = ((uView == LVS_ICON) || (uView == LVS_SMALLICON));

    if (!GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo)) return 1;

    nOldScrollPos = scrollInfo.nPos;
    switch (nScrollCode)
    {
    case SB_INTERNAL:
        break;

    case SB_LINEUP:
	nScrollDiff = (is_an_icon) ? -LISTVIEW_SCROLL_ICON_LINE_SIZE : -1;
        break;

    case SB_LINEDOWN:
	nScrollDiff = (is_an_icon) ? LISTVIEW_SCROLL_ICON_LINE_SIZE : 1;
        break;

    case SB_PAGEUP:
	nScrollDiff = -scrollInfo.nPage;
        break;

    case SB_PAGEDOWN:
	nScrollDiff = scrollInfo.nPage;
        break;

    case SB_THUMBPOSITION:
    case SB_THUMBTRACK:
	nScrollDiff = scrollInfo.nTrackPos - scrollInfo.nPos;
        break;

    default:
	nScrollDiff = 0;
    }

    /* quit right away if pos isn't changing */
    if (nScrollDiff == 0) return 0;
    
    /* calculate new position, and handle overflows */
    nNewScrollPos = scrollInfo.nPos + nScrollDiff;
    if (nScrollDiff > 0) {
	if (nNewScrollPos < nOldScrollPos ||
	    nNewScrollPos > scrollInfo.nMax)
	    nNewScrollPos = scrollInfo.nMax;
    } else {
	if (nNewScrollPos > nOldScrollPos ||
	    nNewScrollPos < scrollInfo.nMin)
	    nNewScrollPos = scrollInfo.nMin;
    }

    /* set the new position, and reread in case it changed */
    scrollInfo.fMask = SIF_POS;
    scrollInfo.nPos = nNewScrollPos;
    nNewScrollPos = SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo, TRUE);
    
    /* carry on only if it really changed */
    if (nNewScrollPos == nOldScrollPos) return 0;
    
    /* now adjust to client coordinates */
    nScrollDiff = nOldScrollPos - nNewScrollPos;
    if (uView == LVS_REPORT) nScrollDiff *= infoPtr->nItemHeight;
   
    /* and scroll the window */ 
    scroll_list(infoPtr, 0, nScrollDiff);

    return 0;
}

/***
 * DESCRIPTION:
 * Performs horizontal scrolling.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] nScrollCode : scroll code
 * [I] nScrollDiff : units to scroll in SB_INTERNAL mode, 0 otherwise
 * [I] hScrollWnd  : scrollbar control window handle
 *
 * RETURN:
 * Zero
 *
 * NOTES:
 *   SB_LINELEFT/SB_LINERIGHT:
 *        for LVS_ICON, LVS_SMALLICON  1 pixel
 *        for LVS_REPORT is 1 pixel
 *        for LVS_LIST  is 1 column --> which is a 1 because the
 *                                      scroll is based on columns not pixels
 *
 */
static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode,
                                INT nScrollDiff, HWND hScrollWnd)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    INT nOldScrollPos, nNewScrollPos;
    SCROLLINFO scrollInfo;

    TRACE("(nScrollCode=%d, nScrollDiff=%d)\n", nScrollCode, nScrollDiff);

    if (infoPtr->hwndEdit) SendMessageW(infoPtr->hwndEdit, WM_KILLFOCUS, 0, 0);

    scrollInfo.cbSize = sizeof(SCROLLINFO);
    scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;

    if (!GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo)) return 1;

    nOldScrollPos = scrollInfo.nPos;
   
    switch (nScrollCode)
    {
    case SB_INTERNAL:
        break;

    case SB_LINELEFT:
	nScrollDiff = -1;
        break;

    case SB_LINERIGHT:
	nScrollDiff = 1;
        break;

    case SB_PAGELEFT:
	nScrollDiff = -scrollInfo.nPage;
        break;

    case SB_PAGERIGHT:
	nScrollDiff = scrollInfo.nPage;
        break;

    case SB_THUMBPOSITION:
    case SB_THUMBTRACK:
	nScrollDiff = scrollInfo.nTrackPos - scrollInfo.nPos;
	break;

    default:
	nScrollDiff = 0;
    }

    /* quit right away if pos isn't changing */
    if (nScrollDiff == 0) return 0;
    
    /* calculate new position, and handle overflows */
    nNewScrollPos = scrollInfo.nPos + nScrollDiff;
    if (nScrollDiff > 0) {
	if (nNewScrollPos < nOldScrollPos ||
	    nNewScrollPos > scrollInfo.nMax)
	    nNewScrollPos = scrollInfo.nMax;
    } else {
	if (nNewScrollPos > nOldScrollPos ||
	    nNewScrollPos < scrollInfo.nMin)
	    nNewScrollPos = scrollInfo.nMin;
    }

    /* set the new position, and reread in case it changed */
    scrollInfo.fMask = SIF_POS;
    scrollInfo.nPos = nNewScrollPos;
    nNewScrollPos = SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE);
    
    /* carry on only if it really changed */
    if (nNewScrollPos == nOldScrollPos) return 0;
    
    if(uView == LVS_REPORT)
        LISTVIEW_UpdateHeaderSize(infoPtr, nNewScrollPos);
      
    /* now adjust to client coordinates */
    nScrollDiff = nOldScrollPos - nNewScrollPos;
    if (uView == LVS_LIST) nScrollDiff *= infoPtr->nItemWidth;
   
    /* and scroll the window */
    scroll_list(infoPtr, nScrollDiff, 0);

  return 0;
}

static LRESULT LISTVIEW_MouseWheel(LISTVIEW_INFO *infoPtr, INT wheelDelta)
{
    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
    INT gcWheelDelta = 0;
    UINT pulScrollLines = 3;
    SCROLLINFO scrollInfo;

    TRACE("(wheelDelta=%d)\n", wheelDelta);

    SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);
    gcWheelDelta -= wheelDelta;

    scrollInfo.cbSize = sizeof(SCROLLINFO);
    scrollInfo.fMask = SIF_POS;

    switch(uView)
    {
    case LVS_ICON:
    case LVS_SMALLICON:
       /*
        *  listview should be scrolled by a multiple of 37 dependently on its dimension or its visible item number
        *  should be fixed in the future.
        */
        if (GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo))
            LISTVIEW_VScroll(infoPtr, SB_THUMBPOSITION,
			     scrollInfo.nPos + (gcWheelDelta < 0) ?
			     LISTVIEW_SCROLL_ICON_LINE_SIZE :
			     -LISTVIEW_SCROLL_ICON_LINE_SIZE, 0);
        break;

    case LVS_REPORT:
        if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines)
        {
            if (GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo))
            {
                int cLineScroll = min(LISTVIEW_GetCountPerColumn(infoPtr), pulScrollLines);
                cLineScroll *= (gcWheelDelta / WHEEL_DELTA);
                LISTVIEW_VScroll(infoPtr, SB_THUMBPOSITION, scrollInfo.nPos + cLineScroll, 0);
            }
        }
        break;

    case LVS_LIST:
        LISTVIEW_HScroll(infoPtr, (gcWheelDelta < 0) ? SB_LINELEFT : SB_LINERIGHT, 0, 0);
        break;
    }
    return 0;
}

/***
 * DESCRIPTION:
 * ???
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : virtual key
 * [I] LONG : key data
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_KeyDown(LISTVIEW_INFO *infoPtr, INT nVirtualKey, LONG lKeyData)
{
  UINT uView =  infoPtr->dwStyle & LVS_TYPEMASK;
  INT nItem = -1;
  NMLVKEYDOWN nmKeyDown;

  TRACE("(nVirtualKey=%d, lKeyData=%ld)\n", nVirtualKey, lKeyData);

  /* send LVN_KEYDOWN notification */
  nmKeyDown.wVKey = nVirtualKey;
  nmKeyDown.flags = 0;
  notify_hdr(infoPtr, LVN_KEYDOWN, &nmKeyDown.hdr);

  switch (nVirtualKey)
  {
  case VK_RETURN:
    if ((infoPtr->nItemCount > 0) && (infoPtr->nFocusedItem != -1))
    {
      notify(infoPtr, NM_RETURN);
      notify(infoPtr, LVN_ITEMACTIVATE);
    }
    break;

  case VK_HOME:
    if (infoPtr->nItemCount > 0)
      nItem = 0;
    break;

  case VK_END:
    if (infoPtr->nItemCount > 0)
      nItem = infoPtr->nItemCount - 1;
    break;

  case VK_LEFT:
    nItem = ListView_GetNextItem(infoPtr->hwndSelf, infoPtr->nFocusedItem, LVNI_TOLEFT);
    break;

  case VK_UP:
    nItem = ListView_GetNextItem(infoPtr->hwndSelf, infoPtr->nFocusedItem, LVNI_ABOVE);
    break;

  case VK_RIGHT:
    nItem = ListView_GetNextItem(infoPtr->hwndSelf, infoPtr->nFocusedItem, LVNI_TORIGHT);
    break;

  case VK_DOWN:
    nItem = ListView_GetNextItem(infoPtr->hwndSelf, infoPtr->nFocusedItem, LVNI_BELOW);
    break;

  case VK_PRIOR:
    if (uView == LVS_REPORT)
      nItem = infoPtr->nFocusedItem - LISTVIEW_GetCountPerColumn(infoPtr);
    else
      nItem = infoPtr->nFocusedItem - LISTVIEW_GetCountPerColumn(infoPtr)
                                    * LISTVIEW_GetCountPerRow(infoPtr);
    if(nItem < 0) nItem = 0;
    break;

  case VK_NEXT:
    if (uView == LVS_REPORT)
      nItem = infoPtr->nFocusedItem + LISTVIEW_GetCountPerColumn(infoPtr);
    else
      nItem = infoPtr->nFocusedItem + LISTVIEW_GetCountPerColumn(infoPtr)
                                    * LISTVIEW_GetCountPerRow(infoPtr);
    if(nItem >= infoPtr->nItemCount) nItem = infoPtr->nItemCount - 1;
    break;
  }

  if ((nItem != -1) && (nItem != infoPtr->nFocusedItem))
      LISTVIEW_KeySelection(infoPtr, nItem);

  return 0;
}

/***
 * DESCRIPTION:
 * Kills the focus.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_KillFocus(LISTVIEW_INFO *infoPtr)
{
    TRACE("()\n");

    /* if we did not have the focus, there's nothing to do */
    if (!infoPtr->bFocus) return 0;
   
    /* send NM_KILLFOCUS notification */
    notify(infoPtr, NM_KILLFOCUS);

    /* if we have a focus rectagle, get rid of it */
    LISTVIEW_ShowFocusRect(infoPtr, FALSE);
    
    /* set window focus flag */
    infoPtr->bFocus = FALSE;

    /* invalidate the selected items before reseting focus flag */
    LISTVIEW_InvalidateSelectedItems(infoPtr);
    
    return 0;
}

/***
 * DESCRIPTION:
 * Processes double click messages (left mouse button).
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] wKey : key flag
 * [I] pts : mouse coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_LButtonDblClk(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pts)
{
    LVHITTESTINFO htInfo;

    TRACE("(key=%hu, X=%hu, Y=%hu)\n", wKey, pts.x, pts.y);

    /* send NM_RELEASEDCAPTURE notification */
    notify(infoPtr, NM_RELEASEDCAPTURE);

    htInfo.pt.x = pts.x;
    htInfo.pt.y = pts.y;

    /* send NM_DBLCLK notification */
    LISTVIEW_HitTest(infoPtr, &htInfo, TRUE, FALSE);
    notify_click(infoPtr, NM_DBLCLK, &htInfo);

    /* To send the LVN_ITEMACTIVATE, it must be on an Item */
    if(htInfo.iItem != -1) notify(infoPtr, LVN_ITEMACTIVATE);

    return 0;
}

/***
 * DESCRIPTION:
 * Processes mouse down messages (left mouse button).
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] wKey : key flag
 * [I] pts : mouse coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pts)
{
  LVHITTESTINFO lvHitTestInfo;
  LONG lStyle = infoPtr->dwStyle;
  static BOOL bGroupSelect = TRUE;
  POINT pt = { pts.x, pts.y };
  INT nItem;

  TRACE("(key=%hu, X=%hu, Y=%hu)\n", wKey, pts.x, pts.y);

  /* send NM_RELEASEDCAPTURE notification */
  notify(infoPtr, NM_RELEASEDCAPTURE);

  if (!infoPtr->bFocus) SetFocus(infoPtr->hwndSelf);

  /* set left button down flag */
  infoPtr->bLButtonDown = TRUE;

  lvHitTestInfo.pt.x = pts.x;
  lvHitTestInfo.pt.y = pts.y;

  nItem = LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE);
  TRACE("at %s, nItem=%d\n", debugpoint(&pt), nItem);
  infoPtr->nEditLabelItem = -1;
  if ((nItem >= 0) && (nItem < infoPtr->nItemCount))
  {
    if (lStyle & LVS_SINGLESEL)
    {
      if (LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED))
        infoPtr->nEditLabelItem = nItem;
      else
        LISTVIEW_SetSelection(infoPtr, nItem);
    }
    else
    {
      if ((wKey & MK_CONTROL) && (wKey & MK_SHIFT))
      {
        if (bGroupSelect)
          LISTVIEW_AddGroupSelection(infoPtr, nItem);
        else
	{
          LVITEMW item;

	  item.state = LVIS_SELECTED | LVIS_FOCUSED;
	  item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;

	  LISTVIEW_SetItemState(infoPtr,nItem,&item);
	  infoPtr->nSelectionMark = nItem;
	}
      }
      else if (wKey & MK_CONTROL)
      {
        LVITEMW item;

	bGroupSelect = (LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED) == 0);
	
	item.state = (bGroupSelect ? LVIS_SELECTED : 0) | LVIS_FOCUSED;
        item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
	LISTVIEW_SetItemState(infoPtr, nItem, &item);
        infoPtr->nSelectionMark = nItem;
      }
      else  if (wKey & MK_SHIFT)
      {
        LISTVIEW_SetGroupSelection(infoPtr, nItem);
      }
      else
      {
	if (LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED))
	  infoPtr->nEditLabelItem = nItem;

	/* set selection (clears other pre-existing selections) */
        LISTVIEW_SetSelection(infoPtr, nItem);
      }
    }
  }
  else
  {
    /* remove all selections */
    LISTVIEW_DeselectAll(infoPtr);
  }

  return 0;
}

/***
 * DESCRIPTION:
 * Processes mouse up messages (left mouse button).
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] wKey : key flag
 * [I] pts : mouse coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_LButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pts)
{
    LVHITTESTINFO lvHitTestInfo;
    
    TRACE("(key=%hu, X=%hu, Y=%hu)\n", wKey, pts.x, pts.y);

    if (!infoPtr->bLButtonDown) return 0;

    lvHitTestInfo.pt.x = pts.x;
    lvHitTestInfo.pt.y = pts.y;

    /* send NM_CLICK notification */
    LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, FALSE);
    notify_click(infoPtr, NM_CLICK, &lvHitTestInfo);

    /* set left button flag */
    infoPtr->bLButtonDown = FALSE;

    /* if we clicked on a selected item, edit the label */
    if(lvHitTestInfo.iItem == infoPtr->nEditLabelItem && (lvHitTestInfo.flags & LVHT_ONITEMLABEL))
        LISTVIEW_EditLabelT(infoPtr, lvHitTestInfo.iItem, TRUE);

    return 0;
}

/***
 * DESCRIPTION:
 * Destroys the listview control (called after WM_DESTROY).
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_NCDestroy(LISTVIEW_INFO *infoPtr)
{
  LONG lStyle = infoPtr->dwStyle;

  TRACE("()\n");

  /* delete all items */
  LISTVIEW_DeleteAllItems(infoPtr);

  /* destroy data structure */
  DPA_Destroy(infoPtr->hdpaItems);
  ranges_destroy(infoPtr->selectionRanges);

  /* destroy image lists */
  if (!(lStyle & LVS_SHAREIMAGELISTS))
  {
      if (infoPtr->himlNormal)
	  ImageList_Destroy(infoPtr->himlNormal);
      if (infoPtr->himlSmall)
	  ImageList_Destroy(infoPtr->himlSmall);
      if (infoPtr->himlState)
	  ImageList_Destroy(infoPtr->himlState);
  }

  /* destroy font, bkgnd brush */
  infoPtr->hFont = 0;
  if (infoPtr->hDefaultFont) DeleteObject(infoPtr->hDefaultFont);
  if (infoPtr->clrBk != CLR_NONE) DeleteObject(infoPtr->hBkBrush);

  /* free listview info pointer*/
  COMCTL32_Free(infoPtr);

  SetWindowLongW(infoPtr->hwndSelf, 0, 0);
  return 0;
}

/***
 * DESCRIPTION:
 * Handles notifications from children.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] INT : control identifier
 * [I] LPNMHDR : notification information
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_Notify(LISTVIEW_INFO *infoPtr, INT nCtrlId, LPNMHDR lpnmh)
{
    UINT uView =  infoPtr->dwStyle & LVS_TYPEMASK;
    
    TRACE("(nCtrlId=%d, lpnmh=%p)\n", nCtrlId, lpnmh);

    /* handle notification from header control */
    if (lpnmh->hwndFrom == infoPtr->hwndHeader)
    {
	LPNMHEADERW lphnm = (LPNMHEADERW)lpnmh;
	
	if (lpnmh->code == HDN_TRACKW || lpnmh->code == HDN_TRACKA)
	{
	    COLUMN_INFO *lpColumnInfo;
	    RECT rcCol;
	    INT dx;

	    if (!(lpColumnInfo = DPA_GetPtr(infoPtr->hdpaColumns, lphnm->iItem))) return 0;
	    if (!(lphnm->pitem->mask & HDI_WIDTH)) return 0;
	    
	    /* determine how much we change since the last know position */
	    dx = lphnm->pitem->cxy - (lpColumnInfo->rcHeader.right - lpColumnInfo->rcHeader.left);
	    
	    /* ajust the column being tracked */
	    lpColumnInfo->rcHeader.right += dx;
	    
	    /* compute the rectangle for the tracked column */
	    rcCol.left = lpColumnInfo->rcHeader.left;
	    rcCol.top = infoPtr->rcList.top;
	    rcCol.right = lpColumnInfo->rcHeader.right;
	    rcCol.bottom = infoPtr->rcList.bottom;
	   
	    LISTVIEW_ScrollColumns(infoPtr, lphnm->iItem + 1, dx);
	    if (uView == LVS_REPORT) LISTVIEW_InvalidateRect(infoPtr, &rcCol);
	}
	else if(lpnmh->code ==  HDN_ITEMCLICKW || lpnmh->code ==  HDN_ITEMCLICKA)
	{
            /* Handle sorting by Header Column */
            NMLISTVIEW nmlv;

            ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
            nmlv.iItem = -1;
            nmlv.iSubItem = lphnm->iItem;
            notify_listview(infoPtr, LVN_COLUMNCLICK, &nmlv);
        }
    }

    return 0;
}

/***
 * DESCRIPTION:
 * Determines the type of structure to use.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structureof the sender
 * [I] hwndFrom : listview window handle
 * [I] nCommand : command specifying the nature of the WM_NOTIFYFORMAT
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_NotifyFormat(LISTVIEW_INFO *infoPtr, HWND hwndFrom, INT nCommand)
{
  TRACE("(hwndFrom=%x, nCommand=%d)\n", hwndFrom, nCommand);

  if (nCommand == NF_REQUERY)
    infoPtr->notifyFormat = SendMessageW(hwndFrom, WM_NOTIFYFORMAT,
                                         (WPARAM)infoPtr->hwndSelf, (LPARAM)NF_QUERY);
  return 0;
}

/***
 * DESCRIPTION:
 * Paints/Repaints the listview control.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] hdc : device context handle
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_Paint(LISTVIEW_INFO *infoPtr, HDC hdc)
{
    TRACE("(hdc=%x)\n", hdc);

    if (hdc) 
	LISTVIEW_Refresh(infoPtr, hdc);
    else
    {
	PAINTSTRUCT ps;

	hdc = BeginPaint(infoPtr->hwndSelf, &ps);
	if (!hdc) return 1;
	if (ps.fErase) LISTVIEW_FillBkgnd(infoPtr, hdc, &ps.rcPaint);
	LISTVIEW_Refresh(infoPtr, hdc);
	EndPaint(infoPtr->hwndSelf, &ps);
    }

    return 0;
}

/***
 * DESCRIPTION:
 * Processes double click messages (right mouse button).
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] wKey : key flag
 * [I] pts : mouse coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_RButtonDblClk(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pts)
{
    LVHITTESTINFO lvHitTestInfo;
    
    TRACE("(key=%hu,X=%hu,Y=%hu)\n", wKey, pts.x, pts.y);

    /* send NM_RELEASEDCAPTURE notification */
    notify(infoPtr, NM_RELEASEDCAPTURE);

    /* send NM_RDBLCLK notification */
    lvHitTestInfo.pt.x = pts.x;
    lvHitTestInfo.pt.y = pts.y;
    LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, FALSE);
    notify_click(infoPtr, NM_RDBLCLK, &lvHitTestInfo);

    return 0;
}

/***
 * DESCRIPTION:
 * Processes mouse down messages (right mouse button).
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] wKey : key flag
 * [I] pts : mouse coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_RButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pts)
{
    LVHITTESTINFO lvHitTestInfo;
    INT nItem;

    TRACE("(key=%hu,X=%hu,Y=%hu)\n", wKey, pts.x, pts.y);

    /* send NM_RELEASEDCAPTURE notification */
    notify(infoPtr, NM_RELEASEDCAPTURE);

    /* make sure the listview control window has the focus */
    if (!infoPtr->bFocus) SetFocus(infoPtr->hwndSelf);

    /* set right button down flag */
    infoPtr->bRButtonDown = TRUE;

    /* determine the index of the selected item */
    lvHitTestInfo.pt.x = pts.x;
    lvHitTestInfo.pt.y = pts.y;
    nItem = LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE);
  
    if ((nItem >= 0) && (nItem < infoPtr->nItemCount))
    {
	LISTVIEW_SetItemFocus(infoPtr, nItem);
	if (!((wKey & MK_SHIFT) || (wKey & MK_CONTROL)) &&
            !LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED))
	    LISTVIEW_SetSelection(infoPtr, nItem);
    }
    else
    {
	LISTVIEW_DeselectAll(infoPtr);
    }

    return 0;
}

/***
 * DESCRIPTION:
 * Processes mouse up messages (right mouse button).
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] wKey : key flag
 * [I] pts : mouse coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_RButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pts)
{
    LVHITTESTINFO lvHitTestInfo;
    POINT pt;

    TRACE("(key=%hu,X=%hu,Y=%hu)\n", wKey, pts.x, pts.y);

    if (!infoPtr->bRButtonDown) return 0;
 
    /* set button flag */
    infoPtr->bRButtonDown = FALSE;

    /* Send NM_RClICK notification */
    lvHitTestInfo.pt.x = pts.x;
    lvHitTestInfo.pt.y = pts.y;
    LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, FALSE);
    notify_click(infoPtr, NM_RCLICK, &lvHitTestInfo);

    /* Change to screen coordinate for WM_CONTEXTMENU */
    pt = lvHitTestInfo.pt;
    ClientToScreen(infoPtr->hwndSelf, &pt);

    /* Send a WM_CONTEXTMENU message in response to the RBUTTONUP */
    SendMessageW(infoPtr->hwndSelf, WM_CONTEXTMENU,
		 (WPARAM)infoPtr->hwndSelf, MAKELPARAM(pt.x, pt.y));

    return 0;
}


/***
 * DESCRIPTION:
 * Sets the cursor.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] hwnd : window handle of window containing the cursor
 * [I] nHittest : hit-test code
 * [I] wMouseMsg : ideintifier of the mouse message
 *
 * RETURN:
 * TRUE if cursor is set
 * FALSE otherwise
 */
static BOOL LISTVIEW_SetCursor(LISTVIEW_INFO *infoPtr, HWND hwnd, UINT nHittest, UINT wMouseMsg)
{
    LVHITTESTINFO lvHitTestInfo;

    if(!(infoPtr->dwLvExStyle & LVS_EX_TRACKSELECT)) return FALSE;

    if(!infoPtr->hHotCursor)  return FALSE;

    GetCursorPos(&lvHitTestInfo.pt);
    if (LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, FALSE, FALSE) < 0) return FALSE;

    SetCursor(infoPtr->hHotCursor);

    return TRUE;
}

/***
 * DESCRIPTION:
 * Sets the focus.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] hwndLoseFocus : handle of previously focused window
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_SetFocus(LISTVIEW_INFO *infoPtr, HWND hwndLoseFocus)
{
    TRACE("(hwndLoseFocus=%x)\n", hwndLoseFocus);

    /* if we have the focus already, there's nothing to do */
    if (infoPtr->bFocus) return 0;
   
    /* send NM_SETFOCUS notification */
    notify(infoPtr, NM_SETFOCUS);

    /* set window focus flag */
    infoPtr->bFocus = TRUE;

    /* put the focus rect back on */
    LISTVIEW_ShowFocusRect(infoPtr, TRUE);

    /* redraw all visible selected items */
    LISTVIEW_InvalidateSelectedItems(infoPtr);

    return 0;
}

/***
 * DESCRIPTION:
 * Sets the font.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] fRedraw : font handle
 * [I] fRedraw : redraw flag
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_SetFont(LISTVIEW_INFO *infoPtr, HFONT hFont, WORD fRedraw)
{
    HFONT oldFont = infoPtr->hFont;

    TRACE("(hfont=%x,redraw=%hu)\n", hFont, fRedraw);

    infoPtr->hFont = hFont ? hFont : infoPtr->hDefaultFont;
    if (infoPtr->hFont == oldFont) return 0;
    
    LISTVIEW_SaveTextMetrics(infoPtr);

    if ((infoPtr->dwStyle & LVS_TYPEMASK) == LVS_REPORT)
	SendMessageW(infoPtr->hwndHeader, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(fRedraw, 0));

    if (fRedraw) LISTVIEW_InvalidateList(infoPtr);

    return 0;
}

/***
 * DESCRIPTION:
 * Message handling for WM_SETREDRAW.
 * For the Listview, it invalidates the entire window (the doc specifies otherwise)
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] bRedraw: state of redraw flag
 *
 * RETURN:
 * DefWinProc return value
 */
static LRESULT LISTVIEW_SetRedraw(LISTVIEW_INFO *infoPtr, BOOL bRedraw)
{
    infoPtr->bRedraw = bRedraw;
    if(bRedraw)
        RedrawWindow(infoPtr->hwndSelf, NULL, 0,
            RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ALLCHILDREN | RDW_ERASENOW);
    return 0;
}

/***
 * DESCRIPTION:
 * Resizes the listview control. This function processes WM_SIZE
 * messages.  At this time, the width and height are not used.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] Width : new width
 * [I] Height : new height
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_Size(LISTVIEW_INFO *infoPtr, int Width, int Height)
{
  LONG lStyle = infoPtr->dwStyle;
  UINT uView = lStyle & LVS_TYPEMASK;

  TRACE("(width=%d, height=%d)\n", Width, Height);

  if (LISTVIEW_UpdateSize(infoPtr))
  {
    if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
    {
        if (lStyle & LVS_ALIGNLEFT)
            LISTVIEW_AlignLeft(infoPtr);
        else
            LISTVIEW_AlignTop(infoPtr);
    }

    LISTVIEW_UpdateScroll(infoPtr);

    LISTVIEW_InvalidateList(infoPtr); /* FIXME: optimize */
  }

  return 0;
}

/***
 * DESCRIPTION:
 * Sets the size information.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 *
 * RETURN:
 * Zero if no size change
 * 1 of size changed
 */
static BOOL LISTVIEW_UpdateSize(LISTVIEW_INFO *infoPtr)
{
  LONG lStyle = infoPtr->dwStyle;
  UINT uView = lStyle & LVS_TYPEMASK;
  RECT rcList;
  RECT rcOld;

  GetClientRect(infoPtr->hwndSelf, &rcList);
  CopyRect(&rcOld,&(infoPtr->rcList));
  infoPtr->rcList.left = 0;
  infoPtr->rcList.right = max(rcList.right - rcList.left, 1);
  infoPtr->rcList.top = 0;
  infoPtr->rcList.bottom = max(rcList.bottom - rcList.top, 1);

  if (uView == LVS_LIST)
  {
    /* Apparently the "LIST" style is supposed to have the same
     * number of items in a column even if there is no scroll bar.
     * Since if a scroll bar already exists then the bottom is already
     * reduced, only reduce if the scroll bar does not currently exist.
     * The "2" is there to mimic the native control. I think it may be
     * related to either padding or edges.  (GLA 7/2002)
     */
    if (!(lStyle & WS_HSCROLL))
    {
      INT nHScrollHeight = GetSystemMetrics(SM_CYHSCROLL);
      if (infoPtr->rcList.bottom > nHScrollHeight)
        infoPtr->rcList.bottom -= (nHScrollHeight + 2);
    }
    else
    {
      if (infoPtr->rcList.bottom > 2)
        infoPtr->rcList.bottom -= 2;
    }
  }
  else if (uView == LVS_REPORT)
  {
    HDLAYOUT hl;
    WINDOWPOS wp;

    hl.prc = &rcList;
    hl.pwpos = &wp;
    Header_Layout(infoPtr->hwndHeader, &hl);

    SetWindowPos(wp.hwnd, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags);

    if (!(LVS_NOCOLUMNHEADER & lStyle))
      infoPtr->rcList.top = max(wp.cy, 0);
  }
  return (EqualRect(&rcOld,&(infoPtr->rcList)));
}

/***
 * DESCRIPTION:
 * Processes WM_STYLECHANGED messages.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the listview structure
 * [I] wStyleType : window style type (normal or extended)
 * [I] lpss : window style information
 *
 * RETURN:
 * Zero
 */
static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
                                 LPSTYLESTRUCT lpss)
{
    UINT uNewView = lpss->styleNew & LVS_TYPEMASK;
    UINT uOldView = lpss->styleOld & LVS_TYPEMASK;

    TRACE("(styletype=%x, styleOld=0x%08lx, styleNew=0x%08lx)\n",
          wStyleType, lpss->styleOld, lpss->styleNew);

    if (wStyleType != GWL_STYLE) return 0;
  
    /* FIXME: if LVS_NOSORTHEADER changed, update header */
    /*        what if LVS_OWNERDATA changed? */
    /*        or LVS_SINGLESEL */
    /*        or LVS_SORT{AS,DES}CENDING */

    infoPtr->dwStyle = lpss->styleNew;

    if (((lpss->styleOld & WS_HSCROLL) != 0)&&
        ((lpss->styleNew & WS_HSCROLL) == 0))
       ShowScrollBar(infoPtr->hwndSelf, SB_HORZ, FALSE);

    if (((lpss->styleOld & WS_VSCROLL) != 0)&&
        ((lpss->styleNew & WS_VSCROLL) == 0))
       ShowScrollBar(infoPtr->hwndSelf, SB_VERT, FALSE);

    if (uNewView != uOldView)
    {
    	SIZE oldIconSize = infoPtr->iconSize;
    	HIMAGELIST himl;
    
        SendMessageW(infoPtr->hwndEdit, WM_KILLFOCUS, 0, 0);
    	ShowWindow(infoPtr->hwndHeader, SW_HIDE);

        ShowScrollBar(infoPtr->hwndSelf, SB_BOTH, FALSE);
        SetRectEmpty(&infoPtr->rcFocus);

        himl = (uNewView == LVS_ICON ? infoPtr->himlNormal : infoPtr->himlSmall);
        update_icon_size(himl, uNewView != LVS_ICON, &infoPtr->iconSize);
    
        if (uNewView == LVS_ICON)
        {
            if ((infoPtr->iconSize.cx != oldIconSize.cx) || (infoPtr->iconSize.cy != oldIconSize.cy))
            {
	  	TRACE("icon old size=(%ld,%ld), new size=(%ld,%ld)\n",
		      oldIconSize.cx, oldIconSize.cy, infoPtr->iconSize.cx, infoPtr->iconSize.cy);
	        LISTVIEW_SetIconSpacing(infoPtr, 0);
            }
        }
        else if (uNewView == LVS_REPORT)
        {
            HDLAYOUT hl;
            WINDOWPOS wp;

            hl.prc = &infoPtr->rcList;
            hl.pwpos = &wp;
            Header_Layout(infoPtr->hwndHeader, &hl);
            SetWindowPos(infoPtr->hwndHeader, infoPtr->hwndSelf, wp.x, wp.y, wp.cx, wp.cy, wp.flags);
        }

        infoPtr->nItemWidth = LISTVIEW_CalculateMaxWidth(infoPtr);
        infoPtr->nItemHeight = LISTVIEW_CalculateMaxHeight(infoPtr);
    }

    if (uNewView == LVS_REPORT)
	ShowWindow(infoPtr->hwndHeader, (LVS_NOCOLUMNHEADER & lpss->styleNew) ? SW_HIDE : SW_SHOWNORMAL);
     
    if ( (uNewView == LVS_ICON || uNewView == LVS_SMALLICON) &&
	 (uNewView != uOldView || ((lpss->styleNew ^ lpss->styleOld) & LVS_ALIGNMASK)) )
    {
	 if (infoPtr->dwStyle & LVS_ALIGNLEFT)
	     LISTVIEW_AlignLeft(infoPtr);
	 else 
	     LISTVIEW_AlignTop(infoPtr);
    }

    /* update the size of the client area */
    LISTVIEW_UpdateSize(infoPtr);

    /* add scrollbars if needed */
    LISTVIEW_UpdateScroll(infoPtr);

    /* invalidate client area + erase background */
    LISTVIEW_InvalidateList(infoPtr);

    /* print the list of unsupported window styles */
    LISTVIEW_UnsupportedStyles(lpss->styleNew);

    return 0;
}

/***
 * DESCRIPTION:
 * Window procedure of the listview control.
 *
 */
static LRESULT WINAPI
LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongW(hwnd, 0);

  TRACE("(uMsg=%x wParam=%x lParam=%lx)\n", uMsg, wParam, lParam);

  if (!infoPtr && (uMsg != WM_CREATE))
    return DefWindowProcW(hwnd, uMsg, wParam, lParam);

  if (infoPtr)
  {
    infoPtr->dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
  }

  switch (uMsg)
  {
  case LVM_APPROXIMATEVIEWRECT:
    return LISTVIEW_ApproximateViewRect(infoPtr, (INT)wParam,
                                        LOWORD(lParam), HIWORD(lParam));
  case LVM_ARRANGE:
    return LISTVIEW_Arrange(infoPtr, (INT)wParam);

/* case LVN_CANCELEDITLABEL */

/* case LVM_CREATEDRAGIMAGE: */

  case LVM_DELETEALLITEMS:
    return LISTVIEW_DeleteAllItems(infoPtr);

  case LVM_DELETECOLUMN:
    return LISTVIEW_DeleteColumn(infoPtr, (INT)wParam);

  case LVM_DELETEITEM:
    return LISTVIEW_DeleteItem(infoPtr, (INT)wParam);

  case LVM_EDITLABELW:
    return (LRESULT)LISTVIEW_EditLabelT(infoPtr, (INT)wParam, TRUE);

  case LVM_EDITLABELA:
    return (LRESULT)LISTVIEW_EditLabelT(infoPtr, (INT)wParam, FALSE);

  /* case LVN_ENABLEGROUPVIEW: */

  case LVM_ENSUREVISIBLE:
    return LISTVIEW_EnsureVisible(infoPtr, (INT)wParam, (BOOL)lParam);

  case LVM_FINDITEMW:
    return LISTVIEW_FindItemW(infoPtr, (INT)wParam, (LPLVFINDINFOW)lParam);

  case LVM_FINDITEMA:
    return LISTVIEW_FindItemA(infoPtr, (INT)wParam, (LPLVFINDINFOA)lParam);

  case LVM_GETBKCOLOR:
    return infoPtr->clrBk;

  /* case LVM_GETBKIMAGE: */

  case LVM_GETCALLBACKMASK:
    return infoPtr->uCallbackMask;

  case LVM_GETCOLUMNA:
    return LISTVIEW_GetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, FALSE);

  case LVM_GETCOLUMNW:
    return LISTVIEW_GetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, TRUE);

  case LVM_GETCOLUMNORDERARRAY:
    return LISTVIEW_GetColumnOrderArray(infoPtr, (INT)wParam, (LPINT)lParam);

  case LVM_GETCOLUMNWIDTH:
    return LISTVIEW_GetColumnWidth(infoPtr, (INT)wParam);

  case LVM_GETCOUNTPERPAGE:
    return LISTVIEW_GetCountPerPage(infoPtr);

  case LVM_GETEDITCONTROL:
    return (LRESULT)infoPtr->hwndEdit;

  case LVM_GETEXTENDEDLISTVIEWSTYLE:
    return infoPtr->dwLvExStyle;

  case LVM_GETHEADER:
    return (LRESULT)infoPtr->hwndHeader;

  case LVM_GETHOTCURSOR:
    return (LRESULT)infoPtr->hHotCursor;

  case LVM_GETHOTITEM:
    return infoPtr->nHotItem;

  case LVM_GETHOVERTIME:
    return infoPtr->dwHoverTime;

  case LVM_GETIMAGELIST:
    return LISTVIEW_GetImageList(infoPtr, (INT)wParam);

  /* case LVN_GETINSERTMARK: */

  /* case LVN_GETINSERTMARKCOLOR: */

  /* case LVN_GETINSERTMARKRECT: */

  case LVM_GETISEARCHSTRINGA:
  case LVM_GETISEARCHSTRINGW:
    FIXME("LVM_GETISEARCHSTRING: unimplemented\n");
    return FALSE;

  case LVM_GETITEMA:
    return LISTVIEW_GetItemExtT(infoPtr, (LPLVITEMW)lParam, FALSE);

  case LVM_GETITEMW:
    return LISTVIEW_GetItemExtT(infoPtr, (LPLVITEMW)lParam, TRUE);

  case LVM_GETITEMCOUNT:
    return infoPtr->nItemCount;

  case LVM_GETITEMPOSITION:
    return LISTVIEW_GetItemPosition(infoPtr, (INT)wParam, (LPPOINT)lParam);

  case LVM_GETITEMRECT:
    return LISTVIEW_GetItemRect(infoPtr, (INT)wParam, (LPRECT)lParam);

  case LVM_GETITEMSPACING:
    return LISTVIEW_GetItemSpacing(infoPtr, (BOOL)wParam);

  case LVM_GETITEMSTATE:
    return LISTVIEW_GetItemState(infoPtr, (INT)wParam, (UINT)lParam);

  case LVM_GETITEMTEXTA:
    return LISTVIEW_GetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, FALSE);

  case LVM_GETITEMTEXTW:
    return LISTVIEW_GetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, TRUE);

  case LVM_GETNEXTITEM:
    return LISTVIEW_GetNextItem(infoPtr, (INT)wParam, LOWORD(lParam));

  case LVM_GETNUMBEROFWORKAREAS:
    FIXME("LVM_GETNUMBEROFWORKAREAS: unimplemented\n");
    return 1;

  case LVM_GETORIGIN:
    return LISTVIEW_GetOrigin(infoPtr, (LPPOINT)lParam);

  /* case LVN_GETOUTLINECOLOR: */

  /* case LVM_GETSELECTEDCOLUMN: */

  case LVM_GETSELECTEDCOUNT:
    return LISTVIEW_GetSelectedCount(infoPtr);

  case LVM_GETSELECTIONMARK:
    return infoPtr->nSelectionMark;

  case LVM_GETSTRINGWIDTHA:
    return LISTVIEW_GetStringWidthT(infoPtr, (LPCWSTR)lParam, FALSE);

  case LVM_GETSTRINGWIDTHW:
    return LISTVIEW_GetStringWidthT(infoPtr, (LPCWSTR)lParam, TRUE);

  case LVM_GETSUBITEMRECT:
    return LISTVIEW_GetSubItemRect(infoPtr, (UINT)wParam, (LPRECT)lParam);

  case LVM_GETTEXTBKCOLOR:
    return infoPtr->clrTextBk;

  case LVM_GETTEXTCOLOR:
    return infoPtr->clrText;

  /* case LVN_GETTILEINFO: */

  /* case LVN_GETTILEVIEWINFO: */

  case LVM_GETTOOLTIPS:
    FIXME("LVM_GETTOOLTIPS: unimplemented\n");
    return FALSE;

  case LVM_GETTOPINDEX:
    return LISTVIEW_GetTopIndex(infoPtr);

  /*case LVM_GETUNICODEFORMAT:
    FIXME("LVM_GETUNICODEFORMAT: unimplemented\n");
    return FALSE;*/

  case LVM_GETVIEWRECT:
    return LISTVIEW_GetViewRect(infoPtr, (LPRECT)lParam);

  case LVM_GETWORKAREAS:
    FIXME("LVM_GETWORKAREAS: unimplemented\n");
    return FALSE;

  /* case LVN_HASGROUP: */

  case LVM_HITTEST:
    return LISTVIEW_HitTest(infoPtr, (LPLVHITTESTINFO)lParam, FALSE, FALSE);

  case LVM_INSERTCOLUMNA:
    return LISTVIEW_InsertColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, FALSE);

  case LVM_INSERTCOLUMNW:
    return LISTVIEW_InsertColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, TRUE);

  /* case LVN_INSERTGROUP: */

  /* case LVN_INSERTGROUPSORTED: */

  case LVM_INSERTITEMA:
    return LISTVIEW_InsertItemT(infoPtr, (LPLVITEMW)lParam, FALSE);

  case LVM_INSERTITEMW:
    return LISTVIEW_InsertItemT(infoPtr, (LPLVITEMW)lParam, TRUE);

  /* case LVN_INSERTMARKHITTEST: */

  /* case LVN_ISGROUPVIEWENABLED: */

  /* case LVN_MAPIDTOINDEX: */

  /* case LVN_INEDXTOID: */

  /* case LVN_MOVEGROUP: */

  /* case LVN_MOVEITEMTOGROUP: */

  case LVM_REDRAWITEMS:
    return LISTVIEW_RedrawItems(infoPtr, (INT)wParam, (INT)lParam);

  /* case LVN_REMOVEALLGROUPS: */

  /* case LVN_REMOVEGROUP: */

  case LVM_SCROLL:
    return LISTVIEW_Scroll(infoPtr, (INT)wParam, (INT)lParam);

  case LVM_SETBKCOLOR:
    return LISTVIEW_SetBkColor(infoPtr, (COLORREF)lParam);

  /* case LVM_SETBKIMAGE: */

  case LVM_SETCALLBACKMASK:
    infoPtr->uCallbackMask = (UINT)wParam;
    return TRUE;

  case LVM_SETCOLUMNA:
    return LISTVIEW_SetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, FALSE);

  case LVM_SETCOLUMNW:
    return LISTVIEW_SetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, TRUE);

  case LVM_SETCOLUMNORDERARRAY:
    return LISTVIEW_SetColumnOrderArray(infoPtr, (INT)wParam, (LPINT)lParam);

  case LVM_SETCOLUMNWIDTH:
    return LISTVIEW_SetColumnWidth(infoPtr, (INT)wParam, SLOWORD(lParam));

  case LVM_SETEXTENDEDLISTVIEWSTYLE:
    return LISTVIEW_SetExtendedListViewStyle(infoPtr, (DWORD)wParam, (DWORD)lParam);

  /* case LVN_SETGROUPINFO: */

  /* case LVN_SETGROUPMETRICS: */

  case LVM_SETHOTCURSOR:
    return (LRESULT)LISTVIEW_SetHotCursor(infoPtr, (HCURSOR)lParam);

  case LVM_SETHOTITEM:
    return LISTVIEW_SetHotItem(infoPtr, (INT)wParam);

  case LVM_SETHOVERTIME:
    return LISTVIEW_SetHoverTime(infoPtr, (DWORD)wParam);

  case LVM_SETICONSPACING:
    return LISTVIEW_SetIconSpacing(infoPtr, (DWORD)lParam);

  case LVM_SETIMAGELIST:
    return (LRESULT)LISTVIEW_SetImageList(infoPtr, (INT)wParam, (HIMAGELIST)lParam);

  /* case LVN_SETINFOTIP: */

  /* case LVN_SETINSERTMARK: */

  /* case LVN_SETINSERTMARKCOLOR: */

  case LVM_SETITEMA:
    return LISTVIEW_SetItemT(infoPtr, (LPLVITEMW)lParam, FALSE);

  case LVM_SETITEMW:
    return LISTVIEW_SetItemT(infoPtr, (LPLVITEMW)lParam, TRUE);

  case LVM_SETITEMCOUNT:
    return LISTVIEW_SetItemCount(infoPtr, (INT)wParam, (DWORD)lParam);

  case LVM_SETITEMPOSITION:
    {
	POINT pt = { SLOWORD(lParam), SHIWORD(lParam) };
        return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, pt);
    }

  case LVM_SETITEMPOSITION32:
    if (lParam == 0) return FALSE;
    return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, *((POINT*)lParam));

  case LVM_SETITEMSTATE:
    return LISTVIEW_SetItemState(infoPtr, (INT)wParam, (LPLVITEMW)lParam);

  case LVM_SETITEMTEXTA:
    return LISTVIEW_SetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, FALSE);

  case LVM_SETITEMTEXTW:
    return LISTVIEW_SetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, TRUE);

  /* case LVN_SETOUTLINECOLOR: */

  /* case LVN_SETSELECTEDCOLUMN: */

  case LVM_SETSELECTIONMARK:
    return LISTVIEW_SetSelectionMark(infoPtr, (INT)lParam);

  case LVM_SETTEXTBKCOLOR:
    return LISTVIEW_SetTextBkColor(infoPtr, (COLORREF)lParam);

  case LVM_SETTEXTCOLOR:
    return LISTVIEW_SetTextColor(infoPtr, (COLORREF)lParam);

  /* case LVN_SETTILEINFO: */

  /* case LVN_SETTILEVIEWINFO: */

  /* case LVN_SETTILEWIDTH: */

  /* case LVM_SETTOOLTIPS: */

  /* case LVM_SETUNICODEFORMAT: */

  /* case LVN_SETVIEW: */

  /* case LVM_SETWORKAREAS: */

  /* case LVN_SORTGROUPS: */

  case LVM_SORTITEMS:
    return LISTVIEW_SortItems(infoPtr, (PFNLVCOMPARE)lParam, (LPARAM)wParam);

  case LVM_SUBITEMHITTEST:
    return LISTVIEW_HitTest(infoPtr, (LPLVHITTESTINFO)lParam, TRUE, FALSE);

  case LVM_UPDATE:
    return LISTVIEW_Update(infoPtr, (INT)wParam);

  case WM_CHAR:
    return LISTVIEW_ProcessLetterKeys( infoPtr, wParam, lParam );

  case WM_COMMAND:
    return LISTVIEW_Command(infoPtr, wParam, lParam);

  case WM_CREATE:
    return LISTVIEW_Create(hwnd, (LPCREATESTRUCTW)lParam);

  case WM_ERASEBKGND:
    return LISTVIEW_EraseBkgnd(infoPtr, (HDC)wParam);

  case WM_GETDLGCODE:
    return DLGC_WANTCHARS | DLGC_WANTARROWS;

  case WM_GETFONT:
    return infoPtr->hFont;

  case WM_HSCROLL:
    return LISTVIEW_HScroll(infoPtr, (INT)LOWORD(wParam), 0, (HWND)lParam);

  case WM_KEYDOWN:
    return LISTVIEW_KeyDown(infoPtr, (INT)wParam, (LONG)lParam);

  case WM_KILLFOCUS:
    return LISTVIEW_KillFocus(infoPtr);

  case WM_LBUTTONDBLCLK:
    return LISTVIEW_LButtonDblClk(infoPtr, (WORD)wParam, MAKEPOINTS(lParam));

  case WM_LBUTTONDOWN:
    return LISTVIEW_LButtonDown(infoPtr, (WORD)wParam, MAKEPOINTS(lParam));

  case WM_LBUTTONUP:
    return LISTVIEW_LButtonUp(infoPtr, (WORD)wParam, MAKEPOINTS(lParam));

  case WM_MOUSEMOVE:
    return LISTVIEW_MouseMove (infoPtr, (WORD)wParam, MAKEPOINTS(lParam));

  case WM_MOUSEHOVER:
    return LISTVIEW_MouseHover(infoPtr, (WORD)wParam, MAKEPOINTS(lParam));

  case WM_NCDESTROY:
    return LISTVIEW_NCDestroy(infoPtr);

  case WM_NOTIFY:
    return LISTVIEW_Notify(infoPtr, (INT)wParam, (LPNMHDR)lParam);

  case WM_NOTIFYFORMAT:
    return LISTVIEW_NotifyFormat(infoPtr, (HWND)wParam, (INT)lParam);

  case WM_PAINT:
    return LISTVIEW_Paint(infoPtr, (HDC)wParam);

  case WM_RBUTTONDBLCLK:
    return LISTVIEW_RButtonDblClk(infoPtr, (WORD)wParam, MAKEPOINTS(lParam));

  case WM_RBUTTONDOWN:
    return LISTVIEW_RButtonDown(infoPtr, (WORD)wParam, MAKEPOINTS(lParam));

  case WM_RBUTTONUP:
    return LISTVIEW_RButtonUp(infoPtr, (WORD)wParam, MAKEPOINTS(lParam));

  case WM_SETCURSOR:
    if(LISTVIEW_SetCursor(infoPtr, (HWND)wParam, LOWORD(lParam), HIWORD(lParam)))
      return TRUE;
    goto fwd_msg;

  case WM_SETFOCUS:
    return LISTVIEW_SetFocus(infoPtr, (HWND)wParam);

  case WM_SETFONT:
    return LISTVIEW_SetFont(infoPtr, (HFONT)wParam, (WORD)lParam);

  case WM_SETREDRAW:
    return LISTVIEW_SetRedraw(infoPtr, (BOOL)wParam);

  case WM_SIZE:
    return LISTVIEW_Size(infoPtr, (int)SLOWORD(lParam), (int)SHIWORD(lParam));

  case WM_STYLECHANGED:
    return LISTVIEW_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam);

  case WM_SYSCOLORCHANGE:
    COMCTL32_RefreshSysColors();
    return 0;

/*	case WM_TIMER: */

  case WM_VSCROLL:
    return LISTVIEW_VScroll(infoPtr, (INT)LOWORD(wParam), 0, (HWND)lParam);

  case WM_MOUSEWHEEL:
      if (wParam & (MK_SHIFT | MK_CONTROL))
          return DefWindowProcW(hwnd, uMsg, wParam, lParam);
      return LISTVIEW_MouseWheel(infoPtr, (short int)HIWORD(wParam));

  case WM_WINDOWPOSCHANGED:
      if (!(((WINDOWPOS *)lParam)->flags & SWP_NOSIZE)) {
	  SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE |
		       SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
	  LISTVIEW_UpdateSize(infoPtr);
	  LISTVIEW_UpdateScroll(infoPtr);
      }
      return DefWindowProcW(hwnd, uMsg, wParam, lParam);

/*	case WM_WININICHANGE: */

  default:
    if ((uMsg >= WM_USER) && (uMsg < WM_APP))
      ERR("unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam);

  fwd_msg:
    /* call default window procedure */
    return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  }

  return 0;
}

/***
 * DESCRIPTION:
 * Registers the window class.
 *
 * PARAMETER(S):
 * None
 *
 * RETURN:
 * None
 */
void LISTVIEW_Register(void)
{
    WNDCLASSW wndClass;

    ZeroMemory(&wndClass, sizeof(WNDCLASSW));
    wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
    wndClass.lpfnWndProc = (WNDPROC)LISTVIEW_WindowProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = sizeof(LISTVIEW_INFO *);
    wndClass.hCursor = LoadCursorW(0, IDC_ARROWW);
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndClass.lpszClassName = WC_LISTVIEWW;
    RegisterClassW(&wndClass);
}

/***
 * DESCRIPTION:
 * Unregisters the window class.
 *
 * PARAMETER(S):
 * None
 *
 * RETURN:
 * None
 */
void LISTVIEW_Unregister(void)
{
    UnregisterClassW(WC_LISTVIEWW, (HINSTANCE)NULL);
}

/***
 * DESCRIPTION:
 * Handle any WM_COMMAND messages
 *
 * PARAMETER(S):
 *
 * RETURN:
 */
static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    switch (HIWORD(wParam))
    {
	case EN_UPDATE:
	{
	    /*
	     * Adjust the edit window size
	     */
	    WCHAR buffer[1024];
	    HDC           hdc = GetDC(infoPtr->hwndEdit);
            HFONT         hFont, hOldFont = 0;
	    RECT	  rect;
	    SIZE	  sz;
	    int		  len;

	    if (!infoPtr->hwndEdit || !hdc) return 0;
	    len = GetWindowTextW(infoPtr->hwndEdit, buffer, sizeof(buffer)/sizeof(buffer[0]));
	    GetWindowRect(infoPtr->hwndEdit, &rect);

            /* Select font to get the right dimension of the string */
            hFont = SendMessageW(infoPtr->hwndEdit, WM_GETFONT, 0, 0);
            if(hFont != 0)
            {
                hOldFont = SelectObject(hdc, hFont);
            }

	    if (GetTextExtentPoint32W(hdc, buffer, lstrlenW(buffer), &sz))
	    {
                TEXTMETRICW textMetric;

                /* Add Extra spacing for the next character */
                GetTextMetricsW(hdc, &textMetric);
                sz.cx += (textMetric.tmMaxCharWidth * 2);

		SetWindowPos (
		    infoPtr->hwndEdit,
		    HWND_TOP,
		    0,
		    0,
		    sz.cx,
		    rect.bottom - rect.top,
		    SWP_DRAWFRAME|SWP_NOMOVE);
	    }
            if(hFont != 0)
                SelectObject(hdc, hOldFont);

	    ReleaseDC(infoPtr->hwndSelf, hdc);

	    break;
	}

	default:
	  return SendMessageW (GetParent (infoPtr->hwndSelf), WM_COMMAND, wParam, lParam);
    }

    return 0;
}


/***
 * DESCRIPTION:
 * Subclassed edit control windproc function
 *
 * PARAMETER(S):
 *
 * RETURN:
 */
static LRESULT EditLblWndProcT(HWND hwnd, UINT uMsg,
	WPARAM wParam, LPARAM lParam, BOOL isW)
{
    LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongW(GetParent(hwnd), 0);
    BOOL cancel = FALSE;

    TRACE("(hwnd=%x, uMsg=%x, wParam=%x, lParam=%lx, isW=%d)\n",
	  hwnd, uMsg, wParam, lParam, isW);

    switch (uMsg)
    {
	case WM_GETDLGCODE:
	  return DLGC_WANTARROWS | DLGC_WANTALLKEYS;

	case WM_KILLFOCUS:
	    break;

	case WM_DESTROY:
	{
	    WNDPROC editProc = infoPtr->EditWndProc;
	    infoPtr->EditWndProc = 0;
	    SetWindowLongW(hwnd, GWL_WNDPROC, (LONG)editProc);
	    return CallWindowProcT(editProc, hwnd, uMsg, wParam, lParam, isW);
	}

	case WM_KEYDOWN:
	    if (VK_ESCAPE == (INT)wParam)
	    {
		cancel = TRUE;
                break;
	    }
	    else if (VK_RETURN == (INT)wParam)
		break;

	default:
	    return CallWindowProcT(infoPtr->EditWndProc, hwnd, uMsg, wParam, lParam, isW);
    }

    /* kill the edit */
    if (infoPtr->hwndEdit)
    {
	LPWSTR buffer = NULL;

        infoPtr->hwndEdit = 0;
	if (!cancel)
	{
	    DWORD len = isW ? GetWindowTextLengthW(hwnd) : GetWindowTextLengthA(hwnd);

	    if (len)
	    {
		if ( (buffer = COMCTL32_Alloc((len+1) * (isW ? sizeof(WCHAR) : sizeof(CHAR)))) )
		{
		    if (isW) GetWindowTextW(hwnd, buffer, len+1);
		    else GetWindowTextA(hwnd, (CHAR*)buffer, len+1);
		}
	    }
	}
	LISTVIEW_EndEditLabelT(infoPtr, buffer, isW);

	if (buffer) COMCTL32_Free(buffer);

    }

    SendMessageW(hwnd, WM_CLOSE, 0, 0);
    return TRUE;
}

/***
 * DESCRIPTION:
 * Subclassed edit control windproc function
 *
 * PARAMETER(S):
 *
 * RETURN:
 */
LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    return EditLblWndProcT(hwnd, uMsg, wParam, lParam, TRUE);
}

/***
 * DESCRIPTION:
 * Subclassed edit control windproc function
 *
 * PARAMETER(S):
 *
 * RETURN:
 */
LRESULT CALLBACK EditLblWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    return EditLblWndProcT(hwnd, uMsg, wParam, lParam, FALSE);
}

/***
 * DESCRIPTION:
 * Creates a subclassed edit cotrol
 *
 * PARAMETER(S):
 *
 * RETURN:
 */
static HWND CreateEditLabelT(LISTVIEW_INFO *infoPtr, LPCWSTR text, DWORD style,
	INT x, INT y, INT width, INT height, BOOL isW)
{
    WCHAR editName[5] = { 'E', 'd', 'i', 't', '\0' };
    HWND hedit;
    SIZE sz;
    HDC hdc;
    HDC hOldFont=0;
    TEXTMETRICW textMetric;
    HINSTANCE hinst = GetWindowLongW(infoPtr->hwndSelf, GWL_HINSTANCE);

    TRACE("(text=%s, ..., isW=%d)\n", debugtext_t(text, isW), isW);

    style |= WS_CHILDWINDOW|WS_CLIPSIBLINGS|ES_LEFT|WS_BORDER;
    hdc = GetDC(infoPtr->hwndSelf);

    /* Select the font to get appropriate metric dimensions */
    if(infoPtr->hFont != 0)
        hOldFont = SelectObject(hdc, infoPtr->hFont);

    /*Get String Lenght in pixels */
    GetTextExtentPoint32W(hdc, text, lstrlenW(text), &sz);

    /*Add Extra spacing for the next character */
    GetTextMetricsW(hdc, &textMetric);
    sz.cx += (textMetric.tmMaxCharWidth * 2);

    if(infoPtr->hFont != 0)
        SelectObject(hdc, hOldFont);

    ReleaseDC(infoPtr->hwndSelf, hdc);
    if (isW)
	hedit = CreateWindowW(editName, text, style, x, y, sz.cx, height, infoPtr->hwndSelf, 0, hinst, 0);
    else
	hedit = CreateWindowA("Edit", (LPCSTR)text, style, x, y, sz.cx, height, infoPtr->hwndSelf, 0, hinst, 0);

    if (!hedit) return 0;

    infoPtr->EditWndProc = (WNDPROC)
	(isW ? SetWindowLongW(hedit, GWL_WNDPROC, (LONG)EditLblWndProcW) :
               SetWindowLongA(hedit, GWL_WNDPROC, (LONG)EditLblWndProcA) );

    SendMessageW(hedit, WM_SETFONT, infoPtr->hFont, FALSE);

    return hedit;
}
