/*
 * Listview control
 *
 * Copyright 1998 Eric Kohl
 *
 * 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>
 *
 * TODO:
 *   - Most messages.
 *   - Most notifications.
 */

#include "windows.h"
#include "commctrl.h"
#include "listview.h"
#include "win.h"
#include "debug.h"


#define LISTVIEW_GetInfoPtr(wndPtr) ((LISTVIEW_INFO *)wndPtr->wExtra[0])


static VOID
LISTVIEW_Refresh (WND *wndPtr, HDC32 hdc)
{
/*    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */



}



/* << LISTVIEW_ApproximateViewRect >> */
/* << LISTVIEW_Arrange >> */
/* << LISTVIEW_CreateDragImage >> */


static LRESULT
LISTVIEW_DeleteAllItems (WND *wndPtr)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    INT32 nItem;
    LISTVIEW_ITEM *lpItem;
    NMLISTVIEW nmlv;
    BOOL32 bNotify;

    if (infoPtr->nItemCount == 0)
	return TRUE;

    TRACE (listview, "\n");

    /* send LVN_DELETEALLITEMS notification */
    ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
    nmlv.hdr.code     = LVN_DELETEALLITEMS;
    nmlv.iItem        = -1;
    bNotify =
	!(BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
				 (WPARAM32)wndPtr->wIDmenu, (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);
	}

	/* get item pointer */
	lpItem = (LISTVIEW_ITEM*)DPA_GetPtr (infoPtr->hdpaItems, nItem);
	if (lpItem) {
	    /* delete item strings */
	    if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
		COMCTL32_Free (lpItem->pszText);

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

    DPA_DeleteAllPtrs (infoPtr->hdpaItems);
    infoPtr->nItemCount = 0;

    return TRUE;
}


static LRESULT
LISTVIEW_DeleteColumn (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    /* INT32 nColumn = (INT32)wParam; */

    /* FIXME ??? */
    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)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    INT32 nItem = (INT32)wParam;
    LISTVIEW_ITEM *lpItem;
    NMLISTVIEW nmlv;

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

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

    /* send notification */
    ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
    nmlv.hdr.code     = LVN_DELETEITEM;
    nmlv.iItem        = nItem;
    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);

    /* remove from item array */
    lpItem = (LISTVIEW_ITEM*)DPA_DeletePtr (infoPtr->hdpaItems, nItem);

    /* delete item strings */
    if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
	COMCTL32_Free (lpItem->pszText);

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

    infoPtr->nItemCount--;

    return TRUE;
}


/* << LISTVIEW_EditLabel >> */
/* << LISTVIEW_EnsureVisible >> */
/* << LISTVIEW_FindItem >> */


static LRESULT
LISTVIEW_GetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

    return infoPtr->clrBk;
}


/* << LISTVIEW_GetBkImage >> */
/* << LISTVIEW_GetCallbackMask >> */


static LRESULT
LISTVIEW_GetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
    INT32 nIndex = (INT32)wParam;
    HDITEM32A hdi;

    if (!lpcol)
	return FALSE;

    TRACE (listview, "(%d %p)\n", nIndex, lpcol);

    ZeroMemory (&hdi, sizeof(HDITEM32A));

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

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

    if (lpcol->mask & LVCF_TEXT)
        hdi.mask |= (HDI_TEXT | HDI_FORMAT);

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

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

    if (!SendMessage32A (infoPtr->hwndHeader, HDM_GETITEM32A,
		    wParam, (LPARAM)&hdi))
	return FALSE;

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

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

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

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

    if ((lpcol->mask & LVCF_TEXT) && (lpcol->pszText) && (hdi.pszText))
	lstrcpyn32A (lpcol->pszText, hdi.pszText, lpcol->cchTextMax);

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

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

    return TRUE;
}


/* << LISTVIEW_GetColumn32W >> */
/* << LISTVIEW_GetColumnOrderArray >> */


__inline__ static LRESULT
LISTVIEW_GetColumnWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    HDITEM32A hdi;

    hdi.mask = HDI_WIDTH;
    if (SendMessage32A (infoPtr->hwndHeader, HDM_GETITEM32A,
			wParam, (LPARAM)&hdi))
	return hdi.cxy;

    return 0;
}


/* << LISTVIEW_GetCountPerPage >> */
/* << LISTVIEW_GetEditControl >> */
/* << LISTVIEW_GetExtendedListviewStyle >> */


__inline__ static LRESULT
LISTVIEW_GetHeader (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

    return infoPtr->hwndHeader;
}


/* << LISTVIEW_GetHotCursor >> */
/* << LISTVIEW_GetHotItem >> */
/* << LISTVIEW_GetHoverTime >> */


static LRESULT
LISTVIEW_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

    TRACE (listview, "(0x%08x)\n", wParam);

    switch (wParam) {
	case LVSIL_NORMAL:
	    return (LRESULT)infoPtr->himlNormal;

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

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

    return (LRESULT)NULL;
}


/* << LISTVIEW_GetISearchString >> */


static LRESULT
LISTVIEW_GetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    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;

    if (lpItem->mask & LVIF_STATE)
	lpItem->state = lpSubItem->state & lpItem->stateMask;

    if (lpItem->mask & LVIF_TEXT) {
	if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A)
	    lpItem->pszText = LPSTR_TEXTCALLBACK32A;
	else
	    Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText,
			   lpItem->cchTextMax);
    }

    if (lpItem->mask & LVIF_IMAGE)
	 lpItem->iImage = lpSubItem->iImage;

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

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

    return TRUE;
}


/* << LISTVIEW_GetItem32W >> */


__inline__ static LRESULT
LISTVIEW_GetItemCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    return infoPtr->nItemCount;
}


static LRESULT
LISTVIEW_GetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    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;

    return TRUE;
}


/* << LISTVIEW_GetItemRect >> */
/* << LISTVIEW_GetItemSpacing >> */
/* << LISTVIEW_GetItemState >> */


static LRESULT
LISTVIEW_GetItemText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    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 0;

    lpSubItem = &lpRow[lpItem->iSubItem];
    if (!lpSubItem)
	return 0;

    if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A) {
	lpItem->pszText = LPSTR_TEXTCALLBACK32A;
	return 0;
    }
    else
	return Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText,
			      lpItem->cchTextMax);
}


/* << LISTVIEW_GetItemText32A >> */


static LRESULT
LISTVIEW_GetNextItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    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);

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

    /* just a simple (preliminary) hack */
    if (nStart == -1)
	return 0;
    else if (nStart < infoPtr->nItemCount - 1)
	return nStart + 1;
    else
	return -1;

    return -1;
}


/* << LISTVIEW_GetNumberOfWorkAreas >> */
/* << LISTVIEW_GetOrigin >> */


static LRESULT
LISTVIEW_GetSelectedCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    /* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */

    TRACE (listview, ": empty stub (returns 0)!\n");

    return 0;
}


/* << LISTVIEW_GetSelectionMark >> */


static LRESULT
LISTVIEW_GetStringWidth32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    LPSTR lpsz = (LPSTR)lParam;
    HFONT32 hFont, hOldFont;
    HDC32 hdc;
    SIZE32 size;

    if (!lpsz)
	return 0;

    TRACE (listview, "(%s)\n", lpsz);

    hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
    hdc = GetDC32 (0);
    hOldFont = SelectObject32 (hdc, hFont);
    GetTextExtentPoint32A (hdc, lpsz, lstrlen32A(lpsz), &size);
    SelectObject32 (hdc, hOldFont);
    ReleaseDC32 (0, hdc);

    TRACE (listview, "-- ret=%d\n", size.cx);

    return (LRESULT)size.cx;
}




__inline__ static LRESULT
LISTVIEW_GetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

    return infoPtr->clrTextBk;
}


__inline__ static LRESULT
LISTVIEW_GetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

    return infoPtr->clrText;
}


static LRESULT
LISTVIEW_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
/*    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */
    LPLVHITTESTINFO lpht = (LPLVHITTESTINFO)lParam;

    FIXME (listview, "(%p): stub!\n", lpht);

    /* FIXME: preliminary */
    lpht->flags = LVHT_NOWHERE;
    lpht->iItem = -1;
    lpht->iSubItem = 0;

    return -1;
}


static LRESULT
LISTVIEW_InsertColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
    INT32 nIndex = (INT32)wParam;
    HDITEM32A hdi;
    INT32 nResult;

    if ((!lpcol) || (infoPtr->nItemCount > 0))
	return -1;

    FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol);

    ZeroMemory (&hdi, sizeof(HDITEM32A));

    if (lpcol->mask & LVCF_FMT) {
	if (nIndex == 0)
	    hdi.fmt |= HDF_LEFT;
	else if (lpcol->fmt & LVCFMT_LEFT)
	    hdi.fmt |= HDF_LEFT;
	else if (lpcol->fmt & LVCFMT_RIGHT)
	    hdi.fmt |= HDF_RIGHT;
	else if (lpcol->fmt & LVCFMT_CENTER)
	    hdi.fmt |= HDF_CENTER;

	if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES)
	    hdi.fmt |= HDF_IMAGE;
	    
	hdi.mask |= HDI_FORMAT;
    }

    if (lpcol->mask & LVCF_WIDTH) {
        hdi.mask |= HDI_WIDTH;
	hdi.cxy = lpcol->cx;
    }
    
    if (lpcol->mask & LVCF_TEXT) {
        hdi.mask |= (HDI_TEXT | HDI_FORMAT);
	hdi.pszText = lpcol->pszText;
	hdi.fmt |= HDF_STRING;
    }

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

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

    nResult = SendMessage32A (infoPtr->hwndHeader, HDM_INSERTITEM32A,
			      wParam, (LPARAM)&hdi);
    if (nResult == -1)
	return -1;

    infoPtr->nColumnCount++;

    return nResult;
}


/* << LISTVIEW_InsertColumn32W >> */


static LRESULT
LISTVIEW_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
    LISTVIEW_ITEM *lpListItem;
    INT32 nIndex;
    NMLISTVIEW nmlv;

    if (!lpItem)
	return -1;

    if ((!infoPtr->nColumnCount) || (lpItem->iSubItem))
	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)
	return -1;

    if (lpItem->mask & LVIF_STATE)
	lpListItem[0].state = lpItem->state;

    if (lpItem->mask & LVIF_TEXT) {
	if (lpItem->pszText == LPSTR_TEXTCALLBACK32A)
	    lpListItem[0].pszText = LPSTR_TEXTCALLBACK32A;
	else
	    Str_SetPtr32A (&lpListItem[0].pszText, lpItem->pszText);
    }

    if (lpItem->mask & LVIF_IMAGE)
	lpListItem[0].iImage = lpItem->iImage;

    if (lpItem->mask & LVIF_PARAM)
	lpListItem[0].lParam = lpItem->lParam;

    if (lpItem->mask & LVIF_INDENT)
	lpListItem[0].iIndent = lpItem->iIndent;

    infoPtr->nItemCount++;

    /* send notification */
    ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
    nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
    nmlv.hdr.idFrom   = wndPtr->wIDmenu;
    nmlv.hdr.code     = LVN_INSERTITEM;
    nmlv.iItem        = nIndex;
    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);

    return nIndex;
}


/* << LISTVIEW_InsertItem32W >> */


static LRESULT
LISTVIEW_RedrawItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
/*    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */

    FIXME (listview, "(%d - %d): empty stub!\n",
	   (INT32)wParam, (INT32)lParam);

    return TRUE;
}


/*
 << LISTVIEW_Scroll >>
*/


static LRESULT
LISTVIEW_SetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

    if (!infoPtr)
	return FALSE;

    /* set background color */
    TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
    infoPtr->clrBk = (COLORREF)lParam;

    return TRUE;
}


/*
 << LISTVIEW_SetBkImage >>
 << LISTVIEW_SetCallbackMask >>
*/


static LRESULT
LISTVIEW_SetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
    INT32 nIndex = (INT32)wParam;
    HDITEM32A hdi;

    if (!lpcol)
	return -1;

    FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol);

    ZeroMemory (&hdi, sizeof(HDITEM32A));

    if (lpcol->mask & LVCF_FMT) {
	if (nIndex == 0)
	    hdi.fmt |= HDF_LEFT;
	else if (lpcol->fmt & LVCFMT_LEFT)
	    hdi.fmt |= HDF_LEFT;
	else if (lpcol->fmt & LVCFMT_RIGHT)
	    hdi.fmt |= HDF_RIGHT;
	else if (lpcol->fmt & LVCFMT_CENTER)
	    hdi.fmt |= HDF_CENTER;

	if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES)
	    hdi.fmt |= HDF_IMAGE;
	    
	hdi.mask |= HDI_FORMAT;
    }

    if (lpcol->mask & LVCF_WIDTH) {
        hdi.mask |= HDI_WIDTH;
	hdi.cxy = lpcol->cx;
    }
    
    if (lpcol->mask & LVCF_TEXT) {
        hdi.mask |= (HDI_TEXT | HDI_FORMAT);
	hdi.pszText = lpcol->pszText;
	hdi.fmt |= HDF_STRING;
    }

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

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

    return (LRESULT)SendMessage32A (infoPtr->hwndHeader, HDM_SETITEM32A,
				    wParam, (LPARAM)&hdi);
}


/*
 << LISTVIEW_SetColumn32W >>
 << LISTVIEW_SetColumnOrderArray >>
 << LISTVIEW_SetColumnWidth >>
 << LISTVIEW_SetExtendedListviewStyle >>
 << LISTVIEW_SetHotCursor >>
 << LISTVIEW_SetHotItem >>
 << LISTVIEW_SetHoverTime >>
 << LISTVIEW_SetIconSpacing >>
*/


static LRESULT
LISTVIEW_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    HIMAGELIST himlTemp = 0;

    TRACE (listview, "(0x%08x 0x%08lx)\n", wParam, lParam);

    switch (wParam) {
	case LVSIL_NORMAL:
	    himlTemp = infoPtr->himlNormal;
	    infoPtr->himlNormal = (HIMAGELIST)lParam;
	    return (LRESULT)himlTemp;

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

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

    return (LRESULT)NULL;
}


static LRESULT
LISTVIEW_SetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
    LISTVIEW_ITEM *lpRow, *lpSubItem;
    NMLISTVIEW nmlv;

    if (!lpItem)
	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.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))
	return FALSE;

    TRACE (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;

    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)
	lpSubItem->iImage = lpItem->iImage;

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

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

    /* send LVN_ITEMCHANGED notification */
    nmlv.hdr.code = LVN_ITEMCHANGED;
    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);

    return TRUE;
}


/* << LISTVIEW_SetItem32W >> */
/* << LISTVIEW_SetItemCount >> */


static LRESULT
LISTVIEW_SetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    INT32 nIndex = (INT32)wParam;

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

    FIXME (listview, "setting position [%d, %d]!\n",
	   (INT32)LOWORD(lParam), (INT32)HIWORD(lParam));

    /* FIXME: set position */

    return TRUE;
}


/*
 << LISTVIEW_SetItemPosition32 >>
 << LISTVIEW_SetItemState >>
*/


static LRESULT
LISTVIEW_SetItemText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    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)
	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;
	}
	else {
	    INT32 len = lstrlen32A (lpItem->pszText);
	    lpSubItem->pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
	    lstrcpy32A (lpSubItem->pszText, lpItem->pszText);
	}
    }

    return TRUE;
}


/*
 << LISTVIEW_SetItemText32W >>
 << LISTVIEW_SetSelectionMark >>
*/


static LRESULT
LISTVIEW_SetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

    if (!infoPtr)
	return FALSE;

    /* set text background color */
    TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
    infoPtr->clrTextBk = (COLORREF)lParam;

    return TRUE;
}


static LRESULT
LISTVIEW_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

    if (!infoPtr)
	return FALSE;

    /* set text color */
    TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
    infoPtr->clrText = (COLORREF)lParam;

    return TRUE;
}


/*
 << LISTVIEW_SetTooltips >>
 << LISTVIEW_SetUnicodeFormat >>
 << LISTVIEW_SetWorkAreas >>
*/


static LRESULT
LISTVIEW_SortItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
/*    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */

    FIXME (listview, "empty stub!\n");

    /* fake success */
    return TRUE;
}


/*
 << LISTVIEW_SubItemHitTest >>
 << LISTVIEW_Update >>
*/



static LRESULT
LISTVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    /* 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;

    /* create header */
    infoPtr->hwndHeader =
	CreateWindow32A (WC_HEADER32A, "", dwStyle,
			 0, 0, 0, 0, wndPtr->hwndSelf,
			 (HMENU32)0, wndPtr->hInstance, NULL);

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

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

    infoPtr->hdpaItems = DPA_Create (10);

    return 0;
}


static LRESULT
LISTVIEW_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

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

    /* destroy dpa */
    DPA_Destroy (infoPtr->hdpaItems);

    /* destroy header */
    if (infoPtr->hwndHeader)
	DestroyWindow32 (infoPtr->hwndHeader);

    /* destroy font */
    infoPtr->hFont = (HFONT32)0;
    if (infoPtr->hDefaultFont)
	DeleteObject32 (infoPtr->hDefaultFont);

    

    return 0;
}


static LRESULT
LISTVIEW_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

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

    return TRUE;
}


__inline__ static LRESULT
LISTVIEW_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

    return infoPtr->hFont;
}


/* << LISTVIEW_HScroll >> */
/* << LISTVIEW_KeyDown >> */


static LRESULT
LISTVIEW_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    NMHDR nmh;

    FIXME (listview, "semi stub!\n");

    nmh.hwndFrom = wndPtr->hwndSelf;
    nmh.idFrom   = wndPtr->wIDmenu;
    nmh.code = NM_KILLFOCUS;

    SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
		    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh);

    infoPtr->bFocus = FALSE;

    return 0;
}


static LRESULT
LISTVIEW_LButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    /* 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_DBLCLK;
    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);

    return 0;
}


static LRESULT
LISTVIEW_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    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_CLICK;
    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);

    if (!infoPtr->bFocus)
	SetFocus32 (wndPtr->hwndSelf);

    return 0;
}


static LRESULT
LISTVIEW_NCCreate (WND *wndPtr, 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) {
	ERR (listview, "could not allocate info memory!\n");
	return 0;
    }

    if ((LISTVIEW_INFO*)wndPtr->wExtra[0] != infoPtr) {
	ERR (listview, "pointer assignment error!\n");
	return 0;
    }

    return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCREATE, wParam, lParam);
}


static LRESULT
LISTVIEW_NCDestroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);




    /* free list view info data */
    COMCTL32_Free (infoPtr);

    return 0;
}


static LRESULT
LISTVIEW_Notify (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    LPNMHDR lpnmh = (LPNMHDR)lParam;

    if (lpnmh->hwndFrom == infoPtr->hwndHeader) {

	FIXME (listview, "WM_NOTIFY from header!\n");
    }
    else {

	FIXME (listview, "WM_NOTIFY from unknown source!\n");
    }

    return 0;
}


static LRESULT
LISTVIEW_Paint (WND *wndPtr, WPARAM32 wParam)
{
    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;
}


static LRESULT
LISTVIEW_RButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    /* 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_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);

    return 0;
}


static LRESULT
LISTVIEW_RButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    /* 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);

    return 0;
}


static LRESULT
LISTVIEW_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
    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);

    infoPtr->bFocus = TRUE;

    return 0;
}


static LRESULT
LISTVIEW_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    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 */
    


    if (lParam) {
	/* force redraw */


    }

    return 0;
}




static LRESULT
LISTVIEW_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);

    GetClientRect32 (wndPtr->hwndSelf, &infoPtr->rcList);

    if (wndPtr->dwStyle & LVS_REPORT) {
	HDLAYOUT hl;
	WINDOWPOS32 wp;
	RECT32 rc;

	rc.top = 0;
	rc.left = 0;
	rc.right = LOWORD(lParam);
	rc.bottom = HIWORD(lParam);

	hl.prc = &rc;
	hl.pwpos = &wp;
	SendMessage32A (infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl);

	SetWindowPos32 (infoPtr->hwndHeader, wndPtr->hwndSelf,
			wp.x, wp.y, wp.cx, wp.cy, wp.flags);

	infoPtr->rcList.top += wp.cy;
    }

    return 0;
}


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_CREATEDRAGIMAGE: */

	case LVM_DELETEALLITEMS:
	    return LISTVIEW_DeleteAllItems (wndPtr);

	case LVM_DELETECOLUMN:
	    return LISTVIEW_DeleteColumn (wndPtr, wParam, lParam);

	case LVM_DELETEITEM:
	    return LISTVIEW_DeleteItem (wndPtr, wParam, lParam);

/*	case LVM_EDITLABEL: */
/*	case LVM_ENSUREVISIBLE: */
/*	case LVM_FINDITEM: */

	case LVM_GETBKCOLOR:
	    return LISTVIEW_GetBkColor (wndPtr, wParam, lParam);

/*	case LVM_GETBKIMAGE: */
/*	case LVM_GETCALLBACKMASK: */

	case LVM_GETCOLUMN32A:
	    return LISTVIEW_GetColumn32A (wndPtr, wParam, lParam);

/*	case LVM_GETCOLUMN32W: */
/*	case LVM_GETCOLUMNORDERARRAY: */

	case LVM_GETCOLUMNWIDTH:
	    return LISTVIEW_GetColumnWidth (wndPtr, wParam, lParam);

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

	case LVM_GETHEADER:
	    return LISTVIEW_GetHeader (wndPtr, wParam, lParam);

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

	case LVM_GETIMAGELIST:
	    return LISTVIEW_GetImageList (wndPtr, wParam, lParam);

/*	case LVM_GETISEARCHSTRING: */

	case LVM_GETITEM32A:
	    return LISTVIEW_GetItem32A (wndPtr, wParam, lParam);

/*	case LVM_GETITEM32W: */

	case LVM_GETITEMCOUNT:
	    return LISTVIEW_GetItemCount (wndPtr, wParam, lParam);

	case LVM_GETITEMPOSITION:
	    return LISTVIEW_GetItemPosition (wndPtr, wParam, lParam);

/*	case LVM_GETITEMRECT: */
/*	case LVM_GETITEMSPACING: */
/*	case LVM_GETITEMSTATE: */

	case LVM_GETITEMTEXT32A:
	    return LISTVIEW_GetItemText32A (wndPtr, wParam, lParam);

/*	case LVM_GETITEMTEXT32W: */

	case LVM_GETNEXTITEM:
	    return LISTVIEW_GetNextItem (wndPtr, wParam, lParam);

/*	case LVM_GETNUMBEROFWORKAREAS: */
/*	case LVM_GETORIGIN: */

	case LVM_GETSELECTEDCOUNT:
	    return LISTVIEW_GetSelectedCount (wndPtr, wParam, lParam);

/*	case LVM_GETSELECTIONMARK: */

	case LVM_GETSTRINGWIDTH32A:
	    return LISTVIEW_GetStringWidth32A (wndPtr, wParam, lParam);

/*	case LVM_GETSTRINGWIDTH32W: */
/*	case LVM_GETSUBITEMRECT: */

	case LVM_GETTEXTBKCOLOR:
	    return LISTVIEW_GetTextBkColor (wndPtr, wParam, lParam);

	case LVM_GETTEXTCOLOR:
	    return LISTVIEW_GetTextColor (wndPtr, wParam, lParam);

/*	case LVM_GETTOOLTIPS: */
/*	case LVM_GETTOPINDEX: */
/*	case LVM_GETUNICODEFORMAT: */
/*	case LVM_GETVIEWRECT: */
/*	case LVM_GETWORKAREAS: */

	case LVM_HITTEST:
	    return LISTVIEW_HitTest (wndPtr, wParam, lParam);

	case LVM_INSERTCOLUMN32A:
	    return LISTVIEW_InsertColumn32A (wndPtr, wParam, lParam);

/*	case LVM_INSERTCOLUMN32W: */

	case LVM_INSERTITEM32A:
	    return LISTVIEW_InsertItem32A (wndPtr, wParam, lParam);

/*	case LVM_INSERTITEM32W: */

	case LVM_REDRAWITEMS:
	    return LISTVIEW_RedrawItems (wndPtr, wParam, lParam);

/*	case LVM_SCROLL: */

	case LVM_SETBKCOLOR:
	    return LISTVIEW_SetBkColor (wndPtr, wParam, lParam);

/*	case LVM_SETBKIMAGE: */
/*	case LVM_SETCALLBACKMASK: */

	case LVM_SETCOLUMN32A:
	    return LISTVIEW_SetColumn32A (wndPtr, wParam, lParam);

/*	case LVM_SETCOLUMN32W: */
/*	case LVM_SETCOLUMNORDERARRAY: */
/*	case LVM_SETCOLUMNWIDTH: */
/*	case LVM_SETEXTENDEDLISTVIEWSTYLE: */
/*	case LVM_SETHOTCURSOR: */
/*	case LVM_SETHOTITEM: */
/*	case LVM_SETHOVERTIME: */
/*	case LVM_SETICONSPACING: */
	
	case LVM_SETIMAGELIST:
	    return LISTVIEW_SetImageList (wndPtr, wParam, lParam);

	case LVM_SETITEM32A:
	    return LISTVIEW_SetItem32A (wndPtr, wParam, lParam);

/*	case LVM_SETITEM32W: */
/*	case LVM_SETITEMCOUNT: */

	case LVM_SETITEMPOSITION:
	    return LISTVIEW_SetItemPosition (wndPtr, wParam, lParam);

/*	case LVM_SETITEMPOSITION32: */
/*	case LVM_SETITEMSTATE: */

	case LVM_SETITEMTEXT32A:
	    return LISTVIEW_SetItemText32A (wndPtr, wParam, lParam);

/*	case LVM_SETITEMTEXT32W: */
/*	case LVM_SETSELECTIONMARK: */

	case LVM_SETTEXTBKCOLOR:
	    return LISTVIEW_SetTextBkColor (wndPtr, wParam, lParam);

	case LVM_SETTEXTCOLOR:
	    return LISTVIEW_SetTextColor (wndPtr, wParam, lParam);

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

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

/*	case LVM_SUBITEMHITTEST: */
/*	case LVM_UPDATE: */



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

	case WM_CREATE:
	    return LISTVIEW_Create (wndPtr, wParam, lParam);

	case WM_DESTROY:
	    return LISTVIEW_Destroy (wndPtr, wParam, lParam);

	case WM_ERASEBKGND:
	    return LISTVIEW_EraseBackground (wndPtr, wParam, lParam);

	case WM_GETDLGCODE:
	    return DLGC_WANTTAB | DLGC_WANTARROWS;

	case WM_GETFONT:
	    return LISTVIEW_GetFont (wndPtr, wParam, lParam);

/*	case WM_HSCROLL: */
/*	case WM_KEYDOWN: */

	case WM_KILLFOCUS:
	    return LISTVIEW_KillFocus (wndPtr, wParam, lParam);

	case WM_LBUTTONDBLCLK:
	    return LISTVIEW_LButtonDblClk (wndPtr, wParam, lParam);

	case WM_LBUTTONDOWN:
	    return LISTVIEW_LButtonDown (wndPtr, wParam, lParam);

/*	case WM_MOUSEMOVE: */
/*	    return LISTVIEW_MouseMove (wndPtr, wParam, lParam); */

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

	case WM_NCDESTROY:
	    return LISTVIEW_NCDestroy (wndPtr, wParam, lParam);

	case WM_NOTIFY:
	    return LISTVIEW_Notify (wndPtr, wParam, lParam);

	case WM_PAINT:
	    return LISTVIEW_Paint (wndPtr, wParam);

	case WM_RBUTTONDBLCLK:
	    return LISTVIEW_RButtonDblClk (wndPtr, wParam, lParam);

	case WM_RBUTTONDOWN:
	    return LISTVIEW_RButtonDown (wndPtr, wParam, lParam);

	case WM_SETFOCUS:
	    return LISTVIEW_SetFocus (wndPtr, wParam, lParam);

	case WM_SETFONT:
	    return LISTVIEW_SetFont (wndPtr, wParam, lParam);

/*	case WM_SETREDRAW: */

	case WM_SIZE:
	    return LISTVIEW_Size (wndPtr, wParam, lParam);

/*	case WM_TIMER: */
/*	case WM_VSCROLL: */
/*	case WM_WINDOWPOSCHANGED: */
/*	case WM_WININICHANGE: */

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


VOID
LISTVIEW_Register (VOID)
{
    WNDCLASS32A wndClass;

    if (GlobalFindAtom32A (WC_LISTVIEW32A)) return;

    ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
    wndClass.lpfnWndProc   = (WNDPROC32)LISTVIEW_WindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(LISTVIEW_INFO *);
    wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
    wndClass.hbrBackground = (HBRUSH32)(COLOR_WINDOW + 1);
    wndClass.lpszClassName = WC_LISTVIEW32A;
 
    RegisterClass32A (&wndClass);
}


VOID
LISTVIEW_Unregister (VOID)
{
    if (GlobalFindAtom32A (WC_LISTVIEW32A))
	UnregisterClass32A (WC_LISTVIEW32A, (HINSTANCE32)NULL);
}

