| /* | 
 |  *	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 <stdarg.h> | 
 | #include <stdlib.h> | 
 | #include <string.h> | 
 |  | 
 | #include "windef.h" | 
 | #include "winerror.h" | 
 | #include "winbase.h" | 
 | #include "winnls.h" | 
 | #include "servprov.h" | 
 | #include "shlguid.h" | 
 | #include "wingdi.h" | 
 | #include "winuser.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; | 
 | 	sv->lpVtbl=&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() && pRegisterDragDrop) | 
 | 	{ | 
 | 	  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 separator*/ | 
 | 	    { | 
 | 	      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; | 
 | 	IContextMenu2 *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, (LPCITEMIDLIST*)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); | 
 | 	  IContextMenu2_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; | 
 | 	  IContextMenu2_InvokeCommand(pCM, &cmi); | 
 |  | 
 | 	  IContextMenu2_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_INSERTITEM: | 
 | 	    TRACE("-- LVN_INSERTITEM (STUB)%p\n",This); | 
 | 	    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() && pDoDragDrop) | 
 | 	      { | 
 | 	        if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda))) | 
 | 	        { | 
 | 	          IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource);	/* own DropSource interface */ | 
 |  | 
 | 	  	  if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)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, (LPCITEMIDLIST*)&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, (LPCITEMIDLIST*)pItems); | 
 |  | 
 | 		/* free pidl array memory */ | 
 | 		HeapFree(GetProcessHeap(), 0, pItems); | 
 |               } | 
 |               else | 
 | 		FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey); | 
 | 	    } | 
 | 	    break; | 
 |  | 
 | 	  default: | 
 | 	    FIXME("-- %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) | 
 | 				{ | 
 | 	  			  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, (LPSTR)IDC_ARROW); | 
 | 	  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, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut); | 
 | 	    break; | 
 | 	} | 
 | 	TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut); | 
 |  | 
 | 	if(!*ppvOut) return E_OUTOFMEMORY; | 
 |  | 
 | 	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 | 
 | }; | 
 |  | 
 |  | 
 | /********************************************************** | 
 |  * 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) | 
 | { | 
 |     UINT 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, | 
 | 	BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue), | 
 | 	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 | 
 | }; |