Sweden-Number/dlls/shell32/shlview.c

1445 lines
44 KiB
C

/*
* ShellView
*
* Copyright 1998 <juergen.schmied@metronet.de>
*
* FIXME: when the ShellView_WndProc gets a WM_NCDESTROY should we do a
* Release() ???
*
*/
#include <stdlib.h>
#include <string.h>
#include "winerror.h"
#include "pidl.h"
#include "shlguid.h"
#include "shlobj.h"
#include "servprov.h"
#include "wine/obj_base.h"
#include "if_macros.h"
#include "shell32_main.h"
#include "shresdef.h"
#include "spy.h"
#include "debug.h"
/***********************************************************************
* IShellView implementation
*/
static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW,REFIID, LPVOID *);
static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW) ;
static ULONG WINAPI IShellView_Release(LPSHELLVIEW);
/* IOleWindow methods */
static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW,HWND * lphwnd);
static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW,BOOL fEnterMode);
/* IShellView methods */
static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW,LPMSG lpmsg);
static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW,BOOL fEnable);
static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW,UINT uState);
static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW);
static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW, IShellView *lpPrevView,LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT * prcView, HWND *phWnd);
static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW);
static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW, LPFOLDERSETTINGS lpfs);
static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam);
static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW);
static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW, LPCITEMIDLIST pidlItem, UINT uFlags);
static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW, UINT uItem, REFIID riid,LPVOID *ppv);
static BOOL ShellView_CanDoIDockingWindow(LPSHELLVIEW);
static struct IShellView_VTable svvt =
{ IShellView_QueryInterface,
IShellView_AddRef,
IShellView_Release,
IShellView_GetWindow,
IShellView_ContextSensitiveHelp,
IShellView_TranslateAccelerator,
IShellView_EnableModeless,
IShellView_UIActivate,
IShellView_Refresh,
IShellView_CreateViewWindow,
IShellView_DestroyViewWindow,
IShellView_GetCurrentInfo,
IShellView_AddPropertySheetPages,
IShellView_SaveViewState,
IShellView_SelectItem,
IShellView_GetItemObject
};
/*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 MENU_OFFSET 1
#define MENU_MAX 100
#define TOOLBAR_ID (L"SHELLDLL_DefView")
/*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)
/* winuser.h */
#define WM_SETTINGCHANGE WM_WININICHANGE
extern void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition,
UINT wID, UINT fType, LPSTR dwTypeData, UINT fState);
typedef struct
{ int idCommand;
int iImage;
int idButtonString;
int idMenuString;
int nStringOffset;
BYTE bState;
BYTE bStyle;
} MYTOOLINFO, *LPMYTOOLINFO;
extern LPCVOID _Resource_Men_MENU_001_0_data;
extern LPCVOID _Resource_Men_MENU_002_0_data;
MYTOOLINFO g_Tools[] =
{ {IDM_VIEW_FILES, 0, IDS_TB_VIEW_FILES, IDS_MI_VIEW_FILES, 0, TBSTATE_ENABLED, TBSTYLE_BUTTON},
{-1, 0, 0, 0, 0, 0, 0}
};
BOOL g_bViewKeys;
BOOL g_bShowIDW;
typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
/**************************************************************************
* IShellView_Constructor
*/
LPSHELLVIEW IShellView_Constructor( LPSHELLFOLDER pFolder, LPCITEMIDLIST pidl)
{ LPSHELLVIEW sv;
sv=(LPSHELLVIEW)HeapAlloc(GetProcessHeap(),0,sizeof(IShellView));
sv->ref=1;
sv->lpvtbl=&svvt;
sv->mpidl = ILClone(pidl);
sv->hMenu = 0;
sv->pSFParent = pFolder;
sv->uSelected = 0;
sv->aSelectedItems = NULL;
if(sv->pSFParent)
sv->pSFParent->lpvtbl->fnAddRef(sv->pSFParent);
TRACE(shell,"(%p)->(%p pidl=%p)\n",sv, pFolder, pidl);
shell32_ObjCount++;
return sv;
}
/**************************************************************************
* helperfunctions for communication with ICommDlgBrowser
*
*/
static BOOL IsInCommDlg(LPSHELLVIEW this)
{ return(this->pCommDlgBrowser != NULL);
}
static HRESULT IncludeObject(LPSHELLVIEW this, LPCITEMIDLIST pidl)
{ if ( IsInCommDlg(this) )
{ TRACE(shell,"ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
return (this->pCommDlgBrowser->lpvtbl->fnIncludeObject(this->pCommDlgBrowser, this, pidl));
}
return S_OK;
}
static HRESULT OnDefaultCommand(LPSHELLVIEW this)
{ if (IsInCommDlg(this))
{ TRACE(shell,"ICommDlgBrowser::OnDefaultCommand\n");
return (this->pCommDlgBrowser->lpvtbl->fnOnDefaultCommand(this->pCommDlgBrowser, this));
}
return S_FALSE;
}
static HRESULT OnStateChange(LPSHELLVIEW this, UINT uFlags)
{ if (IsInCommDlg(this))
{ TRACE(shell,"ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
return (this->pCommDlgBrowser->lpvtbl->fnOnStateChange(this->pCommDlgBrowser, this, uFlags));
}
return S_FALSE;
}
static void SetStyle(LPSHELLVIEW this, DWORD dwAdd, DWORD dwRemove)
{ DWORD tmpstyle;
TRACE(shell,"(%p)\n", this);
tmpstyle = GetWindowLongA(this->hWndList, GWL_STYLE);
SetWindowLongA(this->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
}
static void CheckToolbar(LPSHELLVIEW this)
{ LRESULT result;
TRACE(shell,"\n");
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);
TRACE(shell,"--\n");
}
static void MergeToolBar(LPSHELLVIEW this)
{ LRESULT iStdBMOffset;
LRESULT iViewBMOffset;
TBADDBITMAP ab;
TBBUTTON tbActual[6];
int i;
enum
{ IN_STD_BMP = 0x4000,
IN_VIEW_BMP = 0x8000,
} ;
static const TBBUTTON c_tbDefault[] =
{ { STD_COPY | IN_STD_BMP, FCIDM_SHVIEW_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0, -1},
{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0,0}, 0, -1 },
{ VIEW_LARGEICONS | IN_VIEW_BMP, FCIDM_SHVIEW_BIGICON, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
{ VIEW_SMALLICONS | IN_VIEW_BMP, FCIDM_SHVIEW_SMALLICON, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
{ VIEW_LIST | IN_VIEW_BMP, FCIDM_SHVIEW_LISTVIEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
{ VIEW_DETAILS | IN_VIEW_BMP, FCIDM_SHVIEW_REPORTVIEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 },
} ;
TRACE(shell,"\n");
ab.hInst = HINST_COMMCTRL; /* hinstCommctrl */
ab.nID = IDB_STD_SMALL_COLOR; /* std bitmaps */
IShellBrowser_SendControlMsg(this->pShellBrowser,FCW_TOOLBAR,
TB_ADDBITMAP, 8, (LPARAM)&ab, &iStdBMOffset);
TRACE(shell,"TB_ADDBITMAP returns %lx\n", iStdBMOffset);
ab.nID = IDB_VIEW_SMALL_COLOR; /* std view bitmaps */
IShellBrowser_SendControlMsg(this->pShellBrowser,FCW_TOOLBAR,
TB_ADDBITMAP, 8, (LPARAM)&ab, &iViewBMOffset);
TRACE(shell,"TB_ADDBITMAP returns %lx\n", iViewBMOffset);
for (i=0; i<6; ++i)
{ tbActual[i] = c_tbDefault[i];
if (!(tbActual[i].fsStyle & TBSTYLE_SEP))
{ if (tbActual[i].iBitmap & IN_VIEW_BMP)
{ tbActual[i].iBitmap = (tbActual[i].iBitmap & ~IN_VIEW_BMP) + iViewBMOffset;
}
else if (tbActual[i].iBitmap & IN_STD_BMP)
{ tbActual[i].iBitmap = (tbActual[i].iBitmap & ~IN_STD_BMP) + iStdBMOffset;
}
}
}
IShellBrowser_SetToolbarItems(this->pShellBrowser,tbActual, 6, FCT_MERGE);
CheckToolbar(this);
TRACE(shell,"--\n");
}
/**************************************************************************
* ShellView_CreateList()
*
*/
BOOL ShellView_CreateList (LPSHELLVIEW this)
{ DWORD dwStyle;
TRACE(shell,"%p\n",this);
dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER |
LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT;
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;
/* UpdateShellSettings(); */
return TRUE;
}
/**************************************************************************
* ShellView_InitList()
*
* NOTES
* internal
*/
int nColumn1=120; /* width of column */
int nColumn2=80;
int nColumn3=170;
int nColumn4=60;
BOOL ShellView_InitList(LPSHELLVIEW this)
{ LVCOLUMNA lvColumn;
CHAR szString[50];
TRACE(shell,"%p\n",this);
ListView_DeleteAllItems(this->hWndList);
/*initialize the columns */
lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; /* | LVCF_SUBITEM;*/
lvColumn.fmt = LVCFMT_LEFT;
lvColumn.pszText = szString;
lvColumn.cx = nColumn1;
strcpy(szString,"File");
/*LoadString32A(shell32_hInstance, IDS_COLUMN1, szString, sizeof(szString));*/
ListView_InsertColumnA(this->hWndList, 0, &lvColumn);
lvColumn.cx = nColumn2;
strcpy(szString,"Size");
ListView_InsertColumnA(this->hWndList, 1, &lvColumn);
lvColumn.cx = nColumn3;
strcpy(szString,"Type");
ListView_InsertColumnA(this->hWndList, 2, &lvColumn);
lvColumn.cx = nColumn4;
strcpy(szString,"Modified");
ListView_InsertColumnA(this->hWndList, 3, &lvColumn);
ListView_SetImageList(this->hWndList, ShellSmallIconList, LVSIL_SMALL);
ListView_SetImageList(this->hWndList, ShellBigIconList, LVSIL_NORMAL);
return TRUE;
}
/**************************************************************************
* ShellView_CompareItems()
*
* NOTES
* internal, CALLBACK for DSA_Sort
*/
INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
{ int ret;
TRACE(shell,"pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
if(!lpData)
return 0;
ret = (int)((LPSHELLFOLDER)lpData)->lpvtbl->fnCompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2);
TRACE(shell,"ret=%i\n",ret);
return ret;
}
/**************************************************************************
* ShellView_FillList()
*
* NOTES
* internal
*/
static HRESULT ShellView_FillList(LPSHELLVIEW this)
{ LPENUMIDLIST pEnumIDList;
LPITEMIDLIST pidl;
DWORD dwFetched;
UINT i;
LVITEMA lvItem;
HRESULT hRes;
HDPA hdpa;
TRACE(shell,"%p\n",this);
/* get the itemlist from the shfolder*/
hRes = this->pSFParent->lpvtbl->fnEnumObjects(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 = pDPA_Create(16);
if (!hdpa)
{ return(E_OUTOFMEMORY);
}
/* copy the items into the array*/
while((S_OK == pEnumIDList->lpvtbl->fnNext(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
{ if (pDPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
{ SHFree(pidl);
}
}
/*sort the array*/
pDPA_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);
if (IncludeObject(this, pidl) == S_OK) /* in a commdlg this works as a filemask*/
{ ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listviewitem*/
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) 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*/
ListView_InsertItemA(this->hWndList, &lvItem);
}
else
SHFree(pidl); /* the listview has the COPY*/
}
/*turn the listview's redrawing back on and force it to draw*/
SendMessageA(this->hWndList, WM_SETREDRAW, TRUE, 0);
InvalidateRect(this->hWndList, NULL, TRUE);
UpdateWindow(this->hWndList);
pEnumIDList->lpvtbl->fnRelease(pEnumIDList); /* destroy the list*/
pDPA_Destroy(hdpa);
return S_OK;
}
/**************************************************************************
* ShellView_OnCreate()
*
* NOTES
* internal
*/
LRESULT ShellView_OnCreate(LPSHELLVIEW this)
{ TRACE(shell,"%p\n",this);
if(ShellView_CreateList(this))
{ if(ShellView_InitList(this))
{ ShellView_FillList(this);
}
}
return S_OK;
}
/**************************************************************************
* ShellView_OnSize()
*/
LRESULT ShellView_OnSize(LPSHELLVIEW this, WORD wWidth, WORD wHeight)
{ TRACE(shell,"%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_BuildFileMenu()
*/
HMENU ShellView_BuildFileMenu(LPSHELLVIEW this)
{ CHAR szText[MAX_PATH];
MENUITEMINFOA mii;
int nTools,i;
HMENU hSubMenu;
TRACE(shell,"(%p) semi-stub\n",this);
hSubMenu = CreatePopupMenu();
if(hSubMenu)
{ /*get the number of items in our global array*/
for(nTools = 0; g_Tools[nTools].idCommand != -1; nTools++){}
/*add the menu items*/
for(i = 0; i < nTools; i++)
{ strcpy(szText, "dummy BuildFileMenu");
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
if(TBSTYLE_SEP != g_Tools[i].bStyle) /* no seperator*/
{ mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
mii.dwTypeData = szText;
mii.wID = g_Tools[i].idCommand;
}
else
{ mii.fType = MFT_SEPARATOR;
}
/* tack this item onto the end of the menu */
InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
}
}
TRACE(shell,"-- return (menu=0x%x)\n",hSubMenu);
return hSubMenu;
}
/**************************************************************************
* ShellView_MergeFileMenu()
*/
void ShellView_MergeFileMenu(LPSHELLVIEW this, HMENU hSubMenu)
{ TRACE(shell,"(%p)->(submenu=0x%08x) 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(shell,"--\n");
}
/**************************************************************************
* ShellView_MergeViewMenu()
*/
void ShellView_MergeViewMenu(LPSHELLVIEW this, HMENU hSubMenu)
{ MENUITEMINFOA mii;
TRACE(shell,"(%p)->(submenu=0x%08x)\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 = LoadMenuIndirectA(&_Resource_Men_MENU_001_0_data);
InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
}
}
/**************************************************************************
* ShellView_UpdateMenu()
*/
LRESULT ShellView_UpdateMenu(LPSHELLVIEW this, HMENU hMenu)
{ TRACE(shell,"(%p)->(menu=0x%08x)\n",this,hMenu);
CheckMenuItem(hMenu, IDM_VIEW_FILES, MF_BYCOMMAND | (g_bViewKeys ? MF_CHECKED: MF_UNCHECKED));
if(ShellView_CanDoIDockingWindow(this))
{ EnableMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_ENABLED);
CheckMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | (g_bShowIDW ? MF_CHECKED: MF_UNCHECKED));
}
else
{ EnableMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
CheckMenuItem(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_UNCHECKED);
}
return S_OK;
}
/**************************************************************************
* ShellView_OnDeactivate()
*
* NOTES
* internal
*/
void ShellView_OnDeactivate(LPSHELLVIEW this)
{ TRACE(shell,"%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()
*/
LRESULT ShellView_OnActivate(LPSHELLVIEW this, UINT uState)
{ OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
MENUITEMINFOA mii;
CHAR szText[MAX_PATH];
TRACE(shell,"%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(shell,"-- 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(shell,"-- before fnSetMenuSB\n");
IShellBrowser_SetMenuSB(this->pShellBrowser, this->hMenu, 0, this->hWnd);
}
}
this->uState = uState;
TRACE(shell,"--\n");
return S_OK;
}
/**************************************************************************
* ShellView_OnSetFocus()
*
* NOTES
* internal
*/
LRESULT ShellView_OnSetFocus(LPSHELLVIEW this)
{ TRACE(shell,"%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,this);
ShellView_OnActivate(this, SVUIA_ACTIVATE_FOCUS);
return 0;
}
/**************************************************************************
* ShellView_OnKillFocus()
*/
LRESULT ShellView_OnKillFocus(LPSHELLVIEW this)
{ TRACE(shell,"(%p) stub\n",this);
ShellView_OnActivate(this, SVUIA_ACTIVATE_NOFOCUS);
return 0;
}
/**************************************************************************
* ShellView_AddRemoveDockingWindow()
*/
BOOL ShellView_AddRemoveDockingWindow(LPSHELLVIEW this, BOOL bAdd)
{ BOOL bReturn = FALSE;
HRESULT hr;
LPSERVICEPROVIDER pSP;
LPDOCKINGWINDOWFRAME pFrame;
WARN(shell,"(%p)->(badd=0x%08x) semi-stub\n",this,bAdd);
/* get the browser's IServiceProvider */
hr = IShellBrowser_QueryInterface(this->pShellBrowser, (REFIID)&IID_IServiceProvider, (LPVOID*)&pSP);
if(SUCCEEDED(hr))
{ /*get the IDockingWindowFrame pointer*/
hr = IServiceProvider_QueryService(pSP, (REFGUID)&SID_SShellBrowser, (REFIID)&IID_IDockingWindowFrame, (LPVOID*)&pFrame);
if(SUCCEEDED(hr))
{ if(bAdd)
{ hr = S_OK;
FIXME(shell,"no docking implemented\n");
#if 0
if(!this->pDockingWindow)
{ /* create the toolbar object */
this->pDockingWindow = DockingWindow_Constructor(this, this->hWnd);
}
if(this->pDockingWindow)
{ /*add the toolbar object */
hr = pFrame->lpvtbl->fnAddToolbar(pFrame, (IDockingWindow*)this->pDockingWindow, TOOLBAR_ID, 0);
if(SUCCEEDED(hr))
{ bReturn = TRUE;
}
}
#endif
}
else
{ FIXME(shell,"no docking implemented\n");
#if 0
if(this->pDockingWindow)
{ hr = pFrame->lpvtbl->fnRemoveToolbar(pFrame, (IDockingWindow*)this->pDockingWindow, DWFRF_NORMAL);
if(SUCCEEDED(hr))
{ /* RemoveToolbar should release the toolbar object which will cause */
/*it to destroy itself. Our toolbar object is no longer valid at */
/*this point. */
this->pDockingWindow = NULL;
bReturn = TRUE;
}
}
#endif
}
pFrame->lpvtbl->fnRelease(pFrame);
}
IServiceProvider_Release(pSP);
}
return bReturn;
}
/**************************************************************************
* ShellView_CanDoIDockingWindow()
*/
BOOL ShellView_CanDoIDockingWindow(LPSHELLVIEW this)
{ BOOL bReturn = FALSE;
HRESULT hr;
LPSERVICEPROVIDER pSP;
LPDOCKINGWINDOWFRAME pFrame;
FIXME(shell,"(%p) stub\n",this);
/*get the browser's IServiceProvider*/
hr = IShellBrowser_QueryInterface(this->pShellBrowser, (REFIID)&IID_IServiceProvider, (LPVOID*)&pSP);
if(hr==S_OK)
{ hr = IServiceProvider_QueryService(pSP, (REFGUID)&SID_SShellBrowser, (REFIID)&IID_IDockingWindowFrame, (LPVOID*)&pFrame);
if(SUCCEEDED(hr))
{ bReturn = TRUE;
pFrame->lpvtbl->fnRelease(pFrame);
}
IServiceProvider_Release(pSP);
}
return bReturn;
}
/**************************************************************************
* ShellView_UpdateShellSettings()
*/
void ShellView_UpdateShellSettings(LPSHELLVIEW this)
{ FIXME(shell,"(%p) stub\n",this);
return ;
/*
SHELLFLAGSTATE sfs;
HINSTANCE hinstShell32;
*/
/* Since SHGetSettings is not implemented in all versions of the shell, get the
function address manually at run time. This allows the code to run on all
platforms.*/
/*
ZeroMemory(&sfs, sizeof(sfs));
*/
/* The default, in case any of the following steps fails, is classic Windows 95
style.*/
/*
sfs.fWin95Classic = TRUE;
hinstShell32 = LoadLibrary("shell32.dll");
if(hinstShell32)
{ PFNSHGETSETTINGSPROC pfnSHGetSettings;
pfnSHGetSettings = (PFNSHGETSETTINGSPROC)GetProcAddress(hinstShell32, "SHGetSettings");
if(pfnSHGetSettings)
{ (*pfnSHGetSettings)(&sfs, SSF_DOUBLECLICKINWEBVIEW | SSF_WIN95CLASSIC);
}
FreeLibrary(hinstShell32);
}
DWORD dwExStyles = 0;
if(!sfs.fWin95Classic && !sfs.fDoubleClickInWebView)
dwExStyles |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT | LVS_EX_UNDERLINEHOT;
ListView_SetExtendedListViewStyle(this->hWndList, dwExStyles);
*/
}
/**************************************************************************
* ShellView_OnSettingChange()
*/
LRESULT ShellView_OnSettingChange(LPSHELLVIEW this, LPCSTR lpszSection)
{ TRACE(shell,"(%p) stub\n",this);
/*if(0 == lstrcmpi(lpszSection, "ShellState"))*/
{ ShellView_UpdateShellSettings(this);
return 0;
}
return 0;
}
/**************************************************************************
* ShellView_OnCommand()
*/
LRESULT ShellView_OnCommand(LPSHELLVIEW this,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
{ TRACE(shell,"(%p)->(0x%08lx 0x%08lx 0x%08x) stub\n",this, dwCmdID, dwCmd, hwndCmd);
switch(dwCmdID)
{ case IDM_VIEW_FILES:
g_bViewKeys = ! g_bViewKeys;
IShellView_Refresh(this);
break;
case IDM_VIEW_IDW:
g_bShowIDW = ! g_bShowIDW;
ShellView_AddRemoveDockingWindow(this, g_bShowIDW);
break;
case IDM_MYFILEITEM:
MessageBeep(MB_OK);
break;
case FCIDM_SHVIEW_SMALLICON:
this->FolderSettings.ViewMode = FVM_SMALLICON;
SetStyle (this, LVS_SMALLICON, LVS_TYPEMASK);
break;
case FCIDM_SHVIEW_BIGICON:
this->FolderSettings.ViewMode = FVM_ICON;
SetStyle (this, LVS_ICON, LVS_TYPEMASK);
break;
case FCIDM_SHVIEW_LISTVIEW:
this->FolderSettings.ViewMode = FVM_LIST;
SetStyle (this, LVS_LIST, LVS_TYPEMASK);
break;
case FCIDM_SHVIEW_REPORTVIEW:
this->FolderSettings.ViewMode = FVM_DETAILS;
SetStyle (this, LVS_REPORT, LVS_TYPEMASK);
break;
default:
TRACE(shell,"-- COMMAND 0x%04lx unhandled\n", dwCmdID);
}
return 0;
}
/**************************************************************************
* ShellView_GetSelections()
*
* RETURNS
* number of selected items
*/
UINT ShellView_GetSelections(LPSHELLVIEW this)
{ LVITEMA lvItem;
UINT i;
if (this->aSelectedItems)
{ SHFree(this->aSelectedItems);
}
this->uSelected = ListView_GetSelectedCount(this->hWndList);
this->aSelectedItems = (LPITEMIDLIST*)SHAlloc(this->uSelected * sizeof(LPITEMIDLIST));
TRACE(shell,"selected=%i\n", this->uSelected);
if(this->aSelectedItems)
{ TRACE(shell,"-- Items selected =%u\n", this->uSelected);
ZeroMemory(&lvItem, sizeof(lvItem));
lvItem.mask = LVIF_STATE | LVIF_PARAM;
lvItem.stateMask = LVIS_SELECTED;
lvItem.iItem = 0;
i = 0;
while(ListView_GetItemA(this->hWndList, &lvItem) && (i < this->uSelected))
{ if(lvItem.state & LVIS_SELECTED)
{ this->aSelectedItems[i] = (LPITEMIDLIST)lvItem.lParam;
i++;
TRACE(shell,"-- selected Item found\n");
}
lvItem.iItem++;
}
}
return this->uSelected;
}
/**************************************************************************
* ShellView_DoContextMenu()
*/
void ShellView_DoContextMenu(LPSHELLVIEW this, WORD x, WORD y, BOOL fDefault)
{ UINT uCommand;
DWORD wFlags;
HMENU hMenu;
BOOL fExplore = FALSE;
HWND hwndTree = 0;
INT nMenuIndex;
MENUITEMINFOA mii;
LPCONTEXTMENU pContextMenu = NULL;
CMINVOKECOMMANDINFO cmi;
TRACE(shell,"(%p)->(0x%08x 0x%08x 0x%08x) stub\n",this, x, y, fDefault);
/* look, what's selected and create a context menu object of it*/
if(ShellView_GetSelections(this))
{ this->pSFParent->lpvtbl->fnGetUIObjectOf( this->pSFParent, this->hWndParent, this->uSelected,
this->aSelectedItems, (REFIID)&IID_IContextMenu,
NULL, (LPVOID *)&pContextMenu);
if(pContextMenu)
{ TRACE(shell,"-- pContextMenu\n");
hMenu = CreatePopupMenu();
if( hMenu )
{ /* See if we are in Explore or Open mode. If the browser's tree
is present, then we are in Explore mode.*/
if(SUCCEEDED(IShellBrowser_GetControlWindow(this->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
{ TRACE(shell,"-- explore mode\n");
fExplore = TRUE;
}
wFlags = CMF_NORMAL | (this->uSelected != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
if (SUCCEEDED(pContextMenu->lpvtbl->fnQueryContextMenu( pContextMenu, hMenu, 0, MENU_OFFSET, MENU_MAX, wFlags )))
{ if( fDefault )
{ TRACE(shell,"-- get menu default command\n");
uCommand = nMenuIndex = 0;
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE | MIIM_ID;
while(GetMenuItemInfoA(hMenu, nMenuIndex, TRUE, &mii)) /*find the default item in the menu*/
{ if(mii.fState & MFS_DEFAULT)
{ uCommand = mii.wID;
break;
}
nMenuIndex++;
}
}
else
{ TRACE(shell,"-- track popup\n");
uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,this->hWnd,NULL);
}
if(uCommand > 0)
{ TRACE(shell,"-- uCommand=%u\n", uCommand);
if (IsInCommDlg(this) && (((uCommand-MENU_OFFSET)==IDM_EXPLORE) || ((uCommand-MENU_OFFSET)==IDM_OPEN)))
{ TRACE(shell,"-- dlg: OnDefaultCommand\n");
OnDefaultCommand(this);
}
else
{ TRACE(shell,"-- explore -- invoke command\n");
ZeroMemory(&cmi, sizeof(cmi));
cmi.cbSize = sizeof(cmi);
cmi.hwnd = this->hWndParent;
cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand - MENU_OFFSET);
pContextMenu->lpvtbl->fnInvokeCommand(pContextMenu, &cmi);
}
}
DestroyMenu(hMenu);
}
}
if (pContextMenu)
pContextMenu->lpvtbl->fnRelease(pContextMenu);
}
}
else /* background context menu */
{ hMenu = LoadMenuIndirectA(&_Resource_Men_MENU_002_0_data);
uCommand = TrackPopupMenu( GetSubMenu(hMenu,0),TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,this->hWnd,NULL);
ShellView_OnCommand(this, uCommand, 0,0);
DestroyMenu(hMenu);
}
}
/**************************************************************************
* ShellView_OnNotify()
*/
LRESULT ShellView_OnNotify(LPSHELLVIEW this, UINT CtlID, LPNMHDR lpnmh)
{ NM_LISTVIEW *lpnmlv = (NM_LISTVIEW*)lpnmh;
NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
LPITEMIDLIST pidl;
DWORD dwCursor;
STRRET str;
UINT uFlags;
IExtractIcon *pei;
TRACE(shell,"%p CtlID=%u lpnmh->code=%x\n",this,CtlID,lpnmh->code);
switch(lpnmh->code)
{ case NM_SETFOCUS:
TRACE(shell,"-- NM_SETFOCUS %p\n",this);
ShellView_OnSetFocus(this);
break;
case NM_KILLFOCUS:
TRACE(shell,"-- NM_KILLFOCUS %p\n",this);
ShellView_OnDeactivate(this);
break;
case HDN_ENDTRACKA:
TRACE(shell,"-- HDN_ENDTRACK32A %p\n",this);
/*nColumn1 = ListView_GetColumnWidth(this->hWndList, 0);
nColumn2 = ListView_GetColumnWidth(this->hWndList, 1);*/
break;
case LVN_DELETEITEM:
TRACE(shell,"-- LVN_DELETEITEM %p\n",this);
SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
break;
case LVN_ITEMACTIVATE:
TRACE(shell,"-- LVN_ITEMACTIVATE %p\n",this);
OnStateChange(this, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
ShellView_DoContextMenu(this, 0, 0, TRUE);
break;
case NM_RCLICK:
TRACE(shell,"-- NM_RCLICK %p\n",this);
dwCursor = GetMessagePos();
ShellView_DoContextMenu(this, LOWORD(dwCursor), HIWORD(dwCursor), FALSE);
break;
case LVN_GETDISPINFOA:
TRACE(shell,"-- LVN_GETDISPINFO32A %p\n",this);
pidl = (LPITEMIDLIST)lpdi->item.lParam;
if(lpdi->item.iSubItem) /*is the sub-item information being requested?*/
{ if(lpdi->item.mask & LVIF_TEXT) /*is the text being requested?*/
{ if(_ILIsValue(pidl)) /*is this a value or a folder?*/
{ switch (lpdi->item.iSubItem)
{ case 1: /* size */
_ILGetFileSize (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
break;
case 2: /* extension */
{ char sTemp[64];
if (_ILGetExtension (pidl, sTemp, 64))
{ if (!( HCR_MapTypeToValue(sTemp, sTemp, 64)
&& HCR_MapTypeToValue(sTemp, lpdi->item.pszText, lpdi->item.cchTextMax )))
{ strncpy (lpdi->item.pszText, sTemp, lpdi->item.cchTextMax);
strncat (lpdi->item.pszText, "-file", lpdi->item.cchTextMax);
}
}
else /* no extension found */
{ lpdi->item.pszText[0]=0x00;
}
}
break;
case 3: /* date */
_ILGetFileDate (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
break;
}
}
else /*its a folder*/
{ switch (lpdi->item.iSubItem)
{ case 1:
strcpy(lpdi->item.pszText, "");
break;
case 2:
strncpy (lpdi->item.pszText, "Folder", lpdi->item.cchTextMax);
break;
case 3:
_ILGetFileDate (pidl, lpdi->item.pszText, lpdi->item.cchTextMax);
break;
}
}
TRACE(shell,"-- text=%s\n",lpdi->item.pszText);
}
}
else /*the item text is being requested*/
{ if(lpdi->item.mask & LVIF_TEXT) /*is the text being requested?*/
{ if(SUCCEEDED(this->pSFParent->lpvtbl->fnGetDisplayNameOf(this->pSFParent,pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &str)))
{ if(STRRET_WSTR == str.uType)
{ WideCharToLocal(lpdi->item.pszText, str.u.pOleStr, lpdi->item.cchTextMax);
SHFree(str.u.pOleStr);
}
else if(STRRET_CSTRA == str.uType)
{ strncpy(lpdi->item.pszText, str.u.cStr, lpdi->item.cchTextMax);
}
else
{ FIXME(shell,"type wrong\n");
}
}
TRACE(shell,"-- text=%s\n",lpdi->item.pszText);
}
if(lpdi->item.mask & LVIF_IMAGE) /*is the image being requested?*/
{ if(SUCCEEDED(this->pSFParent->lpvtbl->fnGetUIObjectOf(this->pSFParent,this->hWnd,1,
(LPCITEMIDLIST*)&pidl, (REFIID)&IID_IExtractIcon, NULL, (LPVOID*)&pei)))
{ pei->lpvtbl->fnGetIconLocation(pei, GIL_FORSHELL, NULL, 0, &lpdi->item.iImage, &uFlags);
pei->lpvtbl->fnRelease(pei);
TRACE(shell,"-- image=%x\n",lpdi->item.iImage);
}
}
}
break;
case LVN_ITEMCHANGED:
TRACE(shell,"-- LVN_ITEMCHANGED %p\n",this);
ShellView_GetSelections(this);
OnStateChange(this, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
break;
default:
TRACE (shell,"-- %p WM_COMMAND %s unhandled\n", this, SPY_GetMsgName(lpnmh->code));
break;;
}
return 0;
}
/**************************************************************************
* ShellView_WndProc
*/
LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{ LPSHELLVIEW pThis = (LPSHELLVIEW)GetWindowLongA(hWnd, GWL_USERDATA);
LPCREATESTRUCTA lpcs;
DWORD dwCursor;
TRACE(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
switch (uMessage)
{ case WM_NCCREATE:
{ TRACE(shell,"-- WM_NCCREATE\n");
lpcs = (LPCREATESTRUCTA)lParam;
pThis = (LPSHELLVIEW)(lpcs->lpCreateParams);
SetWindowLongA(hWnd, GWL_USERDATA, (LONG)pThis);
pThis->hWnd = hWnd; /*set the window handle*/
}
break;
case WM_SIZE:
TRACE(shell,"-- WM_SIZE\n");
return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
case WM_SETFOCUS:
TRACE(shell,"-- WM_SETFOCUS\n");
return ShellView_OnSetFocus(pThis);
case WM_KILLFOCUS:
TRACE(shell,"-- WM_KILLFOCUS\n");
return ShellView_OnKillFocus(pThis);
case WM_CREATE:
TRACE(shell,"-- WM_CREATE\n");
return ShellView_OnCreate(pThis);
case WM_SHOWWINDOW:
TRACE(shell,"-- WM_SHOWWINDOW\n");
UpdateWindow(pThis->hWndList);
break;
case WM_ACTIVATE:
TRACE(shell,"-- WM_ACTIVATE\n");
return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
case WM_COMMAND:
TRACE(shell,"-- WM_COMMAND\n");
return ShellView_OnCommand(pThis, GET_WM_COMMAND_ID(wParam, lParam),
GET_WM_COMMAND_CMD(wParam, lParam),
GET_WM_COMMAND_HWND(wParam, lParam));
case WM_INITMENUPOPUP:
TRACE(shell,"-- WM_INITMENUPOPUP\n");
return ShellView_UpdateMenu(pThis, (HMENU)wParam);
case WM_NOTIFY:
TRACE(shell,"-- WM_NOTIFY\n");
return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
case WM_SETTINGCHANGE:
TRACE(shell,"-- WM_SETTINGCHANGE\n");
return ShellView_OnSettingChange(pThis,(LPCSTR)lParam);
case WM_PARENTNOTIFY:
TRACE(shell,"-- WM_PARENTNOTIFY\n");
if ( LOWORD(wParam) == WM_RBUTTONDOWN ) /* fixme: should not be handled here*/
{ dwCursor = GetMessagePos();
ShellView_DoContextMenu(pThis, LOWORD(dwCursor), HIWORD(dwCursor), FALSE);
return TRUE;
}
break;
default:
TRACE(shell,"-- message %s unhandled\n", SPY_GetMsgName(uMessage));
break;
}
return DefWindowProcA (hWnd, uMessage, wParam, lParam);
}
/**************************************************************************
*
*
* The INTERFACE of the IShellView object
*
*
***************************************************************************
* IShellView_QueryInterface
*/
static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW this,REFIID riid, LPVOID *ppvObj)
{ char xriid[50];
WINE_StringFromCLSID((LPCLSID)riid,xriid);
TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
*ppvObj = NULL;
if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
{ *ppvObj = this;
}
else if(IsEqualIID(riid, &IID_IShellView)) /*IShellView*/
{ *ppvObj = (IShellView*)this;
}
if(*ppvObj)
{ (*(LPSHELLVIEW*)ppvObj)->lpvtbl->fnAddRef(this);
TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
return S_OK;
}
TRACE(shell,"-- Interface: E_NOINTERFACE\n");
return E_NOINTERFACE;
}
/**************************************************************************
* IShellView::AddRef
*/
static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW this)
{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
shell32_ObjCount++;
return ++(this->ref);
}
/**************************************************************************
* IShellView_Release
*/
static ULONG WINAPI IShellView_Release(LPSHELLVIEW this)
{ TRACE(shell,"(%p)->()\n",this);
shell32_ObjCount--;
if (!--(this->ref))
{ TRACE(shell," destroying IShellView(%p)\n",this);
if(this->pSFParent)
this->pSFParent->lpvtbl->fnRelease(this->pSFParent);
if (this->aSelectedItems)
SHFree(this->aSelectedItems);
if (this->pCommDlgBrowser)
this->pCommDlgBrowser->lpvtbl->fnRelease(this->pCommDlgBrowser);
HeapFree(GetProcessHeap(),0,this);
return 0;
}
return this->ref;
}
/**************************************************************************
* ShellView_GetWindow
*/
static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW this,HWND * phWnd)
{ TRACE(shell,"(%p)\n",this);
*phWnd = this->hWnd;
return S_OK;
}
static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW this,BOOL fEnterMode)
{ FIXME(shell,"(%p) stub\n",this);
return E_NOTIMPL;
}
/**************************************************************************
* IShellView_TranslateAccelerator
*
* FIXME:
* use the accel functions
*/
static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW this,LPMSG lpmsg)
{ FIXME(shell,"(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",this,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
switch (lpmsg->message)
{ case WM_KEYDOWN: TRACE(shell,"-- key=0x04%x",lpmsg->wParam) ;
}
return S_FALSE;
}
static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW this,BOOL fEnable)
{ FIXME(shell,"(%p) stub\n",this);
return E_NOTIMPL;
}
static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW this,UINT uState)
{ CHAR szName[MAX_PATH];
LRESULT lResult;
int nPartArray[1] = {-1};
TRACE(shell,"(%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);
/*remove the docking window*/
if(g_bShowIDW)
{ ShellView_AddRemoveDockingWindow(this, FALSE);
}
/*only do this if we are active*/
if(uState != SVUIA_DEACTIVATE)
{ /*update the status bar */
strcpy(szName, "dummy32");
this->pSFParent->lpvtbl->fnGetFolderPath( this->pSFParent,
szName + strlen(szName),
sizeof(szName) - strlen(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);
/*add the docking window if necessary */
if(g_bShowIDW)
{ ShellView_AddRemoveDockingWindow(this, TRUE);
}
}
return S_OK;
}
static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW this)
{ TRACE(shell,"(%p)\n",this);
ListView_DeleteAllItems(this->hWndList);
ShellView_FillList(this);
return S_OK;
}
static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW this, IShellView *lpPrevView,
LPCFOLDERSETTINGS lpfs, IShellBrowser * psb, RECT * prcView, HWND *phWnd)
{ WNDCLASSA wc;
/* LRESULT dwResult;*/
*phWnd = 0;
TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView,lpfs, psb, prcView, phWnd);
TRACE(shell,"-- vmode=%x flags=%x left=%i top=%i right=%i bottom=%i\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(shell,"-- 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_CLIPSIBLINGS,
prcView->left, prcView->top, prcView->right - prcView->left, prcView->bottom - prcView->top,
this->hWndParent, 0, shell32_hInstance, (LPVOID)this);
MergeToolBar(this);
if(!*phWnd)
return E_FAIL;
return S_OK;
}
static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW this)
{ TRACE(shell,"(%p)\n",this);
/*Make absolutely sure all our UI is cleaned up.*/
IShellView_UIActivate(this, SVUIA_DEACTIVATE);
if(this->hMenu)
{ DestroyMenu(this->hMenu);
}
DestroyWindow(this->hWnd);
IShellBrowser_Release(this->pShellBrowser);
return S_OK;
}
static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW this, LPFOLDERSETTINGS lpfs)
{ TRACE(shell,"(%p)->(%p) vmode=%x flags=%x\n",this, lpfs,
this->FolderSettings.ViewMode, this->FolderSettings.fFlags);
if (lpfs)
{ *lpfs = this->FolderSettings;
return NOERROR;
}
else
return E_INVALIDARG;
}
static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW this, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
{ FIXME(shell,"(%p) stub\n",this);
return E_NOTIMPL;
}
static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW this)
{ FIXME(shell,"(%p) stub\n",this);
return S_OK;
}
static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW this, LPCITEMIDLIST pidlItem, UINT uFlags)
{ FIXME(shell,"(%p)->(pidl=%p, 0x%08x) stub\n",this, pidlItem, uFlags);
return E_NOTIMPL;
}
static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW this, UINT uItem, REFIID riid, LPVOID *ppvOut)
{ LPUNKNOWN pObj = NULL;
char xriid[50];
WINE_StringFromCLSID((LPCLSID)riid,xriid);
TRACE(shell,"(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",this, uItem, xriid, ppvOut);
*ppvOut = NULL;
if(IsEqualIID(riid, &IID_IContextMenu))
{ ShellView_GetSelections(this);
pObj =(LPUNKNOWN)IContextMenu_Constructor(this->pSFParent,this->aSelectedItems,this->uSelected);
}
else if (IsEqualIID(riid, &IID_IDataObject))
{ ShellView_GetSelections(this);
pObj =(LPUNKNOWN)IDataObject_Constructor(this->hWndParent, this->pSFParent,this->aSelectedItems,this->uSelected);
}
TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut);
if(!pObj)
return E_OUTOFMEMORY;
*ppvOut = pObj;
return S_OK;
}