/*
 * Listview control
 *
 * Copyright 1998 Eric Kohl
 * Copyright 1999 Luc Tourangeau
 *
 * NOTES
 * Listview control implementation. 
 *
 * TODO:
 *
 *   1. Multiple selections in icon or small icon display modes DO NOT
 *      behave like the Microsoft control.
 *   2. No horizontal scrolling when header is larger than the client area.
 *   3. Implement LVM_FINDITEM for key selections.
 *   4. Drawing optimizations.
 *
 * Notifications:
 *   LISTVIEW_Notify : most notifications from children (editbox and header)
 *
 * Data structure:
 *   LISTVIEW_SortItems : empty stub 
 *   LISTVIEW_SetItemCount : empty stub 
 * 
 * Unicode:
 *   LISTVIEW_SetItem32W : no unicode support
 *   LISTVIEW_InsertItem32W : no unicode support
 *   LISTVIEW_InsertColumn32W : no unicode support
 *   LISTVIEW_GetColumnW : no unicode support
 *
 * Advanced functionality:
 *   LISTVIEW_GetNumberOfWorkAreas : not implemented
 *   LISTVIEW_GetNextItem : empty stub
 *   LISTVIEW_GetHotCursor : not implemented
 *   LISTVIEW_GetHotItem : not implemented
 *   LISTVIEW_GetHoverTime : not implemented
 *   LISTVIEW_GetISearchString : not implemented 
 *   LISTVIEW_GetBkImage : not implemented
 *   LISTVIEW_EditLabel : REPORT (need to implement a timer)
 *   LISTVIEW_GetColumnOrderArray : not implemented
 *   LISTVIEW_Arrange : empty stub
 *   LISTVIEW_FindItem : empty stub 
 *   LISTVIEW_ApproximateViewRect : incomplete
 *   LISTVIEW_Scroll : not implemented 
 *   LISTVIEW_KeyDown : page up and page down  + redo small icon and icon 
 *   LISTVIEW_RedrawItems : empty stub
 *   LISTVIEW_Update : not completed
 */

#include <string.h>
#include "winbase.h"
#include "commctrl.h"
#include "listview.h"
#include "debug.h"

DEFAULT_DEBUG_CHANNEL(listview)

/*
 * constants 
 */

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

/* 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 */
#define ICON_TOP_PADDING 2
#define ICON_BOTTOM_PADDING 2

/* padding for label in large icon display mode */
#define LABEL_VERT_OFFSET 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 96 

/* 
 * macros
 */

/* retrieve the number of items in the listview */
#define GETITEMCOUNT(infoPtr) ((infoPtr)->hdpaItems->nItemCount)
#define ListView_LVNotify(hwnd,lCtrlId,plvnm) \
    (BOOL)SendMessageA((hwnd),WM_NOTIFY,(WPARAM)(INT)lCtrlId,(LPARAM)(LPNMLISTVIEW)(plvnm))
#define ListView_Notify(hwnd,lCtrlId,pnmh) \
    (BOOL)SendMessageA((hwnd),WM_NOTIFY,(WPARAM)(INT)lCtrlId,(LPARAM)(LPNMHDR)(pnmh))

/* 
 * forward declarations 
 */

static VOID LISTVIEW_AlignLeft(HWND);
static VOID LISTVIEW_AlignTop(HWND);
static VOID LISTVIEW_AddGroupSelection(HWND, INT);
static VOID LISTVIEW_AddSelection(HWND, INT);
static BOOL LISTVIEW_AddSubItem(HWND, LPLVITEMA);
static INT LISTVIEW_FindInsertPosition(HDPA, INT);
static VOID LISTVIEW_GetItemDispInfo(HWND, INT, LISTVIEW_ITEM *lpItem, INT *, 
                                     UINT *, CHAR **, INT);
static INT LISTVIEW_GetItemHeight(HWND, LONG);
static BOOL LISTVIEW_GetItemPosition(HWND, INT, LPPOINT);
static LRESULT LISTVIEW_GetItemRect(HWND, INT, LPRECT);
static INT LISTVIEW_GetItemWidth(HWND, LONG);
static INT LISTVIEW_GetLabelWidth(HWND, INT);
static LRESULT LISTVIEW_GetOrigin(HWND, LPPOINT);
static LISTVIEW_SUBITEM* LISTVIEW_GetSubItem(HDPA, INT);
static VOID LISTVIEW_GetSubItemDispInfo(HWND hwnd, INT, LPARAM,
                                        LISTVIEW_SUBITEM *, INT, INT *, 
                                        CHAR **, INT);
static LRESULT LISTVIEW_GetViewRect(HWND, LPRECT);
static BOOL LISTVIEW_InitItem(HWND, LISTVIEW_ITEM *, LPLVITEMA);
static BOOL LISTVIEW_InitSubItem(HWND, LISTVIEW_SUBITEM *, LPLVITEMA);
static LRESULT LISTVIEW_MouseSelection(HWND, INT, INT);
static BOOL LISTVIEW_RemoveColumn(HDPA, INT);
static VOID LISTVIEW_RemoveSelections(HWND, INT, INT);
static BOOL LISTVIEW_RemoveSubItem(HDPA, INT);
static BOOL LISTVIEW_ScrollView(HWND, INT, INT);
static VOID LISTVIEW_SetGroupSelection(HWND, INT);
static BOOL LISTVIEW_SetItem(HWND, LPLVITEMA);
static VOID LISTVIEW_SetItemFocus(HWND, INT);
static BOOL LISTVIEW_SetItemPosition(HWND, INT, INT, INT);
static VOID LISTVIEW_SetScroll(HWND, LONG);
static VOID LISTVIEW_SetSelection(HWND, INT);
static VOID LISTVIEW_SetSize(HWND, LONG, LONG, LONG);
static BOOL LISTVIEW_SetSubItem(HWND, LPLVITEMA);
static VOID LISTVIEW_SetViewInfo(HWND, LONG);
static LRESULT LISTVIEW_SetViewRect(HWND, LPRECT);
static BOOL LISTVIEW_ToggleSelection(HWND, INT);
static VOID LISTVIEW_UnsupportedStyles(LONG lStyle);

/***
 * DESCRIPTION:
 * Scrolls the content of the listview.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : number of horizontal scroll positions 
 *           (relative to the current scroll postioon)
 * [I] INT : number of vertical scroll positions
 *           (relative to the current scroll postioon)
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_ScrollView(HWND hwnd, INT nHScroll, INT nVScroll)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0); 
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
  INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
  INT nHScrollPos = 0;
  INT nVScrollPos = 0;
  INT nHScrollInc = 0;
  INT nVScrollInc = 0;
  BOOL bResult = FALSE;

  if (((lStyle & WS_HSCROLL) != 0) && (nHScroll != 0))
  {
    switch (LVS_TYPEMASK & lStyle)
    {
    case LVS_LIST:
      nHScrollInc = nHScroll * infoPtr->nItemWidth;
      break;

    case LVS_REPORT:
      /* TO DO : not implemented at this point. I experiences some 
         problems when performing child window scrolling. */
      break;

    case LVS_SMALLICON:
    case LVS_ICON:
      nHScrollInc = nHScroll * max(nListWidth, nListWidth / 10);
      break;
    }
    
    nHScrollPos = GetScrollPos(hwnd, SB_HORZ) + nHScroll;
  }

  if (((lStyle & WS_VSCROLL) != 0) & (nVScroll != 0))
  {
    switch (LVS_TYPEMASK & lStyle)
    {
    case LVS_REPORT:
      nVScrollInc = nVScroll * infoPtr->nItemHeight;
      nVScrollPos = GetScrollPos(hwnd, SB_VERT) + nVScroll;
      break;
      
    case LVS_SMALLICON:
    case LVS_ICON:
      nVScrollInc = nVScroll * max(nListHeight, nListHeight / 10);
      nVScrollPos = GetScrollPos(hwnd, SB_VERT) + nVScroll;
      break;
    }
  }

  /* perform scroll operation & set new scroll position */
  if ((nHScrollInc != 0) || (nVScrollInc != 0))
  {
    RECT rc;
    HDC hdc = GetDC(hwnd);
    ScrollDC(hdc, -nHScrollInc, -nVScrollInc, &infoPtr->rcList, NULL, 
             (HRGN) NULL, &rc);
    InvalidateRect(hwnd, &rc, TRUE);
    SetScrollPos(hwnd, SB_HORZ, nHScrollPos, TRUE);
    SetScrollPos(hwnd, SB_VERT, nVScrollPos, TRUE);
    ReleaseDC(hwnd, hdc);
    bResult = TRUE;
  }

  return bResult; 
}

/***
 * 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_TYPEMASK & lStyle) == LVS_EDITLABELS)
  {
    FIXME( listview, "  LVS_EDITLABELS\n");
  }

  if ((LVS_TYPEMASK & lStyle) == LVS_NOCOLUMNHEADER)
  {
    FIXME( listview, "  LVS_SORTDESCENDING\n");
  }

  if ((LVS_TYPEMASK & lStyle) == LVS_NOLABELWRAP)
  {
    FIXME( listview, "  LVS_NOLABELWRAP\n");
  }

  if ((LVS_TYPEMASK & lStyle) == LVS_NOSCROLL)
  {
    FIXME( listview, "  LVS_NOSCROLL\n");
  }

  if ((LVS_TYPEMASK & lStyle) == LVS_NOSORTHEADER)
  {
    FIXME( listview, "  LVS_NOSORTHEADER\n");
  }

  if ((LVS_TYPEMASK & lStyle) == LVS_OWNERDRAWFIXED)
  {
    FIXME( listview, "  LVS_OWNERDRAWFIXED\n");
  }

  if ((LVS_TYPEMASK & lStyle) == LVS_SHAREIMAGELISTS)
  {
    FIXME( listview, "  LVS_SHAREIMAGELISTS\n");
  }

  if ((LVS_TYPEMASK & lStyle) == LVS_SHOWSELALWAYS)
  {
    FIXME( listview, "  LVS_SHOWSELALWAYS\n");
  }

  if ((LVS_TYPEMASK & lStyle) == LVS_SINGLESEL)
  {
    FIXME( listview, "  LVS_SINGLESEL\n");
  }

  if ((LVS_TYPEMASK & lStyle) == LVS_SORTASCENDING)
  {
    FIXME( listview, "  LVS_SORTASCENDING\n");
  }

  if ((LVS_TYPEMASK & lStyle) == LVS_SORTDESCENDING)
  {
    FIXME( listview, "  LVS_SORTDESCENDING\n");
  }
}

/***
 * DESCRIPTION:
 * Aligns the items with the top edge of the window.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_AlignTop(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
  POINT ptItem;
  RECT rcView;
  INT i;
  
  switch (LVS_TYPEMASK & lStyle)
  {
  case LVS_SMALLICON:
  case LVS_ICON:
    ZeroMemory(&ptItem, sizeof(POINT));
    ZeroMemory(&rcView, sizeof(RECT));
    if (nListWidth > infoPtr->nItemWidth)
    {
      for (i = 0; i < GETITEMCOUNT(infoPtr); i++)
      {
        if (ptItem.x + infoPtr->nItemWidth > nListWidth)
        {
          ptItem.x = 0;
          ptItem.y += infoPtr->nItemHeight;
        }
        
        LISTVIEW_SetItemPosition(hwnd, i, ptItem.x, ptItem.y);
        ptItem.x += infoPtr->nItemWidth;
        rcView.right = max(rcView.right, ptItem.x);
      }
    }
    else
    {
      for (i = 0; i < GETITEMCOUNT(infoPtr); i++)
      {
        LISTVIEW_SetItemPosition(hwnd, i, ptItem.x, ptItem.y);
        ptItem.x += infoPtr->nItemWidth;
      }
      rcView.right = ptItem.x;
      rcView.bottom = infoPtr->nItemHeight;
    }

    rcView.bottom = ptItem.y + infoPtr->nItemHeight;
    LISTVIEW_SetViewRect(hwnd, &rcView);
  }
}

/***
 * DESCRIPTION:
 * Aligns the items with the left edge of the window.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_AlignLeft(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
  POINT ptItem;
  RECT rcView;
  INT i;
  
  switch (LVS_TYPEMASK & lStyle)
  {
  case LVS_SMALLICON:
  case LVS_ICON:
    ZeroMemory(&ptItem, sizeof(POINT));
    ZeroMemory(&rcView, sizeof(RECT));
    if (nListHeight > infoPtr->nItemHeight)
    {
      for (i = 0; i < GETITEMCOUNT(infoPtr); i++)
      {
        if (ptItem.y + infoPtr->nItemHeight > nListHeight)
        {
          ptItem.y = 0;
          ptItem.x += infoPtr->nItemWidth;
        }

        LISTVIEW_SetItemPosition(hwnd, i, ptItem.x, ptItem.y);
        ptItem.y += infoPtr->nItemHeight;
        rcView.bottom = max(rcView.bottom, ptItem.y);
      }
    }
    else
    {
      for (i = 0; i < GETITEMCOUNT(infoPtr); i++)
      {
        LISTVIEW_SetItemPosition(hwnd, i, ptItem.x, ptItem.y);
        ptItem.y += infoPtr->nItemHeight;
      }
      rcView.bottom = ptItem.y;
      rcView.right = infoPtr->nItemWidth;
    }

    rcView.right = ptItem.x + infoPtr->nItemWidth;
    LISTVIEW_SetViewRect(hwnd, &rcView);
    break;
 }
}

/***
 * DESCRIPTION:
 * Retrieves display information.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index
 * [I] LISTVIEW_ITEM* : listview control item
 * [O] INT : image index
 * [O] UINT : state value
 * [O] CHAR** : string
 * [I] INT : size of string
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_GetItemDispInfo(HWND hwnd, INT nItem, 
                                     LISTVIEW_ITEM *lpItem, INT *pnDispImage, 
                                     UINT *puState, CHAR **ppszDispText, 
                                     INT nDispTextSize)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lCtrlId = GetWindowLongA(hwnd, GWL_ID);
  NMLVDISPINFOA dispInfo;
  ZeroMemory(&dispInfo, sizeof(NMLVDISPINFOA));
 
  if ((pnDispImage != NULL) && (lpItem->iImage == I_IMAGECALLBACK))
  {
    dispInfo.item.mask |= LVIF_IMAGE;
  }

  if ((ppszDispText != NULL) && (lpItem->pszText == LPSTR_TEXTCALLBACKA))
  {
    ZeroMemory(*ppszDispText, sizeof(CHAR)*nDispTextSize);
    dispInfo.item.mask |= LVIF_TEXT;
    dispInfo.item.pszText = *ppszDispText;
    dispInfo.item.cchTextMax = nDispTextSize;
  }

  if ((puState != NULL) && (infoPtr->uCallbackMask != 0))
  {
    dispInfo.item.mask |= LVIF_STATE;
    dispInfo.item.stateMask = infoPtr->uCallbackMask; 
  }

  if (dispInfo.item.mask != 0)
  {
    dispInfo.hdr.hwndFrom = hwnd;
    dispInfo.hdr.idFrom = lCtrlId;
    dispInfo.hdr.code = LVN_GETDISPINFOA;
    dispInfo.item.iItem = nItem;
    dispInfo.item.iSubItem = 0;
    dispInfo.item.lParam = lpItem->lParam;
    ListView_Notify(GetParent(hwnd), lCtrlId, &dispInfo);
  }

  if (pnDispImage != NULL)
  {
    if (dispInfo.item.mask & LVIF_IMAGE)
    {
      *pnDispImage = dispInfo.item.iImage;
    }
    else
    {
      *pnDispImage = lpItem->iImage;
    }
  }

  if (ppszDispText != NULL)
  {
    if (dispInfo.item.mask & LVIF_TEXT)
    {
      if (dispInfo.item.mask & LVIF_DI_SETITEM)
      {
        Str_SetPtrA(&lpItem->pszText, dispInfo.item.pszText);
      }
      *ppszDispText = dispInfo.item.pszText;
    }
    else
    {
      *ppszDispText = lpItem->pszText;
    }
  }

  if (puState != NULL)
  {
    if (dispInfo.item.mask & LVIF_STATE)
    {
      *puState = lpItem->state;
      *puState &= ~dispInfo.item.stateMask;
      *puState |= (dispInfo.item.state & dispInfo.item.stateMask);
    }
    else
    {
      *puState = lpItem->state;
    }
  }
}

/***
 * DESCRIPTION:
 * Retrieves subitem display information.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index
 * [I] LONG : LPARAM of item
 * [I] LISTVIEW_SUBITEM* : listview control subitem
 * [I] INT : subitem position/order 
 * [O] INT : image index
 * [O] UINT : state value
 * [O] CHAR** : display string
 * [I] INT : size of string
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_GetSubItemDispInfo(HWND hwnd, INT nItem, LPARAM lParam,
                                        LISTVIEW_SUBITEM *lpSubItem, 
                                        INT nSubItemPos, INT *pnDispImage, 
                                        CHAR **ppszDispText, INT nDispTextSize)
{
  LONG lCtrlId = GetWindowLongA(hwnd, GWL_ID);
  NMLVDISPINFOA dispInfo;
  ZeroMemory(&dispInfo, sizeof(NMLVDISPINFOA));

  if (lpSubItem == NULL)
  {
    ZeroMemory(*ppszDispText, sizeof(CHAR)*nDispTextSize);
    dispInfo.item.mask |= LVIF_TEXT;
    dispInfo.item.pszText = *ppszDispText;
    dispInfo.item.cchTextMax = nDispTextSize;
    dispInfo.hdr.hwndFrom = hwnd;
    dispInfo.hdr.idFrom = lCtrlId;
    dispInfo.hdr.code = LVN_GETDISPINFOA;
    dispInfo.item.iItem = nItem;
    dispInfo.item.iSubItem = nSubItemPos;
    dispInfo.item.lParam = lParam;
    ListView_Notify(GetParent(hwnd), lCtrlId, &dispInfo);
    if (dispInfo.item.mask & LVIF_DI_SETITEM)
    {
      Str_SetPtrA(&lpSubItem->pszText, dispInfo.item.pszText);
    }
    *ppszDispText = dispInfo.item.pszText;
  }
  else
  {
    if ((pnDispImage != NULL) && (lpSubItem->iImage == I_IMAGECALLBACK))
    {
      dispInfo.item.mask |= LVIF_IMAGE;
    }

    if ((ppszDispText != NULL) && (lpSubItem->pszText == LPSTR_TEXTCALLBACKA))
    {
      ZeroMemory(*ppszDispText, sizeof(CHAR)*nDispTextSize);
      dispInfo.item.mask |= LVIF_TEXT;
      dispInfo.item.pszText = *ppszDispText;
      dispInfo.item.cchTextMax = nDispTextSize;
    }

    if (dispInfo.item.mask != 0)
    {
      dispInfo.hdr.hwndFrom = hwnd;
      dispInfo.hdr.idFrom = lCtrlId;
      dispInfo.hdr.code = LVN_GETDISPINFOA;
      dispInfo.item.iItem = nItem;
      dispInfo.item.iSubItem = lpSubItem->iSubItem;
      dispInfo.item.lParam = lParam;
      ListView_Notify(GetParent(hwnd), lCtrlId, &dispInfo);
    }

    if (pnDispImage != NULL)
    {
      if (dispInfo.item.mask & LVIF_IMAGE)
      {
        *pnDispImage = dispInfo.item.iImage;
      }
      else
      {
        *pnDispImage = lpSubItem->iImage;
      }
    }

    if (ppszDispText != NULL)
    {
      if (dispInfo.item.mask & LVIF_TEXT)
      {
        if (dispInfo.item.mask & LVIF_DI_SETITEM)
        {
          Str_SetPtrA(&lpSubItem->pszText, dispInfo.item.pszText);
        }
        *ppszDispText = dispInfo.item.pszText;
      }
      else
      {
        *ppszDispText = lpSubItem->pszText;
      }
    }
  }
}

/***
 * DESCRIPTION:
 * Calculates the width of an item.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] LONG : window style
 *
 * RETURN:
 * Returns item width.
 */
static INT LISTVIEW_GetItemWidth(HWND hwnd, LONG lStyle)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nHeaderItemCount;
  RECT rcHeaderItem;
  INT nItemWidth = 0;
  INT nLabelWidth;
  INT i;

  TRACE(listview, "(hwnd=%x,lStyle=%lx)\n", hwnd, lStyle);

  switch (LVS_TYPEMASK & lStyle)
  {
  case LVS_ICON:
    nItemWidth = infoPtr->iconSpacing.cx;
    break;

  case LVS_REPORT:
    /* calculate width of header */
    nHeaderItemCount = Header_GetItemCount(infoPtr->hwndHeader);
    for (i = 0; i < nHeaderItemCount; i++)
    {
      if (Header_GetItemRect(infoPtr->hwndHeader, i, &rcHeaderItem) != 0)
      {
        nItemWidth += (rcHeaderItem.right - rcHeaderItem.left);
      }
    }
    break;

  case LVS_SMALLICON:
  case LVS_LIST:
    for (i = 0; i < GETITEMCOUNT(infoPtr); i++)
    { 
      nLabelWidth = LISTVIEW_GetLabelWidth(hwnd, i);
      nItemWidth = max(nItemWidth, nLabelWidth);
    }

    /* default label size */
    if (GETITEMCOUNT(infoPtr) == 0)
    {
      nItemWidth = DEFAULT_COLUMN_WIDTH;
    }
    else
    {
      if (nItemWidth == 0)
      {
        nItemWidth = DEFAULT_LABEL_WIDTH;
      }
      else
      {
        /* add padding */
        nItemWidth += WIDTH_PADDING;
      
        if (infoPtr->himlSmall != NULL)
        {
          nItemWidth += infoPtr->iconSize.cx;
        }

        if (infoPtr->himlState != NULL)
        {
          nItemWidth += infoPtr->iconSize.cx;
        }
      }
    }
    break;

  }

  return nItemWidth;
}

/***
 * DESCRIPTION:
 * Calculates the height of an item.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] LONG : window style
 *
 * RETURN:
 * Returns item width.
 */
static INT LISTVIEW_GetItemHeight(HWND hwnd, LONG lStyle)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nItemHeight = 0;
  TEXTMETRICA tm; 
  HFONT hOldFont;
  HDC hdc;

  switch (LVS_TYPEMASK & lStyle)
  {
  case LVS_ICON:
    nItemHeight = infoPtr->iconSpacing.cy;
    break;

  case LVS_SMALLICON:
  case LVS_REPORT:
  case LVS_LIST:
    hdc = GetDC(hwnd);
    hOldFont = SelectObject(hdc, infoPtr->hFont);
    GetTextMetricsA(hdc, &tm);
    nItemHeight = max(tm.tmHeight, infoPtr->iconSize.cy) + HEIGHT_PADDING;
    SelectObject(hdc, hOldFont);
    ReleaseDC(hwnd, hdc);
    break;
  }

  return nItemHeight;
}

/***
 * DESCRIPTION:
 * Sets diplay information (needed for drawing operations).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * 
 * RETURN:
 * None
 */
static VOID LISTVIEW_SetViewInfo(HWND hwnd, LONG lStyle)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
  INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;

  switch (LVS_TYPEMASK & lStyle)
  {
  case LVS_REPORT:
    /* get number of fully visible items per column */
    infoPtr->nCountPerColumn = max(1, nListHeight / infoPtr->nItemHeight);
    break;

  case LVS_LIST:
    /* get number of fully visible items per column */
    infoPtr->nCountPerColumn = max(1, nListHeight / infoPtr->nItemHeight);
    
    /* get number of fully visible items per row */
    infoPtr->nCountPerRow = max(1, nListWidth / infoPtr->nItemWidth);
    break;
  }
}

/***
 * DESCRIPTION:
 * Adds a block of selections.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index 
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_AddGroupSelection(HWND hwnd, INT nItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nFirst = min(infoPtr->nSelectionMark, nItem);
  INT nLast = max(infoPtr->nSelectionMark, nItem);
  LVITEMA lvItem;
  INT i;

  lvItem.state = LVIS_SELECTED;
  lvItem.stateMask= LVIS_SELECTED;
  
  for (i = nFirst; i <= nLast; i++)
  {
    ListView_SetItemState(hwnd, i, &lvItem);
  }
  
  LISTVIEW_SetItemFocus(hwnd, nItem);
  infoPtr->nSelectionMark = nItem;
}

/***
 * DESCRIPTION:
 * Adds a single selection.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index 
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_AddSelection(HWND hwnd, INT nItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LVITEMA lvItem;

  lvItem.state = LVIS_SELECTED;
  lvItem.stateMask= LVIS_SELECTED;

  ListView_SetItemState(hwnd, nItem, &lvItem);

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

/***
 * DESCRIPTION:
 * Selects or unselects an item.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index 
 *
 * RETURN:
 *   SELECT: TRUE 
 *   UNSELECT : FALSE
 */
static BOOL LISTVIEW_ToggleSelection(HWND hwnd, INT nItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  BOOL bResult;
  LVITEMA lvItem;

  lvItem.stateMask= LVIS_SELECTED;

  if (ListView_GetItemState(hwnd, nItem, LVIS_SELECTED) & LVIS_SELECTED)
  {
    lvItem.state = 0;
    ListView_SetItemState(hwnd, nItem, &lvItem);
    bResult = FALSE;
  }
  else
  {
    lvItem.state = LVIS_SELECTED;
    ListView_SetItemState(hwnd, nItem, &lvItem);
    bResult = TRUE;
  }

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

  return bResult;
}

/***
 * DESCRIPTION:
 * Sets a single group selection.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index 
 *
 * RETURN:
 * None 
 */
static VOID LISTVIEW_SetGroupSelection(HWND hwnd, INT nItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nFirst = min(infoPtr->nSelectionMark, nItem);
  INT nLast = max(infoPtr->nSelectionMark, nItem);
  LVITEMA lvItem;
  INT i;

  if (nFirst > 0)
  {
    LISTVIEW_RemoveSelections(hwnd, 0, nFirst - 1);
  }

  if (nLast < GETITEMCOUNT(infoPtr))
  {
    LISTVIEW_RemoveSelections(hwnd, nLast + 1, GETITEMCOUNT(infoPtr));
  }

  lvItem.state = LVIS_SELECTED;
  lvItem.stateMask = LVIS_SELECTED;

  for (i = nFirst; i <= nLast; i++)
  {
    ListView_SetItemState(hwnd, i, &lvItem);
  }

  LISTVIEW_SetItemFocus(hwnd, nItem);
}

/***
 * DESCRIPTION:
 * Manages the item focus.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index 
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_SetItemFocus(HWND hwnd, INT nItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LVITEMA lvItem;

  lvItem.state = 0;
  lvItem.stateMask = LVIS_FOCUSED;
  ListView_SetItemState(hwnd, infoPtr->nFocusedItem, &lvItem); 
  
  lvItem.state =  LVIS_FOCUSED;
  lvItem.stateMask = LVIS_FOCUSED;
  ListView_SetItemState(hwnd, nItem, &lvItem);

  infoPtr->nFocusedItem = nItem;

  /* if multiple selection is allowed */
  ListView_EnsureVisible(hwnd, nItem, FALSE);
}

/***
 * DESCRIPTION:
 * Sets a single selection.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index 
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_SetSelection(HWND hwnd, INT nItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LVITEMA lvItem;

  if (nItem > 0)
  {
    LISTVIEW_RemoveSelections(hwnd, 0, nItem - 1);
  }

  if (nItem < GETITEMCOUNT(infoPtr))
  {
    LISTVIEW_RemoveSelections(hwnd, nItem + 1, GETITEMCOUNT(infoPtr));
  }

  lvItem.state = 0;
  lvItem.stateMask = LVIS_FOCUSED;
  ListView_SetItemState(hwnd, infoPtr->nFocusedItem, &lvItem); 
  
  lvItem.state =  LVIS_SELECTED | LVIS_FOCUSED;
  lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  ListView_SetItemState(hwnd, nItem, &lvItem);

  infoPtr->nFocusedItem = nItem;
  infoPtr->nSelectionMark = nItem;
}

/***
 * DESCRIPTION:
 * Set selection(s) with keyboard.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index 
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_KeySelection(HWND hwnd, INT nItem)
{
  WORD wShift = HIWORD(GetKeyState(VK_SHIFT));
  WORD wCtrl = HIWORD(GetKeyState(VK_CONTROL));

  if (wShift)
  {
    LISTVIEW_SetGroupSelection(hwnd, nItem); 
  }
  else if (wCtrl)
  {
    LISTVIEW_SetItemFocus(hwnd, nItem);
  }
  else
  {
    LISTVIEW_SetSelection(hwnd, nItem); 

    /* if multiple selection is allowed */
    ListView_EnsureVisible(hwnd, nItem, FALSE);
  }
}

/***
 * DESCRIPTION:
 * Determines the selected item.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : x ccordinate
 * [I] INT : y coordinate
 *
 * RETURN:
 *   SUCCESS : item index
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_MouseSelection(HWND hwnd, INT nPosX, INT nPosY)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  RECT rcItem;
  INT i;
  
  for (i = 0; i < GETITEMCOUNT(infoPtr); i++)
  {
    rcItem.left = LVIR_SELECTBOUNDS;
    if (LISTVIEW_GetItemRect(hwnd, i, &rcItem) == TRUE)
    {
      if ((rcItem.left <= nPosX) && (nPosX <= rcItem.right) && 
          (rcItem.top <= nPosY) && (nPosY <= rcItem.bottom))
      {
        return i;
      }
    }
  }

  return -1;
}

/***
 * DESCRIPTION:
 * Removes all selection states.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index 
 *
 * RETURN:
 *   SUCCCESS : TRUE
 *   FAILURE : FALSE
 */
static VOID LISTVIEW_RemoveSelections(HWND hwnd, INT nFirst, INT nLast)
{
  LVITEMA lvItem;
  INT i;

  lvItem.state = 0;
  lvItem.stateMask = LVIS_SELECTED;

  for (i = nFirst; i <= nLast; i++)
  {
    ListView_SetItemState(hwnd, i, &lvItem);
  }
}

/***
 * DESCRIPTION:
 * Removes a column.
 * 
 * PARAMETER(S):
 * [IO] HDPA : dynamic pointer array handle
 * [I] INT : column index (subitem index)
 *
 * RETURN:
 *   SUCCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_RemoveColumn(HDPA hdpaItems, INT nSubItem)
{
  BOOL bResult = TRUE;
  HDPA hdpaSubItems;
  INT i;

  for (i = 0; i < hdpaItems->nItemCount; i++)
  {
    hdpaSubItems = (HDPA)DPA_GetPtr(hdpaItems, i);
    if (hdpaSubItems != NULL)
    {
      if (LISTVIEW_RemoveSubItem(hdpaSubItems, nSubItem) == FALSE)
      {
        bResult = FALSE;
      }
    }
  }
    
  return bResult;
}

/***
 * DESCRIPTION:
 * Removes a subitem at a given position.
 * 
 * PARAMETER(S):
 * [IO] HDPA : dynamic pointer array handle
 * [I] INT : subitem index
 *
 * RETURN:
 *   SUCCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_RemoveSubItem(HDPA hdpaSubItems, INT nSubItem)
{
  LISTVIEW_SUBITEM *lpSubItem;
  INT i;

  for (i = 1; i < hdpaSubItems->nItemCount; i++)
  {
    lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
    if (lpSubItem != NULL)
    {
      if (lpSubItem->iSubItem == nSubItem)
      {
        /* free string */
        if ((lpSubItem->pszText != NULL) && 
            (lpSubItem->pszText != LPSTR_TEXTCALLBACKA))
        {
          COMCTL32_Free(lpSubItem->pszText);
        }
      
        /* free item */
        COMCTL32_Free(lpSubItem);

        /* free dpa memory */
        if (DPA_DeletePtr(hdpaSubItems, i) == NULL)
        {
          return FALSE;
        }
      }
      else if (lpSubItem->iSubItem > nSubItem)
      {
        return TRUE;
      }
    }
  }    
  
  return TRUE;
}

/***
 * DESCRIPTION:
 * Compares the item information.
 * 
 * PARAMETER(S):
 * [I] LISTVIEW_ITEM *: destination item 
 * [I] LPLVITEM : source item 
 *
 * RETURN:
 *   SUCCCESS : TRUE (EQUAL)
 *   FAILURE : FALSE (NOT EQUAL)
 */
static UINT LISTVIEW_GetItemChanges(LISTVIEW_ITEM *lpItem, LPLVITEMA lpLVItem)
{
  UINT uChanged = 0;

  if ((lpItem != NULL) && (lpLVItem != NULL))
  {
    if (lpLVItem->mask & LVIF_STATE)
    {
      if ((lpItem->state & lpLVItem->stateMask) != 
          (lpLVItem->state & lpLVItem->stateMask))
      {
        uChanged |= LVIF_STATE; 
      }
    }
    
    if (lpLVItem->mask & LVIF_IMAGE)
    {
      if (lpItem->iImage != lpLVItem->iImage)
      {
        uChanged |= LVIF_IMAGE; 
      }
    }
  
    if (lpLVItem->mask & LVIF_PARAM)
    {
      if (lpItem->lParam != lpLVItem->lParam)
      {
        uChanged |= LVIF_PARAM; 
      }
    }
    
    if (lpLVItem->mask & LVIF_INDENT)
    {
      if (lpItem->iIndent != lpLVItem->iIndent)
      {
        uChanged |= LVIF_INDENT; 
      }
    }

    if (lpLVItem->mask & LVIF_TEXT) 
    {
      if (lpLVItem->pszText == LPSTR_TEXTCALLBACKA) 
      {
        if (lpItem->pszText != LPSTR_TEXTCALLBACKA)
        {
          uChanged |= LVIF_TEXT; 
        }
      }
      else
      {
        if (lpItem->pszText == LPSTR_TEXTCALLBACKA)
        {
          uChanged |= LVIF_TEXT; 
        }
      }
    }
  }

  return uChanged;
}

/***
 * DESCRIPTION:
 * Initializes item attributes.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [O] LISTVIEW_ITEM *: destination item 
 * [I] LPLVITEM : source item 
 *
 * RETURN:
 *   SUCCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_InitItem(HWND hwnd, LISTVIEW_ITEM *lpItem, 
                              LPLVITEMA lpLVItem)
{
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  BOOL bResult = FALSE;

  if ((lpItem != NULL) && (lpLVItem != NULL))
  {
    bResult = TRUE;
    
    if (lpLVItem->mask & LVIF_STATE)
    {
      lpItem->state &= ~lpLVItem->stateMask;
      lpItem->state |= (lpLVItem->state & lpLVItem->stateMask);
    }
    
    if (lpLVItem->mask & LVIF_IMAGE)
    {
      lpItem->iImage = lpLVItem->iImage;
    }
  
    if (lpLVItem->mask & LVIF_PARAM)
    {
      lpItem->lParam = lpLVItem->lParam;
    }
    
    if (lpLVItem->mask & LVIF_INDENT)
    {
      lpItem->iIndent = lpLVItem->iIndent;
    }

    if (lpLVItem->mask & LVIF_TEXT) 
    {
      if (lpLVItem->pszText == LPSTR_TEXTCALLBACKA) 
      {
        if ((lStyle & LVS_SORTASCENDING) || (lStyle & LVS_SORTDESCENDING))
        {
          return FALSE;
        }

        if ((lpItem->pszText != NULL) && 
            (lpItem->pszText != LPSTR_TEXTCALLBACKA))
        {
          COMCTL32_Free(lpItem->pszText);
        }
    
        lpItem->pszText = LPSTR_TEXTCALLBACKA;
      }
      else 
      {
        if (lpItem->pszText == LPSTR_TEXTCALLBACKA)
        {
          lpItem->pszText = NULL;
        }
        
        bResult = Str_SetPtrA(&lpItem->pszText, lpLVItem->pszText);
      }
    }
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Initializes subitem attributes.
 *
 * NOTE: the documentation specifies that the operation fails if the user
 * tries to set the indent of a subitem.
 *
 * PARAMETER(S):
 * [I] HWND : window handle
 * [O] LISTVIEW_SUBITEM *: destination subitem
 * [I] LPLVITEM : source subitem
 *
 * RETURN:
 *   SUCCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_InitSubItem(HWND hwnd, LISTVIEW_SUBITEM *lpSubItem, 
                                   LPLVITEMA lpLVItem)
{
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  BOOL bResult = FALSE;
  
  if ((lpSubItem != NULL) && (lpLVItem != NULL))
  {
    if (!(lpLVItem->mask & LVIF_INDENT))
    {
      bResult = TRUE;
      ZeroMemory(lpSubItem, sizeof(LISTVIEW_SUBITEM));

      lpSubItem->iSubItem = lpLVItem->iSubItem;

      if (lpLVItem->mask & LVIF_IMAGE)
      {
        lpSubItem->iImage = lpLVItem->iImage;
      }
      
      if (lpLVItem->mask & LVIF_TEXT) 
      {
        if (lpLVItem->pszText == LPSTR_TEXTCALLBACKA) 
        {
          if ((lStyle & LVS_SORTASCENDING) || (lStyle & LVS_SORTDESCENDING))
          {
            return FALSE;
          } 

          if ((lpSubItem->pszText != NULL) && 
              (lpSubItem->pszText != LPSTR_TEXTCALLBACKA))
          {
            COMCTL32_Free(lpSubItem->pszText);
          }
    
          lpSubItem->pszText = LPSTR_TEXTCALLBACKA;
        }
        else 
        {
          if (lpSubItem->pszText == LPSTR_TEXTCALLBACKA)
          {
            lpSubItem->pszText = NULL;
          }
        
          bResult = Str_SetPtrA(&lpSubItem->pszText, lpLVItem->pszText);
        }
      }
    }
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Adds a subitem at a given position (column index).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] LPLVITEM : new subitem atttributes 
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_AddSubItem(HWND hwnd, LPLVITEMA lpLVItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LISTVIEW_SUBITEM *lpSubItem = NULL;
  BOOL bResult = FALSE;
  HDPA hdpaSubItems;
  INT nPosition, nItem;

  if (lpLVItem != NULL)
  {
    hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
    if (hdpaSubItems != NULL)
    {
      lpSubItem = (LISTVIEW_SUBITEM *)COMCTL32_Alloc(sizeof(LISTVIEW_SUBITEM));
      if (lpSubItem != NULL)
      {
        if (LISTVIEW_InitSubItem(hwnd, lpSubItem, lpLVItem) != FALSE)
        {
          nPosition = LISTVIEW_FindInsertPosition(hdpaSubItems, 
                                                  lpSubItem->iSubItem);
          nItem = DPA_InsertPtr(hdpaSubItems, nPosition, lpSubItem);
          if (nItem != -1)
          {
            bResult = TRUE;
          }            
        }
      }
    }
  }
  
  /* cleanup if unsuccessful */   
  if ((bResult == FALSE) && (lpSubItem != NULL))
  {
    COMCTL32_Free(lpSubItem);
  }
  
  return bResult;
}

/***
 * DESCRIPTION:
 * Finds the dpa insert position (array index).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : subitem index
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static INT LISTVIEW_FindInsertPosition(HDPA hdpaSubItems, INT nSubItem)
{
  LISTVIEW_SUBITEM *lpSubItem;
  INT i;

  for (i = 1; i < hdpaSubItems->nItemCount; i++)
  {
    lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
    if (lpSubItem != NULL)
    {
      if (lpSubItem->iSubItem > nSubItem)
      {
        return i;
      }
    } 
  }

  return hdpaSubItems->nItemCount;
}

/***
 * DESCRIPTION:
 * Retrieves a listview subitem at a given position (column index).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : subitem index
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LISTVIEW_SUBITEM* LISTVIEW_GetSubItem(HDPA hdpaSubItems, INT nSubItem)
{
  LISTVIEW_SUBITEM *lpSubItem;
  INT i;

  for (i = 1; i < hdpaSubItems->nItemCount; i++)
  {
    lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
    if (lpSubItem != NULL)
    {
      if (lpSubItem->iSubItem == nSubItem)
      {
        return lpSubItem;
      }
      else if (lpSubItem->iSubItem > nSubItem)
      {
        return NULL;
      }  
    }
  }
  
  return NULL;
}

/***
 * DESCRIPTION:
 * Sets item attributes.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] LPLVITEM : new item atttributes 
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_SetItem(HWND hwnd, LPLVITEMA lpLVItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  BOOL bResult = FALSE;
  HDPA hdpaSubItems;
  LISTVIEW_ITEM *lpItem;
  NMLISTVIEW nmlv;
  UINT uChanged;
  LONG lCtrlId = GetWindowLongA(hwnd, GWL_ID);

  if (lpLVItem != NULL)
  {
    if (lpLVItem->iSubItem == 0)
    {
      hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
      if (hdpaSubItems != NULL)
      {
        lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, lpLVItem->iSubItem);
        if (lpItem != NULL)
        {
          ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
          nmlv.hdr.hwndFrom = hwnd;
          nmlv.hdr.idFrom = lCtrlId;
          nmlv.hdr.code = LVN_ITEMCHANGING;
          nmlv.lParam = lpItem->lParam;
          uChanged = LISTVIEW_GetItemChanges(lpItem, lpLVItem);
          if (uChanged != 0)
          {
            if (uChanged & LVIF_STATE)
            {
              nmlv.uNewState = lpLVItem->state & lpLVItem->stateMask;
              nmlv.uOldState = lpItem->state & lpLVItem->stateMask;
            }

            nmlv.uChanged = uChanged;
            nmlv.iItem = lpLVItem->iItem;
            nmlv.lParam = lpItem->lParam;
            /* send LVN_ITEMCHANGING notification */
            ListView_LVNotify(GetParent(hwnd), lCtrlId, &nmlv);

            /* copy information */
            bResult = LISTVIEW_InitItem(hwnd, lpItem, lpLVItem);

            /* send LVN_ITEMCHANGED notification */
            nmlv.hdr.code = LVN_ITEMCHANGED;
            ListView_LVNotify(GetParent(hwnd), lCtrlId, &nmlv);
          }
          else
          {
            bResult = TRUE;
          }

          InvalidateRect(hwnd, NULL, FALSE);
        }
      }
    }
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Sets subitem attributes.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] LPLVITEM : new subitem atttributes 
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_SetSubItem(HWND hwnd, LPLVITEMA lpLVItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  BOOL bResult = FALSE;
  HDPA hdpaSubItems;
  LISTVIEW_SUBITEM *lpSubItem;

  if (lpLVItem != NULL)
  {
    if (lpLVItem->iSubItem > 0)
    {
      hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
      if (hdpaSubItems != NULL)
      {
        /* set subitem only if column is present */
        if (Header_GetItemCount(infoPtr->hwndHeader) > lpLVItem->iSubItem)
        {
          lpSubItem = LISTVIEW_GetSubItem(hdpaSubItems, lpLVItem->iSubItem);
          if (lpSubItem != NULL)
          {
            bResult = LISTVIEW_InitSubItem(hwnd, lpSubItem, lpLVItem);
          }
          else
          {
            bResult = LISTVIEW_AddSubItem(hwnd, lpLVItem);
          }
          
          InvalidateRect(hwnd, NULL, FALSE);
        } 
      }
    }
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Retrieves the index of the item at coordinate (0, 0) of the client area.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 *
 * RETURN:
 * item index
 */
static INT LISTVIEW_GetTopIndex(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *) GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  INT nItem = 0;

  switch (LVS_TYPEMASK & lStyle)
  {
  case LVS_LIST:
    if (lStyle & WS_HSCROLL)
    {
      nItem = GetScrollPos(hwnd, SB_HORZ) * infoPtr->nCountPerColumn;
    }
    break;

  case LVS_REPORT:
    if (lStyle & WS_VSCROLL)
    {
      nItem = GetScrollPos(hwnd, SB_VERT);
    }
    break;
  }

  return nItem;
}

/***
 * DESCRIPTION:
 * Evaluates if scrollbars are needed & sets the scroll range/position.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] LONG : window style
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_SetScroll(HWND hwnd, LONG lStyle)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
  INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
  INT nHScrollHeight = GetSystemMetrics(SM_CYHSCROLL);
  INT nVScrollWidth = GetSystemMetrics(SM_CXVSCROLL);
  INT nHiddenWidth;
  INT nHiddenHeight;
  INT nHiddenItemCount;
  INT nScrollPos;
  INT nMaxRange;
  INT nCountPerPage;
  INT nPixPerScrollPos;
  RECT rcView;

  TRACE(listview, "(hwnd=%x,lStyle=%lx)\n", hwnd, lStyle);

  switch (LVS_TYPEMASK & lStyle)
  {
  case LVS_LIST:
    nCountPerPage = infoPtr->nCountPerRow * infoPtr->nCountPerColumn;
    if (nCountPerPage < GETITEMCOUNT(infoPtr))
    {
      /* display horizontal scrollbar */
      if ((lStyle &  WS_HSCROLL) == 0)
      {
	ShowScrollBar(hwnd, SB_HORZ, TRUE);
      }

      /* calculate new scrollbar range */
      nHiddenItemCount = GETITEMCOUNT(infoPtr) - nCountPerPage;
      if ((nHiddenItemCount % infoPtr->nCountPerColumn) == 0)
      {
        nMaxRange = nHiddenItemCount / infoPtr->nCountPerColumn;
      }
     else
      {
        nMaxRange = nHiddenItemCount / infoPtr->nCountPerColumn + 1;
      }
        
      SetScrollRange(hwnd, SB_HORZ, 0, nMaxRange, FALSE);
      nScrollPos = ListView_GetTopIndex(hwnd) / infoPtr->nCountPerColumn;
      SetScrollPos(hwnd, SB_HORZ, nScrollPos, TRUE);
    }
    else
    {
      /* hide scrollbar */
      if ((lStyle & WS_HSCROLL) != 0)
      {
	ShowScrollBar(hwnd, SB_HORZ, FALSE);
      }
    }
    break;
    
  case LVS_REPORT:
/*
 * This section was commented out because I experienced some problems
 * with the scrolling of the header control. The idea was to add a 
 * horizontal scrollbar when the width of the client area was smaller
 * than the width of the header control.
 */

/*     if (infoPtr->nItemWidth > nListWidth) */
/*     { */
/*       if ((lStyle &  WS_HSCROLL) == 0) */
/*       { */
/*         ShowScrollBar(hwnd, SB_HORZ, TRUE); */
/*         LISTVIEW_SetSize(hwnd, lStyle, -1, -1); */
/*         LISTVIEW_SetViewInfo(hwnd, lStyle); */
/*       } */
      
/*       nListWidth = infoPtr->rcList.right - infoPtr->rcList.left; */
/*       nHiddenWidth = infoPtr->nItemWidth - nListWidth; */
/*       nPixPerScrollPos = max(1, nListWidth / 10); */
      
/*       if ((nHiddenWidth % nPixPerScrollPos) == 0) */
/*       { */
/*         nMaxRange = nHiddenWidth / nPixPerScrollPos;  */
/*       } */
/*       else */
/*       { */
/*         nMaxRange = nHiddenWidth / nPixPerScrollPos + 1;  */
/*       } */

/*       SetScrollRange(hwnd, SB_HORZ, 0, nMaxRange, FALSE); */
/*       SetScrollPos(hwnd, SB_HORZ, 0, TRUE); */
/*     } */
/*     else */
/*     { */
/*       if ((lStyle &  WS_HSCROLL) != 0) */
/*       { */
/*         ShowScrollBar(hwnd, SB_HORZ, FASLE); */
/*         LISTVIEW_SetSize(hwnd, lStyle, -1, -1);  */
/*         LISTVIEW_SetViewInfo(hwnd, lStyle);  */
/*       } */
/*     } */
  
    if (infoPtr->nCountPerColumn < GETITEMCOUNT(infoPtr))
    {
      if ((lStyle &  WS_VSCROLL) == 0)
      {
        if (nListWidth > nVScrollWidth)
        {
          ShowScrollBar(hwnd, SB_VERT, TRUE);
          nListWidth -= nVScrollWidth;
        }
      }
        
      /* vertical range & position */
      nMaxRange = GETITEMCOUNT(infoPtr) - infoPtr->nCountPerColumn;
      SetScrollRange(hwnd, SB_VERT, 0, nMaxRange, FALSE);
      SetScrollPos(hwnd, SB_VERT, ListView_GetTopIndex(hwnd), TRUE);
    }
    else
    {
      if ((lStyle &  WS_VSCROLL) != 0)
      {
        ShowScrollBar(hwnd, SB_VERT, FALSE);
        nListWidth += nVScrollWidth;
      }
    }
    break;

  case LVS_ICON:
  case LVS_SMALLICON:
    if (LISTVIEW_GetViewRect(hwnd, &rcView) != FALSE)
    {
      if (rcView.right - rcView.left > nListWidth)
      {
        if ((lStyle & WS_HSCROLL) == 0)
        {
          if (nListHeight > nHScrollHeight)
          {
            ShowScrollBar(hwnd, SB_HORZ, TRUE);
            nListHeight -= nHScrollHeight;
          }
        }
 
        /* calculate size of hidden items */
        nHiddenWidth = rcView.right - rcView.left - nListWidth;
        nPixPerScrollPos = max(1, nListWidth / 10);

        /* vertical range & position */
        if ((nHiddenWidth % nPixPerScrollPos) == 0)
        {
          nMaxRange = nHiddenWidth / nPixPerScrollPos; 
        }
        else
        {
          nMaxRange = nHiddenWidth / nPixPerScrollPos + 1; 
        }

        /* set range and position */
        SetScrollRange(hwnd, SB_HORZ, 0, nMaxRange, FALSE);
        SetScrollPos(hwnd, SB_HORZ, 0, TRUE);
      }
      else
      {
        if ((lStyle &  WS_HSCROLL) != 0)
        {
          ShowScrollBar(hwnd, SB_HORZ, FALSE);
          nListHeight += nHScrollHeight;
        }
      }

      if (rcView.bottom - rcView.top > nListHeight)
      {
        if ((lStyle &  WS_VSCROLL) == 0)
        {
          if (nListWidth > nVScrollWidth)
          {
            ShowScrollBar(hwnd, SB_VERT, TRUE);
            nListWidth -= nVScrollWidth;
          }
        }
        
        /* calculate size of hidden items */
        nHiddenHeight = rcView.bottom - rcView.top - nListHeight;
        nPixPerScrollPos = max(1, nListHeight / 10);
        
        /* set vertical range & position */
        if ((nHiddenHeight % nPixPerScrollPos) == 0)
        {
          nMaxRange = nHiddenHeight / nPixPerScrollPos; 
        }
        else
        {
          nMaxRange = nHiddenHeight / nPixPerScrollPos + 1; 
        }
          
        /* set range and position */
        SetScrollRange(hwnd, SB_VERT, 0, nMaxRange, FALSE);
        SetScrollPos(hwnd, SB_VERT, 0, TRUE);
      }
      else
      {
        if ((lStyle &  WS_VSCROLL) != 0)
        {
          ShowScrollBar(hwnd, SB_VERT, FALSE);
          nListWidth += nVScrollWidth;
        }
      }
    }
    break;
  }
}

/***
 * DESCRIPTION:
 * Draws a subitem.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] HDC : device context handle
 * [I] INT : item index
 * [I] LPARAM : item lparam 
 * [I] LISTVIEW_SUBITEM * : item
 * [I] INT : column index (header index)
 * [I] RECT * : clipping rectangle
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_DrawSubItem(HWND hwnd, HDC hdc, INT nItem, LPARAM lParam,
                                 LISTVIEW_SUBITEM *lpSubItem, INT nColumn, 
                                 RECT *lprc)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  CHAR szDispText[DISP_TEXT_SIZE];
  LPSTR pszDispText = NULL;

  /* set item colors */
  SetBkColor(hdc, infoPtr->clrTextBk);
  SetTextColor(hdc, infoPtr->clrText);
  
  pszDispText = szDispText;
  LISTVIEW_GetSubItemDispInfo(hwnd, nItem, lParam, lpSubItem, nColumn, NULL, 
                              &pszDispText, DISP_TEXT_SIZE);

  /* draw text : using arbitrary offset of 10 pixels */  
  
  ExtTextOutA(hdc, lprc->left, lprc->top, ETO_OPAQUE|ETO_CLIPPED, 
              lprc, pszDispText, lstrlenA(pszDispText), NULL);
}

/***
 * DESCRIPTION:
 * Draws an item.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] HDC : device context handle
 * [I] LISTVIEW_ITEM * : item
 * [I] INT : item index
 * [I] RECT * : clipping rectangle
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_DrawItem(HWND hwnd, HDC hdc, LISTVIEW_ITEM *lpItem, 
                              INT nItem, RECT rc)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0); 
  CHAR szDispText[DISP_TEXT_SIZE];
  LPSTR pszDispText = NULL;
  BOOL bSelected;
  INT nLabelWidth;
  INT nImage;
  UINT uState;

  TRACE(listview, "(hwnd=%x,hdc=%x,lpItem=%p,nItem=%d,rc.left=%d,rctop=%d,rc.right=%d,rc.bottom=%d)\n", hwnd, hdc, lpItem, nItem, rc.left, rc.top, rc.right, rc.bottom);

  pszDispText = szDispText;
  LISTVIEW_GetItemDispInfo(hwnd, nItem, lpItem, &nImage, &uState, &pszDispText,
                           DISP_TEXT_SIZE);
 
 if (uState & LVIS_SELECTED)
  {
    bSelected = TRUE;

    /* set item colors */ 
    SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
    SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
    
    /* set raster mode */
    SetROP2(hdc, R2_XORPEN);
  }
  else
  {
    bSelected = FALSE;
    
    /* set item colors */
    SetBkColor(hdc, infoPtr->clrTextBk);
    SetTextColor(hdc, infoPtr->clrText);
    
    /* set raster mode */
    SetROP2(hdc, R2_COPYPEN);
  }

  /* state icons */
  if (infoPtr->himlState != NULL)
  {
    /* right shift 12 bits to obtain index in image list */
    if (bSelected != FALSE)
    {
      ImageList_Draw(infoPtr->himlState, uState >> 12, hdc, rc.left, 
                     rc.top, ILD_SELECTED);
    }
    else
    {
      ImageList_Draw(infoPtr->himlState, uState >> 12, hdc, rc.left, 
                     rc.top, ILD_NORMAL);
    }
    
    rc.left += infoPtr->iconSize.cx; 
  }
  
  /* small icons */
  if (infoPtr->himlSmall != NULL)
  {
    if (bSelected != FALSE)
    {
      ImageList_Draw(infoPtr->himlSmall, nImage, hdc, rc.left, 
                     rc.top, ILD_SELECTED);
    }
    else
    {
      ImageList_Draw(infoPtr->himlSmall, nImage, hdc, rc.left, 
                     rc.top, ILD_NORMAL);
    }
    
    rc.left += infoPtr->iconSize.cx; 
  }
  
  nLabelWidth = ListView_GetStringWidthA(hwnd, pszDispText);
  if (rc.left + nLabelWidth < rc.right)
  {
    rc.right = rc.left + nLabelWidth;
  } 

  /* draw label */  
  ExtTextOutA(hdc, rc.left, rc.top, ETO_OPAQUE|ETO_CLIPPED, 
              &rc, pszDispText, lstrlenA(pszDispText), NULL);
  
  if (lpItem->state & LVIS_FOCUSED)
  {
    Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); 
  }
}

/***
 * DESCRIPTION:
 * Draws an item when in large icon display mode.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] HDC : device context handle
 * [I] LISTVIEW_ITEM * : item
 * [I] INT : item index
 * [I] RECT * : clipping rectangle
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_DrawLargeItem(HWND hwnd, HDC hdc, LISTVIEW_ITEM *lpItem, 
                                   INT nItem, RECT rc)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0); 
  CHAR szDispText[DISP_TEXT_SIZE];
  LPSTR pszDispText = NULL;
  BOOL bSelected;
  INT nLabelWidth;
  INT nImage;
  UINT uState;
  INT nDrawPosX = 0;
  TEXTMETRICA tm;

  TRACE(listview, "(hwnd=%x,hdc=%x,lpItem=%p,nItem=%d,rc.left=%d,rctop=%d,rc.right=%d,rc.bottom=%d)\n", hwnd, hdc, lpItem, nItem, rc.left, rc.top, rc.right, rc.bottom);

  pszDispText = szDispText;
  LISTVIEW_GetItemDispInfo(hwnd, nItem, lpItem, &nImage, &uState, &pszDispText,
                           DISP_TEXT_SIZE);
  if (uState & LVIS_SELECTED)
  {
    bSelected = TRUE;

    /* set item colors */ 
    SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
    SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
    
    /* set raster mode */
    SetROP2(hdc, R2_XORPEN);
  }
  else
  {
    bSelected = FALSE;

    /* set item colors */
    SetBkColor(hdc, infoPtr->clrTextBk);
    SetTextColor(hdc, infoPtr->clrText);
    
    /* set raster mode */
    SetROP2(hdc, R2_COPYPEN);
  }

  if (infoPtr->himlNormal != NULL)
  {
    rc.top += ICON_TOP_PADDING;
    nDrawPosX = rc.left + (infoPtr->iconSpacing.cx - infoPtr->iconSize.cx) / 2;
    if (bSelected != FALSE)
    {
      ImageList_Draw(infoPtr->himlNormal, nImage, hdc, nDrawPosX, rc.top, 
                     ILD_SELECTED);
    }
    else
    {
      ImageList_Draw(infoPtr->himlNormal, nImage, hdc, nDrawPosX, rc.top, 
                     ILD_NORMAL);
    }
  }

  rc.top += infoPtr->iconSize.cy + ICON_BOTTOM_PADDING; 
  nLabelWidth = ListView_GetStringWidthA(hwnd, pszDispText);
  nDrawPosX = infoPtr->iconSpacing.cx - nLabelWidth;
  if (nDrawPosX > 1)
  {
    rc.left += nDrawPosX / 2;
    rc.right = rc.left + nLabelWidth;
  }
  else
  {
    rc.left += 1;
    rc.right = rc.left + infoPtr->iconSpacing.cx - 1;
  }

  /* draw label */  
  GetTextMetricsA(hdc, &tm);
  rc.bottom = rc.top + tm.tmHeight + HEIGHT_PADDING; 
  ExtTextOutA(hdc, rc.left, rc.top, ETO_OPAQUE|ETO_CLIPPED, 
              &rc, pszDispText, lstrlenA(pszDispText), NULL);
        
  if (lpItem->state & LVIS_FOCUSED)
  {
    Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); 
  }
}

/***
 * DESCRIPTION:
 * Draws listview items when in report display mode.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] HDC : device context handle 
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_RefreshReport(HWND hwnd, HDC hdc)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd,0);
  INT nDrawPosY = infoPtr->rcList.top;
  LISTVIEW_ITEM *lpItem;
  LISTVIEW_SUBITEM *lpSubItem = NULL;
  BOOL bNeedSubItem = TRUE;
  INT nColumnCount;
  HDPA hdpaSubItems;
  RECT rcItem;
  INT  j, k;
  INT nItem;
  INT nLast;

  nItem = ListView_GetTopIndex(hwnd);
  nLast = nItem + infoPtr->nCountPerColumn;
  while (nItem <= nLast)
  {
    hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
    if (hdpaSubItems != NULL)
    {
      lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
      if (lpItem != NULL)
      {
        /* the width of the header items will determine the size of the 
           listview items */
        Header_GetItemRect(infoPtr->hwndHeader, 0, &rcItem);
        rcItem.left += REPORT_MARGINX;
        rcItem.right = max(rcItem.left, rcItem.right - REPORT_MARGINX);
        rcItem.top = nDrawPosY;
        rcItem.bottom = rcItem.top + infoPtr->nItemHeight;
        LISTVIEW_DrawItem(hwnd, hdc, lpItem, nItem, rcItem);
      }

      nColumnCount = Header_GetItemCount(infoPtr->hwndHeader);
      for (k = 1, j = 1; j < nColumnCount; j++)
      {
        Header_GetItemRect(infoPtr->hwndHeader, j, &rcItem);
        rcItem.left += REPORT_MARGINX;
        rcItem.right = max(rcItem.left, rcItem.right - REPORT_MARGINX);
        rcItem.top = nDrawPosY;
        rcItem.bottom = rcItem.top + infoPtr->nItemHeight;

        if (k < hdpaSubItems->nItemCount)
        {
          if (bNeedSubItem != FALSE)
          {
            lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, k);
            k++;
          }

          if (lpSubItem != NULL)
          {
            if (lpSubItem->iSubItem == j)
            {
              LISTVIEW_DrawSubItem(hwnd, hdc, nItem, lpItem->lParam, lpSubItem,
                                   j, &rcItem);
              bNeedSubItem = TRUE;
            }
            else
            {
              LISTVIEW_DrawSubItem(hwnd, hdc, nItem, lpItem->lParam, NULL, j, 
                                   &rcItem);
              bNeedSubItem = FALSE;
            }
          }
          else
          {
            LISTVIEW_DrawSubItem(hwnd, hdc, nItem, lpItem->lParam, NULL, j, 
                                 &rcItem);
            bNeedSubItem = TRUE;
          }
        }
        else
        {
          LISTVIEW_DrawSubItem(hwnd, hdc, nItem, lpItem->lParam, NULL, j, 
                               &rcItem);
        }
      }
    }

    nDrawPosY += infoPtr->nItemHeight;
    nItem++;
  }
}

/***
 * DESCRIPTION:
 * Draws listview items when in list display mode.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] HDC : device context handle 
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_RefreshList(HWND hwnd, HDC hdc)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LISTVIEW_ITEM *lpItem;
  HDPA hdpaSubItems;
  RECT rc;
  INT i, j;
  INT nColumnCount;
  INT nItem = ListView_GetTopIndex(hwnd);

  if (infoPtr->rcList.right > 0)
  {
    /* get number of display columns */
    if (infoPtr->rcList.right % infoPtr->nItemWidth == 0)
    {
      nColumnCount = infoPtr->rcList.right / infoPtr->nItemWidth;
    }
    else
    {
      nColumnCount = infoPtr->rcList.right / infoPtr->nItemWidth + 1;
    }

    for (i = 0; i < nColumnCount; i++)
    {
      j = 0;
      while ((nItem < GETITEMCOUNT(infoPtr)) && 
             (j<infoPtr->nCountPerColumn))
      {
        hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
        if (hdpaSubItems != NULL)
        {
          lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
          if (lpItem != NULL)
          {
            rc.top = j * infoPtr->nItemHeight;
            rc.left = i * infoPtr->nItemWidth;
            rc.bottom = rc.top + infoPtr->nItemHeight;
            rc.right = rc.left + infoPtr->nItemWidth;
            LISTVIEW_DrawItem(hwnd, hdc,  lpItem, nItem, rc);
          }
        }
 
        nItem++;
        j++;
      }
    }
  }
}

/***
 * DESCRIPTION:
 * Draws listview items when in icon or small icon display mode.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] HDC : device context handle 
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_RefreshIcon(HWND hwnd, HDC hdc, BOOL bSmall)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LISTVIEW_ITEM *lpItem;
  HDPA hdpaSubItems;
  POINT ptPosition;
  POINT ptOrigin;
  RECT rc;
  INT i;

  LISTVIEW_GetOrigin(hwnd, &ptOrigin);

  for (i = 0; i < GETITEMCOUNT(infoPtr); i++)
  {
    LISTVIEW_GetItemPosition(hwnd, i, &ptPosition);
    ptPosition.x += ptOrigin.x;
    ptPosition.y += ptOrigin.y;

    if (ptPosition.y + infoPtr->nItemHeight > infoPtr->rcList.top)
    {
      if (ptPosition.x + infoPtr->nItemWidth > infoPtr->rcList.left)
      {
        if (ptPosition.y < infoPtr->rcList.bottom)
        {
          if (ptPosition.x < infoPtr->rcList.right)
          {
            hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, i);
            if (hdpaSubItems != NULL)
            {
              lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
              if (lpItem != NULL)
              {
                rc.top = ptPosition.y;
                rc.left = ptPosition.x;
                rc.bottom = rc.top + infoPtr->nItemHeight;
                rc.right = rc.left + infoPtr->nItemWidth;
                if (bSmall == FALSE)
                {
                  LISTVIEW_DrawLargeItem(hwnd, hdc, lpItem, i, rc);
                }
                else
                {
                  LISTVIEW_DrawItem(hwnd, hdc, lpItem, i, rc);
                }
              }
            }
          }
        }
      }
    }
  }
}

/***
 * DESCRIPTION:
 * Draws listview items.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] HDC : device context handle 
 *
 * RETURN:
 * NoneX
 */
static VOID LISTVIEW_Refresh(HWND hwnd, HDC hdc)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  HFONT hOldFont;
  HPEN hPen, hOldPen;

  /* select font */
  hOldFont = SelectObject(hdc, infoPtr->hFont);

  /* select the doted pen (for drawing the focus box) */
  hPen = CreatePen(PS_DOT, 1, 0);
  hOldPen = SelectObject(hdc, hPen);

  /* select transparent brush (for drawing the focus box) */
  SelectObject(hdc, GetStockObject(NULL_BRUSH)); 

  switch (LVS_TYPEMASK & lStyle)
  {
  case LVS_LIST:
    LISTVIEW_RefreshList(hwnd, hdc); 
    break;
  case LVS_REPORT:
    LISTVIEW_RefreshReport(hwnd, hdc);
    break;
  case LVS_SMALLICON:
    LISTVIEW_RefreshIcon(hwnd, hdc, TRUE);
    break;
  case LVS_ICON:
    LISTVIEW_RefreshIcon(hwnd, hdc, FALSE);
  }

  /* unselect objects */
  SelectObject(hdc, hOldFont);
  SelectObject(hdc, hOldPen);
  
  /* delete pen */
  DeleteObject(hPen);
}


/***
 * DESCRIPTION:
 * Calculates the approximate width and height of a given number of items.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [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(HWND hwnd, INT nItemCount, 
                                            WORD wWidth, WORD wHeight)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  INT nItemCountPerColumn = 1;
  INT nColumnCount = 0;
  DWORD dwViewRect = 0;

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

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

    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 (lStyle & LVS_REPORT)
  {
    /* TO DO */
    }
  else if (lStyle & LVS_SMALLICON)
  {
    /* TO DO */
  }
  else if (lStyle & LVS_ICON)
  {
    /* TO DO */
  }
 
  return dwViewRect;
}

/***
 * DESCRIPTION:
 * Arranges listview items in icon display mode.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : alignment code
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_Arrange(HWND hwnd, INT nAlignCode)
{
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  BOOL bResult = FALSE;

  if (((LVS_TYPEMASK & lStyle) == LVS_ICON) || 
      ((LVS_TYPEMASK & lStyle) == LVS_SMALLICON))
  {
    switch (nAlignCode)
    {
    case LVA_ALIGNLEFT:
      /* TO DO */
      break;
    case LVA_ALIGNTOP:
      /* TO DO */
      break;
    case LVA_DEFAULT:
      /* TO DO */
      break;
    case LVA_SNAPTOGRID:
      /* TO DO */
      break;
    }
  }

  return bResult;
}

/* << LISTVIEW_CreateDragImage >> */

/***
 * DESCRIPTION:
 * Removes all listview items and subitems.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_DeleteAllItems(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lCtrlId = GetWindowLongA(hwnd, GWL_ID);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  LISTVIEW_ITEM *lpItem;
  LISTVIEW_SUBITEM *lpSubItem;
  NMLISTVIEW nmlv;
  BOOL bSuppress;
  BOOL bResult = FALSE;
  INT i;
  INT j;
  HDPA hdpaSubItems;

  TRACE(listview, "(hwnd=%x,)\n", hwnd);

  if (GETITEMCOUNT(infoPtr) > 0)
  {
    /* initialize memory */
    ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
    
    /* send LVN_DELETEALLITEMS notification */
    nmlv.hdr.hwndFrom = hwnd;
    nmlv.hdr.idFrom = lCtrlId;
    nmlv.hdr.code = LVN_DELETEALLITEMS;
    nmlv.iItem = -1;

    /* verify if subsequent LVN_DELETEITEM notifications should be 
       suppressed */
    bSuppress = ListView_LVNotify(GetParent(hwnd), lCtrlId, &nmlv);

    for (i = 0; i < GETITEMCOUNT(infoPtr); 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 ((lpSubItem->pszText != NULL) && 
                (lpSubItem->pszText != LPSTR_TEXTCALLBACKA))
            {
              COMCTL32_Free(lpSubItem->pszText);
            }
            
            /* free subitem */
            COMCTL32_Free(lpSubItem);
          }    
        }
    
        lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
        if (lpItem != NULL)
        {
          if (bSuppress == FALSE)
          {
            /* send LVN_DELETEITEM notification */
            nmlv.hdr.code = LVN_DELETEITEM;
            nmlv.iItem = i;
            nmlv.lParam = lpItem->lParam;
            ListView_LVNotify(GetParent(hwnd), lCtrlId, &nmlv);
          }

          /* free item string */
          if ((lpItem->pszText != NULL) && 
              (lpItem->pszText != LPSTR_TEXTCALLBACKA))
          {
            COMCTL32_Free(lpItem->pszText);
          }
          
          /* free item */
          COMCTL32_Free(lpItem);
        }
        
        DPA_Destroy(hdpaSubItems);
      }
    }

    /* reinitialize listview memory */
    bResult = DPA_DeleteAllPtrs(infoPtr->hdpaItems);
    
    /* align items (set position of each item) */
    switch (lStyle & LVS_TYPEMASK)
    {
    case LVS_ICON:
    case LVS_SMALLICON:
      if (lStyle & LVS_ALIGNLEFT)
      {
        LISTVIEW_AlignLeft(hwnd);
      }
      else
      {
        LISTVIEW_AlignTop(hwnd);
      }
      break;
    }
    
    LISTVIEW_SetScroll(hwnd, lStyle);

    /* invalidate client area (optimization needed) */
    InvalidateRect(hwnd, NULL, TRUE);
  }
  
  return bResult;
}

/***
 * DESCRIPTION:
 * Removes a column from the listview control.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : column index
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_DeleteColumn(HWND hwnd, INT nColumn)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  BOOL bResult = FALSE;
  
  if (Header_DeleteItem(infoPtr->hwndHeader, nColumn) != FALSE)
  {
    bResult = LISTVIEW_RemoveColumn(infoPtr->hdpaItems, nColumn);

    /* reset scroll parameters */
    if ((lStyle & LVS_TYPEMASK) == LVS_REPORT)
    {
      LISTVIEW_SetViewInfo(hwnd, lStyle);
      LISTVIEW_SetScroll(hwnd, lStyle);
    }

    /* refresh client area */
    InvalidateRect(hwnd, NULL, FALSE);
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Removes an item from the listview control.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index  
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_DeleteItem(HWND hwnd, INT nItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  LONG lCtrlId = GetWindowLongA(hwnd, GWL_ID);
  NMLISTVIEW nmlv;
  BOOL bResult = FALSE;
  HDPA hdpaSubItems;
  LISTVIEW_ITEM *lpItem;
  LISTVIEW_SUBITEM *lpSubItem;
  INT i;

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

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

    hdpaSubItems = (HDPA)DPA_DeletePtr(infoPtr->hdpaItems, nItem);
    if (hdpaSubItems != NULL)
    {
      for (i = 1; i < hdpaSubItems->nItemCount; i++)
      {
        lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
        if (lpSubItem != NULL)
        {
          /* free item string */
          if ((lpSubItem->pszText != NULL) && 
              (lpSubItem->pszText != LPSTR_TEXTCALLBACKA))
          {
            COMCTL32_Free(lpSubItem->pszText);
          }
          
          /* free item */
          COMCTL32_Free(lpSubItem);
        }    
      }
    
      lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
      if (lpItem != NULL)
      {
        /* send LVN_DELETEITEM notification */
        nmlv.hdr.hwndFrom = hwnd;
        nmlv.hdr.idFrom = lCtrlId;
        nmlv.hdr.code = LVN_DELETEITEM;
        nmlv.iItem = nItem;
        nmlv.lParam = lpItem->lParam;
        SendMessageA(GetParent(hwnd), WM_NOTIFY, (WPARAM)lCtrlId, 
                     (LPARAM)&nmlv);

        /* free item string */
        if ((lpItem->pszText != NULL) && 
            (lpItem->pszText != LPSTR_TEXTCALLBACKA))
        {
          COMCTL32_Free(lpItem->pszText);
        }
        
        /* free item */
        COMCTL32_Free(lpItem);
      }
      
      bResult = DPA_Destroy(hdpaSubItems);
    }

    /* align items (set position of each item) */
    switch(lStyle & LVS_TYPEMASK)
    {
    case LVS_ICON:
    case LVS_SMALLICON:
      if (lStyle & LVS_ALIGNLEFT)
      {
        LISTVIEW_AlignLeft(hwnd);
      }
      else
      {
        LISTVIEW_AlignTop(hwnd);
      }
      break;
    }

    LISTVIEW_SetScroll(hwnd, lStyle);

    /* refresh client area */
    InvalidateRect(hwnd, NULL, TRUE);
  }
  
  return bResult;
}

/* LISTVIEW_EditLabel */

/***
 * DESCRIPTION:
 * Ensures the specified item is visible, scrolling into view if necessary.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index
 * [I] BOOL : partially or entirely visible
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_EnsureVisible(HWND hwnd, INT nItem, BOOL bPartial)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
  INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
  INT nHScrollPos = 0;
  INT nVScrollPos = 0;
  INT nScrollPosHeight = 0;
  INT nScrollPosWidth = 0;
  RECT rcItem;
  BOOL bResult = FALSE;

  /* ALWAYS bPartial == FALSE, FOR NOW! */

  rcItem.left = LVIR_BOUNDS;
  if (LISTVIEW_GetItemRect(hwnd, nItem, &rcItem) != FALSE)
  {
    if (rcItem.left < infoPtr->rcList.left)
    {
      /* scroll left */
      switch (LVS_TYPEMASK & lStyle)
      {
      case LVS_LIST:
        rcItem.left += infoPtr->rcList.left;
        nScrollPosWidth = infoPtr->nItemWidth;
        break;

      case LVS_SMALLICON:
      case LVS_ICON:
        nScrollPosWidth = max(1, nListWidth / 10);
        rcItem.left += infoPtr->rcList.left;
        break;
      }

      if (rcItem.left % nScrollPosWidth == 0)
      {
        nHScrollPos = rcItem.left / nScrollPosWidth;
      }
      else
      {
        nHScrollPos = rcItem.left / nScrollPosWidth - 1;
      }
    }
    else if (rcItem.right > infoPtr->rcList.right)
    {
      /* scroll right */
      switch (LVS_TYPEMASK & lStyle)
      {
      case LVS_LIST:
        rcItem.right -= infoPtr->rcList.right;
        nScrollPosWidth = infoPtr->nItemWidth;
        break;

      case LVS_SMALLICON:
      case LVS_ICON:
        nScrollPosWidth = max(1, nListWidth / 10);
        rcItem.right -= infoPtr->rcList.right;
        break;
      }

      if (rcItem.right % nScrollPosWidth == 0)
      {
        nHScrollPos = rcItem.right / nScrollPosWidth;
      }
      else
      {
        nHScrollPos = rcItem.right / nScrollPosWidth + 1;
      }
    }
    
    if (rcItem.top < infoPtr->rcList.top)
    {
      /* scroll up */
      switch (LVS_TYPEMASK & lStyle)
      {
      case LVS_REPORT:
        rcItem.top -= infoPtr->rcList.top; 
        nScrollPosHeight = infoPtr->nItemHeight;
        break;

      case LVS_SMALLICON:
      case LVS_ICON:
        nScrollPosHeight = max(1, nListHeight / 10);
        rcItem.top += infoPtr->rcList.top;
        break;
      }

      if (rcItem.top % nScrollPosHeight == 0)
      {
        nVScrollPos = rcItem.top / nScrollPosHeight;
      }
      else
      {
        nVScrollPos = rcItem.top / nScrollPosHeight - 1;
      }
    }
    else if (rcItem.bottom > infoPtr->rcList.bottom)
    {
      switch (LVS_TYPEMASK & lStyle)
      {
      case LVS_REPORT:
        rcItem.bottom -= infoPtr->rcList.bottom;
        nScrollPosHeight = infoPtr->nItemHeight;
        break;

      case LVS_SMALLICON:
      case LVS_ICON:
        nScrollPosHeight = max(1, nListHeight / 10);
        rcItem.bottom -= infoPtr->rcList.bottom;
        break;
      }

      if (rcItem.bottom % nScrollPosHeight == 0)
      {
        nVScrollPos = rcItem.bottom / nScrollPosHeight;
      }
      else
      {
        nVScrollPos = rcItem.bottom / nScrollPosHeight + 1;
      }
    }

    bResult = LISTVIEW_ScrollView(hwnd, nHScrollPos, nVScrollPos);
  }
  
  return bResult;
}

/***
 * DESCRIPTION:
 * Searches for an item with specific characteristics.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : base item index
 * [I] LPLVFINDINFO : item information to look for
 * 
 * RETURN:
 *   SUCCESS : index of item
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_FindItem(HWND hwnd, INT nStart, 
                                 LPLVFINDINFO lpFindInfo)
{
  FIXME (listview, "empty stub!\n");

  return -1; 
}

/***
 * DESCRIPTION:
 * Retrieves the background color of the listview control.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 *
 * RETURN:
 * COLORREF associated with the background.
 */
static LRESULT LISTVIEW_GetBkColor(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  return infoPtr->clrBk;
}

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

/***
 * DESCRIPTION:
 * Retrieves the callback mask.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 *
 * RETURN:
 *  Value of mask
 */
static UINT LISTVIEW_GetCallbackMask(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  return infoPtr->uCallbackMask;
}

/***
 * DESCRIPTION:
 * Retrieves column attributes.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT :  column index
 * [IO] LPLVCOLUMNA : column information
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_GetColumnA(HWND hwnd, INT nItem, 
                                     LPLVCOLUMNA lpColumn)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  HDITEMA hdi;
  BOOL bResult = FALSE;
  
  if (lpColumn != NULL)
  {
    /* initialize memory */
    ZeroMemory(&hdi, sizeof(HDITEMA));
    
    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_FORMAT);
    }

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

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

    bResult = Header_GetItemA(infoPtr->hwndHeader, nItem, &hdi);
    if (bResult != FALSE)
    {
      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 (lpColumn->mask & LVCF_WIDTH)
      {
        lpColumn->cx = hdi.cxy;
      }
      
      if ((lpColumn->mask & LVCF_TEXT) && (lpColumn->pszText) && (hdi.pszText))
      {
        lstrcpynA (lpColumn->pszText, hdi.pszText, lpColumn->cchTextMax);
      }

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

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

  return bResult;
}

/* LISTVIEW_GetColumnW */
/* LISTVIEW_GetColumnOrderArray */

/***
 * DESCRIPTION:
 * Retrieves the column width.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] int : column index
 *
 * RETURN:
 *   SUCCESS : column width
 *   FAILURE : zero 
 */
static LRESULT LISTVIEW_GetColumnWidth(HWND hwnd, INT nColumn)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  HDITEMA hdi;
  INT nColumnWidth = 0;

  switch (LVS_TYPEMASK & lStyle)
  {
  case LVS_LIST:
    nColumnWidth = infoPtr->nItemWidth;
    break;

  case LVS_REPORT:
    /* get column width from header */
    ZeroMemory(&hdi, sizeof(HDITEMA));
    hdi.mask = HDI_WIDTH;
    if (Header_GetItemA(infoPtr->hwndHeader, nColumn, &hdi) != FALSE)
    {
      nColumnWidth = hdi.cxy;
    }
    break;
  }

  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] HWND : window handle
 *
 * RETURN:
 * Number of fully visible items.
 */
static LRESULT LISTVIEW_GetCountPerPage(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  INT nItemCount = 0;

  switch (LVS_TYPEMASK & lStyle)
  {
  case LVS_LIST:
    if (infoPtr->rcList.right / infoPtr->nItemWidth)
    {
      nItemCount = infoPtr->nCountPerRow * infoPtr->nCountPerColumn;
    }
    break;
  
  case LVS_REPORT:
    nItemCount = infoPtr->nCountPerColumn;
    break;
    
  case LVS_SMALLICON:
  case LVS_ICON:
    nItemCount = GETITEMCOUNT(infoPtr);
    break;
  }

  return nItemCount;
}

/* LISTVIEW_GetEditControl */
/* LISTVIEW_GetExtendedListViewStyle */

/***
 * DESCRIPTION:
 * Retrieves the handle to the header control.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 *
 * RETURN:
 * Header handle.
 */
static LRESULT LISTVIEW_GetHeader(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  return infoPtr->hwndHeader;
}

/* LISTVIEW_GetHotCursor */
/* LISTVIEW_GetHotItem */
/* LISTVIEW_GetHoverTime */

/***
 * DESCRIPTION:
 * Retrieves an image list handle.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : image list identifier 
 * 
 * RETURN:
 *   SUCCESS : image list handle
 *   FAILURE : NULL
 */
static LRESULT LISTVIEW_GetImageList(HWND hwnd, INT nImageList)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  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] LPLVITEMA : item info
 * 
 * RETURN:
 *   SUCCESS : TRUE 
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_GetItemA(HWND hwnd, LPLVITEMA lpLVItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LISTVIEW_ITEM *lpItem;
  LISTVIEW_SUBITEM *lpSubItem;
  HDPA hdpaSubItems;
  BOOL bResult = FALSE;

  TRACE(listview, "(hwnd=%x,lpLVItem=%p)\n", hwnd, lpLVItem);

  if (lpLVItem != NULL)
  {
    if ((lpLVItem->iItem >= 0) && (lpLVItem->iItem < GETITEMCOUNT(infoPtr)))
    {
      hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
      if (hdpaSubItems != NULL)
      {
        if (lpLVItem->iSubItem == 0)
        {
          lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
          if (lpItem != NULL)
          {
            bResult = TRUE;

            /* retrieve valid data */
            if (lpLVItem->mask & LVIF_STATE)
            {
              lpLVItem->state = lpItem->state & lpLVItem->stateMask;
            }

            if (lpLVItem->mask & LVIF_TEXT) 
            {
              if (lpItem->pszText == LPSTR_TEXTCALLBACKA)
              {
                lpLVItem->pszText = LPSTR_TEXTCALLBACKA;
              }
              else
              {
                bResult = Str_GetPtrA(lpItem->pszText, lpLVItem->pszText, 
                                        lpLVItem->cchTextMax);
              }
            }

            if (lpLVItem->mask & LVIF_IMAGE)
            {
              lpLVItem->iImage = lpItem->iImage;
            }
          
            if (lpLVItem->mask & LVIF_PARAM)
            {
              lpLVItem->lParam = lpItem->lParam;
            }
      
            if (lpLVItem->mask & LVIF_INDENT)
            {
              lpLVItem->iIndent = lpItem->iIndent;
            }
          }
        }
        else
        {
          lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, 
                                                     lpLVItem->iSubItem);
          if (lpSubItem != NULL)
          {
            bResult = TRUE;

            if (lpLVItem->mask & LVIF_TEXT) 
            {
              if (lpSubItem->pszText == LPSTR_TEXTCALLBACKA)
              {
                lpLVItem->pszText = LPSTR_TEXTCALLBACKA;
              }
              else
              {
                bResult = Str_GetPtrA(lpSubItem->pszText, lpLVItem->pszText, 
                                        lpLVItem->cchTextMax);
              }
            }

            if (lpLVItem->mask & LVIF_IMAGE)
            {
              lpLVItem->iImage = lpSubItem->iImage;
            }
          }
        }
      }
    }
  }

  return bResult;
}

/* LISTVIEW_GetItemW */
/* LISTVIEW_GetHotCursor */
/* LISTVIEW_GetHotItem */
/* LISTVIEW_GetHoverTime> */

/***
 * DESCRIPTION:
 * Retrieves the number of items in the listview control.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * 
 * RETURN:
 * Number of items.
 */
static LRESULT LISTVIEW_GetItemCount(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  return GETITEMCOUNT(infoPtr);
}

/***
 * DESCRIPTION:
 * Retrieves the position (upper-left) of the listview control item.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index
 * [O] LPPOINT : coordinate information
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_GetItemPosition(HWND hwnd, INT nItem, 
                                     LPPOINT lpptPosition)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  BOOL bResult = FALSE;
  HDPA hdpaSubItems;
  LISTVIEW_ITEM *lpItem;
  INT nRow;

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

  if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)) && 
      (lpptPosition != NULL))
  {
    switch (LVS_TYPEMASK & lStyle)
    {
    case LVS_LIST:
      bResult = TRUE;
      nItem = nItem - ListView_GetTopIndex(hwnd);
      if (nItem < 0)
      {
        nRow = nItem % infoPtr->nCountPerColumn;
        if (nRow == 0)
        {
          lpptPosition->x = (nItem / infoPtr->nCountPerColumn * 
                             infoPtr->nItemWidth);
          lpptPosition->y = 0;
        }
        else
        {
          lpptPosition->x = ((nItem / infoPtr->nCountPerColumn - 1) * 
                             infoPtr->nItemWidth);
          lpptPosition->y = ((nRow + infoPtr->nCountPerColumn) * 
                             infoPtr->nItemHeight);  
        }
      }
      else
      {
        lpptPosition->x = (nItem / infoPtr->nCountPerColumn * 
                           infoPtr->nItemWidth);
        lpptPosition->y = (nItem % infoPtr->nCountPerColumn * 
                           infoPtr->nItemHeight);
      }
      break;

    case LVS_REPORT:
      bResult = TRUE;
      lpptPosition->x = REPORT_MARGINX;
      lpptPosition->y = ((nItem - ListView_GetTopIndex(hwnd)) * 
                         infoPtr->nItemHeight) + infoPtr->rcList.top;
      break;

    case LVS_SMALLICON:
    case LVS_ICON:
      hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
      if (hdpaSubItems != NULL)
      {
        lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
        if (lpItem != NULL)
        {
          bResult = TRUE;
          lpptPosition->x = lpItem->ptPosition.x;
          lpptPosition->y = lpItem->ptPosition.y;
        }
      }
      break;
    }
  }
    
  return bResult;
}

/***
 * DESCRIPTION:
 * Retrieves the bounding rectangle for a listview control item.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index
 * [IO] LPRECT : bounding rectangle coordinates
 * 
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_GetItemRect(HWND hwnd, INT nItem, LPRECT lprc)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  BOOL bResult = FALSE;
  POINT ptOrigin;
  POINT ptItem;
  HDC hdc;
  HFONT hOldFont;
  INT nMaxWidth;
  INT nLabelWidth;
  TEXTMETRICA tm;

  TRACE(listview, "(hwnd=%x,nItem=%d,lprc=%p)\n", hwnd, nItem, lprc);

  if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)) && (lprc != NULL))
  {
    if (ListView_GetItemPosition(hwnd, nItem, &ptItem) != FALSE)
    {
      switch(lprc->left)  
      {  
      case LVIR_ICON: 
        switch (LVS_TYPEMASK & lStyle)
        {
        case LVS_ICON:
          if (infoPtr->himlNormal != NULL)
          {
            if (LISTVIEW_GetOrigin(hwnd, &ptOrigin) != FALSE)
            {
              bResult = TRUE;
              lprc->left = ptItem.x + ptOrigin.x;
              lprc->top = ptItem.y + ptOrigin.y;
              lprc->right = lprc->left + infoPtr->iconSize.cx;
              lprc->bottom = (lprc->top + infoPtr->iconSize.cy + 
                              ICON_BOTTOM_PADDING + ICON_TOP_PADDING);
            }
          }
          break;

        case LVS_SMALLICON:
          if (LISTVIEW_GetOrigin(hwnd, &ptOrigin) != FALSE)
          {
            bResult = TRUE;
            lprc->left = ptItem.x + ptOrigin.x;
            lprc->top = ptItem.y + ptOrigin.y;
            lprc->bottom = lprc->top + infoPtr->nItemHeight;

            if (infoPtr->himlState != NULL)
            {
              lprc->left += infoPtr->iconSize.cx;
            }
              
            if (infoPtr->himlSmall != NULL)
            {
              lprc->right = lprc->left + infoPtr->iconSize.cx;
            }
            else
            {
              lprc->right = lprc->left;
            }
          }
          break;

        case LVS_REPORT:
        case LVS_LIST:
          bResult = TRUE;
          lprc->left = ptItem.x;
          lprc->top = ptItem.y;
          lprc->bottom = lprc->top + infoPtr->nItemHeight;

          if (infoPtr->himlState != NULL)
          {
            lprc->left += infoPtr->iconSize.cx;
          }
            
          if (infoPtr->himlSmall != NULL)
          {
            lprc->right = lprc->left + infoPtr->iconSize.cx;
          }
          else
          {
            lprc->right = lprc->left;
          }
          break;
        }
        break;

      case LVIR_LABEL: 
        switch (LVS_TYPEMASK & lStyle)
        {
        case LVS_ICON:
          if (infoPtr->himlNormal != NULL)
          {
            if (LISTVIEW_GetOrigin(hwnd, &ptOrigin) != FALSE)
            {
              bResult = TRUE;
              lprc->left = ptItem.x + ptOrigin.x;
              lprc->top = (ptItem.y + ptOrigin.y + infoPtr->iconSize.cy +
                           ICON_BOTTOM_PADDING + ICON_TOP_PADDING);
              nLabelWidth = LISTVIEW_GetLabelWidth(hwnd, nItem);
              if (infoPtr->iconSpacing.cx - nLabelWidth > 1)
              {
                lprc->left += (infoPtr->iconSpacing.cx - nLabelWidth) / 2;
                lprc->right = lprc->left + nLabelWidth;
              }
              else
              {
                lprc->left += 1;
                lprc->right = lprc->left + infoPtr->iconSpacing.cx - 1;
              }
            
              hdc = GetDC(hwnd);
              hOldFont = SelectObject(hdc, infoPtr->hFont);
              GetTextMetricsA(hdc, &tm);
              lprc->bottom = lprc->top + tm.tmHeight + HEIGHT_PADDING;
              SelectObject(hdc, hOldFont);
              ReleaseDC(hwnd, hdc);
            }              
          }
          break;

        case LVS_SMALLICON:
          if (LISTVIEW_GetOrigin(hwnd, &ptOrigin) != FALSE)
          {
            bResult = TRUE;
            nMaxWidth = lprc->left = ptItem.x + ptOrigin.x; 
            lprc->top = ptItem.y + ptOrigin.y;
            lprc->bottom = lprc->top + infoPtr->nItemHeight;
            
            if (infoPtr->himlState != NULL)
            {
              lprc->left += infoPtr->iconSize.cx;
            }
            
            if (infoPtr->himlSmall != NULL)
            {
              lprc->left += infoPtr->iconSize.cx;
            }
            
            nLabelWidth = LISTVIEW_GetLabelWidth(hwnd, nItem);
            if (lprc->left + nLabelWidth < nMaxWidth + infoPtr->nItemWidth)
            {
              lprc->right = lprc->left + nLabelWidth;
            }
            else
            {
              lprc->right = nMaxWidth + infoPtr->nItemWidth;
            }
          }
          break;

        case LVS_REPORT:
        case LVS_LIST:
          bResult = TRUE;
          lprc->left = ptItem.x; 
          lprc->top = ptItem.y;
          lprc->bottom = lprc->top + infoPtr->nItemHeight;

          if (infoPtr->himlState != NULL)
          {
            lprc->left += infoPtr->iconSize.cx;
          }

          if (infoPtr->himlSmall != NULL)
          {
            lprc->left += infoPtr->iconSize.cx;
          }

          lprc->right = lprc->left + LISTVIEW_GetLabelWidth(hwnd, nItem);
          break;
        }
        break;

      case LVIR_BOUNDS:
        switch (LVS_TYPEMASK & lStyle)
        {
        case LVS_ICON:
          if (infoPtr->himlNormal != NULL)
          {
            if (LISTVIEW_GetOrigin(hwnd, &ptOrigin) != FALSE)
            {
              bResult = TRUE;
              lprc->left = ptItem.x + ptOrigin.x;
              lprc->top = ptItem.y + ptOrigin.y; 
              lprc->right = lprc->left + infoPtr->iconSpacing.cx;
              lprc->bottom = lprc->top + infoPtr->iconSpacing.cy;
            }
          } 
          break;

        case LVS_SMALLICON:
          if (LISTVIEW_GetOrigin(hwnd, &ptOrigin) != FALSE)
          {
            bResult = TRUE;
            lprc->left = ptItem.x +ptOrigin.x; 
            lprc->right = lprc->left;
            lprc->top = ptItem.y + ptOrigin.y;
            lprc->bottom = lprc->top + infoPtr->nItemHeight;
            
            if (infoPtr->himlState != NULL)
            {
              lprc->right += infoPtr->iconSize.cx;
            }
            
            if (infoPtr->himlSmall != NULL)
            {
              lprc->right += infoPtr->iconSize.cx;
            }
            
            lprc->right += LISTVIEW_GetLabelWidth(hwnd, nItem);
          }
          break;

        case LVS_REPORT:
        case LVS_LIST:
          bResult = TRUE;
          lprc->left = ptItem.x; 
          lprc->right = lprc->left;
          lprc->top = ptItem.y;
          lprc->bottom = lprc->top + infoPtr->nItemHeight;

          if (infoPtr->himlState != NULL)
          {
            lprc->right += infoPtr->iconSize.cx;
          }

          if (infoPtr->himlSmall != NULL)
          {
            lprc->right += infoPtr->iconSize.cx;
          }

          lprc->right += LISTVIEW_GetLabelWidth(hwnd, nItem);
          break;
        }
        break;
        
      case LVIR_SELECTBOUNDS:
        switch (LVS_TYPEMASK & lStyle)
        {
        case LVS_ICON:
          if (infoPtr->himlNormal != NULL)
          {
            if (LISTVIEW_GetOrigin(hwnd, &ptOrigin) != FALSE)
            {
              bResult = TRUE;
              lprc->left = ptItem.x + ptOrigin.x;
              lprc->top = ptItem.y + ptOrigin.y;
              lprc->right = lprc->left + infoPtr->iconSpacing.cx;
              lprc->bottom = lprc->top + infoPtr->iconSpacing.cy;
            }
          } 
          break;

        case LVS_SMALLICON:
          if (LISTVIEW_GetOrigin(hwnd, &ptOrigin) != FALSE)
          {
            bResult = TRUE;
            lprc->left = ptItem.x + ptOrigin.x;  
            lprc->top = ptItem.y + ptOrigin.y;
            lprc->bottom = lprc->top + infoPtr->nItemHeight;
            
            if (infoPtr->himlState != NULL)
            {
              lprc->left += infoPtr->iconSize.cx;
            }
            
            lprc->right = lprc->left;
            
            if (infoPtr->himlSmall != NULL)
            {
              lprc->right += infoPtr->iconSize.cx;
            }
            
            lprc->right += LISTVIEW_GetLabelWidth(hwnd, nItem);
          }
          break;

        case LVS_REPORT:
        case LVS_LIST:
          bResult = TRUE;
          lprc->left = ptItem.x; 
          lprc->top = ptItem.y;
          lprc->bottom = lprc->top + infoPtr->nItemHeight;

          if (infoPtr->himlState != NULL)
          {
            lprc->left += infoPtr->iconSize.cx;
          }
          
          lprc->right = lprc->left;
        
          if (infoPtr->himlSmall != NULL)
          {
            lprc->right += infoPtr->iconSize.cx;
          }

          lprc->right += LISTVIEW_GetLabelWidth(hwnd, nItem);
          break;
        }
        break;
      }
    }
  }
        
  return bResult;
}

/***
 * DESCRIPTION:
 * Retrieves the width of a label.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * 
 * RETURN:
 *   SUCCESS : string width (in pixels)
 *   FAILURE : zero
 */

static INT LISTVIEW_GetLabelWidth(HWND hwnd, INT nItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LISTVIEW_ITEM *lpItem;
  HDPA hdpaSubItems;
  INT nLabelWidth = 0;

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

  hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
  if (hdpaSubItems != NULL)
  {
    lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
    if (lpItem != NULL)
    {
      CHAR szDispText[DISP_TEXT_SIZE];
      LPSTR pszDispText = NULL;
      pszDispText = szDispText;
      LISTVIEW_GetItemDispInfo(hwnd, nItem, lpItem, NULL, NULL, &pszDispText,
                               DISP_TEXT_SIZE);
      nLabelWidth = ListView_GetStringWidthA(hwnd, pszDispText);
    }
  }

  return nLabelWidth;
}

/***
 * DESCRIPTION:
 * Retrieves the spacing between listview control items.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] BOOL : flag for small or large icon 
 *
 * RETURN:
 * Horizontal + vertical spacing
 */
static LRESULT LISTVIEW_GetItemSpacing(HWND hwnd, BOOL bSmall)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lResult;

  if (bSmall == FALSE)
  {
    lResult = MAKELONG(infoPtr->iconSpacing.cx, infoPtr->iconSpacing.cy);
  }
  else
  {
    /* TODO: need to store width of smallicon item */
    lResult = MAKELONG(0, infoPtr->nItemHeight);
  }  
  
  return lResult;
}

/***
 * DESCRIPTION:
 * Retrieves the state of a listview control item.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index
 * [I] UINT : state mask
 * 
 * RETURN:
 * State specified by the mask.
 */
static LRESULT LISTVIEW_GetItemState(HWND hwnd, INT nItem, UINT uMask)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LVITEMA lvItem;
  UINT uState = 0;

  if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)))
  {
    ZeroMemory(&lvItem, sizeof(LVITEMA));
    lvItem.iItem = nItem;
    lvItem.stateMask = uMask;
    lvItem.mask = LVIF_STATE;
    if (ListView_GetItemA(hwnd, &lvItem) != FALSE)
    {
      uState = lvItem.state;
    }
  }

  return uState;
}

/***
 * DESCRIPTION:
 * Retrieves the text of a listview control item or subitem. 
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index
 * [IO] LPLVITEMA : item information
 * 
 * RETURN:
 * None
 */
static LRESULT LISTVIEW_GetItemTextA(HWND hwnd, INT nItem, LPLVITEMA lpLVItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LISTVIEW_ITEM *lpItem;
  LISTVIEW_SUBITEM *lpSubItem;
  HDPA hdpaSubItems;
  INT nLength = 0;
  
  if (lpLVItem != NULL)
  {
    if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)))
    {
      hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
      if (hdpaSubItems != NULL)
      {
        if (lpLVItem->iSubItem == 0)
        {
          lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
          if (lpItem != NULL)
          {
            if (lpLVItem->mask & LVIF_TEXT) 
            {
              if (lpItem->pszText == LPSTR_TEXTCALLBACKA)
              {
                lpLVItem->pszText = LPSTR_TEXTCALLBACKA;
              }
              else
              {
                nLength = Str_GetPtrA(lpItem->pszText, lpLVItem->pszText, 
                                      lpLVItem->cchTextMax);
              }
            }
          }
        }
        else
        {
          lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, 
                                                     lpLVItem->iSubItem);
          if (lpSubItem != NULL)
          {
            if (lpLVItem->mask & LVIF_TEXT) 
            {
              if (lpSubItem->pszText == LPSTR_TEXTCALLBACKA)
              {
                lpLVItem->pszText = LPSTR_TEXTCALLBACKA;
              }
              else
              {
                nLength = Str_GetPtrA(lpSubItem->pszText, lpLVItem->pszText, 
                                      lpLVItem->cchTextMax);
              }
            }
          }
        }
      }
    }
  }

  return nLength;
}

/***
 * DESCRIPTION:
 * Searches for an item based on properties + relationships.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index
 * [I] UINT : relationship flag
 * 
 * RETURN:
 *   SUCCESS : item index
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_GetNextItem(HWND hwnd, INT nItem, UINT uFlags)
{
  FIXME (listview, "empty stub!\n");

  return -1;
}

/* LISTVIEW_GetNumberOfWorkAreas */

/***
 * DESCRIPTION:
 * Retrieves the origin coordinates when in icon or small icon display mode.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [O] LPPOINT : coordinate information
 * 
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_GetOrigin(HWND hwnd, LPPOINT lpptOrigin)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left;
  INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
  BOOL bResult = FALSE;

  TRACE(listview, "(hwnd=%x,lpptOrigin=%p)\n", hwnd, lpptOrigin);

  switch (LVS_TYPEMASK & lStyle)
  {
  case LVS_ICON:
  case LVS_SMALLICON:
    if ((lStyle & WS_HSCROLL) != 0)
    {
      lpptOrigin->x = -GetScrollPos(hwnd, SB_HORZ) * nListWidth / 10;
    }
    else
    {
      lpptOrigin->x = 0;
    }

    if ((lStyle & WS_VSCROLL) != 0)
    {
      lpptOrigin->y = -GetScrollPos(hwnd, SB_VERT) * nListHeight / 10;
    }
    else
    {
      lpptOrigin->y = 0;
    }
  
    bResult = TRUE;
    break;
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Retrieves the number of items that are marked as selected.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * 
 * RETURN:
 * Number of items selected.
 */
static LRESULT LISTVIEW_GetSelectedCount(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nSelectedCount = 0;
  INT i;

  for (i = 0; i < GETITEMCOUNT(infoPtr); i++)
  {
    if (ListView_GetItemState(hwnd, i, LVIS_SELECTED) & LVIS_SELECTED)
    {
      nSelectedCount++;
    }
  }

  return nSelectedCount;
}

/***
 * DESCRIPTION:
 * Retrieves item index that marks the start of a multiple selection.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * 
 * RETURN:
 * Index number or -1 if there is no selection mark.
 */
static LRESULT LISTVIEW_GetSelectionMark(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  return infoPtr->nSelectionMark;
}

/***
 * DESCRIPTION:
 * Retrieves the width of a string.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * 
 * RETURN:
 *   SUCCESS : string width (in pixels)
 *   FAILURE : zero
 */
static LRESULT LISTVIEW_GetStringWidthA(HWND hwnd, LPCSTR lpszText)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  HFONT hFont, hOldFont;
  SIZE stringSize;
  HDC hdc;

  ZeroMemory(&stringSize, sizeof(SIZE));
  if (lpszText != NULL)
  {
    hFont = infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont;
    hdc = GetDC(hwnd);
    hOldFont = SelectObject(hdc, hFont);
    GetTextExtentPointA(hdc, lpszText, lstrlenA(lpszText), &stringSize);
    SelectObject(hdc, hOldFont);
    ReleaseDC(hwnd, hdc);
  }

  return stringSize.cx;
}

/***
 * DESCRIPTION:
 * Retrieves the text backgound color.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * 
 * RETURN:
 * COLORREF associated with the the background.
 */
static LRESULT LISTVIEW_GetTextBkColor(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLongA(hwnd, 0);

  return infoPtr->clrTextBk;
}

/***
 * DESCRIPTION:
 * Retrieves the text color.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * 
 * RETURN:
 * COLORREF associated with the text.
 */
static LRESULT LISTVIEW_GetTextColor(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLongA(hwnd, 0);

  return infoPtr->clrText;
}

/***
 * DESCRIPTION:
 * Set the bounding rectangle of all the items.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] LPRECT : bounding rectangle
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetViewRect(HWND hwnd, LPRECT lprcView)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  BOOL bResult = FALSE;

  TRACE(listview, "(hwnd=%x,lprcView->left=%d,lprcView->top=%d,lprcView->right=%d,lprcView->bottom=%d)\n", hwnd, lprcView->left, lprcView->top, lprcView->right, lprcView->bottom);

  if (lprcView != NULL)
  {
    switch (lStyle & LVS_TYPEMASK)
    {
    case LVS_ICON:
    case LVS_SMALLICON:
      bResult = TRUE;
      infoPtr->rcView.left = lprcView->left;
      infoPtr->rcView.top = lprcView->top;
      infoPtr->rcView.right = lprcView->right;
      infoPtr->rcView.bottom = lprcView->bottom;
      break;
    }
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Retrieves the bounding rectangle of all the items.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [O] LPRECT : bounding rectangle
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_GetViewRect(HWND hwnd, LPRECT lprcView)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLongA(hwnd, 0);
  BOOL bResult = FALSE;
  POINT ptOrigin;

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

  if (lprcView != NULL)
  {
    bResult = LISTVIEW_GetOrigin(hwnd, &ptOrigin);
    if (bResult != FALSE)
    {
      lprcView->left = infoPtr->rcView.left + ptOrigin.x;
      lprcView->top = infoPtr->rcView.top + ptOrigin.y;
      lprcView->right = infoPtr->rcView.right + ptOrigin.x;
      lprcView->bottom = infoPtr->rcView.bottom + ptOrigin.y;
    }

    TRACE(listview, "(lprcView->left=%d,lprcView->top=%d,lprcView->right=%d,lprcView->bottom=%d)\n", lprcView->left, lprcView->top, lprcView->right, lprcView->bottom);

  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Determines which section of the item was selected (if any).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [IO] LPLVHITTESTINFO : hit test information
 *
 * RETURN:
 *   SUCCESS : item index
 *   FAILURE : -1
 */
static INT LISTVIEW_HitTestItem(HWND hwnd, LPLVHITTESTINFO lpHitTestInfo)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  RECT rcItem;
  INT i;

  for (i = 0; i < GETITEMCOUNT(infoPtr); i++)
  {
    rcItem.left = LVIR_BOUNDS;
    if (LISTVIEW_GetItemRect(hwnd, i, &rcItem) != FALSE)
    {
      rcItem.left = LVIR_ICON;
      if (LISTVIEW_GetItemRect(hwnd, i, &rcItem) != FALSE)
      {
        if ((lpHitTestInfo->pt.x >= rcItem.left) && 
            (lpHitTestInfo->pt.x <= rcItem.right) && 
            (lpHitTestInfo->pt.y >= rcItem.top) &&
            (lpHitTestInfo->pt.y <= rcItem.bottom))
        {
          lpHitTestInfo->flags = LVHT_ONITEMICON | LVHT_ONITEM;
          lpHitTestInfo->iItem = i;
          lpHitTestInfo->iSubItem = 0;
          return i;
        }
      }
      
      rcItem.left = LVIR_LABEL;
      if (LISTVIEW_GetItemRect(hwnd, i, &rcItem) != FALSE)
      {
        if ((lpHitTestInfo->pt.x >= rcItem.left) && 
            (lpHitTestInfo->pt.x <= rcItem.right) &&
            (lpHitTestInfo->pt.y >= rcItem.top) &&
            (lpHitTestInfo->pt.y <= rcItem.bottom))
        {
          lpHitTestInfo->flags = LVHT_ONITEMLABEL | LVHT_ONITEM;
          lpHitTestInfo->iItem = i;
          lpHitTestInfo->iSubItem = 0;
          return i;
        }
      }

      lpHitTestInfo->flags = LVHT_ONITEMSTATEICON | LVHT_ONITEM;
      lpHitTestInfo->iItem = i;
      lpHitTestInfo->iSubItem = 0;
      return i;
    }
  }
     
  lpHitTestInfo->flags = LVHT_NOWHERE;

  return -1;
}

/***
 * DESCRIPTION:
 * Determines wich listview item is located at the specified position.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [IO} LPLVHITTESTINFO : hit test information
 *
 * RETURN:
 *   SUCCESS : item index
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_HitTest(HWND hwnd, LPLVHITTESTINFO lpHitTestInfo)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nItem = -1;

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

  if (lpHitTestInfo->flags == 0)
  {
    nItem = LISTVIEW_HitTestItem(hwnd, lpHitTestInfo);
  }
  
  return nItem;
}

/***
 * DESCRIPTION:
 * Inserts a new column.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : column index
 * [I] LPLVCOLUMNA : column information
 *
 * RETURN:
 *   SUCCESS : new column index
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_InsertColumnA(HWND hwnd, INT nColumn, 
                                      LPLVCOLUMNA lpColumn)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  HDITEMA hdi;
  INT nNewColumn = -1;

  TRACE(listview,"(hwnd=%x,nColumn=%d,lpColumn=%p)\n",hwnd, nColumn, lpColumn);

  if (lpColumn != NULL) 
  {
    /* initialize memory */
    ZeroMemory(&hdi, sizeof(HDITEMA));

    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)
      {
        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)
      {
        /* ??? */
      }
      
      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 = lstrlenA(lpColumn->pszText);
      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;
    }

    /* insert item in header control */
    nNewColumn = SendMessageA(infoPtr->hwndHeader, HDM_INSERTITEMA,
                             (WPARAM)nColumn, (LPARAM)&hdi);

    LISTVIEW_SetScroll(hwnd, lStyle);
    InvalidateRect(hwnd, NULL, FALSE);
  }

  return nNewColumn;
}

/* LISTVIEW_InsertColumnW  */

/***
 * DESCRIPTION:
 * Inserts a new item in the listview control.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] LPLVITEMA : item information
 *
 * RETURN:
 *   SUCCESS : new item index
 *   FAILURE : -1
 */
static LRESULT LISTVIEW_InsertItemA(HWND hwnd, LPLVITEMA lpLVItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  LONG lCtrlId = GetWindowLongA(hwnd, GWL_ID);
  NMLISTVIEW nmlv;
  INT nItem = -1;
  HDPA hdpaSubItems;
  LISTVIEW_ITEM *lpItem = NULL;

  TRACE(listview, "(hwnd=%x,lpLVItem=%p)\n", hwnd, lpLVItem);

  if (lpLVItem != NULL)
  {
    /* make sure it's not a subitem; cannot insert a subitem */
    if (lpLVItem->iSubItem == 0)
    {
      lpItem = (LISTVIEW_ITEM *)COMCTL32_Alloc(sizeof(LISTVIEW_ITEM));
      if (lpItem != NULL)
      {
        ZeroMemory(lpItem, sizeof(LISTVIEW_ITEM));
        if (LISTVIEW_InitItem(hwnd, lpItem, lpLVItem) != FALSE)
        {
          /* insert item in listview control data structure */
          hdpaSubItems = DPA_Create(8);
          if (hdpaSubItems != NULL)
          {
            nItem = DPA_InsertPtr(hdpaSubItems, 0, lpItem);
            if (nItem != -1)
            {
              nItem = DPA_InsertPtr(infoPtr->hdpaItems, lpLVItem->iItem, 
                                    hdpaSubItems);
              if (nItem != -1)
              {
                /* manage item focus */
                if (lpLVItem->mask & LVIF_STATE)
                {
                  if (lpLVItem->stateMask & LVIS_FOCUSED)
                  {
                    LISTVIEW_SetItemFocus(hwnd, nItem);
                  }           
                }
                
                /* send LVN_INSERTITEM notification */
                ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
                nmlv.hdr.hwndFrom = hwnd;
                nmlv.hdr.idFrom = lCtrlId;
                nmlv.hdr.code = LVN_INSERTITEM;
                nmlv.iItem = nItem;
                nmlv.lParam = lpItem->lParam;;
                ListView_LVNotify(GetParent(hwnd), lCtrlId, &nmlv);
                
                /* align items (set position of each item) */
                switch (lStyle & LVS_TYPEMASK)
                {
                case LVS_ICON:
                case LVS_SMALLICON:
                  if (lStyle & LVS_ALIGNLEFT)
                  {
                    LISTVIEW_AlignLeft(hwnd);
                  }
                  else
                  {
                    LISTVIEW_AlignTop(hwnd);
                  }
                  break;
                }

                LISTVIEW_SetScroll(hwnd, lStyle);
                /* refresh client area */
                InvalidateRect(hwnd, NULL, FALSE);
              }
            }
          }
        }
      }
    }
  }

  /* free memory if unsuccessful */
  if ((nItem == -1) && (lpItem != NULL))
  {
    COMCTL32_Free(lpItem);
  }
  
  return nItem;
}

/* LISTVIEW_InsertItemW */

/***
 * DESCRIPTION:
 * Redraws a range of items.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : first item
 * [I] INT : last item
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_RedrawItems(HWND hwnd, INT nFirst, INT nLast)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0); 
  BOOL bResult = FALSE;
  RECT rc;

  if (nFirst <= nLast)
  {
    if ((nFirst >= 0) && (nFirst < GETITEMCOUNT(infoPtr)))
    {
      if ((nLast >= 0) && (nLast < GETITEMCOUNT(infoPtr)))
      {
        /* bResult = */
        InvalidateRect(hwnd, &rc, FALSE);
      }
    }
  }

  return bResult;
}

/* LISTVIEW_Scroll */

/***
 * DESCRIPTION:
 * Sets the background color.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] COLORREF : background color
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetBkColor(HWND hwnd, COLORREF clrBk)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  infoPtr->clrBk = clrBk;
  InvalidateRect(hwnd, NULL, TRUE);
  
  return TRUE;
}

/***
 * DESCRIPTION:
 * Sets the callback mask. This mask will be used when the parent
 * window stores state information (some or all).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] UINT : state mask
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_SetCallbackMask(HWND hwnd, UINT uMask)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  infoPtr->uCallbackMask = uMask;

  return TRUE;
}

/***
 * DESCRIPTION:
 * Sets the attributes of a header item.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : column index
 * [I] LPLVCOLUMNA : column attributes
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetColumnA(HWND hwnd, INT nColumn, 
                                   LPLVCOLUMNA lpColumn)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  BOOL bResult = FALSE;
  HDITEMA hdi;

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

    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)
      {
        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 = lstrlenA(lpColumn->pszText);
      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 */
    bResult = Header_SetItemA(infoPtr->hwndHeader, nColumn, &hdi);
  }
  
  return bResult;
}

/***
 * DESCRIPTION:
 * Sets the width of a column
 *
 * PARAMETERS:
 * [I] HWND : window handle
 * [I] INT : column index
 * [I] INT : column width
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetColumnWidth(HWND hwnd, INT iCol, INT cx)
{
    LISTVIEW_INFO *infoPtr;
    HDITEMA hdi;
    LRESULT lret;
    LONG lStyle;

    // set column width only if in report mode
    lStyle = GetWindowLongA(hwnd, GWL_STYLE);
    if ((lStyle & LVS_TYPEMASK) != LVS_REPORT)
	return (FALSE);

    // make sure we can get the listview info
    if (!(infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0)))
	return (FALSE);  
    if (!infoPtr->hwndHeader) // make sure we have a header
	return (FALSE);	
	
    // FIXME: currently ignoring LVSCW_AUTOSIZE (-1) and
    // LVSCV_AUTOSIZE_USEHEADER (-2)
    if (cx < 0) 
	return (FALSE);
	
    hdi.mask = HDI_WIDTH;
    hdi.cxy = cx;

    // call header to update the column change
    lret = Header_SetItemA(infoPtr->hwndHeader, (WPARAM)iCol, (LPARAM)&hdi);

    infoPtr->nItemWidth = LISTVIEW_GetItemWidth(hwnd, LVS_REPORT);

    InvalidateRect(hwnd, NULL, TRUE); // force redraw of the listview

    return lret;
}

/***
 * DESCRIPTION:
 * Sets image lists.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : image list type  
 * [I] HIMAGELIST : image list handle
 *
 * RETURN:
 *   SUCCESS : old image list
 *   FAILURE : NULL
 */
static LRESULT LISTVIEW_SetImageList(HWND hwnd, INT nType, HIMAGELIST himl)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  HIMAGELIST himlTemp = 0;

  switch (nType) 
  {
  case LVSIL_NORMAL:
    himlTemp = infoPtr->himlNormal;
    infoPtr->himlNormal = himl;
    return (LRESULT)himlTemp;

  case LVSIL_SMALL:
    himlTemp = infoPtr->himlSmall;
    infoPtr->himlSmall = himl;
    return (LRESULT)himlTemp;

  case LVSIL_STATE:
    himlTemp = infoPtr->himlState;
    infoPtr->himlState = himl;
    return (LRESULT)himlTemp;
  }

  return (LRESULT)NULL;
}


/***
 * DESCRIPTION:
 * Sets the attributes of an item.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] LPLVITEM : item information 
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetItemA(HWND hwnd, LPLVITEMA lpLVItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  BOOL bResult = FALSE;

  if (lpLVItem != NULL)
  {
    if ((lpLVItem->iItem >= 0) && (lpLVItem->iItem < GETITEMCOUNT(infoPtr)))
    {
      if (lpLVItem->iSubItem == 0)
      {
        bResult = LISTVIEW_SetItem(hwnd, lpLVItem);
      }
      else
      {
        bResult = LISTVIEW_SetSubItem(hwnd, lpLVItem);
      }
    }
  }


  return bResult;
}

/* LISTVIEW_SetItemW  */

/***
 * DESCRIPTION:
 * Preallocates memory.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item count (prjected number of items)
 *
 * RETURN:
 * None
 */
static VOID LISTVIEW_SetItemCount(HWND hwnd, INT nItemCount)
{
  FIXME (listview, "empty stub!\n");
}

/***
 * DESCRIPTION:
 * Sets the position of an item.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index
 * [I] INT : x coordinate
 * [I] INT : y coordinate
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_SetItemPosition(HWND hwnd, INT nItem, 
                                     INT nPosX, INT nPosY)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  LISTVIEW_ITEM *lpItem;
  HDPA hdpaSubItems;
  BOOL bResult = FALSE;

  TRACE(listview, "(hwnd=%x,nItem=%d,X=%d,Y=%d)\n", hwnd, nItem, nPosX, nPosY);

  if ((nItem >= 0) || (nItem < GETITEMCOUNT(infoPtr)))
  {
    switch (lStyle & LVS_TYPEMASK)
    {
    case LVS_ICON:
    case LVS_SMALLICON:
      hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
      if (hdpaSubItems != NULL)
      {
        lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
        if (lpItem != NULL)
        {
          bResult = TRUE;
          lpItem->ptPosition.x = nPosX;
          lpItem->ptPosition.y = nPosY;
        }
      }
      break;
    }
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Sets the state of one or many items.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I]INT : item index
 * [I] LPLVITEM : item or subitem info
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetItemState(HWND hwnd, INT nItem, LPLVITEMA lpLVItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  BOOL bResult = FALSE;
  LVITEMA lvItem;
  INT i;

  if (nItem == -1)
  {
    bResult = TRUE;
    ZeroMemory(&lvItem, sizeof(LVITEMA));
    lvItem.mask = LVIF_STATE;
    lvItem.state = lpLVItem->state;
    lvItem.stateMask = lpLVItem->stateMask;
    
    /* apply to all items */
    for (i = 0; i< GETITEMCOUNT(infoPtr); i++)
    {
      lvItem.iItem = i;
      if (ListView_SetItemA(hwnd, &lvItem) == FALSE)
      {
        bResult = FALSE;
      }
    }
  }
  else
  {
    ZeroMemory(&lvItem, sizeof(LVITEMA));
    lvItem.mask = LVIF_STATE;
    lvItem.state = lpLVItem->state;
    lvItem.stateMask = lpLVItem->stateMask;
    lvItem.iItem = nItem;
    bResult = ListView_SetItemA(hwnd, &lvItem);
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Sets the text of an item or subitem.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index
 * [I] LPLVITEMA : item or subitem info
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static BOOL LISTVIEW_SetItemTextA(HWND hwnd, INT nItem, LPLVITEMA lpLVItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  BOOL bResult = FALSE;
  LVITEMA lvItem;

  if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)))
  {
    ZeroMemory(&lvItem, sizeof(LVITEMA));
    lvItem.mask = LVIF_TEXT;
    lvItem.pszText = lpLVItem->pszText;
    lvItem.iItem = nItem;
    lvItem.iSubItem = lpLVItem->iSubItem;
    bResult = ListView_SetItemA(hwnd, &lvItem);
  }
  
  return bResult;
}

/***
 * DESCRIPTION:
 * Sets the text background color.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] COLORREF : text background color
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetTextBkColor(HWND hwnd, COLORREF clrTextBk)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  infoPtr->clrTextBk = clrTextBk;
  InvalidateRect(hwnd, NULL, TRUE);

  return TRUE;
}

/***
 * DESCRIPTION:
 * Sets the text foreground color.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] COLORREF : text color 
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SetTextColor (HWND hwnd, COLORREF clrText)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  infoPtr->clrText = clrText;
  InvalidateRect(hwnd, NULL, TRUE);

  return TRUE;
}

/***
 * DESCRIPTION:
 * Sorts the listview items.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_SortItems(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  FIXME (listview, "empty stub!\n");

  return TRUE;
}

/***
 * DESCRIPTION:
 * Updates an items or rearranges the listview control.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : item index
 *
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_Update(HWND hwnd, INT nItem)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  BOOL bResult = FALSE;
  RECT rc;

  if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)))
  {
    bResult = TRUE;

    /* rearrange with default alignment style */
    if ((lStyle & LVS_AUTOARRANGE) && (((lStyle & LVS_TYPEMASK) == LVS_ICON) ||
        ((lStyle & LVS_TYPEMASK)  == LVS_SMALLICON)))
    {
      ListView_Arrange(hwnd, 0);
    }
    else
    {
      /* get item bounding rectangle */
      rc.left = LVIR_BOUNDS;
      ListView_GetItemRect(hwnd, nItem, &rc);
      InvalidateRect(hwnd, &rc, FALSE);
    }
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Creates the listview control.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_Create(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LPCREATESTRUCTA lpcs = (LPCREATESTRUCTA)lParam;
  LOGFONTA logFont;

  /* initialize info pointer */
  ZeroMemory(infoPtr, sizeof(LISTVIEW_INFO));

  /* determine the type of structures to use */
  infoPtr->notifyFormat = SendMessageA(GetParent(hwnd), WM_NOTIFYFORMAT, 
                                       (WPARAM)hwnd, (LPARAM)NF_QUERY);
  if (infoPtr->notifyFormat != NFR_ANSI)
  {
    FIXME (listview, "ANSI notify format is NOT used\n");
  }
  
  /* initialize color information  */
  infoPtr->clrBk = GetSysColor(COLOR_WINDOW);
  infoPtr->clrText = GetSysColor(COLOR_WINDOWTEXT);
  infoPtr->clrTextBk = GetSysColor(COLOR_WINDOW); 

  /* set default values */
  infoPtr->uCallbackMask = 0;
  infoPtr->nFocusedItem = -1;
  infoPtr->nSelectionMark = -1;
  infoPtr->iconSpacing.cx = GetSystemMetrics(SM_CXICONSPACING);
  infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING);
  ZeroMemory(&infoPtr->rcList, sizeof(RECT));

  /* get default font (icon title) */
  SystemParametersInfoA(SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
  infoPtr->hDefaultFont = CreateFontIndirectA(&logFont);
  infoPtr->hFont = infoPtr->hDefaultFont;
  
  /* create header */
  infoPtr->hwndHeader =	CreateWindowA(WC_HEADERA, (LPCSTR)NULL, 
                                      WS_CHILD | HDS_HORZ | HDS_BUTTONS, 
                                      0, 0, 0, 0, hwnd, (HMENU)0, 
                                      lpcs->hInstance, NULL);

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

  
  switch (lpcs->style & LVS_TYPEMASK)
  {
  case LVS_ICON:
    infoPtr->iconSize.cx = GetSystemMetrics(SM_CXICON);
    infoPtr->iconSize.cy = GetSystemMetrics(SM_CYICON);
    break;

  case LVS_REPORT:
    ShowWindow(infoPtr->hwndHeader, SW_SHOWNORMAL);
  case LVS_SMALLICON:
  case LVS_LIST:
    infoPtr->iconSize.cx = GetSystemMetrics(SM_CXSMICON);
    infoPtr->iconSize.cy = GetSystemMetrics(SM_CYSMICON);
    break;
  }

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

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

  /* initialize size of items */
  infoPtr->nItemWidth = LISTVIEW_GetItemWidth(hwnd, lpcs->style);
  infoPtr->nItemHeight = LISTVIEW_GetItemHeight(hwnd, lpcs->style);

  return 0;
}

/***
 * DESCRIPTION:
 * Erases the background of the listview control.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] WPARAM : device context handle
 * [I] LPARAM : not used
 * 
 * RETURN:
 *   SUCCESS : TRUE
 *   FAILURE : FALSE
 */
static LRESULT LISTVIEW_EraseBackground(HWND hwnd, WPARAM wParam, 
                                        LPARAM lParam)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  BOOL bResult;

  if (infoPtr->clrBk == CLR_NONE) 
  {
    bResult = SendMessageA(GetParent(hwnd), WM_ERASEBKGND, wParam, lParam);
  }
  else 
  {
    RECT rc;
    HBRUSH hBrush = CreateSolidBrush(infoPtr->clrBk);
    GetClientRect(hwnd, &rc);
    FillRect((HDC)wParam, &rc, hBrush);
    DeleteObject(hBrush);
    bResult = TRUE;
  }

  return bResult;
}

/***
 * DESCRIPTION:
 * Retrieves the listview control font.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 *
 * RETURN:
 * Font handle.
 */
static LRESULT LISTVIEW_GetFont(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  return infoPtr->hFont;
}

/***
 * DESCRIPTION:
 * Performs vertical scrolling.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : scroll code
 * [I] INT : scroll position
 * [I] HWND : scrollbar control window handle
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_VScroll(HWND hwnd, INT nScrollCode, INT nScroll, 
                                HWND hScrollWnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  INT nScrollPosInc = 0;
  INT nScrollPos;
  INT nMinRange;
  INT nMaxRange;

  GetScrollRange(hwnd, SB_VERT, &nMinRange, &nMaxRange);
  nScrollPos = GetScrollPos(hwnd, SB_VERT);

  switch (nScrollCode)
  {
  case SB_LINEUP:
    if (nScrollPos > nMinRange)
    {
      nScrollPosInc = -1;
    }
    break;
    
  case SB_LINEDOWN:
    if (nScrollPos < nMaxRange)
    {
      nScrollPosInc = 1;
    }
    break;

  case SB_PAGEUP:
    switch (LVS_TYPEMASK & lStyle)
    {
    case LVS_REPORT:
      if (nScrollPos > nMinRange + infoPtr->nCountPerColumn)
      {
        nScrollPosInc = -infoPtr->nCountPerColumn;
      } 
      else
      {
        nScrollPosInc = nMinRange - nScrollPos;
      }
      break;

    case LVS_SMALLICON:
    case LVS_ICON:
      if (nScrollPos > nMinRange + 10)
      {
        nScrollPosInc = -10;
      }
      else
      {
        nScrollPosInc = nMinRange - nScrollPos;
      }
      break;
    }
    break;

   case SB_PAGEDOWN:
     switch (LVS_TYPEMASK & lStyle)
     {
     case LVS_REPORT:
       if (nScrollPos < nMaxRange - infoPtr->nCountPerColumn)
       {
         nScrollPosInc = infoPtr->nCountPerColumn;
       }
       else
       {
         nScrollPosInc = nMaxRange - nScrollPos;
       }
       break;

     case LVS_SMALLICON:
     case LVS_ICON:
       if (nScrollPos < nMaxRange - 10)
       {
         nScrollPosInc = 10;
       }
       else
       {
         nScrollPosInc = nMaxRange - nScrollPos;
       }
       break;
     }
     break;

   case SB_THUMBPOSITION:
     nScrollPosInc = nScroll - nScrollPos; 
    break;
  }

  if (nScrollPosInc != 0)
  {
    LISTVIEW_ScrollView(hwnd, 0, nScrollPosInc);
  }

  return 0;
}


/***
 * DESCRIPTION:
 * Performs horizontal scrolling.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : scroll code
 * [I] INT : scroll position
 * [I] HWND : scrollbar control window handle
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_HScroll(HWND hwnd, INT nScrollCode, 
                                INT nScroll, HWND hScrollWnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  INT nScrollPosInc = 0;
  INT nScrollPos;
  INT nMinRange;
  INT nMaxRange;

  GetScrollRange(hwnd, SB_HORZ, &nMinRange, &nMaxRange);
  nScrollPos = GetScrollPos(hwnd, SB_HORZ);

  switch (nScrollCode)
  {
  case SB_LINELEFT:
    if (nScrollPos > nMinRange)
    {
      nScrollPosInc = -1;
    }
    break;

  case SB_LINERIGHT:
    if (nScrollPos < nMaxRange)
    {
      nScrollPosInc = 1;
    }
    break;

  case SB_PAGELEFT:
    switch (LVS_TYPEMASK & lStyle)
    {
    case LVS_LIST:
      if (nScrollPos > nMinRange + infoPtr->nCountPerRow)
      {
        nScrollPosInc = -infoPtr->nCountPerRow;
      }
      else
      {
        nScrollPosInc = nMinRange - nScrollPos;
      }
      break;

    case LVS_REPORT:
    case LVS_SMALLICON:
    case LVS_ICON:
      if (nScrollPos > nMinRange + 10)
      {
        nScrollPosInc = -10;
      }
      else
      {
        nScrollPosInc = nMinRange - nScrollPos;
      }
      break;
    }
    break;

  case SB_PAGERIGHT:
    switch (LVS_TYPEMASK & lStyle)
    {
    case LVS_LIST:
      if (nScrollPos < nMaxRange - infoPtr->nCountPerRow)
      {
        nScrollPosInc = infoPtr->nCountPerRow;
      }
      else
      {
        nScrollPosInc = nMaxRange - nScrollPos;
      }
      break;
      
    case LVS_REPORT:
    case LVS_SMALLICON:
    case LVS_ICON:
      if (nScrollPos < nMaxRange - 10)
      {
        nScrollPosInc = 10;
      }
      else
      {
        nScrollPosInc = nMaxRange - nScrollPos;
      }
      break;
    }
    break;

  case SB_THUMBPOSITION:
    nScrollPosInc = nScroll - nScrollPos;
    break;
  }

  if (nScrollPosInc != 0)
  {
    LISTVIEW_ScrollView(hwnd, nScrollPosInc, 0);
  }

  return 0;
}

/***
 * DESCRIPTION:
 * ??? 
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : virtual key 
 * [I] LONG : key data
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_KeyDown(HWND hwnd, INT nVirtualKey, LONG lKeyData)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
  INT nCtrlId = GetWindowLongA(hwnd, GWL_ID);
  INT nCountPerColumn;
  INT nCountPerRow;
  HWND hwndParent = GetParent(hwnd);
  NMLVKEYDOWN nmKeyDown; 
  NMHDR nmh;

  /* send LVN_KEYDOWN notification */
  ZeroMemory(&nmKeyDown, sizeof(NMLVKEYDOWN));
  nmKeyDown.hdr.hwndFrom = hwnd;  
  nmKeyDown.hdr.idFrom = nCtrlId;  
  nmKeyDown.hdr.code = LVN_KEYDOWN;  
  nmKeyDown.wVKey = nVirtualKey; 
  nmKeyDown.flags = 0; 
  SendMessageA(hwndParent, WM_NOTIFY, (WPARAM)nCtrlId, (LPARAM)&nmKeyDown); 
  
  /* initialize */
  nmh.hwndFrom = hwnd;
  nmh.idFrom = nCtrlId;

  switch (nVirtualKey)
  {
  case VK_RETURN:
    if ((GETITEMCOUNT(infoPtr) > 0) && (infoPtr->nFocusedItem != -1))
    {
      /* send NM_RETURN notification */
      nmh.code = NM_RETURN;
      ListView_Notify(hwndParent, nCtrlId, &nmh);
      
      /* send LVN_ITEMACTIVATE notification */
      nmh.code = LVN_ITEMACTIVATE;
      ListView_Notify(hwndParent, nCtrlId, &nmh);
    }
    break;

  case VK_HOME:
    if (GETITEMCOUNT(infoPtr) > 0)
    {
      LISTVIEW_KeySelection(hwnd, 0); 
    }
    break;

  case VK_END:
    if (GETITEMCOUNT(infoPtr) > 0)
    {
      LISTVIEW_KeySelection(hwnd, GETITEMCOUNT(infoPtr) - 1);
    }
    break;

  case VK_LEFT:
    switch (LVS_TYPEMASK & lStyle)
    {
    case LVS_LIST:
      if (infoPtr->nFocusedItem >= infoPtr->nCountPerColumn) 
      {
        LISTVIEW_KeySelection(hwnd, infoPtr->nFocusedItem - 
                              infoPtr->nCountPerColumn);
      }
      break;

    case LVS_SMALLICON:
    case LVS_ICON:
      if (lStyle & LVS_ALIGNLEFT)
      {
        nCountPerColumn = max((infoPtr->rcList.bottom - infoPtr->rcList.top) /
                              infoPtr->nItemHeight, 1);
        if (infoPtr->nFocusedItem >= nCountPerColumn) 
        {
          LISTVIEW_KeySelection(hwnd, infoPtr->nFocusedItem - nCountPerColumn);
        }
      }
      else
      {
        nCountPerRow = max((infoPtr->rcList.right - infoPtr->rcList.left) /
                           infoPtr->nItemWidth, 1);
        if (infoPtr->nFocusedItem % nCountPerRow != 0)
        {
          LISTVIEW_SetSelection(hwnd, infoPtr->nFocusedItem - 1); 
        }
      }
      break;
    }
    break;
  
  case VK_UP:
    switch (LVS_TYPEMASK & lStyle)
    {
    case LVS_LIST:
    case LVS_REPORT:
      if (infoPtr->nFocusedItem > 0)
      {
        LISTVIEW_KeySelection(hwnd, infoPtr->nFocusedItem - 1);
      }
      break;

    default:
      if (lStyle & LVS_ALIGNLEFT)
      {
        nCountPerColumn = max((infoPtr->rcList.bottom - infoPtr->rcList.top) /
                              infoPtr->nItemHeight, 1);
        if (infoPtr->nFocusedItem % nCountPerColumn != 0)
        {
          LISTVIEW_KeySelection(hwnd, infoPtr->nFocusedItem - 1);
        }
      }
      else
      {
        nCountPerRow = max((infoPtr->rcList.right - infoPtr->rcList.left) /
                           infoPtr->nItemWidth, 1);
        if (infoPtr->nFocusedItem >= nCountPerRow)
        {
          LISTVIEW_KeySelection(hwnd, infoPtr->nFocusedItem - nCountPerRow);
        }
      }
    }
    break;
    
  case VK_RIGHT:
    switch (LVS_TYPEMASK & lStyle)
    {
    case LVS_LIST:
      if (infoPtr->nFocusedItem < GETITEMCOUNT(infoPtr) - 
          infoPtr->nCountPerColumn)
      {
        LISTVIEW_KeySelection(hwnd, infoPtr->nFocusedItem +
                              infoPtr->nCountPerColumn);
      }
      break;

    case LVS_ICON:
    case LVS_SMALLICON:
      if (lStyle & LVS_ALIGNLEFT)
      {
        nCountPerColumn = max((infoPtr->rcList.bottom - infoPtr->rcList.top) /
                              infoPtr->nItemHeight, 1);
        if (infoPtr->nFocusedItem < GETITEMCOUNT(infoPtr) - nCountPerColumn)
        {
          LISTVIEW_KeySelection(hwnd, infoPtr->nFocusedItem + nCountPerColumn);
        }
      }
      else
      {
        nCountPerRow = max((infoPtr->rcList.right - infoPtr->rcList.left) /
                           infoPtr->nItemWidth, 1);
        if ((infoPtr->nFocusedItem % nCountPerRow != nCountPerRow - 1) && 
            (infoPtr->nFocusedItem < GETITEMCOUNT(infoPtr) - 1))
        {
          LISTVIEW_KeySelection(hwnd, infoPtr->nFocusedItem + 1);
        }
      }
    }
    break;

  case VK_DOWN:
    switch (LVS_TYPEMASK & lStyle)
    {
    case LVS_LIST:
    case LVS_REPORT:
      if (infoPtr->nFocusedItem < GETITEMCOUNT(infoPtr) - 1)
      {
        LISTVIEW_KeySelection(hwnd, infoPtr->nFocusedItem + 1);
      }
      break;

    case LVS_SMALLICON:
    case LVS_ICON:
      if (lStyle & LVS_ALIGNLEFT)
      {
        nCountPerColumn = max((infoPtr->rcList.bottom - infoPtr->rcList.top) /
                              infoPtr->nItemHeight, 1);
        if (infoPtr->nFocusedItem % nCountPerColumn != nCountPerColumn - 1)
        {
          LISTVIEW_KeySelection(hwnd, infoPtr->nFocusedItem + 1);
        }
      }
      else
      {
        nCountPerRow = max((infoPtr->rcList.right - infoPtr->rcList.left) /
                           infoPtr->nItemWidth, 1);
        if (infoPtr->nFocusedItem < GETITEMCOUNT(infoPtr) - nCountPerRow)
        {
          LISTVIEW_KeySelection(hwnd, infoPtr->nFocusedItem + nCountPerRow);
        }
      }
    }
    break;

  case VK_PRIOR:
    break;

  case VK_NEXT:
    break;
  }

  /* refresh client area */
  InvalidateRect(hwnd, NULL, TRUE);

  return 0;
}

/***
 * DESCRIPTION:
 * Kills the focus.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_KillFocus(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLongA(hwnd, 0);
  INT nCtrlId = GetWindowLongA(hwnd, GWL_ID);
  NMHDR nmh;

  /* send NM_KILLFOCUS notification */
  nmh.hwndFrom = hwnd;
  nmh.idFrom = nCtrlId;
  nmh.code = NM_KILLFOCUS;
  ListView_Notify(GetParent(hwnd), nCtrlId, &nmh);

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

  return 0;
}

/***
 * DESCRIPTION:
 * Processes double click messages (left mouse button).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] WORD : key flag
 * [I] WORD : x coordinate
 * [I] WORD : y coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_LButtonDblClk(HWND hwnd, WORD wKey, WORD wPosX, 
                                      WORD wPosY)
{
  LONG nCtrlId = GetWindowLongA(hwnd, GWL_ID);
  NMHDR nmh;

  TRACE(listview, "(hwnd=%x,key=%hu,X=%hu,Y=%hu)\n", hwnd, wKey, wPosX, wPosY);

  /* send NM_DBLCLK notification */
  nmh.hwndFrom = hwnd;
  nmh.idFrom = nCtrlId;
  nmh.code = NM_DBLCLK;
  ListView_Notify(GetParent(hwnd), nCtrlId, &nmh);

  /* send LVN_ITEMACTIVATE notification */
  nmh.code = LVN_ITEMACTIVATE;
  ListView_Notify(GetParent(hwnd), nCtrlId, &nmh);

  return 0;
}

/***
 * DESCRIPTION:
 * Processes mouse down messages (left mouse button).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] WORD : key flag
 * [I] WORD : x coordinate
 * [I] WORD : y coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_LButtonDown(HWND hwnd, WORD wKey, WORD wPosX, 
                                    WORD wPosY)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nCtrlId = GetWindowLongA(hwnd, GWL_ID);
  static BOOL bGroupSelect = TRUE;
  NMHDR nmh;
  INT nItem;

  TRACE(listview, "(hwnd=%x,key=%hu,X=%hu,Y=%hu)\n", hwnd, wKey, wPosX, wPosY);

  /* send NM_RELEASEDCAPTURE notification */ 
  nmh.hwndFrom = hwnd;
  nmh.idFrom = nCtrlId;
  nmh.code = NM_RELEASEDCAPTURE;
  ListView_Notify(GetParent(hwnd), nCtrlId, &nmh);
 
  if (infoPtr->bFocus == FALSE)
  {
    SetFocus(hwnd);
  }

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

  nItem = LISTVIEW_MouseSelection(hwnd, wPosX, wPosY);
  if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)))
  {
    if ((wKey & MK_CONTROL) && (wKey & MK_SHIFT))
    {
      if (bGroupSelect != FALSE)
      {
        LISTVIEW_AddGroupSelection(hwnd, nItem);
      }
      else
      {
        LISTVIEW_AddSelection(hwnd, nItem);
      }
    }
    else if (wKey & MK_CONTROL)
    {
      bGroupSelect = LISTVIEW_ToggleSelection(hwnd, nItem);
    }
    else  if (wKey & MK_SHIFT)
    {
      LISTVIEW_SetGroupSelection(hwnd, nItem);
    }
    else
    {
      LISTVIEW_SetSelection(hwnd, nItem);
    }
  }
  else
  {
    /* remove all selections */
    LISTVIEW_RemoveSelections(hwnd, 0, GETITEMCOUNT(infoPtr));
  }

  InvalidateRect(hwnd, NULL, TRUE);

  return 0;
}

/***
 * DESCRIPTION:
 * Processes mouse up messages (left mouse button).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] WORD : key flag
 * [I] WORD : x coordinate
 * [I] WORD : y coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_LButtonUp(HWND hwnd, WORD wKey, WORD wPosX, 
                                  WORD wPosY)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  TRACE(listview, "(hwnd=%x,key=%hu,X=%hu,Y=%hu)\n", hwnd, wKey, wPosX, wPosY);

  if (infoPtr->bLButtonDown != FALSE) 
  {
    INT nCtrlId = GetWindowLongA(hwnd, GWL_ID);
    NMHDR nmh;

    /* send NM_CLICK notification */
    nmh.hwndFrom = hwnd;
    nmh.idFrom = nCtrlId;
    nmh.code = NM_CLICK;
    ListView_Notify(GetParent(hwnd), nCtrlId, &nmh);

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

  return 0;
}

/***
 * DESCRIPTION:
 * Creates the listview control (called before WM_CREATE).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] WPARAM : unhandled 
 * [I] LPARAM : widow creation info
 * 
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_NCCreate(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  LISTVIEW_INFO *infoPtr;

  TRACE(listview, "(hwnd=%x,wParam=%x,lParam=%lx)\n", hwnd, wParam, lParam);

  /* allocate memory for info structure */
  infoPtr = (LISTVIEW_INFO *)COMCTL32_Alloc(sizeof(LISTVIEW_INFO));
  SetWindowLongA(hwnd, 0, (LONG)infoPtr);
  if (infoPtr == NULL) 
  {
    ERR(listview, "could not allocate info memory!\n");
    return 0;
  }

  if ((LISTVIEW_INFO *)GetWindowLongA(hwnd, 0) != infoPtr) 
  {
    ERR(listview, "pointer assignment error!\n");
    return 0;
  }

  return DefWindowProcA(hwnd, WM_NCCREATE, wParam, lParam);
}

/***
 * DESCRIPTION:
 * Destroys the listview control (called after WM_DESTROY).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * 
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_NCDestroy(HWND hwnd)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  TRACE(listview, "(hwnd=%x)\n", hwnd);

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

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

  /* destroy font */
  infoPtr->hFont = (HFONT)0;
  if (infoPtr->hDefaultFont)
  {
    DeleteObject(infoPtr->hDefaultFont);
  }

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

  return 0;
}

/***
 * DESCRIPTION:
 * Handles notifications from children.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] INT : control identifier
 * [I] LPNMHDR : notification information
 * 
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_Notify(HWND hwnd, INT nCtrlId, LPNMHDR lpnmh)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  
  if (lpnmh->hwndFrom == infoPtr->hwndHeader) 
  {
    /* handle notification from header control */
    if (lpnmh->code == HDN_ENDTRACKA)
    {
      infoPtr->nItemWidth = LISTVIEW_GetItemWidth(hwnd, LVS_REPORT);
      InvalidateRect(hwnd, NULL, TRUE);
    }
  }

  return 0;
}

/***
 * DESCRIPTION:
 * Determines the type of structure to use.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle of the sender
 * [I] HWND : listview window handle 
 * [I] INT : command specifying the nature of the WM_NOTIFYFORMAT
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_NotifyFormat(HWND hwndFrom, HWND hwnd, INT nCommand)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);

  if (nCommand == NF_REQUERY)
  {
    /* determine the type of structure to use */
    infoPtr->notifyFormat = SendMessageA(hwndFrom, WM_NOTIFYFORMAT, 
                                         (WPARAM)hwnd, (LPARAM)NF_QUERY);
    if (infoPtr->notifyFormat == NFR_UNICODE)
    {
      FIXME (listview, "NO support for unicode structures");
    }
  }

  return 0;
}

/***
 * DESCRIPTION:
 * Paints/Repaints the listview control.
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] HDC : device context handle
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_Paint(HWND hwnd, HDC hdc)
{
  PAINTSTRUCT ps;

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

  if (hdc == 0)
  {
    hdc = BeginPaint(hwnd, &ps);
    LISTVIEW_Refresh(hwnd, hdc);
    EndPaint(hwnd, &ps);
  }
  else
  {
    LISTVIEW_Refresh(hwnd, hdc);
  }

  return 0;
}

/***
 * DESCRIPTION:
 * Processes double click messages (right mouse button).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] WORD : key flag
 * [I] WORD : x coordinate
 * [I] WORD : y coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_RButtonDblClk(HWND hwnd, WORD wKey, WORD wPosX, 
                                      WORD wPosY)
{
  INT nCtrlId = GetWindowLongA(hwnd, GWL_ID);
  NMHDR nmh;

  TRACE(listview, "(hwnd=%x,key=%hu,X=%hu,Y=%hu)\n", hwnd, wKey, wPosX, wPosY);

  /* send NM_RELEASEDCAPTURE notification */ 
  nmh.hwndFrom = hwnd;
  nmh.idFrom = nCtrlId;
  nmh.code = NM_RELEASEDCAPTURE;
  ListView_Notify(GetParent(hwnd), nCtrlId, &nmh);

  /* send NM_RDBLCLK notification */
  nmh.code = NM_RDBLCLK;
  ListView_Notify(GetParent(hwnd), nCtrlId, &nmh);

  return 0;
}

/***
 * DESCRIPTION:
 * Processes mouse down messages (right mouse button).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] WORD : key flag
 * [I] WORD : x coordinate
 * [I] WORD : y coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_RButtonDown(HWND hwnd, WORD wKey, WORD wPosX, 
                                    WORD wPosY)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nCtrlId = GetWindowLongA(hwnd, GWL_ID);
  NMHDR nmh;
  INT nItem;

  TRACE(listview, "(hwnd=%x,key=%hu,X=%hu,Y=%hu)\n", hwnd, wKey, wPosX, wPosY);

  /* send NM_RELEASEDCAPTURE notification */
  nmh.hwndFrom = hwnd;
  nmh.idFrom = nCtrlId;
  nmh.code = NM_RELEASEDCAPTURE;
  ListView_Notify(GetParent(hwnd), nCtrlId, &nmh);
 
  /* make sure the listview control window has the focus */
  if (infoPtr->bFocus == FALSE)
  {
    SetFocus(hwnd);
  }

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

  /* determine the index of the selected item */
  nItem = LISTVIEW_MouseSelection(hwnd, wPosX, wPosY);
  if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)))
  {
    if (!((wKey & MK_SHIFT) || (wKey & MK_CONTROL)))
    {
      LISTVIEW_SetSelection(hwnd, nItem);
    }
  }
  else
  {
    LISTVIEW_RemoveSelections(hwnd, 0, GETITEMCOUNT(infoPtr));
  }

  return 0;
}

/***
 * DESCRIPTION:
 * Processes mouse up messages (right mouse button).
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] WORD : key flag
 * [I] WORD : x coordinate
 * [I] WORD : y coordinate
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_RButtonUp(HWND hwnd, WORD wKey, WORD wPosX, 
                                  WORD wPosY)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nCtrlId = GetWindowLongA(hwnd, GWL_ID);
  NMHDR nmh;

  TRACE(listview, "(hwnd=%x,key=%hu,X=%hu,Y=%hu)\n", hwnd, wKey, wPosX, wPosY);

  if (infoPtr->bRButtonDown != FALSE) 
  {
    /* send NM_RClICK notification */
    ZeroMemory(&nmh, sizeof(NMHDR));
    nmh.hwndFrom = hwnd;
    nmh.idFrom = nCtrlId;
    nmh.code = NM_RCLICK;
    ListView_Notify(GetParent(hwnd), nCtrlId, &nmh);

    /* set button flag */
    infoPtr->bRButtonDown = FALSE;
  }
  
  return 0;
}

/***
 * DESCRIPTION:
 * Sets the focus.  
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] HWND : window handle of previously focused window
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_SetFocus(HWND hwnd, HWND hwndLoseFocus)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  INT nCtrlId = GetWindowLongA(hwnd, GWL_ID);
  NMHDR nmh;

  /* send NM_SETFOCUS notification */
  nmh.hwndFrom = hwnd;
  nmh.idFrom = nCtrlId;
  nmh.code = NM_SETFOCUS;
  ListView_Notify(GetParent(hwnd), nCtrlId, &nmh);

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

  return 0;
}

/***
 * DESCRIPTION:
 * Sets the font.  
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] HFONT : font handle
 * [I] WORD : redraw flag
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_SetFont(HWND hwnd, HFONT hFont, WORD fRedraw)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);

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

  if (hFont == 0)
  {
    infoPtr->hFont = infoPtr->hDefaultFont;
  }
  else
  {
    infoPtr->hFont = hFont;
  }

  if ((LVS_TYPEMASK & lStyle ) == LVS_REPORT)
  {
    /* set header font */
    SendMessageA(infoPtr->hwndHeader, WM_SETFONT, (WPARAM)hFont, 
                   MAKELPARAM(fRedraw, 0));
  }

  /* invalidate listview control client area */
  InvalidateRect(hwnd, NULL, TRUE);
  
  if (fRedraw != FALSE)
  {
    UpdateWindow(hwnd);
  }

  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] HWND : window handle
 * [I] WORD : new width
 * [I] WORD : new height
 *
 * RETURN:
 * Zero
 */
static LRESULT LISTVIEW_Size(HWND hwnd, int Width, int Height)
{
  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);

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

  LISTVIEW_SetSize(hwnd, lStyle, -1, -1);
  switch (lStyle & LVS_TYPEMASK)
  {
  case LVS_LIST:
  case LVS_REPORT:
    LISTVIEW_SetViewInfo(hwnd, lStyle);
    break;
    
  case LVS_ICON:
  case LVS_SMALLICON:
    if (lStyle & LVS_ALIGNLEFT)
    {
      LISTVIEW_AlignLeft(hwnd);
    }
    else
    {
      LISTVIEW_AlignTop(hwnd);
    }
    break;
  }

  LISTVIEW_SetScroll(hwnd, lStyle);

  /* invalidate + erase background */
  InvalidateRect(hwnd, NULL, TRUE);

  return 0;
}

/***
 * DESCRIPTION:
 * Sets the size information for a given style. 
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] LONG : window style
 * [I] WORD : new width 
 * [I] WORD : new height
 *
 * RETURN:
 * Zero
 */
static VOID LISTVIEW_SetSize(HWND hwnd, LONG lStyle, LONG lWidth, LONG lHeight)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  HDLAYOUT hl;
  WINDOWPOS wp;
  RECT rcList;
  
  GetClientRect(hwnd, &rcList);
  if (lWidth == -1)
  {
    infoPtr->rcList.left = max(rcList.left, 0);
    infoPtr->rcList.right = max(rcList.right, 0);
  }
  else
  {
    infoPtr->rcList.left = max(rcList.left, 0);
    infoPtr->rcList.right = infoPtr->rcList.left + max(lWidth, 0);
  }

  if (lHeight == -1)
  {
    infoPtr->rcList.top = max(rcList.top, 0);
    infoPtr->rcList.bottom = max(rcList.bottom, 0);
  }
  else
  {
    infoPtr->rcList.top = max(rcList.top, 0);
    infoPtr->rcList.bottom = infoPtr->rcList.top + max(lHeight, 0);
  }
    
  switch (lStyle & LVS_TYPEMASK)
  {
  case LVS_LIST:
    if ((lStyle & WS_HSCROLL) == 0)
    {
      INT nHScrollHeight;
      nHScrollHeight = GetSystemMetrics(SM_CYHSCROLL);
      if (infoPtr->rcList.bottom > nHScrollHeight)
      { 
        infoPtr->rcList.bottom -= nHScrollHeight;
      }
    }
    break;

  case LVS_REPORT:
    hl.prc = &rcList;
    hl.pwpos = &wp;
    Header_Layout(infoPtr->hwndHeader, &hl);
    infoPtr->rcList.top = max(wp.cy, 0);
    break;
  }
}

/***
 * DESCRIPTION:
 * Processes WM_STYLECHANGED messages. 
 * 
 * PARAMETER(S):
 * [I] HWND : window handle
 * [I] WPARAM : window style type (normal or extended)
 * [I] LPSTYLESTRUCT : window style information
 *
 * RETURN:
 * Zero
 */
static INT LISTVIEW_StyleChanged(HWND hwnd, WPARAM wStyleType, 
                                 LPSTYLESTRUCT lpss)
{
  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
  RECT rcList = infoPtr->rcList;
  HDLAYOUT hl;
  WINDOWPOS wp;

  TRACE(listview, "(hwnd=%x,styletype=%x,stylestruct=%p)\n", 
        hwnd, wStyleType, lpss);

  if (wStyleType == GWL_STYLE)
  {
    if ((lpss->styleOld & WS_HSCROLL) != 0)
    {
      ShowScrollBar(hwnd, SB_HORZ, FALSE);
    }

    if ((lpss->styleOld & WS_VSCROLL) != 0)
    {
      ShowScrollBar(hwnd, SB_VERT, FALSE);
    }

    if ((LVS_TYPEMASK & lpss->styleOld) == LVS_REPORT)
    {
      /* remove header */
      ShowWindow(infoPtr->hwndHeader, SW_HIDE);
    }

    switch (lpss->styleNew & LVS_TYPEMASK)
    {
    case LVS_ICON:
      infoPtr->iconSize.cx = GetSystemMetrics(SM_CXICON);
      infoPtr->iconSize.cy = GetSystemMetrics(SM_CYICON);
      LISTVIEW_SetSize(hwnd, lpss->styleNew, -1, -1);
      infoPtr->nItemWidth = LISTVIEW_GetItemWidth(hwnd, lpss->styleNew);
      infoPtr->nItemHeight = LISTVIEW_GetItemHeight(hwnd, lpss->styleNew);
      if (lpss->styleNew & LVS_ALIGNLEFT)
      {
        LISTVIEW_AlignLeft(hwnd);
      }
      else
      {
        LISTVIEW_AlignTop(hwnd);
      }
      break;

    case LVS_REPORT:
      hl.prc = &rcList;
      hl.pwpos = &wp;
      Header_Layout(infoPtr->hwndHeader, &hl);
      SetWindowPos(infoPtr->hwndHeader, hwnd, wp.x, wp.y, wp.cx, 
                   wp.cy, wp.flags);
      ShowWindow(infoPtr->hwndHeader, SW_SHOWNORMAL);
      infoPtr->iconSize.cx = GetSystemMetrics(SM_CXSMICON);
      infoPtr->iconSize.cy = GetSystemMetrics(SM_CYSMICON);
      infoPtr->nItemWidth = LISTVIEW_GetItemWidth(hwnd, lpss->styleNew);
      infoPtr->nItemHeight = LISTVIEW_GetItemHeight(hwnd, lpss->styleNew);
      LISTVIEW_SetSize(hwnd, lpss->styleNew, -1, -1);
      LISTVIEW_SetViewInfo(hwnd, lpss->styleNew);
      break;

    case LVS_LIST:
      infoPtr->iconSize.cx = GetSystemMetrics(SM_CXSMICON);
      infoPtr->iconSize.cy = GetSystemMetrics(SM_CYSMICON);
      infoPtr->nItemWidth = LISTVIEW_GetItemWidth(hwnd, lpss->styleNew);
      infoPtr->nItemHeight = LISTVIEW_GetItemHeight(hwnd, lpss->styleNew);
      LISTVIEW_SetSize(hwnd, lpss->styleNew, -1, -1);
      LISTVIEW_SetViewInfo(hwnd, lpss->styleNew);
      break;

    case LVS_SMALLICON:
      infoPtr->iconSize.cx = GetSystemMetrics(SM_CXSMICON);
      infoPtr->iconSize.cy = GetSystemMetrics(SM_CYSMICON);
      LISTVIEW_SetSize(hwnd, lpss->styleNew, -1, -1);
      infoPtr->nItemWidth = LISTVIEW_GetItemWidth(hwnd, lpss->styleNew);
      infoPtr->nItemHeight = LISTVIEW_GetItemHeight(hwnd, lpss->styleNew);
      if (lpss->styleNew & LVS_ALIGNLEFT)
      {
        LISTVIEW_AlignLeft(hwnd);
      }
      else
      {
        LISTVIEW_AlignTop(hwnd);
      }
      break;
    }

    LISTVIEW_SetScroll(hwnd, lpss->styleNew);
    
    /* print unsupported styles */
    LISTVIEW_UnsupportedStyles(lpss->styleNew);

    /* invalidate client area */
    InvalidateRect(hwnd, NULL, TRUE);
  }

  return 0;
}

/***
 * DESCRIPTION:
 * Window procedure of the listview control.
 * 
 * PARAMETER(S):
 * [I] HWND :
 * [I] UINT :
 * [I] WPARAM :
 * [I] LPARAM : 
 *
 * RETURN:
 * 
 */
LRESULT WINAPI LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
                                   LPARAM lParam)
{
  switch (uMsg)
  {
  case LVM_APPROXIMATEVIEWRECT: 
    return LISTVIEW_ApproximateViewRect(hwnd, (INT)wParam, 
                                        LOWORD(lParam), HIWORD(lParam));
  case LVM_ARRANGE: 
    return LISTVIEW_Arrange(hwnd, (INT)wParam);

/* case LVM_CREATEDRAGIMAGE: */

  case LVM_DELETEALLITEMS:
    return LISTVIEW_DeleteAllItems(hwnd);

  case LVM_DELETECOLUMN:
    return LISTVIEW_DeleteColumn(hwnd, (INT)wParam);

  case LVM_DELETEITEM:
    return LISTVIEW_DeleteItem(hwnd, (INT)wParam);

/*	case LVM_EDITLABEL: */

  case LVM_ENSUREVISIBLE:
    return LISTVIEW_EnsureVisible(hwnd, (INT)wParam, (BOOL)lParam);

  case LVM_FINDITEMA:
    return LISTVIEW_FindItem(hwnd, (INT)wParam, (LPLVFINDINFO)lParam);

  case LVM_GETBKCOLOR:
    return LISTVIEW_GetBkColor(hwnd);

/*	case LVM_GETBKIMAGE: */

  case LVM_GETCALLBACKMASK:
    return LISTVIEW_GetCallbackMask(hwnd);

  case LVM_GETCOLUMNA:
    return LISTVIEW_GetColumnA(hwnd, (INT)wParam, (LPLVCOLUMNA)lParam);

/*	case LVM_GETCOLUMNW: */
/*	case LVM_GETCOLUMNORDERARRAY: */

  case LVM_GETCOLUMNWIDTH:
    return LISTVIEW_GetColumnWidth(hwnd, (INT)wParam);

  case LVM_GETCOUNTPERPAGE:
    return LISTVIEW_GetCountPerPage(hwnd);

/*	case LVM_GETEDITCONTROL: */
/*	case LVM_GETEXTENDEDLISTVIEWSTYLE: */

  case LVM_GETHEADER:
    return LISTVIEW_GetHeader(hwnd);

/*	case LVM_GETHOTCURSOR: */
/*	case LVM_GETHOTITEM: */
/*	case LVM_GETHOVERTIME: */

  case LVM_GETIMAGELIST:
    return LISTVIEW_GetImageList(hwnd, (INT)wParam);

/*	case LVM_GETISEARCHSTRING: */

  case LVM_GETITEMA:
    return LISTVIEW_GetItemA(hwnd, (LPLVITEMA)lParam);

/*	case LVM_GETITEMW: */

  case LVM_GETITEMCOUNT:
    return LISTVIEW_GetItemCount(hwnd);

  case LVM_GETITEMPOSITION:
    return LISTVIEW_GetItemPosition(hwnd, (INT)wParam, (LPPOINT)lParam);

  case LVM_GETITEMRECT: 
    return LISTVIEW_GetItemRect(hwnd, (INT)wParam, (LPRECT)lParam);

  case LVM_GETITEMSPACING: 
    return LISTVIEW_GetItemSpacing(hwnd, (BOOL)wParam);

  case LVM_GETITEMSTATE: 
    return LISTVIEW_GetItemState(hwnd, (INT)wParam, (UINT)lParam);
    
  case LVM_GETITEMTEXTA:
    LISTVIEW_GetItemTextA(hwnd, (INT)wParam, (LPLVITEMA)lParam);
    break;

/*	case LVM_GETITEMTEXTW: */

  case LVM_GETNEXTITEM:
    return LISTVIEW_GetNextItem(hwnd, (INT)wParam, LOWORD(lParam));

/*	case LVM_GETNUMBEROFWORKAREAS: */

  case LVM_GETORIGIN:
    return LISTVIEW_GetOrigin(hwnd, (LPPOINT)lParam);

  case LVM_GETSELECTEDCOUNT:
    return LISTVIEW_GetSelectedCount(hwnd);

  case LVM_GETSELECTIONMARK: 
    return LISTVIEW_GetSelectionMark(hwnd);

  case LVM_GETSTRINGWIDTHA:
    return LISTVIEW_GetStringWidthA (hwnd, (LPCSTR)lParam);

/*	case LVM_GETSTRINGWIDTHW: */
/*	case LVM_GETSUBITEMRECT: */

  case LVM_GETTEXTBKCOLOR:
    return LISTVIEW_GetTextBkColor(hwnd);

  case LVM_GETTEXTCOLOR:
    return LISTVIEW_GetTextColor(hwnd);

/*	case LVM_GETTOOLTIPS: */

  case LVM_GETTOPINDEX:
    return LISTVIEW_GetTopIndex(hwnd);

/*	case LVM_GETUNICODEFORMAT: */

  case LVM_GETVIEWRECT:
    return LISTVIEW_GetViewRect(hwnd, (LPRECT)lParam);

/*	case LVM_GETWORKAREAS: */

  case LVM_HITTEST:
    return LISTVIEW_HitTest(hwnd, (LPLVHITTESTINFO)lParam);

  case LVM_INSERTCOLUMNA:
    return LISTVIEW_InsertColumnA(hwnd, (INT)wParam, 
                                    (LPLVCOLUMNA)lParam);

/*	case LVM_INSERTCOLUMNW: */

  case LVM_INSERTITEMA:
    return LISTVIEW_InsertItemA(hwnd, (LPLVITEMA)lParam);

/*	case LVM_INSERTITEMW: */

  case LVM_REDRAWITEMS:
    return LISTVIEW_RedrawItems(hwnd, (INT)wParam, (INT)lParam);

/*   case LVM_SCROLL:  */
/*     return LISTVIEW_Scroll(hwnd, (INT)wParam, (INT)lParam); */

  case LVM_SETBKCOLOR:
    return LISTVIEW_SetBkColor(hwnd, (COLORREF)lParam);

/*	case LVM_SETBKIMAGE: */

  case LVM_SETCALLBACKMASK:
    return LISTVIEW_SetCallbackMask(hwnd, (UINT)wParam);

  case LVM_SETCOLUMNA:
    return LISTVIEW_SetColumnA(hwnd, (INT)wParam, (LPLVCOLUMNA)lParam);

/*	case LVM_SETCOLUMNW: */
/*	case LVM_SETCOLUMNORDERARRAY: */

  case LVM_SETCOLUMNWIDTH:
    return LISTVIEW_SetColumnWidth(hwnd, (INT)wParam, (INT)lParam);

/*	case LVM_SETEXTENDEDLISTVIEWSTYLE: */
/*	case LVM_SETHOTCURSOR: */
/*	case LVM_SETHOTITEM: */
/*	case LVM_SETHOVERTIME: */
/*	case LVM_SETICONSPACING: */
	
  case LVM_SETIMAGELIST:
    return LISTVIEW_SetImageList(hwnd, (INT)wParam, (HIMAGELIST)lParam);

  case LVM_SETITEMA:
    return LISTVIEW_SetItemA(hwnd, (LPLVITEMA)lParam);

/*	case LVM_SETITEMW: */

  case LVM_SETITEMCOUNT: 
    LISTVIEW_SetItemCount(hwnd, (INT)wParam);
    break;
    
  case LVM_SETITEMPOSITION:
    return LISTVIEW_SetItemPosition(hwnd, (INT)wParam, (INT)LOWORD(lParam),
                                    (INT)HIWORD(lParam));

/*	case LVM_SETITEMPOSITION: */

  case LVM_SETITEMSTATE: 
    return LISTVIEW_SetItemState(hwnd, (INT)wParam, (LPLVITEMA)lParam);

  case LVM_SETITEMTEXTA:
    return LISTVIEW_SetItemTextA(hwnd, (INT)wParam, (LPLVITEMA)lParam);

/*	case LVM_SETSELECTIONMARK: */

  case LVM_SETTEXTBKCOLOR:
    return LISTVIEW_SetTextBkColor(hwnd, (COLORREF)lParam);

  case LVM_SETTEXTCOLOR:
    return LISTVIEW_SetTextColor(hwnd, (COLORREF)lParam);

/*	case LVM_SETTOOLTIPS: */
/*	case LVM_SETUNICODEFORMAT: */
/*	case LVM_SETWORKAREAS: */

  case LVM_SORTITEMS:
    return LISTVIEW_SortItems(hwnd, wParam, lParam);

/*	case LVM_SUBITEMHITTEST: */

  case LVM_UPDATE: 
    return LISTVIEW_Update(hwnd, (INT)wParam);

/*	case WM_CHAR: */
/*	case WM_COMMAND: */

  case WM_CREATE:
    return LISTVIEW_Create(hwnd, wParam, lParam);
    
  case WM_ERASEBKGND:
    return LISTVIEW_EraseBackground(hwnd, wParam, lParam);

  case WM_GETDLGCODE:
    return DLGC_WANTTAB | DLGC_WANTARROWS;

  case WM_GETFONT:
    return LISTVIEW_GetFont(hwnd);

  case WM_HSCROLL:
    return LISTVIEW_HScroll(hwnd, (INT)LOWORD(wParam), 
                            (INT)HIWORD(wParam), (HWND)lParam);

  case WM_KEYDOWN:
    return LISTVIEW_KeyDown(hwnd, (INT)wParam, (LONG)lParam);

  case WM_KILLFOCUS:
    return LISTVIEW_KillFocus(hwnd);

  case WM_LBUTTONDBLCLK:
    return LISTVIEW_LButtonDblClk(hwnd, (WORD)wParam, LOWORD(lParam), 
                                HIWORD(lParam));
    
  case WM_LBUTTONDOWN:
    return LISTVIEW_LButtonDown(hwnd, (WORD)wParam, LOWORD(lParam), 
                                HIWORD(lParam));
  case WM_LBUTTONUP:
    return LISTVIEW_LButtonUp(hwnd, (WORD)wParam, LOWORD(lParam), 
                              HIWORD(lParam));
    
/*	case WM_MOUSEMOVE: */
/*	    return LISTVIEW_MouseMove (hwnd, wParam, lParam); */

  case WM_NCCREATE:
    return LISTVIEW_NCCreate(hwnd, wParam, lParam);

  case WM_NCDESTROY:
    return LISTVIEW_NCDestroy(hwnd);

  case WM_NOTIFY:
    return LISTVIEW_Notify(hwnd, (INT)wParam, (LPNMHDR)lParam);

  case WM_NOTIFYFORMAT:
    return LISTVIEW_NotifyFormat(hwnd, (HWND)wParam, (INT)lParam);

  case WM_PAINT: 
    return LISTVIEW_Paint(hwnd, (HDC)wParam); 

  case WM_RBUTTONDBLCLK:
    return LISTVIEW_RButtonDblClk(hwnd, (WORD)wParam, LOWORD(lParam), 
                                  HIWORD(lParam));

  case WM_RBUTTONDOWN:
    return LISTVIEW_RButtonDown(hwnd, (WORD)wParam, LOWORD(lParam), 
                                HIWORD(lParam));

  case WM_RBUTTONUP:
    return LISTVIEW_RButtonUp(hwnd, (WORD)wParam, LOWORD(lParam), 
                              HIWORD(lParam));

  case WM_SETFOCUS:
    return LISTVIEW_SetFocus(hwnd, (HWND)wParam);

  case WM_SETFONT:
    return LISTVIEW_SetFont(hwnd, (HFONT)wParam, (WORD)lParam);

/*	case WM_SETREDRAW: */

  case WM_SIZE:
    return LISTVIEW_Size(hwnd, (int)SLOWORD(lParam), (int)SHIWORD(lParam));

  case WM_STYLECHANGED:
    return LISTVIEW_StyleChanged(hwnd, wParam, (LPSTYLESTRUCT)lParam);

/*	case WM_TIMER: */

  case WM_VSCROLL:
    return LISTVIEW_VScroll(hwnd, (INT)LOWORD(wParam), 
                            (INT)HIWORD(wParam), (HWND)lParam);

/*	case WM_WINDOWPOSCHANGED: */
/*	case WM_WININICHANGE: */

  default:
    if (uMsg >= WM_USER)
    {
      ERR(listview, "unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, 
          lParam);
    }

    /* call default window procedure */
    return DefWindowProcA(hwnd, uMsg, wParam, lParam);
  }

  return 0;
}

/***
 * DESCRIPTION:
 * Registers the window class.
 * 
 * PARAMETER(S):
 * None
 *
 * RETURN:
 * None
 */
VOID LISTVIEW_Register(VOID)
{
  WNDCLASSA wndClass;

  if (!GlobalFindAtomA(WC_LISTVIEWA)) 
  {
    ZeroMemory(&wndClass, sizeof(WNDCLASSA));
    wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
    wndClass.lpfnWndProc = (WNDPROC)LISTVIEW_WindowProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = sizeof(LISTVIEW_INFO *);
    wndClass.hCursor = LoadCursorA(0, IDC_ARROWA);
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndClass.lpszClassName = WC_LISTVIEWA;
    RegisterClassA(&wndClass);
  }
}

/***
 * DESCRIPTION:
 * Unregisters the window class.
 * 
 * PARAMETER(S):
 * None
 *
 * RETURN:
 * None
 */
VOID LISTVIEW_Unregister(VOID)
{
  if (GlobalFindAtomA(WC_LISTVIEWA))
  {
    UnregisterClassA(WC_LISTVIEWA, (HINSTANCE)NULL);
  }
}

