1445 lines
44 KiB
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;
|
|
}
|