diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index 6e2319946befd415d5b95d8a01d015a4014db3df..d10ab5666168ac86f50522bf2dcbabe77d8a1e79 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -2,781 +2,2586 @@
  * Listview control
  *
  * Copyright 1998 Eric Kohl
+ * Copyright 1999 Luc Tourangeau
  *
  * NOTES
- *   This is just a dummy control. An author is needed! Any volunteers?
- *   I will only improve this control once in a while.
- *     Eric <ekohl@abo.rhein-zeitung.de>
+ * Listview control implementation. The behavior conforms to version 4.70 
+ * and earlier of the listview contol.
  *
  * TODO:
- *   - Most messages.
- *   - Most notifications.
+ *   Most messages and notifications
+ *   Report, small icon and icon display modes 
  */
 
-#include "windows.h"
+#include <string.h>
 #include "commctrl.h"
 #include "listview.h"
 #include "win.h"
 #include "debug.h"
+#include "winuser.h"
+
+/* prototypes */
+static INT32 LISTVIEW_GetItemCountPerColumn(HWND32 hwnd);
+static INT32 LISTVIEW_GetItemCountPerRow(HWND32 hwnd);
+static INT32 LISTVIEW_GetFirstVisibleItem(HWND32 hwnd);
+static VOID LISTVIEW_SetVisible(HWND32 hwnd, INT32 nItem);
+
+
+/***
+ * DESCRIPTION:
+ * Scrolls the specified item into the visible area.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : item index
+ *
+ * RETURN:
+ * None
+ */
+static VOID LISTVIEW_SetVisible(HWND32 hwnd, INT32 nItem)
+{
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  INT32 nItemCountPerRow;
+  INT32 nItemCountPerColumn;
+  INT32 nLastItem;
+  INT32 nFirstItem;
+  INT32 nHScrollPos;
+  INT32 nVScrollPos;
+
+  /* retrieve the index of the first visible fully item */
+  nFirstItem = LISTVIEW_GetFirstVisibleItem(hwnd);
+
+  /* nunber of fully visible items per row */
+  nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd);
+
+  /* nunber of fully visible items per column */
+  nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd);
+
+  if ((nItemCountPerRow > 0) && (nItemCountPerColumn > 0))
+  {
+    if (lStyle & LVS_LIST)
+    {
+      if (lStyle & WS_HSCROLL)
+      {
+        /* last visible item index */
+        nLastItem = nItemCountPerColumn * nItemCountPerRow + nFirstItem - 1;
+        if (nItem > nLastItem)
+        {
+          /* calculate new scroll position based on item index */
+          if (((nItem - nLastItem) % nItemCountPerColumn) == 0)
+            nHScrollPos = (nItem - nLastItem) / nItemCountPerColumn;
+          else
+            nHScrollPos = (nItem - nLastItem) / nItemCountPerColumn + 1;
+          SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)nHScrollPos, (LPARAM)0);
+        }
+        else if (nItem < nFirstItem)
+        {
+          /* calculate new scroll position based on item index */
+          if (((nItem - nFirstItem) % nItemCountPerColumn) == 0)
+            nHScrollPos = (nItem - nFirstItem) / nItemCountPerColumn;
+          else
+            nHScrollPos = (nItem - nFirstItem) / nItemCountPerColumn - 1;
+          SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)nHScrollPos, (LPARAM)0);
+        }
+      }
+    }
+    else if (lStyle & LVS_REPORT)
+    {
+      if (lStyle & WS_VSCROLL)
+      {
+        if (nFirstItem > 0)
+        {
+          nLastItem = nItemCountPerColumn + nFirstItem;
+        }
+        else
+{
+          nLastItem = nItemCountPerColumn + nFirstItem - 1;
+        }
+
+        if (nItem > nLastItem)
+        {
+          /* calculate new scroll position based on item index */
+          nVScrollPos = nItem - nLastItem;
+          SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)0, (LPARAM)nVScrollPos);
+        }
+        else if (nItem < nFirstItem)
+        {
+          /* calculate new scroll position based on item index */
+          nVScrollPos = nItem - nFirstItem;
+          SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)0, (LPARAM)nVScrollPos);
+        }
+      }
+    }
+    else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON))
+    {
+      if (lStyle & WS_VSCROLL)
+      {
+        /* last visible item index */
+        nLastItem = nItemCountPerColumn * nItemCountPerRow + nFirstItem - 1;
+        if (nItem > nLastItem)
+        {
+          /* calculate new scroll position based on item index */
+          nVScrollPos = (nItem - nLastItem) / nItemCountPerRow + 1;
+          SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)0, (LPARAM)nVScrollPos);
+        }
+        else if (nItem < nFirstItem)
+        {
+          /* calculate new scroll position based on item index */
+          nHScrollPos = (nItem - nFirstItem) / nItemCountPerRow - 1;
+          SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)0, (LPARAM)nHScrollPos);
+        }
+      }
+    }
 
+    /* refresh display */
+    InvalidateRect32(hwnd, NULL, FALSE);
+    UpdateWindow32(hwnd);
 
-#define LISTVIEW_GetInfoPtr(wndPtr) ((LISTVIEW_INFO *)wndPtr->wExtra[0])
+}
+}
 
+/***
+ * DESCRIPTION:
+ * Retrieves the index of the item at coordinate (0, 0) of the client area.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ * item index
+ */
+static INT32 LISTVIEW_GetFirstVisibleItem(HWND32 hwnd)
+{
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  INT32 nItemCountPerRow;
+  INT32 nItemCountPerColumn;
+  INT32 nMinRange;
+  INT32 nMaxRange;
+  INT32 nHScrollPos;
+/*  INT32 nVScrollPos; */
+  INT32 nItem = 0;
+
+  /* get number of items per column */
+  nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd);
+
+  /* get number of fully visble items per row */ 
+  nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd);
+
+  if ((nItemCountPerRow > 0) && (nItemCountPerColumn > 0))
+  {
+    if (lStyle & LVS_LIST)
+    {
+      if (lStyle & WS_HSCROLL)
+      {
+        GetScrollRange32(hwnd, SB_HORZ, &nMinRange, &nMaxRange);
+        nHScrollPos = GetScrollPos32(hwnd, SB_HORZ);
+        if (nMinRange < nHScrollPos)
+        {
+          nItem = ((nHScrollPos - nMinRange) * nItemCountPerColumn * 
+                   nItemCountPerRow);
+        }
+      }
+    }
+    else if (lStyle & LVS_REPORT)
+    {
+      /* TO DO */
+    }
+    else if (lStyle & LVS_SMALLICON)
+    {
+      /* TO DO */
+    }
+    else if (lStyle & LVS_ICON)
+    {
+      /* TO DO */
+    }
+  }
+
+  return nItem;
+}
 
-static VOID
-LISTVIEW_Refresh (WND *wndPtr, HDC32 hdc)
+/***
+ * DESCRIPTION:
+ * Retrieves the number of items per row. In other words, the number 
+ * visible display columns.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ * Number of items per row.
+ */
+static INT32 LISTVIEW_GetItemCountPerRow(HWND32 hwnd)
 {
-/*    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  INT32 nItemCountPerRow = 0;
 
+  if (infoPtr->nWidth > 0)
+  {
+    if (lStyle & LVS_LIST)
+    {
+      if (infoPtr->nColumnWidth > 0)
+      {
+        nItemCountPerRow = infoPtr->nWidth / infoPtr->nColumnWidth;
+        if (nItemCountPerRow == 0)
+          nItemCountPerRow = 1;
+      }
+    }
+    else if (lStyle & LVS_REPORT)
+    {
+      /* TO DO */
+    }
+    else if (lStyle & LVS_SMALLICON)
+    {
+      /* TO DO */
+    }
+    else if (lStyle & LVS_ICON)
+    {
+      /* TO DO */
+    }
+  }
 
+  return nItemCountPerRow; 
+}
 
+/***
+ * DESCRIPTION:
+ * Retrieves the number of items that can be displayed vertically in   
+ * the listview.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ * Number of items per column.
+ */
+static INT32 LISTVIEW_GetItemCountPerColumn(HWND32 hwnd)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  INT32 nItemCountPerColumn = 0;
+  
+  if (infoPtr->nHeight > 0)
+  {
+    if (lStyle & LVS_LIST)
+    {
+      if (infoPtr->nItemHeight > 0)
+        nItemCountPerColumn = infoPtr->nHeight / infoPtr->nItemHeight;
+    }
+    else if (lStyle & LVS_REPORT)
+    {
+      /* TO DO */
+    }
+    else if (lStyle & LVS_SMALLICON)
+    {
+      /* TO DO */
+    }
+    else if (lStyle & LVS_ICON)
+    {
+      /* TO DO */
+    }
+  }
+
+  return nItemCountPerColumn;
 }
 
+/***
+ * DESCRIPTION:
+ * Retrieves the number of columns needed to display  
+ * all the items in listview.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ * Number of columns.
+ */
+static INT32 LISTVIEW_GetColumnCount(HWND32 hwnd)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle  = GetWindowLong32A(hwnd, GWL_STYLE);
+  INT32 nColumnCount = 0;
+  INT32 nItemCountPerColumn;
+
+  nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd);
+
+ if ((infoPtr->nItemCount > 0) && (nItemCountPerColumn > 0))
+ {
+   if (lStyle & LVS_LIST)
+   {
+     if ((infoPtr->nItemCount % nItemCountPerColumn) == 0)
+     {
+       nColumnCount = infoPtr->nItemCount / nItemCountPerColumn ;
+     }
+     else
+     {
+       nColumnCount = infoPtr->nItemCount / nItemCountPerColumn + 1;
+     }
+   }
+   else if (lStyle & LVS_REPORT)
+   {
+     /* TO DO */
+   }
+   else if (lStyle & LVS_SMALLICON)
+   {
+     /* TO DO */
+   }
+   else if (lStyle & LVS_ICON)
+   {
+     /* TO DO */
+   }
+ }
+
+  return nColumnCount;
+}
 
+/***
+ * DESCRIPTION:
+ * Sets the scrolling parameters.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ * None
+ */
+static VOID LISTVIEW_SetScroll(HWND32 hwnd)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  INT32 nColumnCount;
+  INT32 nItemCountPerRow;
+  INT32 nItemCountPerColumn;
+  INT32 nMinRange, nMaxRange;
+  INT32 nHScrollPos;
+/*   INT32 nVScrollPos; */
+
+  nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd);
+  nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd);
+
+  if ((nItemCountPerColumn > 0) && (nItemCountPerRow > 0))
+  {
+    if (lStyle & LVS_LIST)
+    {
+      /* get number of columns needed to display all the listview items */
+      nColumnCount = LISTVIEW_GetColumnCount(hwnd);      
+      if (nColumnCount > 0) 
+      {
+        if (nColumnCount > nItemCountPerRow)
+        {
+          /* add scrollbar if not already present */
+          if (!(lStyle & WS_HSCROLL))
+          {
+            /* display scrollbar */
+            ShowScrollBar32(hwnd, SB_HORZ, TRUE);
+        
+            /* set scrollbar range and position */
+            nMaxRange = nColumnCount - nItemCountPerRow;
+            SetScrollRange32(hwnd, SB_HORZ, 0, nMaxRange, FALSE);
+            SetScrollPos32(hwnd, SB_HORZ, 0, TRUE);
+          }
+          else
+          {
+            nHScrollPos = GetScrollPos32(hwnd, SB_HORZ);
+            GetScrollRange32(hwnd, SB_HORZ, &nMinRange, &nMaxRange);
+            if (nMaxRange != nColumnCount - nItemCountPerRow)
+            {
+              nMaxRange = nColumnCount - nItemCountPerRow;
+              SetScrollRange32(hwnd, SB_HORZ, nMinRange, nMaxRange, FALSE);
+
+              if (nHScrollPos > nMaxRange)
+                nHScrollPos = nMaxRange;
+        
+              SetScrollPos32(hwnd, SB_HORZ, nHScrollPos, TRUE);
+            }
+          }
+          
+          /* refresh the client area */
+          InvalidateRect32(hwnd,NULL, TRUE);
+          UpdateWindow32(hwnd);
+        }
+        else
+        {
+          /* remove scrollbar if present */
+          if (lStyle & WS_HSCROLL)
+          {
+            /* hide scrollbar */
+            ShowScrollBar32(hwnd, SB_HORZ, FALSE);
+
+            /* refresh the client area */
+            InvalidateRect32(hwnd,NULL, TRUE);
+            UpdateWindow32(hwnd);
+          }
+        }
+      }
+    }
+    else if (lStyle & LVS_REPORT) 
+    {
+      HDLAYOUT hl;
+      WINDOWPOS32 wp;
+      RECT32 rc;
+        
+      rc.top = 0;
+      rc.left = 0;
+      rc.right = infoPtr->nWidth;
+      rc.bottom = infoPtr->nHeight;
+
+      hl.prc = &rc;
+      hl.pwpos = &wp;
+      SendMessage32A(infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl);
+      
+      SetWindowPos32(infoPtr->hwndHeader, hwnd,
+                     wp.x, wp.y, wp.cx, wp.cy, wp.flags);
+      
+/*       infoPtr->rcList.top += wp.cy; */
+    }
+    else if (lStyle & LVS_SMALLICON) 
+    {
+      /* TO DO */
+    }
+    else if (lStyle & LVS_ICON) 
+    {
+      /* TO DO */
+    }
+  }
+}
 
-/* << LISTVIEW_ApproximateViewRect >> */
-/* << LISTVIEW_Arrange >> */
-/* << LISTVIEW_CreateDragImage >> */
+/***
+ * DESCRIPTION:
+ * Modifies the state (selected and focused) of the listview items.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : focused item index
+ * [I] BOOL32 : flag for determining weither the control keys are used or not
+ * [I] BOOL32 : flag for determining the input type (mouse or keyboard)
+ *
+ * RETURN:
+ * None
+ */
+static VOID LISTVIEW_SetItemStates(HWND32 hwnd, INT32 nFocusedItem, 
+                                   BOOL32 bVirtualKeys, BOOL32 bMouseInput)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  WORD wShift = HIWORD(GetKeyState32(VK_SHIFT));
+  WORD wCtrl = HIWORD(GetKeyState32(VK_CONTROL));
+  INT32 i;
+  LVITEM32A lvItem;
+
+  /* initialize memory */
+  ZeroMemory(&lvItem, sizeof(LVITEM32A));
+    
+  if (wShift && (bVirtualKeys == TRUE))
+  {
+    /* reset the selected and focused states of all the items */
+    lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
+    lvItem.state = 0;
+    SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem);
+
+    if (infoPtr->nSelectionMark > nFocusedItem)
+    {
+      for (i = infoPtr->nSelectionMark; i > nFocusedItem; i--)
+      {
+        /* select items */
+        lvItem.stateMask = LVIS_SELECTED;
+        lvItem.state = LVIS_SELECTED;
+        SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)i, (LPARAM)&lvItem);
+      }
+    }
+    else
+    {
+      for (i = infoPtr->nSelectionMark; i < nFocusedItem; i++)
+      {
+        /* select items */
+        lvItem.stateMask = LVIS_SELECTED;
+        lvItem.state = LVIS_SELECTED;
+        SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)i, (LPARAM)&lvItem);
+      }
+    }
 
+    /* select anf focus item */
+    lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
+    lvItem.state = LVIS_SELECTED | LVIS_FOCUSED;
+    SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)i, (LPARAM)&lvItem);
+  }
+  else
+  {
+    if (wCtrl && (bVirtualKeys == TRUE))
+    {
+      /* make sure the focus is lost */
+      lvItem.stateMask = LVIS_FOCUSED;
+      lvItem.state = 0;
+      SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem);
+
+      if (bMouseInput == TRUE)
+      {
+        if (SendMessage32A(hwnd, LVM_GETITEMSTATE, (WPARAM32)nFocusedItem, 
+                           (LPARAM)LVIS_SELECTED) & LVIS_SELECTED)
+        {
+          /* focus and unselect (toggle selection) */
+          lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
+          lvItem.state = LVIS_FOCUSED;
+          SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)nFocusedItem, 
+                         (LPARAM)&lvItem);
+        }
+        else
+        {
+          /* select and focus */
+          lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
+          lvItem.state = LVIS_SELECTED | LVIS_FOCUSED;
+          SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)nFocusedItem, 
+                         (LPARAM)&lvItem);
+        }
+        
+        /* set the group selection start position */
+        infoPtr->nSelectionMark = nFocusedItem;
+      }
+      else
+      {
+        /* focus */
+        lvItem.stateMask = LVIS_FOCUSED;
+        lvItem.state = LVIS_FOCUSED;
+        SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)nFocusedItem, 
+                       (LPARAM)&lvItem);
+      }
+    }
+    else
+    {
+      /* clear selection and focus for all the items */
+      lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
+      lvItem.state = 0;
+      SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem);
+
+      /* set select and focus for this particular item */
+      lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
+      lvItem.state = LVIS_FOCUSED | LVIS_SELECTED;
+      SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)nFocusedItem, 
+                     (LPARAM)&lvItem);
+
+      /* set the new group selection start position */
+      infoPtr->nSelectionMark = nFocusedItem;
+    }
+  }
+}
 
-static LRESULT
-LISTVIEW_DeleteAllItems (WND *wndPtr)
+/***
+ * DESCRIPTION:
+ * Draws listview items when in list display maode.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] HDC32 : device context handle 
+ *
+ * RETURN:
+ * None
+ */
+static VOID LISTVIEW_RefreshList(HWND32 hwnd, HDC32 hdc)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    INT32 nItem;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
     LISTVIEW_ITEM *lpItem;
-    NMLISTVIEW nmlv;
-    BOOL32 bNotify;
+  HFONT32 hOldFont;
+  HPEN32 hPen, hOldPen;
+  INT32 nItemCountPerColumn;
+  INT32 nItemCountPerRow;
+  INT32 nSmallIconWidth;
+  SIZE32 labelSize;
+  INT32 nDrawPosX = 0;
+  INT32 nDrawPosY = 0;
+  BOOL32 bSelected;
+  RECT32 rcBoundingBox;
+  COLORREF clrHighlight;
+  COLORREF clrHighlightText;
+  INT32 i;
+  INT32 nColumn = 0;
+  INT32 nRow;
+  INT32 j;
+
+  /* get number of items per column */
+  nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd);
+
+  /* get number of items per row */
+  nItemCountPerRow = LISTVIEW_GetItemCountPerColumn(hwnd);
+  
+  if ((nItemCountPerColumn > 0) && (nItemCountPerRow > 0))
+  {
+     /* select font */
+    hOldFont = SelectObject32(hdc, infoPtr->hFont);
+
+    /* inititialize system dependent information */
+    clrHighlight = GetSysColor32(COLOR_HIGHLIGHT);
+    clrHighlightText = GetSysColor32(COLOR_HIGHLIGHTTEXT);
+    nSmallIconWidth = GetSystemMetrics32(SM_CXSMICON);  
+
+    /* select transparent brush (for drawing the focus box) */
+    SelectObject32(hdc, GetStockObject32(NULL_BRUSH)); 
+
+    /* select the doted pen (for drawing the focus box) */
+    hPen = CreatePen32(PS_DOT, 1, 0);
+    hOldPen = SelectObject32(hdc, hPen);
+
+    /* get starting index */
+    i = LISTVIEW_GetFirstVisibleItem(hwnd);
+    
+    /* DRAW ITEMS */
+    for (j = 0; i < infoPtr->nItemCount; i++, j++)
+    {
+      /* set draw position for current item */
+      nRow = j % nItemCountPerColumn;
+      nColumn = j / nItemCountPerColumn;
+      if (nRow == 0)
+        nDrawPosY = 0;
+      else
+        nDrawPosY += infoPtr->nItemHeight;
+
+      nDrawPosX = nColumn * infoPtr->nColumnWidth;
+    
+      /* get item */
+      lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, i);
+      if (lpItem != NULL)
+      {
+        if (lpItem->state & LVIS_SELECTED)
+        {
+          bSelected = TRUE;
+        
+          /* set item colors */ 
+          SetBkColor32(hdc, clrHighlight);
+          SetTextColor32(hdc, clrHighlightText);
+
+          /* set raster mode */
+          SetROP232(hdc, R2_XORPEN);
+        }
+        else
+        {
+          bSelected = FALSE;
+          
+          /* set item colors */
+          SetBkColor32(hdc, infoPtr->clrTextBk);
+          SetTextColor32(hdc, infoPtr->clrText);
+          
+          /* set raster mode */
+          SetROP232(hdc, R2_COPYPEN);
+        }
+
+        /* state images */
+        if (infoPtr->himlState != NULL)
+        {
+          /* right shift 12 bits to obtain index in image list */
+          if (bSelected == TRUE)
+            ImageList_Draw(infoPtr->himlState, lpItem->state >> 12, hdc, 
+                           nDrawPosX, nDrawPosY, ILD_SELECTED);
+          else
+            ImageList_Draw(infoPtr->himlState, lpItem->state >> 12, hdc, 
+                           nDrawPosX, nDrawPosY, ILD_NORMAL);
+        
+          nDrawPosX += nSmallIconWidth; 
+        }
+
+        /* small icons */
+        if (infoPtr->himlSmall != NULL)
+        {
+          if (bSelected == TRUE)
+            ImageList_Draw(infoPtr->himlSmall, lpItem->iImage, hdc, nDrawPosX, 
+                           nDrawPosY, ILD_SELECTED);
+          else
+            ImageList_Draw(infoPtr->himlSmall, lpItem->iImage, hdc, nDrawPosX, 
+                           nDrawPosY, ILD_NORMAL);
+        
+          nDrawPosX += nSmallIconWidth; 
+        }
+
+        /* get string size (in pixels) */
+        GetTextExtentPoint32A(hdc, lpItem->pszText, 
+                              lstrlen32A(lpItem->pszText), &labelSize);
+
+        /* define a bounding box */
+        rcBoundingBox.left = nDrawPosX;
+        rcBoundingBox.top = nDrawPosY;
+
+        /* 2 pixels for padding purposes */
+        rcBoundingBox.right = nDrawPosX + labelSize.cx + 2;
+
+        /* padding already included in infoPtr->nItemHeight */
+        rcBoundingBox.bottom = nDrawPosY + infoPtr->nItemHeight;
+      
+        /* draw text */  
+        ExtTextOut32A(hdc, nDrawPosX + 1, nDrawPosY+ 1, 
+                      ETO_OPAQUE|ETO_CLIPPED, &rcBoundingBox, 
+                      lpItem->pszText, lstrlen32A(lpItem->pszText), NULL);
+      
+        if (lpItem->state & LVIS_FOCUSED)
+          Rectangle32(hdc, rcBoundingBox.left, rcBoundingBox.top, 
+                      rcBoundingBox.right, rcBoundingBox.bottom); 
+      }
+    }
+
+    /* unselect objects */
+    SelectObject32(hdc, hOldFont);
+    SelectObject32(hdc, hOldPen);
+
+    /* delete pen */
+    DeleteObject32(hPen);
+  }
+}
 
-    if (infoPtr->nItemCount == 0)
-	return TRUE;
+/***
+ * DESCRIPTION:
+ * Draws listview items when in report display mode.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] HDC32 : device context handle 
+ *
+ * RETURN:
+ * None
+ */
+static VOID LISTVIEW_RefreshReport(HWND32 hwnd, HDC32 hdc)
+{
+  /* TO DO */
+}
 
-    TRACE (listview, "\n");
+/***
+ * DESCRIPTION:
+ * Draws listview items when in small icon display mode.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] HDC32 : device context handle 
+ *
+ * RETURN:
+ * None
+ */
+static VOID LISTVIEW_RefreshSmallIcon(HWND32 hwnd, HDC32 hdc)
+{
+  /* TO DO */
+}
 
+/***
+ * DESCRIPTION:
+ * Draws listview items when in icon display mode.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] HDC32 : device context handle 
+ *
+ * RETURN:
+ * None
+ */
+static VOID LISTVIEW_RefreshIcon(HWND32 hwnd, HDC32 hdc)
+{
+  /* TO DO */
+}
+
+/***
+ * DESCRIPTION:
+ * Draws listview items.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] HDC32 : device context handle 
+ *
+ * RETURN:
+ * None
+ */
+static VOID LISTVIEW_Refresh(HWND32 hwnd, HDC32 hdc)
+{
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  
+  if (lStyle & LVS_LIST)
+  {
+    LISTVIEW_RefreshList(hwnd, hdc);
+  }
+  else if (lStyle & LVS_REPORT)
+  {
+    LISTVIEW_RefreshReport(hwnd, hdc);
+  }
+  else if (lStyle & LVS_SMALLICON)
+  {
+    LISTVIEW_RefreshSmallIcon(hwnd, hdc);
+  }
+  else if (lStyle & LVS_ICON)
+  {
+    LISTVIEW_RefreshIcon(hwnd, hdc);
+  }
+}
+
+
+/***
+ * DESCRIPTION:
+ * Calculates the approximate width and height of a given number of items.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : number of items
+ * [I] INT32 : width
+ * [I] INT32 : height
+ *
+ * RETURN:
+ * Returns a DWORD. The width in the low word and the height in high word.
+ */
+static LRESULT LISTVIEW_ApproximateViewRect(HWND32 hwnd, INT32 nItemCount, 
+                                            WORD wWidth, WORD wHeight)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  INT32 nItemCountPerColumn = 1;
+  INT32 nColumnCount = 0;
+  DWORD dwViewRect = 0;
+
+  if (nItemCount == -1)
+    nItemCount = infoPtr->nItemCount;
+
+  if (lStyle & LVS_LIST)
+  {
+    if (wHeight == 0xFFFF)
+    {
+      /* use current height */
+      wHeight = infoPtr->nHeight;
+    }
+
+    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;
+      }
+    }
+
+    wHeight = nItemCountPerColumn * infoPtr->nItemHeight + 2;
+    wWidth = nColumnCount * infoPtr->nColumnWidth + 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] HWND32 : window handle
+ * [I] INT32 : alignment code
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_Arrange(HWND32 hwnd, INT32 nAlignCode)
+{
+  /* LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); */
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  BOOL32 bResult = FALSE;
+
+  if (lStyle & LVS_ICON)
+  {
+    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 */
+    }
+  }
+
+  return bResult;
+}
+
+/* << LISTVIEW_CreateDragImage >> */
+
+/***
+ * DESCRIPTION:
+ * Removes all listview items.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_DeleteAllItems(HWND32 hwnd)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
+  LISTVIEW_ITEM *lpItem;
+  NMLISTVIEW nmlv;
+  BOOL32 bNotify;
+  INT32 i;
+  BOOL32 bResult = TRUE;
+
+  if (infoPtr->nItemCount > 0)
+  {
     /* send LVN_DELETEALLITEMS notification */
     ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
-    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
-    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+    nmlv.hdr.hwndFrom = hwnd;
+    nmlv.hdr.idFrom = lCtrlId;
     nmlv.hdr.code     = LVN_DELETEALLITEMS;
     nmlv.iItem        = -1;
-    bNotify =
-	!(BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-				 (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+    bNotify = !(BOOL32)SendMessage32A(GetParent32(hwnd), WM_NOTIFY, 
+                                      (WPARAM32)lCtrlId, (LPARAM)&nmlv);
 
     nmlv.hdr.code     = LVN_DELETEITEM;
 
-    for (nItem = 0; nItem < infoPtr->nItemCount; nItem++) {
-	/* send notification */
-	if (bNotify) {
-	    nmlv.iItem = nItem;
-	    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-			    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+    for (i = 0; i < infoPtr->nItemCount; i++) 
+    {
+      if (bNotify == TRUE)
+      {
+        /* send LVN_DELETEITEM notification */
+        nmlv.iItem = i;
+        SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                       (LPARAM)&nmlv);
 	}
 
-	/* get item pointer */
-	lpItem = (LISTVIEW_ITEM*)DPA_GetPtr (infoPtr->hdpaItems, nItem);
-	if (lpItem) {
-	    /* delete item strings */
-	    if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
+      /* get item */
+      lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, i);
+      if (lpItem != NULL) 
+      {
+        /* free item string */
+        if ((lpItem->pszText != NULL) && 
+            (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
 		COMCTL32_Free (lpItem->pszText);
 
-	    /* free item data */
+        /* free item */
 	    COMCTL32_Free (lpItem);
 	}
     }
 
+    /* ???? needs follow up */ 
     DPA_DeleteAllPtrs (infoPtr->hdpaItems);
+ 
+    /* reset item counter */
     infoPtr->nItemCount = 0;
 
-    return TRUE;
+    /* reset scrollbar */
+    LISTVIEW_SetScroll(hwnd);
 }
 
+  return bResult;
+}
 
-static LRESULT
-LISTVIEW_DeleteColumn (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Removes a column from the listview control.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : column index
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_DeleteColumn(HWND32 hwnd, INT32 nColumn)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    /* INT32 nColumn = (INT32)wParam; */
+/*   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); */
 
     /* FIXME ??? */
-    if (infoPtr->nItemCount > 0)
-	return FALSE;
-
-    if (!SendMessage32A (infoPtr->hwndHeader, HDM_DELETEITEM, wParam, 0))
-	return FALSE;
-
-    infoPtr->nColumnCount--;
-
-    FIXME (listview, "semi stub!\n");
+/* if (infoPtr->nItemCount > 0) */
+/* return FALSE; */
+/* if (!SendMessage32A(infoPtr->hwndHeader, HDM_DELETEITEM, wParam, 0)) */
+/* return FALSE; */
+/* infoPtr->nColumnCount--; */
+/* FIXME (listview, "semi stub!\n"); */
 
     return TRUE;
 }
 
-
-static LRESULT
-LISTVIEW_DeleteItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Removes an item from the listview control.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : item index  
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_DeleteItem(HWND32 hwnd, INT32 nItem)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    INT32 nItem = (INT32)wParam;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
     LISTVIEW_ITEM *lpItem;
     NMLISTVIEW nmlv;
+  BOOL32 bResult = FALSE;
 
-    if ((nItem < 0) || (nItem >= infoPtr->nItemCount))
-	return FALSE;
-
-    TRACE (listview, "(%d)\n", nItem);
-
-    /* send notification */
+  if ((nItem >= 0) && (nItem < infoPtr->nItemCount))
+  {
+    /* send LVN_DELETEITEM notification */
     ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
-    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
-    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+    nmlv.hdr.hwndFrom = hwnd;
+    nmlv.hdr.idFrom = lCtrlId;
     nmlv.hdr.code     = LVN_DELETEITEM;
     nmlv.iItem        = nItem;
-    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+    SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                   (LPARAM)&nmlv);
 
-    /* remove from item array */
+    /* remove item */
     lpItem = (LISTVIEW_ITEM*)DPA_DeletePtr (infoPtr->hdpaItems, nItem);
-
-    /* delete item strings */
-    if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
+    if (lpItem != NULL)
+    {
+      /* free item string */
+      if ((lpItem->pszText != NULL) && 
+          (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
 	COMCTL32_Free (lpItem->pszText);
 
-    /* free item data */
+      /* free item */
     COMCTL32_Free (lpItem);
+    }
 
+    /* decrement item counter */
     infoPtr->nItemCount--;
 
-    return TRUE;
+    /* reset some of the draw data */
+    LISTVIEW_SetScroll(hwnd);
+   
+    bResult = TRUE;
 }
 
+  return bResult;
+}
 
 /* << LISTVIEW_EditLabel >> */
 /* << LISTVIEW_EnsureVisible >> */
-/* << LISTVIEW_FindItem >> */
 
+/***
+ * DESCRIPTION:
+ * Searches for an item with specific characteristics.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : base item index
+ * [I] LPLVFINDINFO : item information to look for
+ * 
+ * RETURN:
+ *   SUCCESS : index of item
+ *   FAILURE : -1
+ */
+static LRESULT LISTVIEW_FindItem(HWND32 hwnd, INT32 nStart, 
+                                 LPLVFINDINFO lpFindInfo)
+{
+/*   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); */
+/*   LISTVIEW_ITEM *lpItem; */
+/*   INT32 nItem; */
+/*   INT32 nEnd = infoPtr->nItemCount; */
+/*   BOOL32 bWrap = FALSE; */
+/*   if (nStart == -1) */
+/*     nStart = 0; */
+/*   else */
+/*     nStart++ ; */
+/*   if (lpFindInfo->flags & LVFI_PARAM) */
+/*   { */
+/*     for (nItem = nStart; nItem < nEnd; nItem++) */
+/*     { */
+       /* get item pointer */ 
+/*       lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); */
+/*       if (lpItem != NULL)  */
+/*       { */
+/*         if (lpFindInfo->lParam == lpItem->lParam) */
+/*           return nItem; */
+/*       } */
+/*     } */
+/*   } */
+/*   else */
+/*   { */
+/*     if (lpFindInfo->flags & LVFI_PARTIAL) */
+/*     { */
+/*       for (nItem = nStart; nItem < nEnd; nItem++) */
+/*       { */
+         /* get item pointer */
+/*         lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); */
+/*         if (lpItem)  */
+/*         { */
+/*           if (strncmp(lpItem->pszText, lpFindInfo->psz, strlen(lpFindInfo->psz))  */
+/*               == 0) */
+/*             return nItem; */
+/*         } */
+/*       } */
+/*     } */
+
+/*     if (lpFindInfo->flags & LVFI_STRING) */
+/*     { */
+/*       for (nItem = nStart; nItem < nEnd; nItem++) */
+/*       { */
+         /* get item pointer */
+/*         lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); */
+/*         if (lpItem != NULL)  */
+/*         { */
+/*           if (strcmp(lpItem->pszText, lpFindInfo->psz) == 0) */
+/*             return nItem; */
+/*         } */
+/*       } */
+/*     } */
+    
+/*     if ((lpFindInfo->flags & LVFI_WRAP) && nStart)  */
+/*     { */
+/*       nEnd = nStart; */
+/*       nStart = 0; */
+/*       bWrap = TRUE; */
+/*     } */
+/*     else */
+/*       bWrap = FALSE; */
+
+   return -1; 
+}
 
-static LRESULT
-LISTVIEW_GetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves the background color of the listview control.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ * COLORREF associated with the background.
+ */
+static LRESULT LISTVIEW_GetBkColor(HWND32 hwnd)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
 
     return infoPtr->clrBk;
 }
 
+/***
+ * DESCRIPTION:
+ * Retrieves the background image of the listview control.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [O] LPLVMKBIMAGE : background image information
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+/* static LRESULT LISTVIEW_GetBkImage(HWND32 hwnd, LPLVBKIMAGE lpBkImage) */
+/* { */
+/*   return FALSE; */
+/* } */
 
-/* << LISTVIEW_GetBkImage >> */
 /* << LISTVIEW_GetCallbackMask >> */
 
-
-static LRESULT
-LISTVIEW_GetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves column attributes.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 :  column index
+ * [IO] LPLVCOLUMN32A : column information
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_GetColumn32A(HWND32 hwnd, INT32 nIndex, 
+                                     LPLVCOLUMN32A lpColumn)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
-    INT32 nIndex = (INT32)wParam;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
     HDITEM32A hdi;
 
-    if (!lpcol)
+  if (lpColumn == NULL)
 	return FALSE;
 
-    TRACE (listview, "(%d %p)\n", nIndex, lpcol);
-
     ZeroMemory (&hdi, sizeof(HDITEM32A));
 
-    if (lpcol->mask & LVCF_FMT)
+  if (lpColumn->mask & LVCF_FMT)
 	hdi.mask |= HDI_FORMAT;
 
-    if (lpcol->mask & LVCF_WIDTH)
+  if (lpColumn->mask & LVCF_WIDTH)
         hdi.mask |= HDI_WIDTH;
 
-    if (lpcol->mask & LVCF_TEXT)
+  if (lpColumn->mask & LVCF_TEXT)
         hdi.mask |= (HDI_TEXT | HDI_FORMAT);
 
-    if (lpcol->mask & LVCF_IMAGE)
+  if (lpColumn->mask & LVCF_IMAGE)
         hdi.mask |= HDI_IMAGE;
 
-    if (lpcol->mask & LVCF_ORDER)
+  if (lpColumn->mask & LVCF_ORDER)
         hdi.mask |= HDI_ORDER;
 
     if (!SendMessage32A (infoPtr->hwndHeader, HDM_GETITEM32A,
-		    wParam, (LPARAM)&hdi))
+                       (WPARAM32)nIndex, (LPARAM)&hdi))
 	return FALSE;
 
-    if (lpcol->mask & LVCF_FMT) {
-	lpcol->fmt = 0;
+  if (lpColumn->mask & LVCF_FMT) 
+  {
+    lpColumn->fmt = 0;
 
 	if (hdi.fmt & HDF_LEFT)
-	    lpcol->fmt |= LVCFMT_LEFT;
+      lpColumn->fmt |= LVCFMT_LEFT;
 	else if (hdi.fmt & HDF_RIGHT)
-	    lpcol->fmt |= LVCFMT_RIGHT;
+      lpColumn->fmt |= LVCFMT_RIGHT;
 	else if (hdi.fmt & HDF_CENTER)
-	    lpcol->fmt |= LVCFMT_CENTER;
+      lpColumn->fmt |= LVCFMT_CENTER;
 
 	if (hdi.fmt & HDF_IMAGE)
-	    lpcol->fmt |= LVCFMT_COL_HAS_IMAGES;
+      lpColumn->fmt |= LVCFMT_COL_HAS_IMAGES;
     }
 
-    if (lpcol->mask & LVCF_WIDTH)
-	lpcol->cx = hdi.cxy;
+  if (lpColumn->mask & LVCF_WIDTH)
+    lpColumn->cx = hdi.cxy;
 
-    if ((lpcol->mask & LVCF_TEXT) && (lpcol->pszText) && (hdi.pszText))
-	lstrcpyn32A (lpcol->pszText, hdi.pszText, lpcol->cchTextMax);
+  if ((lpColumn->mask & LVCF_TEXT) && (lpColumn->pszText) && (hdi.pszText))
+    lstrcpyn32A (lpColumn->pszText, hdi.pszText, lpColumn->cchTextMax);
 
-    if (lpcol->mask & LVCF_IMAGE)
-	lpcol->iImage = hdi.iImage;
+  if (lpColumn->mask & LVCF_IMAGE)
+    lpColumn->iImage = hdi.iImage;
 
-    if (lpcol->mask & LVCF_ORDER)
-	lpcol->iOrder = hdi.iOrder;
+  if (lpColumn->mask & LVCF_ORDER)
+    lpColumn->iOrder = hdi.iOrder;
 
     return TRUE;
 }
 
-
 /* << LISTVIEW_GetColumn32W >> */
 /* << LISTVIEW_GetColumnOrderArray >> */
 
-
-__inline__ static LRESULT
-LISTVIEW_GetColumnWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves the column width when list or report display mode.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] int32 : column index
+ *
+ * RETURN:
+ *   SUCCESS : column width
+ *   FAILURE : zero 
+ */
+static LRESULT LISTVIEW_GetColumnWidth(HWND32 hwnd, INT32 nColumn)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
     HDITEM32A hdi;
-
+  INT32 nColumnWidth = 0;
+
+  if ((lStyle & LVS_LIST) || (lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON))
+  {
+    nColumnWidth = infoPtr->nColumnWidth;
+  }
+  else if (lStyle & LVS_REPORT)
+  {
+    /* verify validity of index */
+    if ((nColumn >= 0) && (nColumn < infoPtr->nColumnCount))
+    {
+      /* get column width from header */
     hdi.mask = HDI_WIDTH;
     if (SendMessage32A (infoPtr->hwndHeader, HDM_GETITEM32A,
-			wParam, (LPARAM)&hdi))
-	return hdi.cxy;
+                         (WPARAM32)nColumn, (LPARAM)&hdi))
+        nColumnWidth = hdi.cxy;
+    }
+  }
 
-    return 0;
+  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] HWND32 : window handle
+ *
+ * RETURN:
+ * Number of fully visible items.
+ */
+static LRESULT LISTVIEW_GetCountPerPage(HWND32 hwnd)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  INT32 nItemCount = 0;
+  INT32 nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd);
+  INT32 nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd);
+
+  if (lStyle & LVS_LIST)
+  {
+    if ((nItemCountPerRow > 0) && (nItemCountPerColumn > 0))
+    {
+      nItemCount = nItemCountPerRow * nItemCountPerColumn;
+    }
+  }
+  else if (lStyle & LVS_REPORT)
+  {
+    nItemCount = nItemCountPerColumn;
+  }
+  else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON))
+  {
+    nItemCount = infoPtr->nItemCount;
+  }
+
+  return nItemCount;
+}
 
-/* << LISTVIEW_GetCountPerPage >> */
 /* << LISTVIEW_GetEditControl >> */
-/* << LISTVIEW_GetExtendedListviewStyle >> */
-
-
-__inline__ static LRESULT
-LISTVIEW_GetHeader (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/* << LISTVIEW_GetExtendedListViewStyle >> */
+
+/***
+ * DESCRIPTION:
+ * Retrieves a header handle.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ * Header handle.
+ */
+static LRESULT LISTVIEW_GetHeader(HWND32 hwnd)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
 
     return infoPtr->hwndHeader;
 }
 
-
 /* << LISTVIEW_GetHotCursor >> */
 /* << LISTVIEW_GetHotItem >> */
 /* << LISTVIEW_GetHoverTime >> */
 
-
-static LRESULT
-LISTVIEW_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves an image list handle.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : image list identifier 
+ * 
+ * RETURN:
+ *   SUCCESS : image list handle
+ *   FAILURE : NULL
+ */
+static LRESULT LISTVIEW_GetImageList(HWND32 hwnd, INT32 nImageList)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-
-    TRACE (listview, "(0x%08x)\n", wParam);
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  HIMAGELIST himl = NULL;
 
-    switch (wParam) {
+  switch (nImageList) 
+  {
 	case LVSIL_NORMAL:
-	    return (LRESULT)infoPtr->himlNormal;
-
+    himl = infoPtr->himlNormal;
 	case LVSIL_SMALL:
-	    return (LRESULT)infoPtr->himlSmall;
-
+    himl = infoPtr->himlSmall;
 	case LVSIL_STATE:
-	    return (LRESULT)infoPtr->himlState;
+    himl = infoPtr->himlState;
     }
 
-    return (LRESULT)NULL;
+  return (LRESULT)himl;
 }
 
 
 /* << LISTVIEW_GetISearchString >> */
 
-
-static LRESULT
-LISTVIEW_GetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves item attributes.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [IO] LPLVITEM32A : item info
+ * 
+ * RETURN:
+ *   SUCCESS : TRUE 
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_GetItem32A(HWND32 hwnd, LPLVITEM32A lpItem)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
-    LISTVIEW_ITEM *lpRow, *lpSubItem;
-
-    if (!lpItem)
-	return FALSE;
-
-    if ((lpItem->iItem < 0) || (lpItem->iItem >= infoPtr->nItemCount))
-	return FALSE;
-
-    if ((lpItem->iSubItem < 0) || (lpItem->iSubItem >= infoPtr->nColumnCount))
-	return FALSE;
-
-    FIXME (listview, "(%d %d %p)\n",
-	   lpItem->iItem, lpItem->iSubItem, lpItem);
-
-    lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem);
-    if (!lpRow)
-	return FALSE;
-
-    lpSubItem = &lpRow[lpItem->iSubItem];
-    if (!lpSubItem)
-	return FALSE;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LISTVIEW_ITEM *lpListItem;
+  BOOL32 bResult = FALSE;
 
+  if (lpItem != NULL)
+  {
+    if ((lpItem->iItem >= 0) && (lpItem->iItem < infoPtr->nItemCount))
+    {
+      /* get item */
+      lpListItem = DPA_GetPtr(infoPtr->hdpaItems, lpItem->iItem);
+      if (lpListItem != NULL)
+      {
+        /* not tested for subitem > 0 */
+        lpListItem += lpItem->iSubItem;
+        if (lpListItem != NULL) 
+        {
+          /* retrieve valid data */
     if (lpItem->mask & LVIF_STATE)
-	lpItem->state = lpSubItem->state & lpItem->stateMask;
+            lpItem->state = lpListItem->state & lpItem->stateMask;
 
-    if (lpItem->mask & LVIF_TEXT) {
-	if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A)
+          if (lpItem->mask & LVIF_TEXT) 
+          {
+            if (lpListItem->pszText == LPSTR_TEXTCALLBACK32A)
 	    lpItem->pszText = LPSTR_TEXTCALLBACK32A;
 	else
-	    Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText,
+              Str_GetPtr32A(lpListItem->pszText, lpItem->pszText, 
 			   lpItem->cchTextMax);
     }
 
     if (lpItem->mask & LVIF_IMAGE)
-	 lpItem->iImage = lpSubItem->iImage;
+            lpItem->iImage = lpListItem->iImage;
 
     if (lpItem->mask & LVIF_PARAM)
-	lpItem->lParam = lpSubItem->lParam;
+            lpItem->lParam = lpListItem->lParam;
 
     if (lpItem->mask & LVIF_INDENT)
-	lpItem->iIndent = lpSubItem->iIndent;
+            lpItem->iIndent = lpListItem->iIndent;
 
-    return TRUE;
+          bResult = TRUE;
 }
+      }
+    }
+  }
 
+  return bResult;
+}
 
 /* << LISTVIEW_GetItem32W >> */
+/* << LISTVIEW_GetHotCursor >> */
+/* << LISTVIEW_GetHotItem >> */
+/* << LISTVIEW_GetHoverTime >> */
 
-
-__inline__ static LRESULT
-LISTVIEW_GetItemCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves the number of items in the listview control.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * 
+ * RETURN:
+ * Number of items.
+ */
+static LRESULT LISTVIEW_GetItemCount(HWND32 hwnd)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0);
+
     return infoPtr->nItemCount;
 }
 
-
-static LRESULT
-LISTVIEW_GetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves the position (upper-left) of the listview control item.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : item index
+ * [O] LPPOINT32 : coordinate information
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_GetItemPosition(HWND32 hwnd, INT32 nItem, 
+                                        LPPOINT32 lpPt)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LPPOINT32 lpPt = (LPPOINT32)lParam;
-    INT32 nIndex = (INT32)wParam;
-
-    if (!lpPt)
-	return FALSE;
-    if ((nIndex < 0) || (nIndex >= infoPtr->nItemCount))
-	return FALSE;
-
-    FIXME (listview, "returning position [0,0]!\n");
-    lpPt->x = 0;
-    lpPt->y = 0;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  INT32 nColumn;
+  INT32 nRow;
+  BOOL32 bResult = FALSE;
+  INT32 nItemCountPerColumn;
+  INT32 nItemCountPerRow;
+  INT32 nFirstItem;
+  INT32 nLastItem;
+
+  if ((nItem >= 0) && (nItem < infoPtr->nItemCount) && (lpPt != NULL))
+  {
+    if (lStyle & LVS_LIST)
+{
+      nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd);
+      nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd);
+
+      if ((nItemCountPerColumn > 0) && (nItemCountPerRow > 0))
+      {
+        nFirstItem = LISTVIEW_GetFirstVisibleItem(hwnd); 
+        nLastItem = nFirstItem + nItemCountPerRow * nItemCountPerRow - 1;
+
+        if ((nItem >= nFirstItem) || (nItem <= nLastItem))
+        {
+          nItem -= nFirstItem; 
+
+          /* get column */
+          nColumn = nItem / nItemCountPerColumn;
+
+          /* get row */
+          nRow = nItem % nItemCountPerColumn;
+
+          /* X coordinate of the column */
+          lpPt->x = nColumn * infoPtr->nColumnWidth;
+
+          /* Y coordinate of the item */
+          lpPt->y = nRow * infoPtr->nItemHeight;
+
+          bResult = TRUE;
+        }
+      }
+      else if (lStyle & LVS_REPORT)
+      {
+        /* TO DO */
+      }
+      else if (lStyle & LVS_SMALLICON)
+      {
+        /* TO DO */
+      }
+      else if (lStyle & LVS_ICON)
+{
+        /* TO DO */
+      }
+    }
+  }
 
-    return TRUE;
+  return bResult;
 }
 
+/***
+ * DESCRIPTION:
+ * Retrieves the bounding rectangle for a listview control item.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : item index
+ * [IO] LPRECT32 : bounding rectangle coordinates
+ * 
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_GetItemRect(HWND32 hwnd, INT32 nItem, LPRECT32 lpRect)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LISTVIEW_ITEM *lpItem;
+  POINT32 pt;
+  INT32 nLabelWidth;
+  BOOL32 bResult = FALSE;
+  INT32 nSmallIconWidth;
+
+  nSmallIconWidth = GetSystemMetrics32(SM_CXSMICON);
+
+  if ((nItem < 0) || (nItem >= infoPtr->nItemCount) || (lpRect == NULL))
+    return FALSE;
+
+  /* get item */
+  lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem);
+  if (lpItem == NULL) 
+    return FALSE;
+
+  if (!SendMessage32A(hwnd, LVM_GETITEMPOSITION, (WPARAM32)nItem, (LPARAM)&pt))
+    return FALSE;
+
+  nLabelWidth = SendMessage32A(hwnd, LVM_GETSTRINGWIDTH32A, (WPARAM32)0, 
+                               (LPARAM)lpItem->pszText);
+  switch(lpRect->left) 
+  { 
+  case LVIR_BOUNDS: 
+    lpRect->left = pt.x;
+    lpRect->top = pt.y;
+    lpRect->right = lpRect->left + nSmallIconWidth + nLabelWidth;
+    lpRect->bottom = lpRect->top + infoPtr->nItemHeight;
+    bResult = TRUE;
+    break;
+  case LVIR_ICON:
+    lpRect->left = pt.x;
+    lpRect->top = pt.y;
+    lpRect->right = lpRect->left + nSmallIconWidth;
+    lpRect->bottom = lpRect->top + infoPtr->nItemHeight;
+    bResult = TRUE;
+    break;
+  case LVIR_LABEL: 
+    lpRect->left = pt.x + nSmallIconWidth;
+    lpRect->top = pt.y;
+    lpRect->right = lpRect->left + nLabelWidth;
+    lpRect->bottom = infoPtr->nItemHeight;
+    bResult = TRUE;
+    break;
+  case LVIR_SELECTBOUNDS:
+    /* TO DO */
+    break;
+  }
+        
+  return bResult;
+}
 
-/* << LISTVIEW_GetItemRect >> */
-/* << LISTVIEW_GetItemSpacing >> */
-/* << LISTVIEW_GetItemState >> */
+/***
+ * DESCRIPTION:
+ * Retrieves the spacing between listview control items.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] BOOL32 : small icon (TRUE) or large icon (FALSE)
+ *
+ * RETURN:
+ * Horizontal + vertical spacing
+ */
+static LRESULT LISTVIEW_GetItemSpacing(HWND32 hwnd, BOOL32 bSmall)
+{
+  INT32 nSmallIconHSpacing;
+  INT32 nSmallIconVSpacing;
+  INT32 nIconHSpacing;
+  INT32 nIconVSpacing;
+  LONG lResult = 0;
+
+  if (bSmall == TRUE)
+  {
+    /* ??? */
+    nSmallIconHSpacing = 0;
+    nSmallIconVSpacing = 0;
+    lResult = MAKELONG(nSmallIconHSpacing, nSmallIconVSpacing);
+    }
+    else
+  {
+    nIconHSpacing = GetSystemMetrics32(SM_CXICONSPACING);
+    nIconVSpacing = GetSystemMetrics32(SM_CYICONSPACING);
+    lResult = MAKELONG(nIconHSpacing, nIconVSpacing);
+  }
+  
+  return lResult;
+}
 
+/***
+ * DESCRIPTION:
+ * Retrieves the state of a listview control item.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : item index
+ * [I] UINT32 : state mask
+ * 
+ * RETURN:
+ * State specified by the mask.
+ */
+static LRESULT LISTVIEW_GetItemState(HWND32 hwnd, INT32 nItem, UINT32 uMask)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LISTVIEW_ITEM *lpItem;
+  INT32 nState = 0;
+
+  if ((nItem >= 0) && (nItem < infoPtr->nItemCount))
+  {
+    lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem);
+    if (lpItem != NULL) 
+      nState =   lpItem->state & uMask;
+  }
+
+  return nState;
+}
 
-static LRESULT
-LISTVIEW_GetItemText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves the text of a listview control item or subitem. 
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : item index
+ * [IO] LPLVITEM32A : item information
+ * 
+ * RETURN:
+ * None
+ */
+static VOID LISTVIEW_GetItemText32A(HWND32 hwnd, INT32 nItem, 
+                                    LPLVITEM32A lpItem)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
-    INT32 nItem = (INT32)wParam;
-    LISTVIEW_ITEM *lpRow, *lpSubItem;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LISTVIEW_ITEM *lpListItem;
 
-    TRACE (listview, "(%d %p)\n", nItem, lpItem);
+  if ((nItem < 0) || (nItem >= infoPtr->nItemCount) || (lpItem == NULL))
+    return;
 
-    lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem);
-    if (!lpRow)
-	return 0;
+  lpListItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem);
+  if (lpListItem == NULL)
+    return;
 
-    lpSubItem = &lpRow[lpItem->iSubItem];
-    if (!lpSubItem)
-	return 0;
+  lpListItem += lpItem->iSubItem;
+  if (lpListItem == NULL)
+    return;
 
-    if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A) {
-	lpItem->pszText = LPSTR_TEXTCALLBACK32A;
-	return 0;
-    }
+  if (lpListItem->pszText == LPSTR_TEXTCALLBACK32A) 
+    lpItem->pszText = LPSTR_TEXTCALLBACK32A;
     else
-	return Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText,
-			      lpItem->cchTextMax);
+    Str_GetPtr32A(lpListItem->pszText, lpItem->pszText, lpItem->cchTextMax);
 }
 
-
-/* << LISTVIEW_GetItemText32A >> */
-
-
-static LRESULT
-LISTVIEW_GetNextItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Searches for an item based on properties + relationships.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : item index
+ * [I] UINT32 : relationship flag
+ * 
+ * RETURN:
+ *   SUCCESS : item index
+ *   FAILURE : -1
+ */
+static LRESULT LISTVIEW_GetNextItem (HWND32 hwnd, INT32 nItem, UINT32 uFlags)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    INT32 nStart = (INT32)wParam;
-    UINT32 uFlags = (UINT32)LOWORD(lParam);
-
-    FIXME (listview, "(%d, 0x%x): semi stub!\n", nStart, uFlags);
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  INT32 nResult = -1;
 
-    if (infoPtr->nItemCount <= 0)
-	return -1;
+  /* start at begin */
+  if (nItem == -1)
+    nItem = 0;
 
-    /* just a simple (preliminary) hack */
-    if (nStart == -1)
-	return 0;
-    else if (nStart < infoPtr->nItemCount - 1)
-	return nStart + 1;
-    else
-	return -1;
-
-    return -1;
+  if ((nItem >= 0) && (nItem < infoPtr->nItemCount))
+  {
+    /* TO DO */
 }
 
+  return nResult;
+}
 
 /* << LISTVIEW_GetNumberOfWorkAreas >> */
-/* << LISTVIEW_GetOrigin >> */
 
-
-static LRESULT
-LISTVIEW_GetSelectedCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves the current origin when in icon or small icon display mode.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [O] LPPOINT32 : coordinate information
+ * 
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_GetOrigin(HWND32 hwnd, LPPOINT32 lpOrigin)
 {
-    /* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_ID);
+  BOOL32 bResult = FALSE;
+
+  if (lStyle & LVS_SMALLICON) 
+  {
+    /* TO DO */
+  }
+  else if (lStyle & LVS_ICON)
+  {
+    /* TO DO */
+  }
+
+  return bResult;
+}
 
-    TRACE (listview, ": empty stub (returns 0)!\n");
+/***
+ * DESCRIPTION:
+ * Retrieves the number of items that are marked as selected.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * 
+ * RETURN:
+ * Number of items selected.
+ */
+static LRESULT LISTVIEW_GetSelectedCount(HWND32 hwnd)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LISTVIEW_ITEM *lpItem;
+  INT32 nSelectedCount = 0;
+  INT32 i;
+
+  for (i = 0; i < infoPtr->nItemCount; i++)
+  {
+    lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, i);
+    if (lpItem != NULL)
+    {
+      if (lpItem->state & LVIS_SELECTED)
+        nSelectedCount++;
+    }
+  }
 
-    return 0;
+  return nSelectedCount;
 }
 
+/***
+ * DESCRIPTION:
+ * Retrieves item index that marks the start of a multiple selection.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * 
+ * RETURN:
+ * Index number or -1 if there is no selection mark.
+ */
+static LRESULT LISTVIEW_GetSelectionMark(HWND32 hwnd)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  INT32 nResult = -1;
 
-/* << LISTVIEW_GetSelectionMark >> */
+  if (SendMessage32A(hwnd, LVM_GETSELECTEDCOUNT, (WPARAM32)0, (LPARAM)0) != 0)
+    nResult = infoPtr->nSelectionMark;
 
+  return nResult;
+}
 
-static LRESULT
-LISTVIEW_GetStringWidth32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves the width of a string.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * 
+ * RETURN:
+ *   SUCCESS : string width (in pixels)
+ *   FAILURE : zero
+ */
+static LRESULT LISTVIEW_GetStringWidth32A(HWND32 hwnd, LPCSTR lpsz)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LPSTR lpsz = (LPSTR)lParam;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
     HFONT32 hFont, hOldFont;
     HDC32 hdc;
-    SIZE32 size;
-
-    if (!lpsz)
-	return 0;
-
-    TRACE (listview, "(%s)\n", lpsz);
+  SIZE32 textSize;
+  INT32 nResult = 0;
 
+  if (lpsz != NULL)
+  {
     hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
-    hdc = GetDC32 (0);
+    hdc = GetDC32(hwnd);
     hOldFont = SelectObject32 (hdc, hFont);
-    GetTextExtentPoint32A (hdc, lpsz, lstrlen32A(lpsz), &size);
+    GetTextExtentPoint32A(hdc, lpsz, lstrlen32A(lpsz), &textSize);
     SelectObject32 (hdc, hOldFont);
-    ReleaseDC32 (0, hdc);
-
-    TRACE (listview, "-- ret=%d\n", size.cx);
+    ReleaseDC32(hwnd, hdc);
+    nResult = textSize.cx;
+  }
 
-    return (LRESULT)size.cx;
+  return nResult;
 }
 
+/***
+ * DESCRIPTION:
+ * Retrieves the text backgound color.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * 
+ * RETURN:
+ * COLORREF associated with the the background.
+ */
+static LRESULT LISTVIEW_GetTextBkColor(HWND32 hwnd)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0);
 
+  return infoPtr->clrTextBk;
+}
 
-
-__inline__ static LRESULT
-LISTVIEW_GetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves the text color.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * 
+ * RETURN:
+ * COLORREF associated with the text.
+ */
+static LRESULT LISTVIEW_GetTextColor(HWND32 hwnd)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0);
 
-    return infoPtr->clrTextBk;
+  return infoPtr->clrText;
 }
 
-
-__inline__ static LRESULT
-LISTVIEW_GetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Retrieves the bounding rectangle of all the items.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [O] LPRECT32 : bounding rectangle
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_GetViewRect(HWND32 hwnd, LPRECT32 lpBoundingRect)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+  /* LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); */
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  BOOL32 bResult = FALSE;
 
-    return infoPtr->clrText;
+  if (lpBoundingRect != NULL)
+  {
+    if ((lStyle & LVS_ICON) || (lStyle & LVS_SMALLICON))
+    {
+      /* TO DO */
+    }
+  }
+
+  return bResult;
 }
 
+/***
+ * DESCRIPTION:
+ * Determines item index when in small icon view.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [IO] LPLVHITTESTINFO : hit test information
+ *
+ * RETURN:
+ *   SUCCESS : item index
+ *   FAILURE : -1
+ */
+static LRESULT HitTestSmallIconView(HWND32 hwnd, LPLVHITTESTINFO lpHitTestInfo)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LISTVIEW_ITEM *lpItem;
+  INT32 nColumn;
+  INT32 nRow;
+  INT32 nItem = 0;
+  INT32 nLabelWidth;
+  INT32 nOffset;
+  INT32 nPosX = 0;
+  INT32 nSmallIconWidth;
+  INT32 nItemCountPerRow;
+
+  /* get column */
+  nColumn = lpHitTestInfo->pt.x / infoPtr->nColumnWidth;
+
+  /* get row */
+  nRow = lpHitTestInfo->pt.y / infoPtr->nItemHeight;
+  
+  /* calculate offset from start of column (in pixels) */
+  nOffset = lpHitTestInfo->pt.x % infoPtr->nColumnWidth;
+
+  /* get recommended width of a small icon */
+  nSmallIconWidth = GetSystemMetrics32(SM_CXSMICON);
+
+  /* calculate index */
+  nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd);
+  nItem = nRow * nItemCountPerRow + LISTVIEW_GetFirstVisibleItem(hwnd) + nColumn;
+
+  /* verify existance of item */
+  if (nItem < infoPtr->nItemCount)
+  {
+    /* get item */
+    lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem);
+    if (lpItem != NULL)
+    {
+      if (infoPtr->himlState != NULL)
+      {
+        nPosX += nSmallIconWidth;
+        if (nOffset <= nPosX)
+        {
+          lpHitTestInfo->flags = LVHT_ONITEMSTATEICON | LVHT_ONITEM;
+          lpHitTestInfo->iItem = nItem;
+          lpHitTestInfo->iSubItem = 0;
+          return nItem;
+        }
+      }
+
+      if (infoPtr->himlSmall != NULL)
+      {
+        nPosX += nSmallIconWidth;
+        if (nOffset <= nPosX)
+        {
+          lpHitTestInfo->flags = LVHT_ONITEMICON | LVHT_ONITEM;
+          lpHitTestInfo->iItem = nItem;
+          lpHitTestInfo->iSubItem = 0;
+          return nItem;
+}
+      }
 
-static LRESULT
-LISTVIEW_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+      /* get width of label in pixels */
+      nLabelWidth = SendMessage32A(hwnd, LVM_GETSTRINGWIDTH32A, (WPARAM32)0, 
+                                   (LPARAM)lpItem->pszText); 
+      nLabelWidth += nPosX;
+
+      if (nOffset <= nLabelWidth)
 {
-/*    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */
-    LPLVHITTESTINFO lpht = (LPLVHITTESTINFO)lParam;
+        lpHitTestInfo->flags = LVHT_ONITEMLABEL | LVHT_ONITEM;
+        lpHitTestInfo->iItem = nItem;
+        lpHitTestInfo->iSubItem = 0;
+          return nItem;
+      }
+    }
+  }
 
-    FIXME (listview, "(%p): stub!\n", lpht);
+  /* hit is not on an item */
+  lpHitTestInfo->flags = LVHT_NOWHERE; 
+     
+  return -1;
+}
 
-    /* FIXME: preliminary */
-    lpht->flags = LVHT_NOWHERE;
-    lpht->iItem = -1;
-    lpht->iSubItem = 0;
+/***
+ * DESCRIPTION:
+ * Determines item index when in list display mode.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [IO] LPLVHITTESTINFO : hit test information
+ *
+ * RETURN:
+ *   SUCCESS : item index
+ *   FAILURE : -1
+ */
+static LRESULT HitTestListView(HWND32 hwnd, LPLVHITTESTINFO lpHitTestInfo)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LISTVIEW_ITEM *lpItem;
+  INT32 nColumn;
+  INT32 nRow;
+  INT32 nItem = 0;
+  INT32 nLabelWidth;
+  INT32 nOffset;
+  INT32 nPosX = 0;
+  INT32 nSmallIconWidth;
+  INT32 nItemCountPerColumn;
+
+  /* get column */
+  nColumn = lpHitTestInfo->pt.x / infoPtr->nColumnWidth;
+
+  /* get row */ 
+  nRow = lpHitTestInfo->pt.y / infoPtr->nItemHeight;
+  
+  /* calculate offset from start of column (in pixels) */
+  nOffset = lpHitTestInfo->pt.x % infoPtr->nColumnWidth;
+
+  /* get recommended width of a small icon */
+  nSmallIconWidth = GetSystemMetrics32(SM_CXSMICON);
+
+  /* calculate index */
+  nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd);
+  nItem = (nColumn * nItemCountPerColumn + LISTVIEW_GetFirstVisibleItem(hwnd) 
+           + nRow);
+
+  /* verify existance of item */
+  if (nItem < infoPtr->nItemCount)
+  {
+    /* get item */
+    lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem);
+    if (lpItem != NULL)
+    {
+      if (infoPtr->himlState != NULL)
+      {
+        nPosX += nSmallIconWidth;
+        if (nOffset <= nPosX)
+        {
+          lpHitTestInfo->flags = LVHT_ONITEMSTATEICON | LVHT_ONITEM;
+          lpHitTestInfo->iItem = nItem;
+          lpHitTestInfo->iSubItem = 0;
+          return nItem;
+        }
+      }
+
+      if (infoPtr->himlSmall != NULL)
+      {
+        nPosX += nSmallIconWidth;
+        if (nOffset <= nPosX)
+{
+          lpHitTestInfo->flags = LVHT_ONITEMICON | LVHT_ONITEM;
+          lpHitTestInfo->iItem = nItem;
+          lpHitTestInfo->iSubItem = 0;
+          return nItem;
+        }
+      }
+
+      /* get width of label in pixels */
+      nLabelWidth = SendMessage32A(hwnd, LVM_GETSTRINGWIDTH32A, (WPARAM32)0, 
+                                   (LPARAM)lpItem->pszText); 
+      nLabelWidth += nPosX;
+
+      if (nOffset <= nLabelWidth)
+      {
+        lpHitTestInfo->flags = LVHT_ONITEMLABEL | LVHT_ONITEM;
+        lpHitTestInfo->iItem = nItem;
+        lpHitTestInfo->iSubItem = 0;
+          return nItem;
+      }
+    }
+  }
 
+  /* hit is not on an item */
+  lpHitTestInfo->flags = LVHT_NOWHERE; 
+     
     return -1;
 }
 
+/***
+ * DESCRIPTION:
+ * Determines wich listview item is located at the specified position.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [IO} LPLVHITTESTINFO : hit test information
+ *
+ * RETURN:
+ *   SUCCESS : item index
+ *   FAILURE : -1
+ */
+static LRESULT LISTVIEW_HitTest(HWND32 hwnd, LPLVHITTESTINFO lpHitTestInfo)
+{
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+
+  if (lStyle & LVS_LIST)
+    return HitTestListView(hwnd, lpHitTestInfo);
+  else if (lStyle & LVS_REPORT)
+  {
+    /* TO DO */
+  }
+  else if (lStyle & LVS_SMALLICON)
+  {
+    return HitTestSmallIconView(hwnd, lpHitTestInfo);
+  }
+  else if (lStyle & LVS_ICON)
+  {
+    /* TO DO */
+  }
+
+  return -1;
+}
 
-static LRESULT
-LISTVIEW_InsertColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Inserts a new column.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : column index
+ * [I] LPLVCOLUMN32A : column information
+ *
+ * RETURN:
+ *   SUCCESS : new column index
+ *   FAILURE : -1
+ */
+static LRESULT LISTVIEW_InsertColumn32A(HWND32 hwnd, INT32 nIndex, 
+                                        LPLVCOLUMN32A lpColumn)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
-    INT32 nIndex = (INT32)wParam;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0);
     HDITEM32A hdi;
     INT32 nResult;
 
-    if ((!lpcol) || (infoPtr->nItemCount > 0))
+  if ((lpColumn == NULL) || (infoPtr->nItemCount > 0))
 	return -1;
 
-    FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol);
+  FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpColumn);
 
+  /* initialize memory */
     ZeroMemory (&hdi, sizeof(HDITEM32A));
 
-    if (lpcol->mask & LVCF_FMT) {
+  if (lpColumn->mask & LVCF_FMT) 
+  {
 	if (nIndex == 0)
 	    hdi.fmt |= HDF_LEFT;
-	else if (lpcol->fmt & LVCFMT_LEFT)
+    else if (lpColumn->fmt & LVCFMT_LEFT)
 	    hdi.fmt |= HDF_LEFT;
-	else if (lpcol->fmt & LVCFMT_RIGHT)
+    else if (lpColumn->fmt & LVCFMT_RIGHT)
 	    hdi.fmt |= HDF_RIGHT;
-	else if (lpcol->fmt & LVCFMT_CENTER)
+    else if (lpColumn->fmt & LVCFMT_CENTER)
 	    hdi.fmt |= HDF_CENTER;
-
-	if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES)
+    if (lpColumn->fmt & LVCFMT_COL_HAS_IMAGES)
 	    hdi.fmt |= HDF_IMAGE;
 	    
 	hdi.mask |= HDI_FORMAT;
     }
 
-    if (lpcol->mask & LVCF_WIDTH) {
+  if (lpColumn->mask & LVCF_WIDTH) 
+  {
         hdi.mask |= HDI_WIDTH;
-	hdi.cxy = lpcol->cx;
+    hdi.cxy = lpColumn->cx;
     }
     
-    if (lpcol->mask & LVCF_TEXT) {
+  if (lpColumn->mask & LVCF_TEXT) 
+  {
         hdi.mask |= (HDI_TEXT | HDI_FORMAT);
-	hdi.pszText = lpcol->pszText;
+    hdi.pszText = lpColumn->pszText;
 	hdi.fmt |= HDF_STRING;
     }
 
-    if (lpcol->mask & LVCF_IMAGE) {
+  if (lpColumn->mask & LVCF_IMAGE) 
+  {
         hdi.mask |= HDI_IMAGE;
-	hdi.iImage = lpcol->iImage;
+    hdi.iImage = lpColumn->iImage;
     }
 
-    if (lpcol->mask & LVCF_ORDER) {
+  if (lpColumn->mask & LVCF_ORDER) 
+  {
         hdi.mask |= HDI_ORDER;
-	hdi.iOrder = lpcol->iOrder;
+    hdi.iOrder = lpColumn->iOrder;
     }
 
     nResult = SendMessage32A (infoPtr->hwndHeader, HDM_INSERTITEM32A,
-			      wParam, (LPARAM)&hdi);
+                           (WPARAM32)nIndex, (LPARAM)&hdi);
     if (nResult == -1)
 	return -1;
 
+  /* increment column counter */
     infoPtr->nColumnCount++;
 
     return nResult;
 }
 
-
 /* << LISTVIEW_InsertColumn32W >> */
 
-
-static LRESULT
-LISTVIEW_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Inserts a new item in the listview control.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] LPLVITEM32A : item information
+ *
+ * RETURN:
+ *   SUCCESS : new item index
+ *   FAILURE : -1
+ */
+static LRESULT LISTVIEW_InsertItem32A(HWND32 hwnd, LPLVITEM32A lpItem)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
     LISTVIEW_ITEM *lpListItem;
-    INT32 nIndex;
+  INT32 nItem;
     NMLISTVIEW nmlv;
+  LVITEM32A lvItem;
+  INT32 nColumnWidth = 0;
+  INT32 nSmallIconWidth;
 
-    if (!lpItem)
+  if (lpItem == NULL)
 	return -1;
 
-    if ((!infoPtr->nColumnCount) || (lpItem->iSubItem))
+  if (lpItem->iSubItem != 0)
 	return -1;
 
-    FIXME (listview, "(%d %p)\n", lpItem->iItem, lpItem);
-    FIXME (listview, "(%p %p)\n", infoPtr, infoPtr->hdpaItems);
-
-    lpListItem = (LISTVIEW_ITEM*)COMCTL32_Alloc (infoPtr->nColumnCount * sizeof(LISTVIEW_ITEM));
-    nIndex = DPA_InsertPtr (infoPtr->hdpaItems, lpItem->iItem, lpListItem);
-    if (nIndex == -1)
+  /* allocate memory */
+  lpListItem = (LISTVIEW_ITEM *)COMCTL32_Alloc(sizeof(LISTVIEW_ITEM));
+  if (lpListItem == NULL)
 	return -1;
 
-    if (lpItem->mask & LVIF_STATE)
-	lpListItem[0].state = lpItem->state;
+  nSmallIconWidth = GetSystemMetrics32(SM_CXSMICON);
+
+  /* initialize listview control item */
+  ZeroMemory(lpListItem, sizeof(LISTVIEW_ITEM));
 
-    if (lpItem->mask & LVIF_TEXT) {
+  /* copy only valid data */
+  if (lpItem->mask & LVIF_TEXT) 
+  {
 	if (lpItem->pszText == LPSTR_TEXTCALLBACK32A)
-	    lpListItem[0].pszText = LPSTR_TEXTCALLBACK32A;
+    {
+      if ((lStyle & LVS_SORTASCENDING) || (lStyle & LVS_SORTDESCENDING))
+        return -1;
+
+      lpListItem->pszText = LPSTR_TEXTCALLBACK32A;
+    }
 	else
-	    Str_SetPtr32A (&lpListItem[0].pszText, lpItem->pszText);
+    {
+      nColumnWidth = SendMessage32A(hwnd, LVM_GETSTRINGWIDTH32A, 
+                                    (WPARAM32)0, (LPARAM)lpItem->pszText);
+
+      /* add padding for separating columns */
+      nColumnWidth += 10;
+
+      /* calculate column width; make sure it's at least 96 pixels */
+      if (nColumnWidth < 96)
+        nColumnWidth = 96;
+        
+      Str_SetPtr32A(&lpListItem->pszText, lpItem->pszText);
+    }
+  }
+
+  if (lpItem->mask & LVIF_STATE)
+  {
+    if (lpItem->stateMask & LVIS_FOCUSED)
+    {
+      /* clear LVIS_FOCUSED states */
+      ZeroMemory(&lvItem, sizeof(LVITEM32A));
+      lvItem.stateMask = LVIS_FOCUSED;
+      lvItem.state = 0;
+      SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem);
+
+      /* set focused item index */
+      infoPtr->nFocusedItem = lpItem->iItem;
     }
 
+    lpListItem->state = lpItem->state & lpItem->stateMask;
+  }
+
     if (lpItem->mask & LVIF_IMAGE)
-	lpListItem[0].iImage = lpItem->iImage;
+    lpListItem->iImage = lpItem->iImage;
 
     if (lpItem->mask & LVIF_PARAM)
-	lpListItem[0].lParam = lpItem->lParam;
+    lpListItem->lParam = lpItem->lParam;
 
     if (lpItem->mask & LVIF_INDENT)
-	lpListItem[0].iIndent = lpItem->iIndent;
+    lpListItem->iIndent = lpItem->iIndent;
 
+  /* insert item in listview control data structure */
+  nItem = DPA_InsertPtr(infoPtr->hdpaItems, lpItem->iItem, lpListItem);
+  if (nItem == -1)
+    return -1;
+
+  /* increment item counter */
     infoPtr->nItemCount++;
 
-    /* send notification */
+  /* calculate column width */
+  if (infoPtr->himlSmall != NULL)
+    nColumnWidth += nSmallIconWidth;
+
+  /* calculate column width */
+  if (infoPtr->himlState != NULL)
+    nColumnWidth += nSmallIconWidth;
+
+  /* set column width */
+   if (nColumnWidth > infoPtr->nColumnWidth)
+     infoPtr->nColumnWidth = nColumnWidth;
+
+  /* set drawing data */
+  LISTVIEW_SetScroll(hwnd);
+
+  /* send LVN_INSERTITEM notification */
     ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
-    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
-    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+  nmlv.hdr.hwndFrom = hwnd;
+  nmlv.hdr.idFrom = lCtrlId;
     nmlv.hdr.code     = LVN_INSERTITEM;
-    nmlv.iItem        = nIndex;
-    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+  nmlv.iItem = nItem;
+  SendMessage32A(GetParent32 (hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                 (LPARAM)&nmlv);
 
-    return nIndex;
-}
+  InvalidateRect32(hwnd, NULL, FALSE);
+  UpdateWindow32(hwnd);
 
+  return nItem;
+}
 
 /* << LISTVIEW_InsertItem32W >> */
 
-
-static LRESULT
-LISTVIEW_RedrawItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Redraws a range of items.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : first item
+ * [I] INT32 : last item
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_RedrawItems(HWND32 hwnd, INT32 nFirst, INT32 nLast)
 {
-/*    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); 
 
-    FIXME (listview, "(%d - %d): empty stub!\n",
-	   (INT32)wParam, (INT32)lParam);
+  if (nFirst > nLast)
+    return FALSE;
 
-    return TRUE;
-}
+  if ((nFirst < 0) || (nFirst >= infoPtr->nItemCount))
+    return FALSE;
 
+  if ((nLast < 0) || (nLast >= infoPtr->nItemCount))
+    return FALSE;
 
-/*
- << LISTVIEW_Scroll >>
-*/
+  /* TO DO */
 
+  return TRUE;
+}
 
-static LRESULT
-LISTVIEW_SetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Scrolls the content of a listview.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : amount of horizontal scrolling
+ * [I] INT32 : amount of vertical scrolling
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_Scroll(HWND32 hwnd, INT32 nHScroll, INT32 nVScroll)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-
-    if (!infoPtr)
-	return FALSE;
-
-    /* set background color */
-    TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
-    infoPtr->clrBk = (COLORREF)lParam;
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  BOOL32 bResult = FALSE;
+  INT32 nHScrollPos;
+  INT32 nMinRange;
+  INT32 nMaxRange;
+
+  if (lStyle & LVS_LIST)
+  {
+    nHScrollPos = GetScrollPos32(hwnd, SB_HORZ);
+    GetScrollRange32(hwnd, SB_HORZ, &nMinRange, &nMaxRange);
+
+    if ((nMinRange <= nHScrollPos + nHScroll) && 
+        (nHScrollPos + nHScroll <= nMaxRange))
+    {
+      bResult = TRUE;
+      nHScrollPos += nHScroll;
+      SetScrollPos32(hwnd, SB_HORZ, nHScrollPos, TRUE);
 
-    return TRUE;
+      /* refresh client area */
+      InvalidateRect32(hwnd, NULL, TRUE);
+      UpdateWindow32(hwnd);
+    }
+  }  
+  else if (lStyle & LVS_REPORT)
+  {
+    /* TO DO */
+}
+  else if (lStyle & LVS_SMALLICON)
+  {
+    /* TO DO */
+  }
+  else if (lStyle & LVS_ICON)
+  {
+    /* TO DO */
+  }
+
+  return bResult; 
 }
 
-
-/*
- << LISTVIEW_SetBkImage >>
- << LISTVIEW_SetCallbackMask >>
+/***
+ * DESCRIPTION:
+ * Sets the background color.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] COLORREF : background color
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
 */
+static LRESULT LISTVIEW_SetBkColor(HWND32 hwnd, COLORREF clrBk)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
 
+  infoPtr->clrBk = clrBk;
+  InvalidateRect32(hwnd, NULL, TRUE);
 
-static LRESULT
-LISTVIEW_SetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+  return TRUE;
+}
+
+/***
+ * DESCRIPTION:
+ * Sets column attributes.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : column index
+ * [I] LPLVCOLUMN32A : column information
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_SetColumn32A(HWND32 hwnd, INT32 nIndex, 
+                                     LPLVCOLUMN32A lpColumn)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
-    INT32 nIndex = (INT32)wParam;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
     HDITEM32A hdi;
 
-    if (!lpcol)
+  if (lpColumn == NULL)
 	return -1;
 
-    FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol);
-
+  /* initialize memory */
     ZeroMemory (&hdi, sizeof(HDITEM32A));
 
-    if (lpcol->mask & LVCF_FMT) {
+  if (lpColumn->mask & LVCF_FMT) 
+  {
 	if (nIndex == 0)
 	    hdi.fmt |= HDF_LEFT;
-	else if (lpcol->fmt & LVCFMT_LEFT)
+    else if (lpColumn->fmt & LVCFMT_LEFT)
 	    hdi.fmt |= HDF_LEFT;
-	else if (lpcol->fmt & LVCFMT_RIGHT)
+    else if (lpColumn->fmt & LVCFMT_RIGHT)
 	    hdi.fmt |= HDF_RIGHT;
-	else if (lpcol->fmt & LVCFMT_CENTER)
+    else if (lpColumn->fmt & LVCFMT_CENTER)
 	    hdi.fmt |= HDF_CENTER;
 
-	if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES)
+    if (lpColumn->fmt & LVCFMT_COL_HAS_IMAGES)
 	    hdi.fmt |= HDF_IMAGE;
 	    
 	hdi.mask |= HDI_FORMAT;
     }
 
-    if (lpcol->mask & LVCF_WIDTH) {
+  if (lpColumn->mask & LVCF_WIDTH) 
+  {
         hdi.mask |= HDI_WIDTH;
-	hdi.cxy = lpcol->cx;
+    hdi.cxy = lpColumn->cx;
     }
     
-    if (lpcol->mask & LVCF_TEXT) {
+  if (lpColumn->mask & LVCF_TEXT) 
+  {
         hdi.mask |= (HDI_TEXT | HDI_FORMAT);
-	hdi.pszText = lpcol->pszText;
+    hdi.pszText = lpColumn->pszText;
 	hdi.fmt |= HDF_STRING;
     }
 
-    if (lpcol->mask & LVCF_IMAGE) {
+  if (lpColumn->mask & LVCF_IMAGE) 
+  {
         hdi.mask |= HDI_IMAGE;
-	hdi.iImage = lpcol->iImage;
+    hdi.iImage = lpColumn->iImage;
     }
 
-    if (lpcol->mask & LVCF_ORDER) {
+  if (lpColumn->mask & LVCF_ORDER) 
+  {
         hdi.mask |= HDI_ORDER;
-	hdi.iOrder = lpcol->iOrder;
+    hdi.iOrder = lpColumn->iOrder;
     }
 
     return (LRESULT)SendMessage32A (infoPtr->hwndHeader, HDM_SETITEM32A,
-				    wParam, (LPARAM)&hdi);
+                                  (WPARAM32)nIndex, (LPARAM)&hdi);
 }
 
-
-/*
- << LISTVIEW_SetColumn32W >>
- << LISTVIEW_SetColumnOrderArray >>
- << LISTVIEW_SetColumnWidth >>
- << LISTVIEW_SetExtendedListviewStyle >>
- << LISTVIEW_SetHotCursor >>
- << LISTVIEW_SetHotItem >>
- << LISTVIEW_SetHoverTime >>
- << LISTVIEW_SetIconSpacing >>
+/***
+ * DESCRIPTION:
+ * Sets image list.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : image list type  
+ * [I] HIMAGELIST : image list handle
+ *
+ * RETURN:
+ *   SUCCESS : old image list
+ *   FAILURE : NULL
 */
-
-
-static LRESULT
-LISTVIEW_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+static LRESULT LISTVIEW_SetImageList(HWND32 hwnd, INT32 nType, HIMAGELIST himl)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
     HIMAGELIST himlTemp = 0;
 
-    TRACE (listview, "(0x%08x 0x%08lx)\n", wParam, lParam);
-
-    switch (wParam) {
+  switch (nType) 
+  {
 	case LVSIL_NORMAL:
 	    himlTemp = infoPtr->himlNormal;
-	    infoPtr->himlNormal = (HIMAGELIST)lParam;
+    infoPtr->himlNormal = himl;
 	    return (LRESULT)himlTemp;
-
 	case LVSIL_SMALL:
 	    himlTemp = infoPtr->himlSmall;
-	    infoPtr->himlSmall = (HIMAGELIST)lParam;
+    infoPtr->himlSmall = himl;
 	    return (LRESULT)himlTemp;
-
 	case LVSIL_STATE:
 	    himlTemp = infoPtr->himlState;
-	    infoPtr->himlState = (HIMAGELIST)lParam;
+    infoPtr->himlState = himl;
 	    return (LRESULT)himlTemp;
     }
 
@@ -784,249 +2589,364 @@ LISTVIEW_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 }
 
 
-static LRESULT
-LISTVIEW_SetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Sets item attributes.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] LPLVITEM32 : item information 
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_SetItem32A(HWND32 hwnd, LPLVITEM32A lpItem)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
-    LISTVIEW_ITEM *lpRow, *lpSubItem;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
+  LISTVIEW_ITEM *lpListItem;
     NMLISTVIEW nmlv;
 
-    if (!lpItem)
+  if (lpItem == NULL)
 	return FALSE;
 
     if ((lpItem->iItem < 0) || (lpItem->iItem >= infoPtr->nItemCount))
 	return FALSE;
 
-    if ((lpItem->iSubItem < 0) || (lpItem->iSubItem >= infoPtr->nColumnCount))
-	return FALSE;
-
     /* send LVN_ITEMCHANGING notification */
     ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
-    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
-    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
+  nmlv.hdr.hwndFrom = hwnd;
+  nmlv.hdr.idFrom = lCtrlId;
     nmlv.hdr.code     = LVN_ITEMCHANGING;
     nmlv.iItem        = lpItem->iItem;
     nmlv.iSubItem     = lpItem->iSubItem;
     nmlv.uChanged     = lpItem->mask;
-
-    if (!SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-			 (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv))
+  if (SendMessage32A(GetParent32(hwnd), WM_NOTIFY,  (WPARAM32)lCtrlId, 
+                     (LPARAM)&nmlv) == FALSE) 
 	return FALSE;
 
-    TRACE (listview, "(%d %d %p)\n",
-	   lpItem->iItem, lpItem->iSubItem, lpItem);
-
-    lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem);
-    if (!lpRow)
+  /* get item */
+  lpListItem = DPA_GetPtr(infoPtr->hdpaItems, lpItem->iItem);
+  if (lpListItem == NULL)
+    return FALSE;
+
+  /* copy valid data */
+  if (lpItem->iSubItem > 0)
+  {
+    /* verify existance of sub-item */
+    lpListItem += lpItem->iSubItem;
+    if (lpListItem == NULL)
 	return FALSE;
 
-    lpSubItem = &lpRow[lpItem->iSubItem];
-    if (!lpSubItem)
+    /* exit if indent attribute is valid */
+    if (lpItem->mask & LVIF_INDENT)
 	return FALSE;
 
-    if (lpItem->mask & LVIF_STATE)
-	lpSubItem->state = (lpSubItem->state & lpItem->stateMask) | lpItem->state;
-
-    if (lpItem->mask & LVIF_TEXT) {
-	if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) {
-	    if ((lpSubItem->pszText) &&
-		(lpSubItem->pszText != LPSTR_TEXTCALLBACK32A))
-		COMCTL32_Free (lpSubItem->pszText);
-	    lpSubItem->pszText = LPSTR_TEXTCALLBACK32A;
-	}
-	else {
-	    if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A)
-		lpSubItem->pszText = NULL;
-	    Str_SetPtr32A (&lpSubItem->pszText, lpItem->pszText);
+    if (lpItem->mask & LVIF_IMAGE)
+    {
+      /* set sub-item attribute */
+    }
+
 	}
+  else
+  {
+    if (lpItem->mask & LVIF_STATE)
+    {
+      lpListItem->state &= ~lpItem->stateMask;
+      lpListItem->state |= (lpItem->state & lpItem->stateMask);
     }
 
     if (lpItem->mask & LVIF_IMAGE)
-	lpSubItem->iImage = lpItem->iImage;
+      lpListItem->iImage = lpItem->iImage;
 
     if (lpItem->mask & LVIF_PARAM)
-	lpSubItem->lParam = lpItem->lParam;
+      lpListItem->lParam = lpItem->lParam;
 
     if (lpItem->mask & LVIF_INDENT)
-	lpSubItem->iIndent = lpItem->iIndent;
+      lpListItem->iIndent = lpItem->iIndent;
+  }
+  
+  if (lpItem->mask & LVIF_TEXT) 
+  {
+    if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) 
+    {
+      if ((lpListItem->pszText != NULL) &&
+          (lpListItem->pszText != LPSTR_TEXTCALLBACK32A))
+        COMCTL32_Free (lpListItem->pszText);
+
+      lpListItem->pszText = LPSTR_TEXTCALLBACK32A;
+    }
+    else 
+    {
+      if (lpListItem->pszText == LPSTR_TEXTCALLBACK32A)
+        lpListItem->pszText = NULL;
+      
+      if (Str_SetPtr32A(&lpListItem->pszText, lpItem->pszText) == FALSE)
+        return FALSE;
+    }
+  }
 
     /* send LVN_ITEMCHANGED notification */
     nmlv.hdr.code = LVN_ITEMCHANGED;
-    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+  SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                 (LPARAM)&nmlv);
 
     return TRUE;
 }
 
-
 /* << LISTVIEW_SetItem32W >> */
-/* << LISTVIEW_SetItemCount >> */
-
 
-static LRESULT
-LISTVIEW_SetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/* LISTVIEW_SetItemCount*/
+
+/***
+ * DESCRIPTION:
+ * Sets item position.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : item index
+ * [I] INT32 : x coordinate
+ * [I] INT32 : y coordinate
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_SetItemPosition(HWND32 hwnd, INT32 nItem, 
+                                        INT32 nPosX, INT32 nPosY)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    INT32 nIndex = (INT32)wParam;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
 
-    if ((nIndex < 0) || (nIndex >= infoPtr->nItemCount))
+  if ((nItem < 0) || (nItem >= infoPtr->nItemCount))
 	return FALSE;
 
-    FIXME (listview, "setting position [%d, %d]!\n",
-	   (INT32)LOWORD(lParam), (INT32)HIWORD(lParam));
+  if ((lStyle & LVS_ICON) && (lStyle & LVS_SMALLICON))
+  {
+    /* get item */
+
+    /* set position of item */
 
-    /* FIXME: set position */
+    /* refresh */
+    if (lStyle & LVS_AUTOARRANGE)
+    {
+      InvalidateRect32(hwnd, NULL, FALSE);
+      UpdateWindow32(hwnd);
+    }
 
     return TRUE;
 }
 
+  return FALSE;
+}
 
-/*
- << LISTVIEW_SetItemPosition32 >>
- << LISTVIEW_SetItemState >>
+/***
+ * DESCRIPTION:
+ * Sets the state of one or many items.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I]INT32 : item index
+ * [I] LPLVITEM32 : item information 
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
 */
-
-
-static LRESULT
-LISTVIEW_SetItemText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+static LRESULT LISTVIEW_SetItemState(HWND32 hwnd, INT32 nItem, 
+                                     LPLVITEM32A lpItem)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
-    INT32 nItem = (INT32)wParam;
-    LISTVIEW_ITEM *lpRow, *lpSubItem;
-
-    TRACE (listview, "(%d %p)\n", nItem, lpItem);
-
-    lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem);
-    if (!lpRow)
-	return FALSE;
-
-    lpSubItem = &lpRow[lpItem->iSubItem];
-    if (!lpSubItem)
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LISTVIEW_ITEM *lpListItem;
+  INT32 i;
+
+  if (nItem == -1)
+  {
+    /* apply to all the items */
+    for (i = 0; i< infoPtr->nItemCount; i++)
+    {
+      lpListItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, i);
+      if (lpListItem == NULL)
 	return FALSE;
 
-    if (lpSubItem->pszText) {
-	if (lpSubItem->pszText != LPSTR_TEXTCALLBACK32A)
-	    COMCTL32_Free (lpSubItem->pszText);
-	lpSubItem->pszText = NULL;
-    }
-    if (lpItem->pszText) {
-	if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) {
-	    lpItem->pszText = LPSTR_TEXTCALLBACK32A;
+      lpListItem->state &= ~lpItem->stateMask;
+      lpListItem->state |= (lpItem->state & lpItem->stateMask);
 	}
-	else {
-	    INT32 len = lstrlen32A (lpItem->pszText);
-	    lpSubItem->pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
-	    lstrcpy32A (lpSubItem->pszText, lpItem->pszText);
 	}
+  else if ((nItem >= 0) && (nItem < infoPtr->nItemCount))
+  {
+    lpListItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem);
+    if (lpListItem == NULL)
+      return FALSE;
+
+    /* set state */
+    lpListItem->state &= ~lpItem->stateMask;
+    lpListItem->state |= (lpItem->state & lpItem->stateMask);
     }
+  else
+    return FALSE;
 
     return TRUE;
 }
 
-
-/*
- << LISTVIEW_SetItemText32W >>
- << LISTVIEW_SetSelectionMark >>
+/***
+ * DESCRIPTION:
+ * Sets the text background color.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] COLORREF : text background color
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
 */
-
-
-static LRESULT
-LISTVIEW_SetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+static LRESULT LISTVIEW_SetTextBkColor(HWND32 hwnd, COLORREF clrTextBk)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-
-    if (!infoPtr)
-	return FALSE;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
 
-    /* set text background color */
-    TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
-    infoPtr->clrTextBk = (COLORREF)lParam;
+  infoPtr->clrTextBk = clrTextBk;
 
     return TRUE;
 }
 
-
-static LRESULT
-LISTVIEW_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Sets the text background color.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] COLORREF : text color 
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_SetTextColor (HWND32 hwnd, COLORREF clrText)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-
-    if (!infoPtr)
-	return FALSE;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
 
-    /* set text color */
-    TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
-    infoPtr->clrText = (COLORREF)lParam;
+  infoPtr->clrText = clrText;
 
     return TRUE;
 }
 
-
-/*
- << LISTVIEW_SetTooltips >>
- << LISTVIEW_SetUnicodeFormat >>
- << LISTVIEW_SetWorkAreas >>
+/***
+ * DESCRIPTION:
+ * ??
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
 */
-
-
-static LRESULT
-LISTVIEW_SortItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+static LRESULT LISTVIEW_SortItems(HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
-/*    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */
+/*  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0); */
 
     FIXME (listview, "empty stub!\n");
 
-    /* fake success */
     return TRUE;
 }
 
-
-/*
- << LISTVIEW_SubItemHitTest >>
- << LISTVIEW_Update >>
+/***
+ * DESCRIPTION:
+ * Updates an items.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : item index
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
 */
-
-
-
-static LRESULT
-LISTVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+static LRESULT LISTVIEW_Update(HWND32 hwnd, INT32 nItem)
 {
-    /* info structure is created at NCCreate */
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LOGFONT32A logFont;
-    DWORD dwStyle = WS_CHILD | WS_VISIBLE; 
-
-    TRACE (listview, "styles 0x%08lx 0x%08lx\n",
-	   wndPtr->dwStyle, wndPtr->dwExStyle);
-
-    /* initialize info structure */
-    infoPtr->clrBk = CLR_NONE;
-    infoPtr->clrText = RGB(0, 0, 0); /* preliminary */
-    infoPtr->clrTextBk = RGB(255, 255, 255); /* preliminary */
-
-    if (!(wndPtr->dwStyle & LVS_REPORT) ||
-	 (wndPtr->dwStyle & LVS_NOCOLUMNHEADER))
-	dwStyle |= HDS_HIDDEN;
-    if (!(wndPtr->dwStyle & LVS_NOSORTHEADER))
-	dwStyle |= HDS_BUTTONS;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  RECT32 rcItemRect;
+  BOOL32 bResult = FALSE;
+
+  if ((nItem >= 0) || (nItem < infoPtr->nItemCount))
+  {
+    /* get item bounding rectangle */
+    rcItemRect.left = LVIR_BOUNDS;
+    SendMessage32A(hwnd, LVM_GETITEMRECT, (WPARAM32)nItem, 
+                   (LPARAM)&rcItemRect);
+
+    InvalidateRect32(hwnd, &rcItemRect, FALSE);
+
+    /* rearrange with default alignment style */
+    if ((lStyle & LVS_AUTOARRANGE) && 
+        ((lStyle & LVS_ICON) || (lStyle & LVS_SMALLICON)))
+      SendMessage32A(hwnd, LVM_ARRANGE, (WPARAM32)LVA_DEFAULT, (LPARAM)0);
+  }
+
+  return bResult;
+}
 
-    /* create header */
-    infoPtr->hwndHeader =
-	CreateWindow32A (WC_HEADER32A, "", dwStyle,
-			 0, 0, 0, 0, wndPtr->hwndSelf,
-			 (HMENU32)0, wndPtr->hInstance, NULL);
+/***
+ * DESCRIPTION:
+ * Creates a listview control.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_Create(HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); 
+  LOGFONT32A logFont;
+  HFONT32 hOldFont;
+  HDC32 hdc;
+  TEXTMETRIC32A tm;
+  INT32 nSmallIconHeight;
+
+  /* initialize color information  */
+  infoPtr->clrBk = GetSysColor32(COLOR_WINDOW);
+  infoPtr->clrText = GetSysColor32(COLOR_WINDOWTEXT);
+  infoPtr->clrTextBk = GetSysColor32(COLOR_WINDOW); 
 
     /* get default font (icon title) */
     SystemParametersInfo32A (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
     infoPtr->hDefaultFont = CreateFontIndirect32A (&logFont);
     infoPtr->hFont = infoPtr->hDefaultFont;
 
+  /* initialize column width */
+  infoPtr->nColumnWidth = 96;
+
+  /* get text height */
+  hdc = GetDC32(hwnd);
+  hOldFont = SelectObject32(hdc, infoPtr->hFont);
+  GetTextMetrics32A(hdc, &tm);
+
+  /* initialize item height with padding */
+  if (!(lStyle & LVS_ICON)) 
+  {
+    nSmallIconHeight = GetSystemMetrics32(SM_CYSMICON);
+    infoPtr->nItemHeight = max(tm.tmHeight, nSmallIconHeight) + 2;
+  }
+
+  SelectObject32(hdc, hOldFont);
+  ReleaseDC32(hwnd, hdc);
+
+ /* create header */
+  infoPtr->hwndHeader =	CreateWindow32A(WC_HEADER32A, "", lStyle, 0, 0, 0, 0, 
+                                        hwnd, (HMENU32)0, 
+                                        GetWindowLong32A(hwnd, GWL_HINSTANCE),
+                                        NULL);
     /* set header font */
-    SendMessage32A (infoPtr->hwndHeader, WM_SETFONT,
-		    (WPARAM32)infoPtr->hFont, (LPARAM)TRUE);
+  SendMessage32A(infoPtr->hwndHeader, WM_SETFONT, (WPARAM32)infoPtr->hFont, 
+                 (LPARAM)TRUE);
 
+  /* allocate memory */
     infoPtr->hdpaItems = DPA_Create (10);
 
     return 0;
@@ -1034,12 +2954,12 @@ LISTVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 
 
 static LRESULT
-LISTVIEW_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+LISTVIEW_Destroy (HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+    LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0);
 
     /* delete all items */
-    LISTVIEW_DeleteAllItems (wndPtr);
+    LISTVIEW_DeleteAllItems(hwnd);
 
     /* destroy dpa */
     DPA_Destroy (infoPtr->hdpaItems);
@@ -1053,147 +2973,538 @@ LISTVIEW_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
     if (infoPtr->hDefaultFont)
 	DeleteObject32 (infoPtr->hDefaultFont);
 
-    
+    infoPtr->nColumnWidth = 96;
 
     return 0;
 }
 
-
-static LRESULT
-LISTVIEW_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Erases the background of the listview control
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ *   SUCCESS : TRUE
+ *   FAILURE : FALSE
+ */
+static LRESULT LISTVIEW_EraseBackground(HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  BOOL32 bResult;
+
+  if (infoPtr->clrBk == CLR_NONE) 
+    bResult = SendMessage32A(GetParent32(hwnd), WM_ERASEBKGND, wParam, lParam);
+  else 
+  {
+    HBRUSH32 hBrush = CreateSolidBrush32(infoPtr->clrBk);
+    RECT32   clientRect;
+
+    GetClientRect32(hwnd, &clientRect);
+    FillRect32((HDC32)wParam, &clientRect, hBrush);
+    DeleteObject32(hBrush);
+    bResult = TRUE;
+  }
+
+  return bResult;
+}
 
-    if (infoPtr->clrBk == CLR_NONE) {
-	return SendMessage32A (GetParent32 (wndPtr->hwndSelf),
-			       WM_ERASEBKGND, wParam, lParam);
-    }
-    else {
-	HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
-	FillRect32 ((HDC32)wParam, &infoPtr->rcList, hBrush);
-	DeleteObject32 (hBrush);
-	return FALSE;
-    }
+/***
+ * DESCRIPTION:
+ * Gets the listview control font.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ * Font handle.
+ */
+static LRESULT LISTVIEW_GetFont(HWND32 hwnd)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
 
-    return TRUE;
+  return infoPtr->hFont;
 }
 
-
-__inline__ static LRESULT
-LISTVIEW_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Performs horizontal scrolling.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : scroll code
+ * [I] INT32 : scroll position
+ * [I] HWND32 : scrollbar control window handle
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_HScroll(HWND32 hwnd, INT32 nScrollCode, 
+                                INT32 nScrollPos, HWND32 hScrollWnd)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  INT32 nHScrollPos;
+  INT32 nMinRange;
+  INT32 nMaxRange;
+
+  GetScrollRange32(hwnd, SB_HORZ, &nMinRange, &nMaxRange);
+  nHScrollPos = GetScrollPos32(hwnd, SB_HORZ);
+
+  if (lStyle & LVS_LIST)
+  {
+    switch (nScrollCode)
+    {
+    case SB_LINELEFT:
+      if (nHScrollPos > nMinRange)
+        nHScrollPos--;
+      break;
+    case SB_LINERIGHT:
+      if (nHScrollPos < nMaxRange)
+        nHScrollPos++;
+      break;
+    case SB_PAGELEFT:
+      if (nHScrollPos > nMinRange)
+        nHScrollPos--;
+      break;
+    case SB_PAGERIGHT:
+      if (nHScrollPos < nMaxRange)
+        nHScrollPos++;
+      break;
+    case SB_THUMBPOSITION:
+      nHScrollPos = nScrollPos;
+    break;
+    }
+
+    SetScrollPos32(hwnd, SB_HORZ, nHScrollPos, TRUE);
 
-    return infoPtr->hFont;
+    /* refresh client area */
+    InvalidateRect32(hwnd, NULL, TRUE);
+    UpdateWindow32(hwnd);
+  }
+
+  return 0;
 }
 
+/***
+ * DESCRIPTION:
+ * ?????
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : virtual key 
+ * [I] LONG : key data
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_KeyDown(HWND32 hwnd, INT32 nVirtualKey, LONG lKeyData)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
+  HWND32 hwndParent = GetParent32(hwnd);
+  INT32 nItemCountPerColumn;
+  INT32 nItemCountPerRow;
+  NMHDR nmh;
+  INT32 nColumn;
+/*   NMLVKEYDOWN nmKeyDown; */
+
+  /* send LVN_KEYDOWN notification */
+/*   nmh.hwndFrom = hwnd; */
+/*   nmh.idFrom = lCtrlId; */
+/*   nmh.code = LVN_KEYDOWN; */
+/*   nmKeyDown.hdr = nmh; */
+/*   nmKeyDown..wVKey = nVirtualKey; */
+/*   nmKeyCode.flags = 0; */
+/*   SendMessage32A(hwndParent, WM_NOTIFY, (WPARAM32)lCtrlId, (LPARAM)&nmKeyDown); */
+
+  switch (nVirtualKey)
+  {
+  case VK_RETURN:
+    if ((infoPtr->nItemCount > 0) && (infoPtr->nFocusedItem != -1))
+    {
+      /* send NM_RETURN notification */
+      nmh.code = NM_RETURN;
+      SendMessage32A(hwndParent, WM_NOTIFY, (WPARAM32)lCtrlId, (LPARAM)&nmh);
+
+      /* send LVN_ITEMACTIVATE notification */
+      nmh.code = LVN_ITEMACTIVATE;
+      SendMessage32A(hwndParent, WM_NOTIFY, (WPARAM32)lCtrlId, (LPARAM)&nmh);
+    }
+    break;
 
-/* << LISTVIEW_HScroll >> */
-/* << LISTVIEW_KeyDown >> */
+  case VK_HOME:
+    if (infoPtr->nItemCount > 0)
+    {
+      /* set item state(s) */
+      infoPtr->nFocusedItem = 0;
+      LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE);
 
+      /* make item visible */
+      LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem);
+    }
+    break;
 
-static LRESULT
-LISTVIEW_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+  case VK_END:
+    if (infoPtr->nItemCount > 0)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    NMHDR nmh;
+      /* set item state(s) */
+      infoPtr->nFocusedItem = infoPtr->nItemCount - 1;
+      LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE);
+
+      /* make item visible */
+      LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem);
+    }
 
-    FIXME (listview, "semi stub!\n");
+    break;
 
-    nmh.hwndFrom = wndPtr->hwndSelf;
-    nmh.idFrom   = wndPtr->wIDmenu;
-    nmh.code = NM_KILLFOCUS;
+  case VK_LEFT:
+    if (lStyle & LVS_LIST)
+    {
+      nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd);
+      if (infoPtr->nFocusedItem >= nItemCountPerColumn) 
+      {
+         /* set item state(s) */
+        infoPtr->nFocusedItem -= nItemCountPerColumn;
+        LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE);
+
+        /* make item visible */
+        LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem);
+      }
+    }
+    else if (lStyle & LVS_REPORT)
+    {
+      /* TO DO ; does not affect the focused item, it only scrolls */
+    }
+    else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON))
+    {
+      nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd);
+      nColumn = infoPtr->nFocusedItem % nItemCountPerRow;
+      if (nColumn != 0)
+      {
+        infoPtr->nFocusedItem -= 1; 
+        LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE);
+
+        /* refresh display */
+        InvalidateRect32(hwnd, NULL, FALSE);
+        UpdateWindow32(hwnd);
+      }
+    }
+    break;
+    
+  case VK_UP:
+    if ((lStyle & LVS_LIST) || (lStyle & LVS_REPORT))
+    {
+      if (infoPtr->nFocusedItem > 0)
+      {
+        infoPtr->nFocusedItem -= 1;
+        LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE);
 
-    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh);
+        LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem);
+}
+    }
+    else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON))
+    {
+      nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd);
+      if (infoPtr->nFocusedItem >= nItemCountPerRow)
+      {
+        infoPtr->nFocusedItem -= nItemCountPerRow;
+        LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE);
+
+        LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem);
+      }
+    }
+    break;
 
-    infoPtr->bFocus = FALSE;
+  case VK_RIGHT:
+    if (lStyle & LVS_LIST)
+{
+      nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd);
+      if (infoPtr->nFocusedItem < infoPtr->nItemCount - nItemCountPerColumn)
+      {
+        infoPtr->nFocusedItem += nItemCountPerColumn;
+        LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE);
 
-    return 0;
+        LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem);
+    }
+    }
+    else if (lStyle & LVS_REPORT)
+    {
+    }
+    else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON))
+    {
+      nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd);
+      nColumn = infoPtr->nFocusedItem % nItemCountPerRow;
+      if (nColumn != nItemCountPerRow - 1)
+      {
+        infoPtr->nFocusedItem += 1; 
+        LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE);
+
+        /* refresh display */
+        InvalidateRect32(hwnd, NULL, FALSE);
+        UpdateWindow32(hwnd);
 }
 
+    }
+    break;
 
-static LRESULT
-LISTVIEW_LButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+  case VK_DOWN:
+    if ((lStyle & LVS_LIST) || (lStyle & LVS_REPORT))
 {
-    /* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */
-    NMLISTVIEW nmlv;
+      if (infoPtr->nFocusedItem < infoPtr->nItemCount - 1)
+      {
+        infoPtr->nFocusedItem += 1;
+        LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE);
 
-    FIXME (listview, "semi stub!\n");
+        LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem);
+}
+    }
+    else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON))
+    {
+      nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd);
+      if (infoPtr->nFocusedItem < infoPtr->nItemCount - nItemCountPerRow)
+      {
+        infoPtr->nFocusedItem += nItemCountPerRow;
+        LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE);
+
+        LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem);
+      }
+    }
+    break;
 
-    ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
-    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
-    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
-    nmlv.hdr.code = NM_DBLCLK;
-    nmlv.iItem    = -1;
-    nmlv.iSubItem = 0;
-    nmlv.ptAction.x = (INT32)LOWORD(lParam);
-    nmlv.ptAction.y = (INT32)HIWORD(lParam);
+  case VK_PRIOR:
+    break;
 
-    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+  case VK_NEXT:
+    break;
+  }
 
-    return 0;
+  return 0;
 }
 
-
-static LRESULT
-LISTVIEW_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Kills the focus.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_KillFocus(HWND32 hwnd)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    NMLISTVIEW nmlv;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0);
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
+    NMHDR nmh;
 
-    FIXME (listview, "semi stub!\n");
+  nmh.hwndFrom = hwnd;
+  nmh.idFrom = lCtrlId;
+    nmh.code = NM_KILLFOCUS;
+  SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                 (LPARAM)&nmh);
 
-    ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
-    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
-    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
-    nmlv.hdr.code = NM_CLICK;
-    nmlv.iItem    = -1;
-    nmlv.iSubItem = 0;
-    nmlv.ptAction.x = (INT32)LOWORD(lParam);
-    nmlv.ptAction.y = (INT32)HIWORD(lParam);
+  /* set window focus flag */
+    infoPtr->bFocus = FALSE;
 
-    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+    return 0;
+}
 
-    if (!infoPtr->bFocus)
-	SetFocus32 (wndPtr->hwndSelf);
+/***
+ * DESCRIPTION:
+ * Left mouse button double click.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] WORD : key flag
+ * [I] WORD : x coordinate
+ * [I] WORD : y coordinate
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_LButtonDblClk(HWND32 hwnd, WORD wKey, WORD wPosX, 
+                                      WORD wPosY)
+{
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
+  NMHDR nmh;
+
+  /* send NM_DBLCLK notification */
+  nmh.hwndFrom = hwnd;
+  nmh.idFrom = lCtrlId;
+  nmh.code = NM_DBLCLK;
+  SendMessage32A(GetParent32 (hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                 (LPARAM)&nmh);
+
+  /* send LVN_ITEMACTIVATE notification */
+  nmh.code = LVN_ITEMACTIVATE;
+  SendMessage32A(GetParent32 (hwnd), WM_NOTIFY, (WPARAM32)lCtrlId,
+                 (LPARAM)&nmh);
+
+  return 0;
+}
 
-    return 0;
+/***
+ * DESCRIPTION:
+ * Left mouse button down.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] WORD : key flag
+ * [I] WORD : x coordinate
+ * [I] WORD : y coordinate
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_LButtonDown(HWND32 hwnd, WORD wKey, WORD wPosX, 
+                                    WORD wPosY)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
+  LVHITTESTINFO hitTestInfo;
+  LVITEM32A lvItem;
+  NMHDR nmh;
+  INT32 nItem;
+
+  /* send NM_RELEASEDCAPTURE notification */ 
+  nmh.hwndFrom = hwnd;
+  nmh.idFrom = lCtrlId;
+  nmh.code = NM_RELEASEDCAPTURE;
+  SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                 (LPARAM)&nmh);
+
+  if (infoPtr->bFocus == FALSE)
+    SetFocus32(hwnd);
+
+  /* set left button down flag */
+  infoPtr->bLButtonDown = TRUE;
+
+  /* set left button hit coordinates */
+  hitTestInfo.pt.x = wPosX;
+  hitTestInfo.pt.y = wPosY;
+  
+  /* perform hit test */
+  nItem = SendMessage32A(hwnd, LVM_HITTEST, (WPARAM32)0, (LPARAM)&hitTestInfo);
+    if ((nItem >= 0) && (nItem < infoPtr->nItemCount))
+  {
+    /* perform state changes (selection and focus) */
+    infoPtr->nFocusedItem = nItem;
+    LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, TRUE);
+
+    /* scroll intem into view if doing a multiple selection */
+
+    if ((wKey & MK_CONTROL) || (wKey & MK_SHIFT))
+{
+      LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem);
+    }
+    else
+    {
+      /* refresh display */
+      InvalidateRect32(hwnd, NULL, FALSE);
+      UpdateWindow32(hwnd);
+    }
+  }
+  else
+  {
+    /* clear selection(s) */
+    ZeroMemory(&lvItem, sizeof(LVITEM32A));
+    lvItem.stateMask = LVIS_SELECTED;
+    lvItem.state = 0;
+    SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem);
+
+    /* repaint everything */
+    InvalidateRect32(hwnd, NULL, FALSE);
+    UpdateWindow32(hwnd);
+  }
+
+  return 0;
 }
 
+/***
+ * DESCRIPTION:
+ * Left mouse button up.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] WORD : key flag
+ * [I] WORD : x coordinate
+ * [I] WORD : y coordinate
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_LButtonUp(HWND32 hwnd, WORD wKey, WORD wPosX, 
+                                  WORD wPosY)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
+  NMHDR nmh;
+
+  if (infoPtr->bLButtonDown == TRUE) 
+  {
+    /* send NM_CLICK notification */
+    nmh.hwndFrom = hwnd;
+    nmh.idFrom = lCtrlId;
+    nmh.code = NM_CLICK;
+    SendMessage32A(GetParent32 (hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                     (LPARAM)&nmh);
+  }
+
+  /* set left button flag */
+  infoPtr->bLButtonDown = FALSE;
+
+    return 0;
+}
 
-static LRESULT
-LISTVIEW_NCCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Creates the listview control (called before WM_CREATE).
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] WPARAM32 : unhandled 
+ * [I] LPARAM : widow creation info
+ * 
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_NCCreate(HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
     LISTVIEW_INFO *infoPtr;
 
     /* allocate memory for info structure */
     infoPtr = (LISTVIEW_INFO *)COMCTL32_Alloc (sizeof(LISTVIEW_INFO));
-    wndPtr->wExtra[0] = (DWORD)infoPtr;
-
-    if (infoPtr == NULL) {
+  SetWindowLong32A(hwnd, 0, (LONG)infoPtr);
+  if (infoPtr == NULL) 
+  {
 	ERR (listview, "could not allocate info memory!\n");
 	return 0;
     }
 
-    if ((LISTVIEW_INFO*)wndPtr->wExtra[0] != infoPtr) {
+  if ((LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0) != infoPtr) 
+  {
 	ERR (listview, "pointer assignment error!\n");
 	return 0;
     }
 
-    return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCREATE, wParam, lParam);
+  return DefWindowProc32A(hwnd, WM_NCCREATE, wParam, lParam);
 }
 
-
-static LRESULT
-LISTVIEW_NCDestroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Destroys the listview control (called after WM_DESTROY).
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * 
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_NCDestroy(HWND32 hwnd)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-
-
-
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
 
     /* free list view info data */
     COMCTL32_Free (infoPtr);
@@ -1201,297 +3512,477 @@ LISTVIEW_NCDestroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
     return 0;
 }
 
-
-static LRESULT
-LISTVIEW_Notify (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Handles notification from children.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] INT32 : control identifier
+ * [I] LPNMHDR : notification information
+ * 
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_Notify(HWND32 hwnd, INT32 nCtrlId, LPNMHDR lpnmh)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    LPNMHDR lpnmh = (LPNMHDR)lParam;
-
-    if (lpnmh->hwndFrom == infoPtr->hwndHeader) {
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
 
+  if (lpnmh->hwndFrom == infoPtr->hwndHeader) 
+  {
+    /* handle notification from header control */
 	FIXME (listview, "WM_NOTIFY from header!\n");
     }
-    else {
-
+  else 
+  {
+    /* handle notification from unknown source */
 	FIXME (listview, "WM_NOTIFY from unknown source!\n");
     }
 
     return 0;
 }
 
-
-static LRESULT
-LISTVIEW_Paint (WND *wndPtr, WPARAM32 wParam)
+/***
+ * DESCRIPTION:
+ * Draws the listview control.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] HDC32 : device context handle
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_Paint(HWND32 hwnd, HDC32 hdc)
 {
-    HDC32 hdc;
     PAINTSTRUCT32 ps;
 
-    hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
-    LISTVIEW_Refresh (wndPtr, hdc);
-    if (!wParam)
-	EndPaint32 (wndPtr->hwndSelf, &ps);
-    return 0;
+  if (hdc == 0)
+  {
+    hdc = BeginPaint32(hwnd, &ps);
+    LISTVIEW_Refresh(hwnd, hdc);
+    EndPaint32(hwnd, &ps);
 }
+  else
+    LISTVIEW_Refresh(hwnd, hdc);
 
+  return 0;
+}
 
-static LRESULT
-LISTVIEW_RButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Right mouse button double clisk.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] WORD : key flag
+ * [I] WORD : x coordinate
+ * [I] WORD : y coordinate
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_RButtonDblClk(HWND32 hwnd, WORD wKey, WORD wPosX, 
+                                      WORD wPosY)
 {
-    /* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */
-    NMLISTVIEW nmlv;
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
+  NMHDR nmh;
 
-    FIXME (listview, "semi stub!\n");
+  /* send NM_RELEASEDCAPTURE notification */ 
+  nmh.hwndFrom = hwnd;
+  nmh.idFrom = lCtrlId;
+  nmh.code = NM_RELEASEDCAPTURE;
+  SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                 (LPARAM)&nmh);
 
-    ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
-    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
-    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
-    nmlv.hdr.code = NM_RDBLCLK;
-    nmlv.iItem    = -1;
-    nmlv.iSubItem = 0;
-    nmlv.ptAction.x = (INT32)LOWORD(lParam);
-    nmlv.ptAction.y = (INT32)HIWORD(lParam);
-
-    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+  /* send NM_RDBLCLK notification */
+  nmh.code = NM_RDBLCLK;
+  SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                 (LPARAM)&nmh);
 
     return 0;
 }
 
-
-static LRESULT
-LISTVIEW_RButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Right mouse button input.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] WORD : key flag
+ * [I] WORD : x coordinate
+ * [I] WORD : y coordinate
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_RButtonDown(HWND32 hwnd, WORD wKey, WORD wPosX, 
+                                    WORD wPosY)
 {
-    /* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */
-    NMLISTVIEW nmlv;
-
-    FIXME (listview, "semi stub!\n");
-
-    ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
-    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
-    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
-    nmlv.hdr.code = NM_RCLICK;
-    nmlv.iItem    = -1;
-    nmlv.iSubItem = 0;
-    nmlv.ptAction.x = (INT32)LOWORD(lParam);
-    nmlv.ptAction.y = (INT32)HIWORD(lParam);
-
-    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
+  LVHITTESTINFO hitTestInfo;
+  NMHDR nmh;
+  LVITEM32A lvItem;
+  INT32 nItem;
+
+  /* The syslistview32 control sends a NM_RELEASEDCAPTURE notification.
+     I do not know why, but I decided to send it as well for compatibility 
+     purposes. */
+  ZeroMemory(&nmh, sizeof(NMHDR));
+  nmh.hwndFrom = hwnd;
+  nmh.idFrom = lCtrlId;
+  nmh.code = NM_RELEASEDCAPTURE;
+  SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                 (LPARAM)&nmh);
+ 
+  /* make sure listview control has focus */
+  if (infoPtr->bFocus == FALSE)
+    SetFocus32(hwnd);
+
+  /* set left button down flag */
+  infoPtr->bRButtonDown = TRUE;
+
+  /* set hit coordinates */
+  hitTestInfo.pt.x = wPosX;
+  hitTestInfo.pt.y = wPosY;
+
+  /* perform hit test */
+  nItem = SendMessage32A(hwnd, LVM_HITTEST, (WPARAM32)0, (LPARAM)&hitTestInfo);
+  if ((nItem >= 0) && (nItem < infoPtr->nItemCount))
+  {
+    /* perform state changes (selection and focus) */
+    infoPtr->nFocusedItem = nItem;
+    LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, FALSE, TRUE);
+  }
+  else
+  {
+    /* clear selection(s) */
+    ZeroMemory(&lvItem, sizeof(LVITEM32A));
+    lvItem.stateMask = LVIS_SELECTED;
+    lvItem.state = 0;
+    SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem);
+  }
+
+  /* repaint everything */
+  InvalidateRect32(hwnd, NULL, FALSE);
+  UpdateWindow32(hwnd);
 
     return 0;
 }
 
-
-static LRESULT
-LISTVIEW_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Right mouse button up.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] WORD : key flag
+ * [I] WORD : x coordinate
+ * [I] WORD : y coordinate
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_RButtonUp(HWND32 hwnd, WORD wKey, WORD wPosX, 
+                                  WORD wPosY)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
     NMHDR nmh;
 
-    FIXME (listview, "semi stub!\n");
-
-    nmh.hwndFrom = wndPtr->hwndSelf;
-    nmh.idFrom   = wndPtr->wIDmenu;
-    nmh.code = NM_SETFOCUS;
-
-    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
-		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh);
+  if (infoPtr->bRButtonDown == TRUE) 
+  {
+    /* initialize notification information */
+    ZeroMemory(&nmh, sizeof(NMHDR));
+    nmh.hwndFrom = hwnd;
+    nmh.idFrom = lCtrlId;
+    nmh.code = NM_RCLICK;
+    SendMessage32A(GetParent32 (hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                   (LPARAM)&nmh);
+  }
 
-    infoPtr->bFocus = TRUE;
+  /* set button flag */
+  infoPtr->bRButtonDown = FALSE;
 
     return 0;
 }
 
-
-static LRESULT
-LISTVIEW_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Sets the focus.  
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] HWND32 : window handle of previously focused window
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_SetFocus(HWND32 hwnd, HWND32 hwndLoseFocus)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-    HFONT32 hFont = (HFONT32)wParam;
-
-    infoPtr->hFont = hFont ? hFont : infoPtr->hDefaultFont;
-
-    /* set header font */
-    SendMessage32A (infoPtr->hwndHeader, WM_SETFONT, wParam, lParam);
-
-    /* reinitialize the listview */
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID);
+  NMHDR nmh;
     
+  /* send NM_SETFOCUS notification */
+  nmh.hwndFrom = hwnd;
+  nmh.idFrom = lCtrlId;
+  nmh.code = NM_SETFOCUS;
+  SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, 
+                 (LPARAM)&nmh);
 
+  /* set window focus flag */
+  infoPtr->bFocus = TRUE;
 
-    if (lParam) {
-	/* force redraw */
+  return 0;
+}
 
+/***
+ * DESCRIPTION:
+ * Sets the font.  
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] HFONT32 : font handle
+ * [I] WORD : redraw flag
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_SetFont(HWND32 hwnd, HFONT32 hFont, WORD fRedraw)
+{
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
 
+  if (hFont == 0)
+  {
+    infoPtr->hFont = infoPtr->hDefaultFont;
+  }
+  else
+  {
+    infoPtr->hFont = hFont;
     }
 
-    return 0;
+  if (lStyle & LVS_REPORT)
+  {
+    /* set font of header */
+    SendMessage32A(infoPtr->hwndHeader, WM_SETFONT, (WPARAM32)hFont, 
+                   MAKELPARAM(fRedraw, 0));
 }
 
+  /* invalidate listview control client area */
+  InvalidateRect32(hwnd, NULL, FALSE);
 
+  if (fRedraw == TRUE)
+    UpdateWindow32(hwnd);
 
+  return 0;
+}
 
-static LRESULT
-LISTVIEW_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Resizes the listview control.  
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 : window handle
+ * [I] WORD : new width
+ * [I] WORD : new height
+ *
+ * RETURN:
+ * Zero
+ */
+static LRESULT LISTVIEW_Size(HWND32 hwnd, WORD wWidth, WORD wHeight)
 {
-    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
-
-    GetClientRect32 (wndPtr->hwndSelf, &infoPtr->rcList);
-
-    if (wndPtr->dwStyle & LVS_REPORT) {
-	HDLAYOUT hl;
-	WINDOWPOS32 wp;
-	RECT32 rc;
+  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0);
+  LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE);
+  INT32 nHScrollHeight;
 
-	rc.top = 0;
-	rc.left = 0;
-	rc.right = LOWORD(lParam);
-	rc.bottom = HIWORD(lParam);
+  if (lStyle & LVS_LIST)
+  {
+    if (!(lStyle & WS_HSCROLL))
+    {
+      nHScrollHeight = GetSystemMetrics32(SM_CYHSCROLL);
+      if (wHeight > nHScrollHeight)
+        wHeight -= nHScrollHeight;
+    }
 
-	hl.prc = &rc;
-	hl.pwpos = &wp;
-	SendMessage32A (infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl);
+    infoPtr->nHeight = (INT32)wHeight;
+    infoPtr->nWidth = (INT32)wWidth;
+  }
 
-	SetWindowPos32 (infoPtr->hwndHeader, wndPtr->hwndSelf,
-			wp.x, wp.y, wp.cx, wp.cy, wp.flags);
+  /* set scrollbar(s) if needed */
+  LISTVIEW_SetScroll(hwnd);
 
-	infoPtr->rcList.top += wp.cy;
-    }
+  /* refresh client area */
+  InvalidateRect32(hwnd, NULL, TRUE);
+  UpdateWindow32(hwnd);
 
     return 0;
 }
 
-
-LRESULT WINAPI
-LISTVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
+/***
+ * DESCRIPTION:
+ * Window procedure of the listview control.
+ * 
+ * PARAMETER(S):
+ * [I] HWND32 :
+ * [I] UINT32 :
+ * [I] WPARAM32 :
+ * [I] LPARAM : 
+ *
+ * RETURN:
+ * 
+ */
+LRESULT WINAPI LISTVIEW_WindowProc(HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam,
+                                   LPARAM lParam)
 {
-    WND *wndPtr = WIN_FindWndPtr(hwnd);
-
     switch (uMsg)
     {
-/*	case LVM_APPROXIMATEVIEWRECT: */
-/*	case LVM_ARRANGE: */
+  case LVM_APPROXIMATEVIEWRECT: 
+    return LISTVIEW_ApproximateViewRect(hwnd, (INT32)wParam, 
+                                        LOWORD(lParam), HIWORD(lParam));
+  case LVM_ARRANGE: 
+    return LISTVIEW_Arrange(hwnd, (INT32)wParam);
+
 /*	case LVM_CREATEDRAGIMAGE: */
 
 	case LVM_DELETEALLITEMS:
-	    return LISTVIEW_DeleteAllItems (wndPtr);
+    return LISTVIEW_DeleteAllItems(hwnd);
 
 	case LVM_DELETECOLUMN:
-	    return LISTVIEW_DeleteColumn (wndPtr, wParam, lParam);
+    return LISTVIEW_DeleteColumn(hwnd, (INT32)wParam);
 
 	case LVM_DELETEITEM:
-	    return LISTVIEW_DeleteItem (wndPtr, wParam, lParam);
+    return LISTVIEW_DeleteItem(hwnd, (INT32)wParam);
 
 /*	case LVM_EDITLABEL: */
 /*	case LVM_ENSUREVISIBLE: */
-/*	case LVM_FINDITEM: */
+
+  case LVM_FINDITEM32A:
+    return LISTVIEW_FindItem(hwnd, (INT32)wParam, (LPLVFINDINFO)lParam);
 
 	case LVM_GETBKCOLOR:
-	    return LISTVIEW_GetBkColor (wndPtr, wParam, lParam);
+    return LISTVIEW_GetBkColor(hwnd);
 
 /*	case LVM_GETBKIMAGE: */
 /*	case LVM_GETCALLBACKMASK: */
 
 	case LVM_GETCOLUMN32A:
-	    return LISTVIEW_GetColumn32A (wndPtr, wParam, lParam);
+    return LISTVIEW_GetColumn32A(hwnd, (INT32)wParam, (LPLVCOLUMN32A)lParam);
 
 /*	case LVM_GETCOLUMN32W: */
 /*	case LVM_GETCOLUMNORDERARRAY: */
 
 	case LVM_GETCOLUMNWIDTH:
-	    return LISTVIEW_GetColumnWidth (wndPtr, wParam, lParam);
+    return LISTVIEW_GetColumnWidth(hwnd, (INT32)wParam);
+
+  case LVM_GETCOUNTPERPAGE:
+    return LISTVIEW_GetCountPerPage(hwnd);
 
-/*	case LVM_GETCOUNTPERPAGE: */
 /*	case LVM_GETEDITCONTROL: */
 /*	case LVM_GETEXTENDEDLISTVIEWSTYLE: */
 
 	case LVM_GETHEADER:
-	    return LISTVIEW_GetHeader (wndPtr, wParam, lParam);
+    return LISTVIEW_GetHeader(hwnd);
 
 /*	case LVM_GETHOTCURSOR: */
 /*	case LVM_GETHOTITEM: */
 /*	case LVM_GETHOVERTIME: */
 
 	case LVM_GETIMAGELIST:
-	    return LISTVIEW_GetImageList (wndPtr, wParam, lParam);
+    return LISTVIEW_GetImageList(hwnd, (INT32)wParam);
 
 /*	case LVM_GETISEARCHSTRING: */
 
 	case LVM_GETITEM32A:
-	    return LISTVIEW_GetItem32A (wndPtr, wParam, lParam);
+    return LISTVIEW_GetItem32A(hwnd, (LPLVITEM32A)lParam);
 
 /*	case LVM_GETITEM32W: */
 
 	case LVM_GETITEMCOUNT:
-	    return LISTVIEW_GetItemCount (wndPtr, wParam, lParam);
+    return LISTVIEW_GetItemCount(hwnd);
 
 	case LVM_GETITEMPOSITION:
-	    return LISTVIEW_GetItemPosition (wndPtr, wParam, lParam);
+    return LISTVIEW_GetItemPosition(hwnd, (INT32)wParam, (LPPOINT32)lParam);
 
-/*	case LVM_GETITEMRECT: */
-/*	case LVM_GETITEMSPACING: */
-/*	case LVM_GETITEMSTATE: */
+  case LVM_GETITEMRECT: 
+    return LISTVIEW_GetItemRect(hwnd, (INT32)wParam, (LPRECT32)lParam);
 
+  case LVM_GETITEMSPACING: 
+    return LISTVIEW_GetItemSpacing(hwnd, (BOOL32)wParam);
+
+  case LVM_GETITEMSTATE: 
+    return LISTVIEW_GetItemState(hwnd, (INT32)wParam, (UINT32)lParam);
+    
 	case LVM_GETITEMTEXT32A:
-	    return LISTVIEW_GetItemText32A (wndPtr, wParam, lParam);
+    LISTVIEW_GetItemText32A(hwnd, (INT32)wParam, (LPLVITEM32A)lParam);
+    break;
 
 /*	case LVM_GETITEMTEXT32W: */
 
 	case LVM_GETNEXTITEM:
-	    return LISTVIEW_GetNextItem (wndPtr, wParam, lParam);
+    return LISTVIEW_GetNextItem(hwnd, (INT32)wParam, LOWORD(lParam));
 
 /*	case LVM_GETNUMBEROFWORKAREAS: */
-/*	case LVM_GETORIGIN: */
+  case LVM_GETORIGIN:
+    return LISTVIEW_GetOrigin(hwnd, (LPPOINT32)lParam);
 
 	case LVM_GETSELECTEDCOUNT:
-	    return LISTVIEW_GetSelectedCount (wndPtr, wParam, lParam);
+    return LISTVIEW_GetSelectedCount(hwnd);
 
-/*	case LVM_GETSELECTIONMARK: */
+  case LVM_GETSELECTIONMARK: 
+    return LISTVIEW_GetSelectionMark(hwnd);
 
 	case LVM_GETSTRINGWIDTH32A:
-	    return LISTVIEW_GetStringWidth32A (wndPtr, wParam, lParam);
+    return LISTVIEW_GetStringWidth32A (hwnd, (LPCSTR)lParam);
 
 /*	case LVM_GETSTRINGWIDTH32W: */
 /*	case LVM_GETSUBITEMRECT: */
 
 	case LVM_GETTEXTBKCOLOR:
-	    return LISTVIEW_GetTextBkColor (wndPtr, wParam, lParam);
+    return LISTVIEW_GetTextBkColor(hwnd);
 
 	case LVM_GETTEXTCOLOR:
-	    return LISTVIEW_GetTextColor (wndPtr, wParam, lParam);
+    return LISTVIEW_GetTextColor(hwnd);
 
 /*	case LVM_GETTOOLTIPS: */
 /*	case LVM_GETTOPINDEX: */
 /*	case LVM_GETUNICODEFORMAT: */
-/*	case LVM_GETVIEWRECT: */
+
+  case LVM_GETVIEWRECT:
+    return LISTVIEW_GetViewRect(hwnd, (LPRECT32)lParam);
+
 /*	case LVM_GETWORKAREAS: */
 
 	case LVM_HITTEST:
-	    return LISTVIEW_HitTest (wndPtr, wParam, lParam);
+    return LISTVIEW_HitTest(hwnd, (LPLVHITTESTINFO)lParam);
 
 	case LVM_INSERTCOLUMN32A:
-	    return LISTVIEW_InsertColumn32A (wndPtr, wParam, lParam);
+    return LISTVIEW_InsertColumn32A(hwnd, (INT32)wParam, 
+                                    (LPLVCOLUMN32A)lParam);
 
 /*	case LVM_INSERTCOLUMN32W: */
 
 	case LVM_INSERTITEM32A:
-	    return LISTVIEW_InsertItem32A (wndPtr, wParam, lParam);
+    return LISTVIEW_InsertItem32A(hwnd, (LPLVITEM32A)lParam);
 
 /*	case LVM_INSERTITEM32W: */
 
 	case LVM_REDRAWITEMS:
-	    return LISTVIEW_RedrawItems (wndPtr, wParam, lParam);
+    return LISTVIEW_RedrawItems(hwnd, (INT32)wParam, (INT32)lParam);
 
-/*	case LVM_SCROLL: */
+  case LVM_SCROLL: 
+    return LISTVIEW_Scroll(hwnd, (INT32)wParam, (INT32)lParam);
 
 	case LVM_SETBKCOLOR:
-	    return LISTVIEW_SetBkColor (wndPtr, wParam, lParam);
+    return LISTVIEW_SetBkColor(hwnd, (COLORREF)lParam);
 
 /*	case LVM_SETBKIMAGE: */
 /*	case LVM_SETCALLBACKMASK: */
 
 	case LVM_SETCOLUMN32A:
-	    return LISTVIEW_SetColumn32A (wndPtr, wParam, lParam);
+    return LISTVIEW_SetColumn32A(hwnd, (INT32)wParam, (LPLVCOLUMN32A)lParam);
 
 /*	case LVM_SETCOLUMN32W: */
 /*	case LVM_SETCOLUMNORDERARRAY: */
@@ -1503,105 +3994,121 @@ LISTVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
 /*	case LVM_SETICONSPACING: */
 	
 	case LVM_SETIMAGELIST:
-	    return LISTVIEW_SetImageList (wndPtr, wParam, lParam);
+    return LISTVIEW_SetImageList(hwnd, (INT32)wParam, (HIMAGELIST)lParam);
 
 	case LVM_SETITEM32A:
-	    return LISTVIEW_SetItem32A (wndPtr, wParam, lParam);
+    return LISTVIEW_SetItem32A(hwnd, (LPLVITEM32A)lParam);
 
 /*	case LVM_SETITEM32W: */
 /*	case LVM_SETITEMCOUNT: */
 
 	case LVM_SETITEMPOSITION:
-	    return LISTVIEW_SetItemPosition (wndPtr, wParam, lParam);
+    return LISTVIEW_SetItemPosition(hwnd, (INT32)wParam, 
+                                    (INT32)LOWORD(lParam), 
+                                    (INT32) HIWORD(lParam));
 
 /*	case LVM_SETITEMPOSITION32: */
-/*	case LVM_SETITEMSTATE: */
 
-	case LVM_SETITEMTEXT32A:
-	    return LISTVIEW_SetItemText32A (wndPtr, wParam, lParam);
+  case LVM_SETITEMSTATE: 
+    return LISTVIEW_SetItemState(hwnd, (INT32)wParam, (LPLVITEM32A)lParam);
 
-/*	case LVM_SETITEMTEXT32W: */
+/*	case LVM_SETITEMTEXT: */
 /*	case LVM_SETSELECTIONMARK: */
 
 	case LVM_SETTEXTBKCOLOR:
-	    return LISTVIEW_SetTextBkColor (wndPtr, wParam, lParam);
+    return LISTVIEW_SetTextBkColor(hwnd, (COLORREF)lParam);
 
 	case LVM_SETTEXTCOLOR:
-	    return LISTVIEW_SetTextColor (wndPtr, wParam, lParam);
+    return LISTVIEW_SetTextColor(hwnd, (COLORREF)lParam);
 
 /*	case LVM_SETTOOLTIPS: */
 /*	case LVM_SETUNICODEFORMAT: */
 /*	case LVM_SETWORKAREAS: */
 
 	case LVM_SORTITEMS:
-	    return LISTVIEW_SortItems (wndPtr, wParam, lParam);
+    return LISTVIEW_SortItems(hwnd, wParam, lParam);
 
 /*	case LVM_SUBITEMHITTEST: */
-/*	case LVM_UPDATE: */
-
 
+  case LVM_UPDATE: 
+    return LISTVIEW_Update(hwnd, (INT32)wParam);
 
 /*	case WM_CHAR: */
 /*	case WM_COMMAND: */
 
 	case WM_CREATE:
-	    return LISTVIEW_Create (wndPtr, wParam, lParam);
+    return LISTVIEW_Create(hwnd, wParam, lParam);
 
 	case WM_DESTROY:
-	    return LISTVIEW_Destroy (wndPtr, wParam, lParam);
+    return LISTVIEW_Destroy(hwnd, wParam, lParam);
 
 	case WM_ERASEBKGND:
-	    return LISTVIEW_EraseBackground (wndPtr, wParam, lParam);
+    return LISTVIEW_EraseBackground (hwnd, wParam, lParam);
 
 	case WM_GETDLGCODE:
 	    return DLGC_WANTTAB | DLGC_WANTARROWS;
 
 	case WM_GETFONT:
-	    return LISTVIEW_GetFont (wndPtr, wParam, lParam);
+    return LISTVIEW_GetFont(hwnd);
+
+  case WM_HSCROLL:
+    return LISTVIEW_HScroll(hwnd, (INT32)LOWORD(wParam), 
+                            (INT32)HIWORD(wParam), (HWND32)lParam);
 
-/*	case WM_HSCROLL: */
-/*	case WM_KEYDOWN: */
+  case WM_KEYDOWN:
+    return LISTVIEW_KeyDown(hwnd, (INT32)wParam, (LONG)lParam);
 
 	case WM_KILLFOCUS:
-	    return LISTVIEW_KillFocus (wndPtr, wParam, lParam);
+    return LISTVIEW_KillFocus(hwnd);
 
 	case WM_LBUTTONDBLCLK:
-	    return LISTVIEW_LButtonDblClk (wndPtr, wParam, lParam);
+    return LISTVIEW_LButtonDblClk(hwnd, (WORD)wParam, LOWORD(lParam), 
+                                HIWORD(lParam));
 
 	case WM_LBUTTONDOWN:
-	    return LISTVIEW_LButtonDown (wndPtr, wParam, lParam);
+    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 (wndPtr, wParam, lParam); */
+/*	    return LISTVIEW_MouseMove (hwnd, wParam, lParam); */
 
 	case WM_NCCREATE:
-	    return LISTVIEW_NCCreate (wndPtr, wParam, lParam);
+    return LISTVIEW_NCCreate(hwnd, wParam, lParam);
 
 	case WM_NCDESTROY:
-	    return LISTVIEW_NCDestroy (wndPtr, wParam, lParam);
+    return LISTVIEW_NCDestroy(hwnd);
 
 	case WM_NOTIFY:
-	    return LISTVIEW_Notify (wndPtr, wParam, lParam);
+    return LISTVIEW_Notify(hwnd, (INT32)wParam, (LPNMHDR)lParam);
 
 	case WM_PAINT:
-	    return LISTVIEW_Paint (wndPtr, wParam);
+    return LISTVIEW_Paint(hwnd, (HDC32)wParam); 
 
 	case WM_RBUTTONDBLCLK:
-	    return LISTVIEW_RButtonDblClk (wndPtr, wParam, lParam);
+    return LISTVIEW_RButtonDblClk(hwnd, (WORD)wParam, LOWORD(lParam), 
+                                  HIWORD(lParam));
 
 	case WM_RBUTTONDOWN:
-	    return LISTVIEW_RButtonDown (wndPtr, wParam, lParam);
+    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 (wndPtr, wParam, lParam);
+    return LISTVIEW_SetFocus(hwnd, (HWND32)wParam);
 
 	case WM_SETFONT:
-	    return LISTVIEW_SetFont (wndPtr, wParam, lParam);
+    return LISTVIEW_SetFont(hwnd, (HFONT32)wParam, (WORD)lParam);
 
 /*	case WM_SETREDRAW: */
 
 	case WM_SIZE:
-	    return LISTVIEW_Size (wndPtr, wParam, lParam);
+    return LISTVIEW_Size(hwnd, LOWORD(lParam), HIWORD(lParam));
 
 /*	case WM_TIMER: */
 /*	case WM_VSCROLL: */
@@ -1612,19 +4119,30 @@ LISTVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
 	    if (uMsg >= WM_USER)
 		ERR (listview, "unknown msg %04x wp=%08x lp=%08lx\n",
 		     uMsg, wParam, lParam);
+
+    /* call default window procedure */
 	    return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
     }
+
     return 0;
 }
 
-
-VOID
-LISTVIEW_Register (VOID)
+/***
+ * DESCRIPTION:`
+ * Registers the window class.
+ * 
+ * PARAMETER(S):
+ * None
+ *
+ * RETURN:
+ * None
+ */
+VOID LISTVIEW_Register(VOID)
 {
     WNDCLASS32A wndClass;
 
-    if (GlobalFindAtom32A (WC_LISTVIEW32A)) return;
-
+  if (!GlobalFindAtom32A(WC_LISTVIEW32A)) 
+  {
     ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
     wndClass.lpfnWndProc   = (WNDPROC32)LISTVIEW_WindowProc;
@@ -1633,13 +4151,21 @@ LISTVIEW_Register (VOID)
     wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
     wndClass.hbrBackground = (HBRUSH32)(COLOR_WINDOW + 1);
     wndClass.lpszClassName = WC_LISTVIEW32A;
- 
     RegisterClass32A (&wndClass);
 }
+}
 
-
-VOID
-LISTVIEW_Unregister (VOID)
+/***
+ * DESCRIPTION:
+ * Unregisters the window class.
+ * 
+ * PARAMETER(S):
+ * None
+ *
+ * RETURN:
+ * None
+ */
+VOID LISTVIEW_Unregister(VOID)
 {
     if (GlobalFindAtom32A (WC_LISTVIEW32A))
 	UnregisterClass32A (WC_LISTVIEW32A, (HINSTANCE32)NULL);
diff --git a/include/commctrl.h b/include/commctrl.h
index 535c5bb07171889444d71194182e26375c37de02..990b05ec9940f3db4f979c11b9713dd31197639d 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -5,9 +5,9 @@
 #ifndef __WINE_COMMCTRL_H
 #define __WINE_COMMCTRL_H
 
-#include "windows.h"
+#include "wintypes.h"
+#include "winuser.h"
 #include "imagelist.h"
-#include "prsht.h" 
 
 /* c++ likes nameless unions whereas c doesnt */
 /* (used in property sheet structures)        */
@@ -1798,7 +1798,6 @@ typedef struct {
 
 #define TVITEM     WINELIB_NAME_AW(TVITEM)
 #define LPTVITEM   WINELIB_NAME_AW(LPTVITEM)
-
 #define TV_ITEM	    TVITEM
 
 typedef struct {
@@ -1832,7 +1831,6 @@ typedef struct {
 #define TVITEMEX   WINELIB_NAME_AW(TVITEMEX)
 #define LPTVITEMEX WINELIB_NAME_AW(LPTVITEMEX)
 
-
 typedef struct tagTVINSERTSTRUCT32A {
         HTREEITEM hParent;
         HTREEITEM hInsertAfter;
@@ -1860,7 +1858,6 @@ typedef struct tagTVINSERTSTRUCT32W {
 
 
 
-
 typedef struct tagNMTREEVIEW32A {
 	NMHDR	hdr;
 	UINT32	action;
@@ -2156,6 +2153,18 @@ typedef struct tagNMTVGETINFOTIP32W
 #define LVSIL_SMALL             1
 #define LVSIL_STATE             2
 
+#define LVIS_FOCUSED            0x0001
+#define LVIS_SELECTED           0x0002
+#define LVIS_CUT                0x0004
+#define LVIS_DROPHILITED        0x0008
+#define LVIS_ACTIVATING         0x0020
+
+#define LVFI_PARAM              0X0001
+#define LVFI_STRING             0X0002
+#define LVFI_PARTIAL            0X0008
+#define LVFI_WRAP               0X0020  
+#define LVFI_NEARESTXY          0X0040
+
 #define LVIF_TEXT               0x0001
 #define LVIF_IMAGE              0x0002
 #define LVIF_PARAM              0x0004
@@ -2163,6 +2172,11 @@ typedef struct tagNMTVGETINFOTIP32W
 #define LVIF_INDENT             0x0010
 #define LVIF_NORECOMPUTE        0x0800
 
+#define LVIR_BOUNDS             0x0000
+#define LVIR_LABEL              0x0002
+#define LVIR_ICON               0x0001
+#define LVIR_SELECTBOUNDS       0x0003 
+
 #define LVIS_FOCUSED            0x0001
 #define LVIS_SELECTED           0x0002
 #define LVIS_CUT                0x0004
@@ -2331,6 +2345,10 @@ typedef struct tagNMTVGETINFOTIP32W
 #define LVN_SETDISPINFO32W      (LVN_FIRST-78)
 #define LVN_SETDISPINFO WINELIB_NAME_AW(LVN_SETDISPINFO)
 
+#define LVA_ALIGNLEFT           0x0000
+#define LVA_DEFAULT             0x0001
+#define LVA_ALIGNTOP            0x0002
+#define LVA_SNAPTOGRID          0x0005
 
 typedef struct tagLVITEMA
 {
diff --git a/include/listview.h b/include/listview.h
index b140b8006a68a3a5ab1585fe5556a9c18bdc1dab..f027c96b27ca55005ca745afb8bcd8c3687a4c17 100644
--- a/include/listview.h
+++ b/include/listview.h
@@ -27,14 +27,20 @@ typedef struct tagLISTVIEW_INFO
     HIMAGELIST himlNormal;
     HIMAGELIST himlSmall;
     HIMAGELIST himlState;
-    INT32      nItemCount;
+  BOOL32 bLButtonDown;
+  BOOL32 bRButtonDown;
     INT32      nColumnCount;
+  INT32 nFocusedItem;
+  INT32 nItemCount;
+  INT32 nItemHeight;
+  INT32 nColumnWidth;
+  INT32 nSelectionMark;
     HWND32     hwndHeader;
     HFONT32    hDefaultFont;
     HFONT32    hFont;
-    RECT32     rcList;       /* "client" area of the list (without header) */
+  INT32 nWidth;
+  INT32 nHeight;
     BOOL32     bFocus;
-
     DWORD      dwExStyle;    /* extended listview style */
     HDPA       hdpaItems;