/*
 *	ShellView
 *
 *	Copyright 1998,1999	<juergen.schmied@debitel.net>
 *
 * This is the view visualizing the data provied by the shellfolder.
 * No direct access to data from pidls should be done from here.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * FIXME: The order by part of the background context menu should be
 * buily according to the columns shown.
 *
 * FIXME: Load/Save the view state from/into the stream provied by
 * the ShellBrowser
 *
 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
 *
 * FIXME: ShellView_FillList: consider sort orders
 *
 * FIXME: implement the drag and drop in the old (msg-based) way
 *
 * FIXME: when the ShellView_WndProc gets a WM_NCDESTROY should we do a
 * Release() ???
 */

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

#include <stdlib.h>
#include <string.h>

#include "windef.h"
#include "winerror.h"
#include "winnls.h"
#include "servprov.h"
#include "shlguid.h"
#include "shlobj.h"
#include "undocshell.h"
#include "shresdef.h"
#include "wine/debug.h"

#include "docobj.h"
#include "pidl.h"
#include "shell32_main.h"
#include "shellfolder.h"

WINE_DEFAULT_DEBUG_CHANNEL(shell);

typedef struct
{   BOOL    bIsAscending;
    INT     nHeaderID;
    INT     nLastHeaderID;
}LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;

typedef struct
{	ICOM_VFIELD(IShellView);
	DWORD		ref;
	ICOM_VTABLE(IOleCommandTarget)*	lpvtblOleCommandTarget;
	ICOM_VTABLE(IDropTarget)*	lpvtblDropTarget;
	ICOM_VTABLE(IDropSource)*	lpvtblDropSource;
	ICOM_VTABLE(IViewObject)*	lpvtblViewObject;
	IShellFolder*	pSFParent;
	IShellFolder2*	pSF2Parent;
	IShellBrowser*	pShellBrowser;
	ICommDlgBrowser*	pCommDlgBrowser;
	HWND		hWnd;		/* SHELLDLL_DefView */
	HWND		hWndList;	/* ListView control */
	HWND		hWndParent;
	FOLDERSETTINGS	FolderSettings;
	HMENU		hMenu;
	UINT		uState;
	UINT		cidl;
	LPITEMIDLIST	*apidl;
        LISTVIEW_SORT_INFO ListViewSortInfo;
	HANDLE		hNotify;	/* change notification handle */
	HANDLE		hAccel;
} IShellViewImpl;

static struct ICOM_VTABLE(IShellView) svvt;

static struct ICOM_VTABLE(IOleCommandTarget) ctvt;
#define _IOleCommandTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblOleCommandTarget)))
#define _ICOM_THIS_From_IOleCommandTarget(class, name) class* This = (class*)(((char*)name)-_IOleCommandTarget_Offset);

static struct ICOM_VTABLE(IDropTarget) dtvt;
#define _IDropTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropTarget)))
#define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);

static struct ICOM_VTABLE(IDropSource) dsvt;
#define _IDropSource_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropSource)))
#define _ICOM_THIS_From_IDropSource(class, name) class* This = (class*)(((char*)name)-_IDropSource_Offset);

static struct ICOM_VTABLE(IViewObject) vovt;
#define _IViewObject_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblViewObject)))
#define _ICOM_THIS_From_IViewObject(class, name) class* This = (class*)(((char*)name)-_IViewObject_Offset);

/* ListView Header ID's */
#define LISTVIEW_COLUMN_NAME 0
#define LISTVIEW_COLUMN_SIZE 1
#define LISTVIEW_COLUMN_TYPE 2
#define LISTVIEW_COLUMN_TIME 3
#define LISTVIEW_COLUMN_ATTRIB 4

/*menu items */
#define IDM_VIEW_FILES  (FCIDM_SHVIEWFIRST + 0x500)
#define IDM_VIEW_IDW    (FCIDM_SHVIEWFIRST + 0x501)
#define IDM_MYFILEITEM  (FCIDM_SHVIEWFIRST + 0x502)

#define ID_LISTVIEW     2000

#define SHV_CHANGE_NOTIFY WM_USER + 0x1111

/*windowsx.h */
#define GET_WM_COMMAND_ID(wp, lp)               LOWORD(wp)
#define GET_WM_COMMAND_HWND(wp, lp)             (HWND)(lp)
#define GET_WM_COMMAND_CMD(wp, lp)              HIWORD(wp)

extern void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition,
			UINT wID, UINT fType, LPSTR dwTypeData, UINT fState);

/*
  Items merged into the toolbar and and the filemenu
*/
typedef struct
{  int   idCommand;
   int   iImage;
   int   idButtonString;
   int   idMenuString;
   BYTE  bState;
   BYTE  bStyle;
} MYTOOLINFO, *LPMYTOOLINFO;

MYTOOLINFO Tools[] =
{
{ FCIDM_SHVIEW_BIGICON,    0, 0, IDS_VIEW_LARGE,   TBSTATE_ENABLED, TBSTYLE_BUTTON },
{ FCIDM_SHVIEW_SMALLICON,  0, 0, IDS_VIEW_SMALL,   TBSTATE_ENABLED, TBSTYLE_BUTTON },
{ FCIDM_SHVIEW_LISTVIEW,   0, 0, IDS_VIEW_LIST,    TBSTATE_ENABLED, TBSTYLE_BUTTON },
{ FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, TBSTYLE_BUTTON },
{ -1, 0, 0, 0, 0, 0}
};

typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);

/**********************************************************
 *	IShellView_Constructor
 */
IShellView * IShellView_Constructor( IShellFolder * pFolder)
{	IShellViewImpl * sv;
	sv=(IShellViewImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
	sv->ref=1;
	ICOM_VTBL(sv)=&svvt;
	sv->lpvtblOleCommandTarget=&ctvt;
	sv->lpvtblDropTarget=&dtvt;
	sv->lpvtblDropSource=&dsvt;
	sv->lpvtblViewObject=&vovt;

	sv->pSFParent = pFolder;
	if(pFolder) IShellFolder_AddRef(pFolder);
	IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);

	TRACE("(%p)->(%p)\n",sv, pFolder);
	return (IShellView *) sv;
}

/**********************************************************
 *
 * ##### helperfunctions for communication with ICommDlgBrowser #####
 */
static BOOL IsInCommDlg(IShellViewImpl * This)
{	return(This->pCommDlgBrowser != NULL);
}

static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
{
	HRESULT ret = S_OK;

	if ( IsInCommDlg(This) )
	{
	  TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
	  ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
	  TRACE("--0x%08lx\n", ret);
	}
	return ret;
}

static HRESULT OnDefaultCommand(IShellViewImpl * This)
{
	HRESULT ret = S_FALSE;

	if (IsInCommDlg(This))
	{
	  TRACE("ICommDlgBrowser::OnDefaultCommand\n");
	  ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
	  TRACE("--\n");
	}
	return ret;
}

static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
{
	HRESULT ret = S_FALSE;

	if (IsInCommDlg(This))
	{
	  TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
	  ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
	  TRACE("--\n");
	}
	return ret;
}
/**********************************************************
 *	set the toolbar of the filedialog buttons
 *
 * - activates the buttons from the shellbrowser according to
 *   the view state
 */
static void CheckToolbar(IShellViewImpl * This)
{
	LRESULT result;

	TRACE("\n");

	if (IsInCommDlg(This))
	{
	  IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
		FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
	  IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
		FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
	  IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
		FCIDM_TB_SMALLICON, TRUE, &result);
	  IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
		FCIDM_TB_REPORTVIEW, TRUE, &result);
	}
}

/**********************************************************
 *
 * ##### helperfunctions for initializing the view #####
 */
/**********************************************************
 *	change the style of the listview control
 */
static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
{
	DWORD tmpstyle;

	TRACE("(%p)\n", This);

	tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
	SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
}

/**********************************************************
* ShellView_CreateList()
*
* - creates the list view window
*/
static BOOL ShellView_CreateList (IShellViewImpl * This)
{	DWORD dwStyle;

	TRACE("%p\n",This);

	dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
		  LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;

	switch (This->FolderSettings.ViewMode)
	{
	  case FVM_ICON:	dwStyle |= LVS_ICON;		break;
	  case FVM_DETAILS: 	dwStyle |= LVS_REPORT;		break;
	  case FVM_SMALLICON: 	dwStyle |= LVS_SMALLICON;	break;
	  case FVM_LIST: 	dwStyle |= LVS_LIST;		break;
	  default:		dwStyle |= LVS_LIST;		break;
	}

	if (This->FolderSettings.fFlags & FWF_AUTOARRANGE)	dwStyle |= LVS_AUTOARRANGE;
	/*if (This->FolderSettings.fFlags && FWF_DESKTOP); used from explorer*/
	if (This->FolderSettings.fFlags & FWF_SINGLESEL)	dwStyle |= LVS_SINGLESEL;

	This->hWndList=CreateWindowExA( WS_EX_CLIENTEDGE,
					WC_LISTVIEWA,
					NULL,
					dwStyle,
					0,0,0,0,
					This->hWnd,
					(HMENU)ID_LISTVIEW,
					shell32_hInstance,
					NULL);

	if(!This->hWndList)
	  return FALSE;

        This->ListViewSortInfo.bIsAscending = TRUE;
        This->ListViewSortInfo.nHeaderID = -1;
        This->ListViewSortInfo.nLastHeaderID = -1;

        /*  UpdateShellSettings(); */
	return TRUE;
}

/**********************************************************
* ShellView_InitList()
*
* - adds all needed columns to the shellview
*/
static BOOL ShellView_InitList(IShellViewImpl * This)
{
	LVCOLUMNA	lvColumn;
	SHELLDETAILS	sd;
	int	i;
	char	szTemp[50];

	TRACE("%p\n",This);

	ListView_DeleteAllItems(This->hWndList);

	lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
	lvColumn.pszText = szTemp;

	if (This->pSF2Parent)
	{
	  for (i=0; 1; i++)
	  {
	    if (!SUCCEEDED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
	      break;
	    lvColumn.fmt = sd.fmt;
	    lvColumn.cx = sd.cxChar*8; /* chars->pixel */
	    StrRetToStrNA( szTemp, 50, &sd.str, NULL);
	    ListView_InsertColumnA(This->hWndList, i, &lvColumn);
	  }
	}
	else
	{
	  FIXME("no SF2\n");
	}

	ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
	ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);

	return TRUE;
}
/**********************************************************
* ShellView_CompareItems()
*
* NOTES
*  internal, CALLBACK for DSA_Sort
*/
static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
{
	int ret;
	TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);

	if(!lpData) return 0;

	ret =  (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
	TRACE("ret=%i\n",ret);
	return ret;
}

/*************************************************************************
 * ShellView_ListViewCompareItems
 *
 * Compare Function for the Listview (FileOpen Dialog)
 *
 * PARAMS
 *     lParam1       [I] the first ItemIdList to compare with
 *     lParam2       [I] the second ItemIdList to compare with
 *     lpData        [I] The column ID for the header Ctrl to process
 *
 * RETURNS
 *     A negative value if the first item should precede the second,
 *     a positive value if the first item should follow the second,
 *     or zero if the two items are equivalent
 *
 * NOTES
 *	FIXME: function does what ShellView_CompareItems is supposed to do.
 *	unify it and figure out how to use the undocumented first parameter
 *	of IShellFolder_CompareIDs to do the job this function does and
 *	move this code to IShellFolder.
 *	make LISTVIEW_SORT_INFO obsolete
 *	the way this function works is only usable if we had only
 *	filesystemfolders  (25/10/99 jsch)
 */
static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
{
    INT nDiff=0;
    FILETIME fd1, fd2;
    char strName1[MAX_PATH], strName2[MAX_PATH];
    BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
    LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
    LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
    LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;


    bIsFolder1 = _ILIsFolder(pItemIdList1);
    bIsFolder2 = _ILIsFolder(pItemIdList2);
    bIsBothFolder = bIsFolder1 && bIsFolder2;

    /* When sorting between a File and a Folder, the Folder gets sorted first */
    if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
    {
        nDiff = bIsFolder1 ? -1 : 1;
    }
    else
    {
        /* Sort by Time: Folders or Files can be sorted */

        if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
        {
            _ILGetFileDateTime(pItemIdList1, &fd1);
            _ILGetFileDateTime(pItemIdList2, &fd2);
            nDiff = CompareFileTime(&fd2, &fd1);
        }
        /* Sort by Attribute: Folder or Files can be sorted */
        else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
        {
            _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
            _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
            nDiff = strcasecmp(strName1, strName2);
        }
        /* Sort by FileName: Folder or Files can be sorted */
        else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
        {
            /* Sort by Text */
            _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
            _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
            nDiff = strcasecmp(strName1, strName2);
        }
        /* Sort by File Size, Only valid for Files */
        else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
        {
            nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
        }
        /* Sort by File Type, Only valid for Files */
        else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
        {
            /* Sort by Type */
            _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
            _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
            nDiff = strcasecmp(strName1, strName2);
        }
    }
    /*  If the Date, FileSize, FileType, Attrib was the same, sort by FileName */

    if(nDiff == 0)
    {
        _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
        _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
        nDiff = strcasecmp(strName1, strName2);
    }

    if(!pSortInfo->bIsAscending)
    {
        nDiff = -nDiff;
    }

    return nDiff;

}

/**********************************************************
*  LV_FindItemByPidl()
*/
static int LV_FindItemByPidl(
	IShellViewImpl * This,
	LPCITEMIDLIST pidl)
{
	LVITEMA lvItem;
	ZeroMemory(&lvItem, sizeof(LVITEMA));
	lvItem.mask = LVIF_PARAM;
	for(lvItem.iItem = 0; ListView_GetItemA(This->hWndList, &lvItem); lvItem.iItem++)
	{
	  LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
	  HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
	  if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
	  {
	    return lvItem.iItem;
	  }
  	}
	return -1;
}

/**********************************************************
* LV_AddItem()
*/
static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
{
	LVITEMA	lvItem;

	TRACE("(%p)(pidl=%p)\n", This, pidl);

	ZeroMemory(&lvItem, sizeof(lvItem));	/* create the listview item*/
	lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;	/*set the mask*/
	lvItem.iItem = ListView_GetItemCount(This->hWndList);	/*add the item to the end of the list*/
	lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl));				/*set the item's data*/
	lvItem.pszText = LPSTR_TEXTCALLBACKA;			/*get text on a callback basis*/
	lvItem.iImage = I_IMAGECALLBACK;			/*get the image on a callback basis*/
	return (-1==ListView_InsertItemA(This->hWndList, &lvItem))? FALSE: TRUE;
}

/**********************************************************
* LV_DeleteItem()
*/
static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
{
	int nIndex;

	TRACE("(%p)(pidl=%p)\n", This, pidl);

	nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
	return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
}

/**********************************************************
* LV_RenameItem()
*/
static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
{
	int nItem;
	LVITEMA lvItem;

	TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);

	nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
	if ( -1 != nItem )
	{
	  ZeroMemory(&lvItem, sizeof(lvItem));	/* create the listview item*/
	  lvItem.mask = LVIF_PARAM;		/* only the pidl */
	  lvItem.iItem = nItem;
	  ListView_GetItemA(This->hWndList, &lvItem);

	  SHFree((LPITEMIDLIST)lvItem.lParam);
	  lvItem.mask = LVIF_PARAM;
	  lvItem.iItem = nItem;
	  lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew));	/* set the item's data */
	  ListView_SetItemA(This->hWndList, &lvItem);
	  ListView_Update(This->hWndList, nItem);
	  return TRUE;					/* FIXME: better handling */
	}
	return FALSE;
}
/**********************************************************
* ShellView_FillList()
*
* - gets the objectlist from the shellfolder
* - sorts the list
* - fills the list into the view
*/

static HRESULT ShellView_FillList(IShellViewImpl * This)
{
	LPENUMIDLIST	pEnumIDList;
	LPITEMIDLIST	pidl;
	DWORD		dwFetched;
	INT		i;
	HRESULT		hRes;
	HDPA		hdpa;

	TRACE("%p\n",This);

	/* get the itemlist from the shfolder*/
	hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
	if (hRes != S_OK)
	{
	  if (hRes==S_FALSE)
	    return(NOERROR);
	  return(hRes);
	}

	/* create a pointer array */
	hdpa = DPA_Create(16);
	if (!hdpa)
	{
	  return(E_OUTOFMEMORY);
	}

	/* copy the items into the array*/
	while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
	{
	  if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
	  {
	    SHFree(pidl);
	  }
	}

	/* sort the array */
	DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);

	/*turn the listview's redrawing off*/
	SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);

	for (i=0; i < DPA_GetPtrCount(hdpa); ++i) 	/* DPA_GetPtrCount is a macro*/
	{
	  pidl = (LPITEMIDLIST)DPA_GetPtr(hdpa, i);

	  /* in a commdlg This works as a filemask*/
	  if ( IncludeObject(This, pidl)==S_OK )
	    LV_AddItem(This, pidl);
	  SHFree(pidl);
	}

	/*turn the listview's redrawing back on and force it to draw*/
	SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);

	IEnumIDList_Release(pEnumIDList); /* destroy the list*/
	DPA_Destroy(hdpa);

	return S_OK;
}

/**********************************************************
*  ShellView_OnCreate()
*/
static LRESULT ShellView_OnCreate(IShellViewImpl * This)
{
	IDropTarget* pdt;
	NOTIFYREGISTER ntreg;
	IPersistFolder2 * ppf2 = NULL;

	TRACE("%p\n",This);

	if(ShellView_CreateList(This))
	{
	  if(ShellView_InitList(This))
	  {
	    ShellView_FillList(This);
	  }
	}

	if(GetShellOle())
	{
	  if (SUCCEEDED(IShellFolder_CreateViewObject(This->pSFParent, This->hWnd, &IID_IDropTarget, (LPVOID*)&pdt)))
	  {
	    pRegisterDragDrop(This->hWnd, pdt);
	    IDropTarget_Release(pdt);
	  }
	}

	/* register for receiving notifications */
	IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
	if (ppf2)
	{
	  IPersistFolder2_GetCurFolder(ppf2, &ntreg.pidlPath);
	  ntreg.bWatchSubtree = FALSE;
	  This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
	  SHFree(ntreg.pidlPath);
	  IPersistFolder2_Release(ppf2);
	}

	This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");

	return S_OK;
}

/**********************************************************
 *	#### Handling of the menus ####
 */

/**********************************************************
* ShellView_BuildFileMenu()
*/
static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
{	CHAR	szText[MAX_PATH];
	MENUITEMINFOA	mii;
	int	nTools,i;
	HMENU	hSubMenu;

	TRACE("(%p)\n",This);

	hSubMenu = CreatePopupMenu();
	if(hSubMenu)
	{ /*get the number of items in our global array*/
	  for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}

	  /*add the menu items*/
	  for(i = 0; i < nTools; i++)
	  {
	    LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);

	    ZeroMemory(&mii, sizeof(mii));
	    mii.cbSize = sizeof(mii);
	    mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;

	    if(TBSTYLE_SEP != Tools[i].bStyle) /* no seperator*/
	    {
	      mii.fType = MFT_STRING;
	      mii.fState = MFS_ENABLED;
	      mii.dwTypeData = szText;
	      mii.wID = Tools[i].idCommand;
	    }
	    else
	    {
	      mii.fType = MFT_SEPARATOR;
	    }
	    /* tack This item onto the end of the menu */
	    InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
	  }
	}
	TRACE("-- return (menu=%p)\n",hSubMenu);
	return hSubMenu;
}
/**********************************************************
* ShellView_MergeFileMenu()
*/
static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
{	TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);

	if(hSubMenu)
	{ /*insert This item at the beginning of the menu */
	  _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
	  _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);

	}
	TRACE("--\n");
}

/**********************************************************
* ShellView_MergeViewMenu()
*/

static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
{	MENUITEMINFOA	mii;

	TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);

	if(hSubMenu)
	{ /*add a separator at the correct position in the menu*/
	  _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);

	  ZeroMemory(&mii, sizeof(mii));
	  mii.cbSize = sizeof(mii);
	  mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
	  mii.fType = MFT_STRING;
	  mii.dwTypeData = "View";
	  mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
	  InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
	}
}

/**********************************************************
*   ShellView_GetSelections()
*
* - fills the this->apidl list with the selected objects
*
* RETURNS
*  number of selected items
*/
static UINT ShellView_GetSelections(IShellViewImpl * This)
{
	LVITEMA	lvItem;
	UINT	i = 0;

	if (This->apidl)
	{
	  SHFree(This->apidl);
	}

	This->cidl = ListView_GetSelectedCount(This->hWndList);
	This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));

	TRACE("selected=%i\n", This->cidl);

	if(This->apidl)
	{
	  TRACE("-- Items selected =%u\n", This->cidl);

	  ZeroMemory(&lvItem, sizeof(lvItem));
	  lvItem.mask = LVIF_STATE | LVIF_PARAM;
	  lvItem.stateMask = LVIS_SELECTED;

	  while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
	  {
	    if(lvItem.state & LVIS_SELECTED)
	    {
	      This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
	      i++;
	      TRACE("-- selected Item found\n");
	    }
	    lvItem.iItem++;
	  }
	}
	return This->cidl;

}
/**********************************************************
 *	ShellView_DoContextMenu()
 */
static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
{	UINT	uCommand;
	DWORD	wFlags;
	HMENU	hMenu;
	BOOL	fExplore = FALSE;
	HWND	hwndTree = 0;
	LPCONTEXTMENU	pContextMenu = NULL;
	IContextMenu *	pCM = NULL;
	CMINVOKECOMMANDINFO	cmi;

	TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);

	/* look, what's selected and create a context menu object of it*/
	if( ShellView_GetSelections(This) )
	{
	  IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, This->apidl,
					(REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);

	  if(pContextMenu)
	  {
	    TRACE("-- pContextMenu\n");
	    hMenu = CreatePopupMenu();

	    if( hMenu )
	    {
	      /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
	      if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
	      {
	        TRACE("-- explore mode\n");
	        fExplore = TRUE;
	      }

	      /* build the flags depending on what we can do with the selected item */
	      wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);

	      /* let the ContextMenu merge its items in */
	      if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
	      {
		if( bDefault )
		{
		  TRACE("-- get menu default command\n");
		  uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
		}
		else
		{
		  TRACE("-- track popup\n");
		  uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
		}

		if(uCommand > 0)
		{
		  TRACE("-- uCommand=%u\n", uCommand);
		  if (IsInCommDlg(This) && ((uCommand==FCIDM_SHVIEW_EXPLORE) || (uCommand==FCIDM_SHVIEW_OPEN)))
		  {
		    TRACE("-- dlg: OnDefaultCommand\n");
		    OnDefaultCommand(This);
		  }
		  else
		  {
		    TRACE("-- explore -- invoke command\n");
		    ZeroMemory(&cmi, sizeof(cmi));
		    cmi.cbSize = sizeof(cmi);
		    cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
		    cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
		    IContextMenu_InvokeCommand(pContextMenu, &cmi);
		  }
		}
		DestroyMenu(hMenu);
	      }
	    }
	    if (pContextMenu)
	      IContextMenu_Release(pContextMenu);
	  }
	}
	else	/* background context menu */
	{
	  hMenu = CreatePopupMenu();

	  pCM = ISvBgCm_Constructor(This->pSFParent);
	  IContextMenu_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);

	  uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
	  DestroyMenu(hMenu);

	  TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);

	  ZeroMemory(&cmi, sizeof(cmi));
	  cmi.cbSize = sizeof(cmi);
	  cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
	  cmi.hwnd = This->hWndParent;
	  IContextMenu_InvokeCommand(pCM, &cmi);

	  IContextMenu_Release(pCM);
	}
}

/**********************************************************
 *	##### message handling #####
 */

/**********************************************************
*  ShellView_OnSize()
*/
static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
{
	TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);

	/*resize the ListView to fit our window*/
	if(This->hWndList)
	{
	  MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
	}

	return S_OK;
}
/**********************************************************
* ShellView_OnDeactivate()
*
* NOTES
*  internal
*/
static void ShellView_OnDeactivate(IShellViewImpl * This)
{
	TRACE("%p\n",This);

	if(This->uState != SVUIA_DEACTIVATE)
	{
	  if(This->hMenu)
	  {
	    IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
	    IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
	    DestroyMenu(This->hMenu);
	    This->hMenu = 0;
	  }

	  This->uState = SVUIA_DEACTIVATE;
	}
}

/**********************************************************
* ShellView_OnActivate()
*/
static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
{	OLEMENUGROUPWIDTHS   omw = { {0, 0, 0, 0, 0, 0} };
	MENUITEMINFOA         mii;
	CHAR                szText[MAX_PATH];

	TRACE("%p uState=%x\n",This,uState);

	/*don't do anything if the state isn't really changing */
	if(This->uState == uState)
	{
	  return S_OK;
	}

	ShellView_OnDeactivate(This);

	/*only do This if we are active */
	if(uState != SVUIA_DEACTIVATE)
	{
	  /*merge the menus */
	  This->hMenu = CreateMenu();

	  if(This->hMenu)
	  {
	    IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
	    TRACE("-- after fnInsertMenusSB\n");

	    /*build the top level menu get the menu item's text*/
	    strcpy(szText,"dummy 31");

	    ZeroMemory(&mii, sizeof(mii));
	    mii.cbSize = sizeof(mii);
	    mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
	    mii.fType = MFT_STRING;
	    mii.fState = MFS_ENABLED;
	    mii.dwTypeData = szText;
	    mii.hSubMenu = ShellView_BuildFileMenu(This);

	    /*insert our menu into the menu bar*/
	    if(mii.hSubMenu)
	    {
	      InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
	    }

	    /*get the view menu so we can merge with it*/
	    ZeroMemory(&mii, sizeof(mii));
	    mii.cbSize = sizeof(mii);
	    mii.fMask = MIIM_SUBMENU;

	    if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
	    {
	      ShellView_MergeViewMenu(This, mii.hSubMenu);
	    }

	    /*add the items that should only be added if we have the focus*/
	    if(SVUIA_ACTIVATE_FOCUS == uState)
	    {
	      /*get the file menu so we can merge with it */
	      ZeroMemory(&mii, sizeof(mii));
	      mii.cbSize = sizeof(mii);
	      mii.fMask = MIIM_SUBMENU;

	      if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
	      {
	        ShellView_MergeFileMenu(This, mii.hSubMenu);
	      }
	    }
	    TRACE("-- before fnSetMenuSB\n");
	    IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
	  }
	}
	This->uState = uState;
	TRACE("--\n");
	return S_OK;
}

/**********************************************************
*  ShellView_OnSetFocus()
*
*/
static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
{
	TRACE("%p\n",This);

	/* Tell the browser one of our windows has received the focus. This
	should always be done before merging menus (OnActivate merges the
	menus) if one of our windows has the focus.*/

	IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
	ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);

	/* Set the focus to the listview */
	SetFocus(This->hWndList);

	/* Notify the ICommDlgBrowser interface */
	OnStateChange(This,CDBOSC_SETFOCUS);

	return 0;
}

/**********************************************************
* ShellView_OnKillFocus()
*/
static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
{
	TRACE("(%p) stub\n",This);

	ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
	/* Notify the ICommDlgBrowser */
	OnStateChange(This,CDBOSC_KILLFOCUS);

	return 0;
}

/**********************************************************
* ShellView_OnCommand()
*
* NOTES
*	the CmdID's are the ones from the context menu
*/
static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
{
	TRACE("(%p)->(0x%08lx 0x%08lx %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);

	switch(dwCmdID)
	{
	  case FCIDM_SHVIEW_SMALLICON:
	    This->FolderSettings.ViewMode = FVM_SMALLICON;
	    SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
	    CheckToolbar(This);
	    break;

	  case FCIDM_SHVIEW_BIGICON:
	    This->FolderSettings.ViewMode = FVM_ICON;
	    SetStyle (This, LVS_ICON, LVS_TYPEMASK);
	    CheckToolbar(This);
	    break;

	  case FCIDM_SHVIEW_LISTVIEW:
	    This->FolderSettings.ViewMode = FVM_LIST;
	    SetStyle (This, LVS_LIST, LVS_TYPEMASK);
	    CheckToolbar(This);
	    break;

	  case FCIDM_SHVIEW_REPORTVIEW:
	    This->FolderSettings.ViewMode = FVM_DETAILS;
	    SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
	    CheckToolbar(This);
	    break;

	  /* the menu-ID's for sorting are 0x30... see shrec.rc */
	  case 0x30:
	  case 0x31:
	  case 0x32:
	  case 0x33:
	    This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
	    This->ListViewSortInfo.bIsAscending = TRUE;
	    This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
	    ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
	    break;

	  default:
	    TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
	}
	return 0;
}

/**********************************************************
* ShellView_OnNotify()
*/

static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
{	LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
	NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
	LPITEMIDLIST pidl;

	TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);

	switch(lpnmh->code)
	{
	  case NM_SETFOCUS:
	    TRACE("-- NM_SETFOCUS %p\n",This);
	    ShellView_OnSetFocus(This);
	    break;

	  case NM_KILLFOCUS:
	    TRACE("-- NM_KILLFOCUS %p\n",This);
	    ShellView_OnDeactivate(This);
	    /* Notify the ICommDlgBrowser interface */
	    OnStateChange(This,CDBOSC_KILLFOCUS);
	    break;

	  case HDN_ENDTRACKA:
	    TRACE("-- HDN_ENDTRACKA %p\n",This);
	    /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
	    nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
	    break;

	  case LVN_DELETEITEM:
	    TRACE("-- LVN_DELETEITEM %p\n",This);
	    SHFree((LPITEMIDLIST)lpnmlv->lParam);     /*delete the pidl because we made a copy of it*/
	    break;

	  case LVN_ITEMACTIVATE:
	    TRACE("-- LVN_ITEMACTIVATE %p\n",This);
	    OnStateChange(This, CDBOSC_SELCHANGE);  /* the browser will get the IDataObject now */
	    ShellView_DoContextMenu(This, 0, 0, TRUE);
	    break;

	  case LVN_COLUMNCLICK:
	    This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
	    if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
	    {
	      This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
	    }
	    else
	    {
	      This->ListViewSortInfo.bIsAscending = TRUE;
	    }
	    This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;

	    ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
	    break;

	  case LVN_GETDISPINFOA:
          case LVN_GETDISPINFOW:
	    TRACE("-- LVN_GETDISPINFO %p\n",This);
	    pidl = (LPITEMIDLIST)lpdi->item.lParam;

	    if(lpdi->item.mask & LVIF_TEXT)	/* text requested */
	    {
	      if (This->pSF2Parent)
	      {
	        SHELLDETAILS sd;
	        IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
                if (lpnmh->code == LVN_GETDISPINFOA)
                {
                    StrRetToStrNA( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
                    TRACE("-- text=%s\n",lpdi->item.pszText);
                }
                else /* LVN_GETDISPINFOW */
                {
                    StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
                    TRACE("-- text=%s\n",debugstr_w((WCHAR*)(lpdi->item.pszText)));
                }
	      }
	      else
	      {
	        FIXME("no SF2\n");
	      }
	    }
	    if(lpdi->item.mask & LVIF_IMAGE)	/* image requested */
	    {
	      lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
	    }
	    break;

	  case LVN_ITEMCHANGED:
	    TRACE("-- LVN_ITEMCHANGED %p\n",This);
	    OnStateChange(This, CDBOSC_SELCHANGE);  /* the browser will get the IDataObject now */
	    break;

	  case LVN_BEGINDRAG:
	  case LVN_BEGINRDRAG:
	    TRACE("-- LVN_BEGINDRAG\n");

	    if (ShellView_GetSelections(This))
	    {
	      IDataObject * pda;
	      DWORD dwAttributes = SFGAO_CANLINK;
	      DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;

	      if(GetShellOle())
	      {
	        if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
	        {
	          IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource);	/* own DropSource interface */

	  	  if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, This->apidl, &dwAttributes)))
		  {
		    if (dwAttributes & SFGAO_CANLINK)
		    {
		      dwEffect |= DROPEFFECT_LINK;
		    }
		  }

	          if (pds)
	          {
	            DWORD dwEffect;
		    pDoDragDrop(pda, pds, dwEffect, &dwEffect);
		  }
	          IDataObject_Release(pda);
	        }
	      }
	    }
	    break;

	  case LVN_BEGINLABELEDITA:
	    {
	      DWORD dwAttr = SFGAO_CANRENAME;
	      pidl = (LPITEMIDLIST)lpdi->item.lParam;

	      TRACE("-- LVN_BEGINLABELEDITA %p\n",This);

	      IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &dwAttr);
	      if (SFGAO_CANRENAME & dwAttr)
	      {
	        return FALSE;
	      }
	      return TRUE;
	    }
	    break;

	  case LVN_ENDLABELEDITA:
	    {
	      TRACE("-- LVN_ENDLABELEDITA %p\n",This);
	      if (lpdi->item.pszText)
	      {
	        HRESULT hr;
		WCHAR wszNewName[MAX_PATH];
		LVITEMA lvItem;

		ZeroMemory(&lvItem, sizeof(LVITEMA));
		lvItem.iItem = lpdi->item.iItem;
		lvItem.mask = LVIF_PARAM;
		ListView_GetItemA(This->hWndList, &lvItem);

		pidl = (LPITEMIDLIST)lpdi->item.lParam;
                if (!MultiByteToWideChar( CP_ACP, 0, lpdi->item.pszText, -1, wszNewName, MAX_PATH ))
                    wszNewName[MAX_PATH-1] = 0;
	        hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, wszNewName, SHGDN_INFOLDER, &pidl);

		if(SUCCEEDED(hr) && pidl)
		{
	          lvItem.mask = LVIF_PARAM;
		  lvItem.lParam = (LPARAM)pidl;
		  ListView_SetItemA(This->hWndList, &lvItem);
		  return TRUE;
		}
	      }
	      return FALSE;
	    }
	    break;

	  case LVN_KEYDOWN:
	    {
	    /*  MSG msg;
	      msg.hwnd = This->hWnd;
	      msg.message = WM_KEYDOWN;
	      msg.wParam = plvKeyDown->wVKey;
	      msg.lParam = 0;
	      msg.time = 0;
	      msg.pt = 0;*/

	      LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;

              /* initiate a rename of the selected file or directory */
              if(plvKeyDown->wVKey == VK_F2)
              {
                /* see how many files are selected */
                int i = ListView_GetSelectedCount(This->hWndList);

                /* get selected item */
                if(i == 1)
                {
                  /* get selected item */
                  i = ListView_GetNextItem(This->hWndList, -1,
			LVNI_SELECTED);

                  ListView_EnsureVisible(This->hWndList, i, 0);
                  ListView_EditLabelA(This->hWndList, i);
                }
              }
#if 0
	      TranslateAccelerator(This->hWnd, This->hAccel, &msg)
#endif
	      else if(plvKeyDown->wVKey == VK_DELETE)
              {
		UINT i;
		int item_index;
		LVITEMA item;
		LPITEMIDLIST* pItems;
		ISFHelper *psfhlp;

		IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
		 	(LPVOID*)&psfhlp);

		if(!(i = ListView_GetSelectedCount(This->hWndList)))
		  break;

		/* allocate memory for the pidl array */
		pItems = HeapAlloc(GetProcessHeap(), 0,
			sizeof(LPITEMIDLIST) * i);

		/* retrieve all selected items */
		i = 0;
		item_index = -1;
		while(ListView_GetSelectedCount(This->hWndList) > i)
		{
		  /* get selected item */
		  item_index = ListView_GetNextItem(This->hWndList,
			item_index, LVNI_SELECTED);
		  item.iItem = item_index;
		  ListView_GetItemA(This->hWndList, &item);

		  /* get item pidl */
		  pItems[i] = (LPITEMIDLIST)item.lParam;

		  i++;
		}

		/* perform the item deletion */
		ISFHelper_DeleteItems(psfhlp, i, pItems);

		/* free pidl array memory */
		HeapFree(GetProcessHeap(), 0, pItems);
              }
              else
		FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
	    }
	    break;

	  default:
	    TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
	    break;
	}
	return 0;
}

/**********************************************************
* ShellView_OnChange()
*/

static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
{

	TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
	switch(wEventId)
	{
	  case SHCNE_MKDIR:
	  case SHCNE_CREATE:
	    LV_AddItem(This, Pidls[0]);
	    break;
	  case SHCNE_RMDIR:
	  case SHCNE_DELETE:
	    LV_DeleteItem(This, Pidls[0]);
	    break;
	  case SHCNE_RENAMEFOLDER:
	  case SHCNE_RENAMEITEM:
	    LV_RenameItem(This, Pidls[0], Pidls[1]);
	    break;
	  case SHCNE_UPDATEITEM:
	    break;
	}
	return TRUE;
}
/**********************************************************
*  ShellView_WndProc
*/

static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
	IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongA(hWnd, GWL_USERDATA);
	LPCREATESTRUCTA lpcs;

	TRACE("(hwnd=%p msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);

	switch (uMessage)
	{
	  case WM_NCCREATE:
	    lpcs = (LPCREATESTRUCTA)lParam;
	    pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
	    SetWindowLongA(hWnd, GWL_USERDATA, (LONG)pThis);
	    pThis->hWnd = hWnd;        /*set the window handle*/
	    break;

	  case WM_SIZE:		return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
	  case WM_SETFOCUS:	return ShellView_OnSetFocus(pThis);
	  case WM_KILLFOCUS:	return ShellView_OnKillFocus(pThis);
	  case WM_CREATE:	return ShellView_OnCreate(pThis);
	  case WM_ACTIVATE:	return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
	  case WM_NOTIFY:	return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
	  case WM_COMMAND:      return ShellView_OnCommand(pThis,
					GET_WM_COMMAND_ID(wParam, lParam),
					GET_WM_COMMAND_CMD(wParam, lParam),
					GET_WM_COMMAND_HWND(wParam, lParam));
	  case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);

	  case WM_CONTEXTMENU:  ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
	                        return 0;

	  case WM_SHOWWINDOW:	UpdateWindow(pThis->hWndList);
				break;

	  case WM_GETDLGCODE:   return SendMessageA(pThis->hWndList,uMessage,0,0);

	  case WM_DESTROY:	if(GetShellOle())
				{
	  			  pRevokeDragDrop(pThis->hWnd);
				}
				SHChangeNotifyDeregister(pThis->hNotify);
	                        break;
	}

	return DefWindowProcA (hWnd, uMessage, wParam, lParam);
}
/**********************************************************
*
*
*  The INTERFACE of the IShellView object
*
*
**********************************************************
*  IShellView_QueryInterface
*/
static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
{
	ICOM_THIS(IShellViewImpl, iface);

	TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);

	*ppvObj = NULL;

	if(IsEqualIID(riid, &IID_IUnknown))
	{
	  *ppvObj = This;
	}
	else if(IsEqualIID(riid, &IID_IShellView))
	{
	  *ppvObj = (IShellView*)This;
	}
	else if(IsEqualIID(riid, &IID_IOleCommandTarget))
	{
	  *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
	}
	else if(IsEqualIID(riid, &IID_IDropTarget))
	{
	  *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
	}
	else if(IsEqualIID(riid, &IID_IDropSource))
	{
	  *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
	}
	else if(IsEqualIID(riid, &IID_IViewObject))
	{
	  *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
	}

	if(*ppvObj)
	{
	  IUnknown_AddRef( (IUnknown*)*ppvObj );
	  TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
	  return S_OK;
	}
	TRACE("-- Interface: E_NOINTERFACE\n");
	return E_NOINTERFACE;
}

/**********************************************************
*  IShellView_AddRef
*/
static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
{
	ICOM_THIS(IShellViewImpl, iface);

	TRACE("(%p)->(count=%lu)\n",This,This->ref);

	return ++(This->ref);
}
/**********************************************************
*  IShellView_Release
*/
static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
{
	ICOM_THIS(IShellViewImpl, iface);

	TRACE("(%p)->()\n",This);

	if (!--(This->ref))
	{
	  TRACE(" destroying IShellView(%p)\n",This);

	  if(This->pSFParent)
	    IShellFolder_Release(This->pSFParent);

	  if(This->pSF2Parent)
	    IShellFolder2_Release(This->pSF2Parent);

	  if (This->apidl)
	    SHFree(This->apidl);

	  HeapFree(GetProcessHeap(),0,This);
	  return 0;
	}
	return This->ref;
}

/**********************************************************
*  ShellView_GetWindow
*/
static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
{
	ICOM_THIS(IShellViewImpl, iface);

	TRACE("(%p)\n",This);

	*phWnd = This->hWnd;

	return S_OK;
}

static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
{
	ICOM_THIS(IShellViewImpl, iface);

	FIXME("(%p) stub\n",This);

	return E_NOTIMPL;
}

/**********************************************************
* IShellView_TranslateAccelerator
*
* FIXME:
*  use the accel functions
*/
static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
{
#if 0
	ICOM_THIS(IShellViewImpl, iface);

	FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
#endif

	if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
	{
	  TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
	}
	return S_FALSE; /* not handled */
}

static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
{
	ICOM_THIS(IShellViewImpl, iface);

	FIXME("(%p) stub\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
{
	ICOM_THIS(IShellViewImpl, iface);

/*
	CHAR	szName[MAX_PATH];
*/
	LRESULT	lResult;
	int	nPartArray[1] = {-1};

	TRACE("(%p)->(state=%x) stub\n",This, uState);

	/*don't do anything if the state isn't really changing*/
	if(This->uState == uState)
	{
	  return S_OK;
	}

	/*OnActivate handles the menu merging and internal state*/
	ShellView_OnActivate(This, uState);

	/*only do This if we are active*/
	if(uState != SVUIA_DEACTIVATE)
	{

/*
	  GetFolderPath is not a method of IShellFolder
	  IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
*/
	  /* set the number of parts */
	  IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
	  						(LPARAM)nPartArray, &lResult);

	  /* set the text for the parts */
/*
	  IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
							0, (LPARAM)szName, &lResult);
*/
	}

	return S_OK;
}

static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
{
	ICOM_THIS(IShellViewImpl, iface);

	TRACE("(%p)\n",This);

	ListView_DeleteAllItems(This->hWndList);
	ShellView_FillList(This);

	return S_OK;
}

static HRESULT WINAPI IShellView_fnCreateViewWindow(
	IShellView * iface,
	IShellView *lpPrevView,
	LPCFOLDERSETTINGS lpfs,
	IShellBrowser * psb,
	RECT * prcView,
	HWND  *phWnd)
{
	ICOM_THIS(IShellViewImpl, iface);

	WNDCLASSA wc;
	*phWnd = 0;


	TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
	TRACE("-- vmode=%x flags=%x left=%li top=%li right=%li bottom=%li\n",lpfs->ViewMode, lpfs->fFlags ,prcView->left,prcView->top, prcView->right, prcView->bottom);

	/*set up the member variables*/
	This->pShellBrowser = psb;
	This->FolderSettings = *lpfs;

	/*get our parent window*/
	IShellBrowser_AddRef(This->pShellBrowser);
	IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));

	/* try to get the ICommDlgBrowserInterface, adds a reference !!! */
	This->pCommDlgBrowser=NULL;
	if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
			(REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
	{
	  TRACE("-- CommDlgBrowser\n");
	}

	/*if our window class has not been registered, then do so*/
	if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
	{
	  ZeroMemory(&wc, sizeof(wc));
	  wc.style		= CS_HREDRAW | CS_VREDRAW;
	  wc.lpfnWndProc	= (WNDPROC) ShellView_WndProc;
	  wc.cbClsExtra		= 0;
	  wc.cbWndExtra		= 0;
	  wc.hInstance		= shell32_hInstance;
	  wc.hIcon		= 0;
	  wc.hCursor		= LoadCursorA (0, IDC_ARROWA);
	  wc.hbrBackground	= (HBRUSH) (COLOR_WINDOW + 1);
	  wc.lpszMenuName	= NULL;
	  wc.lpszClassName	= SV_CLASS_NAME;

	  if(!RegisterClassA(&wc))
	    return E_FAIL;
	}

	*phWnd = CreateWindowExA(0,
				SV_CLASS_NAME,
				NULL,
				WS_CHILD | WS_VISIBLE | WS_TABSTOP,
				prcView->left,
				prcView->top,
				prcView->right - prcView->left,
				prcView->bottom - prcView->top,
				This->hWndParent,
				0,
				shell32_hInstance,
				(LPVOID)This);

	CheckToolbar(This);

	if(!*phWnd) return E_FAIL;

	return S_OK;
}

static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
{
	ICOM_THIS(IShellViewImpl, iface);

	TRACE("(%p)\n",This);

	/*Make absolutely sure all our UI is cleaned up.*/
	IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);

	if(This->hMenu)
	{
	  DestroyMenu(This->hMenu);
	}

	DestroyWindow(This->hWnd);
	if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
	if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);


	return S_OK;
}

static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
{
	ICOM_THIS(IShellViewImpl, iface);

	TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
		This->FolderSettings.ViewMode, This->FolderSettings.fFlags);

	if (!lpfs) return E_INVALIDARG;

	*lpfs = This->FolderSettings;
	return NOERROR;
}

static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
{
	ICOM_THIS(IShellViewImpl, iface);

	FIXME("(%p) stub\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
{
	ICOM_THIS(IShellViewImpl, iface);

	FIXME("(%p) stub\n",This);

	return S_OK;
}

static HRESULT WINAPI IShellView_fnSelectItem(
	IShellView * iface,
	LPCITEMIDLIST pidl,
	UINT uFlags)
{
	ICOM_THIS(IShellViewImpl, iface);
	int i;

	TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);

	i = LV_FindItemByPidl(This, pidl);

	if (i != -1)
	{
	  LVITEMA lvItem;

	  if(uFlags & SVSI_ENSUREVISIBLE)
	    ListView_EnsureVisible(This->hWndList, i, 0);

          ZeroMemory(&lvItem, sizeof(LVITEMA));
	  lvItem.mask = LVIF_STATE;
	  lvItem.iItem = 0;

          while(ListView_GetItemA(This->hWndList, &lvItem))
	  {
	    if (lvItem.iItem == i)
	    {
	      if (uFlags & SVSI_SELECT)
	        lvItem.state |= LVIS_SELECTED;
	      else
		lvItem.state &= ~LVIS_SELECTED;

	      if(uFlags & SVSI_FOCUSED)
	        lvItem.state &= ~LVIS_FOCUSED;
	    }
	    else
	    {
	      if (uFlags & SVSI_DESELECTOTHERS)
	        lvItem.state &= ~LVIS_SELECTED;
	    }
	    ListView_SetItemA(This->hWndList, &lvItem);
	    lvItem.iItem++;
	  }


	  if(uFlags & SVSI_EDIT)
	    ListView_EditLabelA(This->hWndList, i);

	}
	return S_OK;
}

static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
{
	ICOM_THIS(IShellViewImpl, iface);

	TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);

	*ppvOut = NULL;

	switch(uItem)
	{
	  case SVGIO_BACKGROUND:
	    *ppvOut = ISvBgCm_Constructor(This->pSFParent);
	    break;

	  case SVGIO_SELECTION:
	    ShellView_GetSelections(This);
	    IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, This->apidl, riid, 0, ppvOut);
	    break;
	}
	TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);

	if(!*ppvOut) return E_OUTOFMEMORY;

	return S_OK;
}

static HRESULT WINAPI IShellView_fnEditItem(
	IShellView * iface,
	LPITEMIDLIST pidl)
{
	ICOM_THIS(IShellViewImpl, iface);
	int i;

	TRACE("(%p)->(pidl=%p)\n",This, pidl);

	i = LV_FindItemByPidl(This, pidl);
	if (i != -1)
	{
	  SetFocus(This->hWndList);
	  ListView_EditLabelA(This->hWndList, i);
	}
	return S_OK;
}

static struct ICOM_VTABLE(IShellView) svvt =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	IShellView_fnQueryInterface,
	IShellView_fnAddRef,
	IShellView_fnRelease,
	IShellView_fnGetWindow,
	IShellView_fnContextSensitiveHelp,
	IShellView_fnTranslateAccelerator,
	IShellView_fnEnableModeless,
	IShellView_fnUIActivate,
	IShellView_fnRefresh,
	IShellView_fnCreateViewWindow,
	IShellView_fnDestroyViewWindow,
	IShellView_fnGetCurrentInfo,
	IShellView_fnAddPropertySheetPages,
	IShellView_fnSaveViewState,
	IShellView_fnSelectItem,
	IShellView_fnGetItemObject,
	IShellView_fnEditItem
};


/**********************************************************
 * ISVOleCmdTarget_QueryInterface (IUnknown)
 */
static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
	IOleCommandTarget *	iface,
	REFIID			iid,
	LPVOID*			ppvObj)
{
	_ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);

	return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
}

/**********************************************************
 * ISVOleCmdTarget_AddRef (IUnknown)
 */
static ULONG WINAPI ISVOleCmdTarget_AddRef(
	IOleCommandTarget *	iface)
{
	_ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);

	return IShellFolder_AddRef((IShellFolder*)This);
}

/**********************************************************
 * ISVOleCmdTarget_Release (IUnknown)
 */
static ULONG WINAPI ISVOleCmdTarget_Release(
	IOleCommandTarget *	iface)
{
	_ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);

	return IShellFolder_Release((IShellFolder*)This);
}

/**********************************************************
 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
 */
static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
	IOleCommandTarget *iface,
	const GUID* pguidCmdGroup,
	ULONG cCmds,
	OLECMD * prgCmds,
	OLECMDTEXT* pCmdText)
{
    int i;
    _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);

    FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
              This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);

    if (!prgCmds)
        return E_POINTER;
    for (i = 0; i < cCmds; i++)
    {
        FIXME("\tprgCmds[%d].cmdID = %ld\n", i, prgCmds[i].cmdID);
        prgCmds[i].cmdf = 0;
    }
    return OLECMDERR_E_UNKNOWNGROUP;
}

/**********************************************************
 * ISVOleCmdTarget_Exec (IOleCommandTarget)
 *
 * nCmdID is the OLECMDID_* enumeration
 */
static HRESULT WINAPI ISVOleCmdTarget_Exec(
	IOleCommandTarget *iface,
	const GUID* pguidCmdGroup,
	DWORD nCmdID,
	DWORD nCmdexecopt,
	VARIANT* pvaIn,
	VARIANT* pvaOut)
{
	_ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);

	FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
              This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);

	if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
	   (nCmdID == 0x29) &&
	   (nCmdexecopt == 4) && pvaOut)
	   return S_OK;
	if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
	   (nCmdID == 9) &&
	   (nCmdexecopt == 0))
	   return 1;

	return OLECMDERR_E_UNKNOWNGROUP;
}

static ICOM_VTABLE(IOleCommandTarget) ctvt =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	ISVOleCmdTarget_QueryInterface,
	ISVOleCmdTarget_AddRef,
	ISVOleCmdTarget_Release,
	ISVOleCmdTarget_QueryStatus,
	ISVOleCmdTarget_Exec
};

/**********************************************************
 * ISVDropTarget implementation
 */

static HRESULT WINAPI ISVDropTarget_QueryInterface(
	IDropTarget *iface,
	REFIID riid,
	LPVOID *ppvObj)
{
	_ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);

	TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);

	return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
}

static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
{
	_ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);

	TRACE("(%p)->(count=%lu)\n",This,This->ref);

	return IShellFolder_AddRef((IShellFolder*)This);
}

static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
{
	_ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);

	TRACE("(%p)->(count=%lu)\n",This,This->ref);

	return IShellFolder_Release((IShellFolder*)This);
}

static HRESULT WINAPI ISVDropTarget_DragEnter(
	IDropTarget 	*iface,
	IDataObject	*pDataObject,
	DWORD		grfKeyState,
	POINTL		pt,
	DWORD		*pdwEffect)
{

	_ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);

	FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);

	return E_NOTIMPL;
}

static HRESULT WINAPI ISVDropTarget_DragOver(
	IDropTarget	*iface,
	DWORD		grfKeyState,
	POINTL		pt,
	DWORD		*pdwEffect)
{
	_ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);

	FIXME("Stub: This=%p\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI ISVDropTarget_DragLeave(
	IDropTarget	*iface)
{
	_ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);

	FIXME("Stub: This=%p\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI ISVDropTarget_Drop(
	IDropTarget	*iface,
	IDataObject*	pDataObject,
	DWORD		grfKeyState,
	POINTL		pt,
	DWORD		*pdwEffect)
{
	_ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);

	FIXME("Stub: This=%p\n",This);

	return E_NOTIMPL;
}

static struct ICOM_VTABLE(IDropTarget) dtvt =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	ISVDropTarget_QueryInterface,
	ISVDropTarget_AddRef,
	ISVDropTarget_Release,
	ISVDropTarget_DragEnter,
	ISVDropTarget_DragOver,
	ISVDropTarget_DragLeave,
	ISVDropTarget_Drop
};

/**********************************************************
 * ISVDropSource implementation
 */

static HRESULT WINAPI ISVDropSource_QueryInterface(
	IDropSource *iface,
	REFIID riid,
	LPVOID *ppvObj)
{
	_ICOM_THIS_From_IDropSource(IShellViewImpl, iface);

	TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);

	return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
}

static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
{
	_ICOM_THIS_From_IDropSource(IShellViewImpl, iface);

	TRACE("(%p)->(count=%lu)\n",This,This->ref);

	return IShellFolder_AddRef((IShellFolder*)This);
}

static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
{
	_ICOM_THIS_From_IDropSource(IShellViewImpl, iface);

	TRACE("(%p)->(count=%lu)\n",This,This->ref);

	return IShellFolder_Release((IShellFolder*)This);
}
static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
	IDropSource *iface,
	BOOL fEscapePressed,
	DWORD grfKeyState)
{
	_ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
	TRACE("(%p)\n",This);

	if (fEscapePressed)
	  return DRAGDROP_S_CANCEL;
	else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
	  return DRAGDROP_S_DROP;
	else
	  return NOERROR;
}

static HRESULT WINAPI ISVDropSource_GiveFeedback(
	IDropSource *iface,
	DWORD dwEffect)
{
	_ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
	TRACE("(%p)\n",This);

	return DRAGDROP_S_USEDEFAULTCURSORS;
}

static struct ICOM_VTABLE(IDropSource) dsvt =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	ISVDropSource_QueryInterface,
	ISVDropSource_AddRef,
	ISVDropSource_Release,
	ISVDropSource_QueryContinueDrag,
	ISVDropSource_GiveFeedback
};
/**********************************************************
 * ISVViewObject implementation
 */

static HRESULT WINAPI ISVViewObject_QueryInterface(
	IViewObject *iface,
	REFIID riid,
	LPVOID *ppvObj)
{
	_ICOM_THIS_From_IViewObject(IShellViewImpl, iface);

	TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);

	return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
}

static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
{
	_ICOM_THIS_From_IViewObject(IShellViewImpl, iface);

	TRACE("(%p)->(count=%lu)\n",This,This->ref);

	return IShellFolder_AddRef((IShellFolder*)This);
}

static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
{
	_ICOM_THIS_From_IViewObject(IShellViewImpl, iface);

	TRACE("(%p)->(count=%lu)\n",This,This->ref);

	return IShellFolder_Release((IShellFolder*)This);
}

static HRESULT WINAPI ISVViewObject_Draw(
	IViewObject 	*iface,
	DWORD dwDrawAspect,
	LONG lindex,
	void* pvAspect,
	DVTARGETDEVICE* ptd,
	HDC hdcTargetDev,
	HDC hdcDraw,
	LPCRECTL lprcBounds,
	LPCRECTL lprcWBounds,
	IVO_ContCallback pfnContinue,
	DWORD dwContinue)
{

	_ICOM_THIS_From_IViewObject(IShellViewImpl, iface);

	FIXME("Stub: This=%p\n",This);

	return E_NOTIMPL;
}
static HRESULT WINAPI ISVViewObject_GetColorSet(
	IViewObject 	*iface,
	DWORD dwDrawAspect,
	LONG lindex,
	void *pvAspect,
	DVTARGETDEVICE* ptd,
	HDC hicTargetDevice,
	LOGPALETTE** ppColorSet)
{

	_ICOM_THIS_From_IViewObject(IShellViewImpl, iface);

	FIXME("Stub: This=%p\n",This);

	return E_NOTIMPL;
}
static HRESULT WINAPI ISVViewObject_Freeze(
	IViewObject 	*iface,
	DWORD dwDrawAspect,
	LONG lindex,
	void* pvAspect,
	DWORD* pdwFreeze)
{

	_ICOM_THIS_From_IViewObject(IShellViewImpl, iface);

	FIXME("Stub: This=%p\n",This);

	return E_NOTIMPL;
}
static HRESULT WINAPI ISVViewObject_Unfreeze(
	IViewObject 	*iface,
	DWORD dwFreeze)
{

	_ICOM_THIS_From_IViewObject(IShellViewImpl, iface);

	FIXME("Stub: This=%p\n",This);

	return E_NOTIMPL;
}
static HRESULT WINAPI ISVViewObject_SetAdvise(
	IViewObject 	*iface,
	DWORD aspects,
	DWORD advf,
	IAdviseSink* pAdvSink)
{

	_ICOM_THIS_From_IViewObject(IShellViewImpl, iface);

	FIXME("Stub: This=%p\n",This);

	return E_NOTIMPL;
}
static HRESULT WINAPI ISVViewObject_GetAdvise(
	IViewObject 	*iface,
	DWORD* pAspects,
	DWORD* pAdvf,
	IAdviseSink** ppAdvSink)
{

	_ICOM_THIS_From_IViewObject(IShellViewImpl, iface);

	FIXME("Stub: This=%p\n",This);

	return E_NOTIMPL;
}


static struct ICOM_VTABLE(IViewObject) vovt =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	ISVViewObject_QueryInterface,
	ISVViewObject_AddRef,
	ISVViewObject_Release,
	ISVViewObject_Draw,
	ISVViewObject_GetColorSet,
	ISVViewObject_Freeze,
	ISVViewObject_Unfreeze,
	ISVViewObject_SetAdvise,
	ISVViewObject_GetAdvise
};
