初步修复
This commit is contained in:
parent
8fc4357cc6
commit
e4714f3f0e
46705 changed files with 12004901 additions and 0 deletions
772
Server/ServiceMonitorEx/External/UltimateToolbox/source/OXShellObjectList.cpp
vendored
Normal file
772
Server/ServiceMonitorEx/External/UltimateToolbox/source/OXShellObjectList.cpp
vendored
Normal file
|
|
@ -0,0 +1,772 @@
|
|||
// OXShellObjectList.cpp : implementation file
|
||||
//
|
||||
// Version: 9.3
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "OXShellObjectList.h"
|
||||
#include "OXMainRes.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
// delimiter for filter
|
||||
const TCHAR OXSHELLLIST_EXT_DELIMITER=_T('|');
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COXShellObjectList
|
||||
|
||||
COXShellObjectList::COXShellObjectList(BOOL bEnableContextMenu/*=TRUE*/,
|
||||
BOOL bOnlyFileSystemItems/*=TRUE*/,
|
||||
BOOL bNotifyError/*=TRUE*/,
|
||||
LPCTSTR lpszFilter/*=_T("")*/)
|
||||
{
|
||||
SetEnableContextMenu(bEnableContextMenu);
|
||||
SetOnlyFileSystemItems(bOnlyFileSystemItems);
|
||||
SetNotifyError(bNotifyError);
|
||||
|
||||
SetFilter(lpszFilter);
|
||||
|
||||
m_lpsfCurrentParentFolder=NULL;
|
||||
m_lpFullIDLCurrentParentFolder=NULL;
|
||||
|
||||
m_hShellImageListLarge=NULL;
|
||||
m_hShellImageListSmall=NULL;
|
||||
|
||||
m_nRedraw=0;
|
||||
|
||||
m_bInitialized=FALSE;
|
||||
}
|
||||
|
||||
COXShellObjectList::~COXShellObjectList()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(COXShellObjectList, CListCtrl)
|
||||
//{{AFX_MSG_MAP(COXShellObjectList)
|
||||
ON_NOTIFY_REFLECT_EX(NM_DBLCLK, OnDblClick)
|
||||
ON_NOTIFY_REFLECT_EX(LVN_BEGINLABELEDIT, OnBeginLabelEdit)
|
||||
ON_NOTIFY_REFLECT_EX(LVN_ENDLABELEDIT, OnEndLabelEdit)
|
||||
#ifdef OXSHELLLIST_WATCHFORDIR
|
||||
ON_MESSAGE(WM_OX_FILE_NOTIFY, OnDirChangeNotify)
|
||||
#endif // OXSHELLLIST_WATCHFORDIR
|
||||
ON_WM_CONTEXTMENU()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COXShellObjectList message handlers
|
||||
|
||||
BOOL COXShellObjectList::PopulateList(const LPSHELLFOLDER lpFolder,
|
||||
const LPITEMIDLIST lpFullIDL)
|
||||
{
|
||||
ASSERT_VALID(this);
|
||||
ASSERT(lpFolder!=NULL);
|
||||
|
||||
if(!::IsWindow(GetSafeHwnd()))
|
||||
return FALSE;
|
||||
|
||||
if(!m_bInitialized)
|
||||
{
|
||||
if(!Init())
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Clean up ListCtrl
|
||||
DeleteAllItems();
|
||||
|
||||
// Fill ListCtrl with objects in lpFolder folder.
|
||||
FillListWithSubitems(lpFolder,lpFullIDL);
|
||||
|
||||
// We cannot sort item using just their display names. We have to
|
||||
// request shell to sort items.
|
||||
SortItems(COXShellNamespaceNavigator::CompareObjectsProc,NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL COXShellObjectList::PopulateList(CString sFolderStartFrom/*=_T("")*/)
|
||||
{
|
||||
ASSERT_VALID(this);
|
||||
|
||||
if(!::IsWindow(GetSafeHwnd()))
|
||||
return FALSE;
|
||||
|
||||
if(!m_bInitialized)
|
||||
{
|
||||
if(!Init())
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// now let's fill ListCtrl with shell namespace objects that is located
|
||||
// in sFolderStartFrom folder. If sFolderStartFrom is NULL then we use
|
||||
// Desktop as start folder
|
||||
|
||||
// shell folder returned by that function have to be released afterwards
|
||||
LPSHELLFOLDER lpFolder=m_navigator.GetShellFolder(sFolderStartFrom);
|
||||
if(lpFolder==NULL)
|
||||
return FALSE;
|
||||
|
||||
LPITEMIDLIST lpidlFull;
|
||||
if(!m_navigator.GetShellFolderFullIDL(sFolderStartFrom,&lpidlFull))
|
||||
{
|
||||
// Release the folder
|
||||
lpFolder->Release();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Clean up ListCtrl
|
||||
DeleteAllItems();
|
||||
|
||||
// Fill ListCtrl with objects in lpFolder folder.
|
||||
FillListWithSubitems(lpFolder,lpidlFull);
|
||||
|
||||
lpFolder->Release();
|
||||
|
||||
// We cannot sort item using just their display names. We have to
|
||||
// request shell to sort items.
|
||||
SortItems(COXShellNamespaceNavigator::CompareObjectsProc,NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
CString COXShellObjectList::GetFullPath(int nItem) const
|
||||
{
|
||||
ASSERT(nItem>=0 && nItem<GetItemCount());
|
||||
|
||||
// retrieve associated structure
|
||||
LPNAMESPACEOBJECT lpNameSpaceObject=(LPNAMESPACEOBJECT)GetItemData(nItem);
|
||||
if(lpNameSpaceObject==NULL)
|
||||
return _T("");
|
||||
|
||||
return m_navigator.GetFullPath(lpNameSpaceObject->lpFullIDL);
|
||||
}
|
||||
|
||||
|
||||
BOOL COXShellObjectList::FillListWithSubitems(const LPSHELLFOLDER lpFolder,
|
||||
const LPITEMIDLIST lpFullIDL)
|
||||
{
|
||||
ASSERT(lpFolder);
|
||||
|
||||
CWaitCursor wait;
|
||||
|
||||
// Initialize enumeration of objects within given folder
|
||||
if(!m_navigator.InitObjectsEnumerator(lpFolder,lpFullIDL))
|
||||
return FALSE;
|
||||
|
||||
// After we get pointer to IEnumIDList interface we can use its methods to
|
||||
// retrieve information about all objects of given lpFolder
|
||||
//
|
||||
|
||||
// structures for inserting new items in our ListCtrl
|
||||
LV_ITEM lvi;
|
||||
|
||||
BOOL bLast;
|
||||
// Loop through Shell Namespace items
|
||||
LPNAMESPACEOBJECT lpNameSpaceObject=m_navigator.EnumerateObjectNext(bLast);
|
||||
while(!bLast)
|
||||
{
|
||||
BOOL bQualified=lpNameSpaceObject!=NULL;
|
||||
if(bQualified && GetOnlyFileSystemItems())
|
||||
{
|
||||
bQualified=(lpNameSpaceObject->dwFlags&SFGAO_FILESYSANCESTOR ||
|
||||
lpNameSpaceObject->dwFlags&SFGAO_FILESYSTEM);
|
||||
}
|
||||
if(bQualified && (lpNameSpaceObject->dwFlags&SFGAO_FILESYSTEM) &&
|
||||
!(lpNameSpaceObject->dwFlags&SFGAO_FOLDER))
|
||||
{
|
||||
bQualified=IsMatchingFilter(lpNameSpaceObject->szDisplayName);
|
||||
}
|
||||
if(bQualified && IsQualified(lpNameSpaceObject))
|
||||
{
|
||||
// We define text, image (including selected) and lParam value
|
||||
// which is going to be a pointer to NAMESPACEOBJECT structure
|
||||
lvi.mask=LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
|
||||
// NAMESPACEOBJECT structure is already filled
|
||||
lvi.lParam=(LPARAM)lpNameSpaceObject;
|
||||
|
||||
// display name
|
||||
lvi.pszText=lpNameSpaceObject->szDisplayName;
|
||||
|
||||
// image
|
||||
int nListImageIndex=-1;
|
||||
if(!m_mapImageIndex.Lookup(lpNameSpaceObject->nImageSmall,nListImageIndex))
|
||||
{
|
||||
nListImageIndex=PtrToInt(m_mapImageIndex.GetCount());
|
||||
m_mapImageIndex.SetAt(lpNameSpaceObject->nImageSmall,nListImageIndex);
|
||||
HICON hIcon=ImageList_ExtractIcon(
|
||||
0,m_hShellImageListLarge,lpNameSpaceObject->nImageSmall);
|
||||
ASSERT(hIcon!=NULL);
|
||||
lvi.iImage=m_imageListLarge.Add(hIcon);
|
||||
ASSERT(lvi.iImage!=-1 && lvi.iImage==nListImageIndex);
|
||||
VERIFY(::DestroyIcon(hIcon));
|
||||
hIcon=ImageList_ExtractIcon(
|
||||
0,m_hShellImageListSmall,lpNameSpaceObject->nImageSmall);
|
||||
ASSERT(hIcon!=NULL);
|
||||
VERIFY(m_imageListSmall.Add(hIcon)==lvi.iImage);
|
||||
VERIFY(::DestroyIcon(hIcon));
|
||||
}
|
||||
else
|
||||
{
|
||||
lvi.iImage=nListImageIndex;
|
||||
}
|
||||
/////////////////////
|
||||
|
||||
// index and subitem
|
||||
lvi.iItem=GetItemCount();
|
||||
lvi.iSubItem=0;
|
||||
|
||||
// We collected all information we needed. It's time to insert
|
||||
// new item in our ListCtrl.
|
||||
int nItem=InsertItem(&lvi);
|
||||
ASSERT(nItem!=-1);
|
||||
|
||||
// retrieve info about size, type and modification date of the
|
||||
// file system object
|
||||
if(lpNameSpaceObject->dwFlags&SFGAO_FILESYSTEM)
|
||||
{
|
||||
CString sFullPath=m_navigator.GetFullPath(lpNameSpaceObject->lpFullIDL);
|
||||
ASSERT(!sFullPath.IsEmpty());
|
||||
|
||||
CFileStatus fileStatus;
|
||||
if(CFile::GetStatus(sFullPath,fileStatus))
|
||||
{
|
||||
if((lpNameSpaceObject->dwFlags&SFGAO_FOLDER)!=SFGAO_FOLDER)
|
||||
{
|
||||
// request size
|
||||
CString sFileSize;
|
||||
sFileSize.Format(_T("%dKB"),
|
||||
(fileStatus.m_size>1024 ? fileStatus.m_size/1024 : 1));
|
||||
SetItem(nItem,1,LVIF_TEXT,sFileSize,0,0,0,0);
|
||||
}
|
||||
|
||||
// modified
|
||||
CString sModified=fileStatus.m_mtime.Format(_T("%c"));
|
||||
SetItem(nItem,3,LVIF_TEXT,sModified,0,0,0,0);
|
||||
}
|
||||
|
||||
SHFILEINFO shfi;
|
||||
if(SHGetFileInfo(sFullPath,NULL,&shfi,sizeof(shfi),
|
||||
SHGFI_TYPENAME)!=0)
|
||||
{
|
||||
// file type
|
||||
CString sItemType(_T(""));
|
||||
sItemType=(LPCTSTR)shfi.szTypeName;
|
||||
SetItem(nItem,2,LVIF_TEXT,sItemType,0,0,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
lpNameSpaceObject=m_navigator.EnumerateObjectNext(bLast);
|
||||
}
|
||||
|
||||
// Release enumerator
|
||||
m_navigator.ReleaseObjectsEnumerator();
|
||||
|
||||
#ifdef OXSHELLLIST_WATCHFORDIR
|
||||
if(m_lpFullIDLCurrentParentFolder!=NULL)
|
||||
{
|
||||
CString sCurrentFolder=m_navigator.GetFullPath(m_lpFullIDLCurrentParentFolder);
|
||||
if(!sCurrentFolder.IsEmpty())
|
||||
m_fileWatcher.RemoveWatch(sCurrentFolder);
|
||||
|
||||
sCurrentFolder=m_navigator.GetFullPath(lpFullIDL);
|
||||
if(!sCurrentFolder.IsEmpty())
|
||||
{
|
||||
if(m_fileWatcher.AddWatch(sCurrentFolder,FALSE,
|
||||
COXFileWatcher::OXFileWatchChangeDirName|
|
||||
COXFileWatcher::OXFileWatchChangeFileName))
|
||||
{
|
||||
m_fileWatcher.EnableWindowNotification(sCurrentFolder,this,TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE(_T("COXShellObjectList::FillListWithSubitems: failed to set a file watcher for the current parent folder\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // OXSHELLLIST_WATCHFORDIR
|
||||
|
||||
m_lpsfCurrentParentFolder=lpFolder;
|
||||
m_lpFullIDLCurrentParentFolder=lpFullIDL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL COXShellObjectList::OnDblClick(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pNMHDR);
|
||||
|
||||
// TODO: Add your control notification handler code here
|
||||
*pResult = 0;
|
||||
|
||||
// if double click over a folder we expand it or otherwise invoke
|
||||
// the default command for a file
|
||||
//
|
||||
|
||||
// Get the item that was double clicked in screen coordinates
|
||||
CPoint ptMouseCursor;
|
||||
if(!::GetCursorPos(&ptMouseCursor))
|
||||
{
|
||||
TRACE(_T("COXShellObjectList::OnDblClick: GetCursorPos() failed\n"));
|
||||
return FALSE;
|
||||
}
|
||||
ScreenToClient(&ptMouseCursor);
|
||||
|
||||
// Use HitTest function to define the list item by coordinate
|
||||
UINT nFlags=NULL;
|
||||
int nItem=HitTest(ptMouseCursor,&nFlags);
|
||||
|
||||
if(nItem!=-1 && (nFlags&LVHT_ONITEM)!=0)
|
||||
{
|
||||
// Get folder info associated with item
|
||||
LPNAMESPACEOBJECT lpNameSpaceObject=
|
||||
(LPNAMESPACEOBJECT)GetItemData(nItem);
|
||||
ASSERT(lpNameSpaceObject!=NULL);
|
||||
|
||||
if((lpNameSpaceObject->dwFlags&SFGAO_FOLDER)!=SFGAO_FOLDER)
|
||||
{
|
||||
if(!m_navigator.InvokeDefaultCommand(lpNameSpaceObject->lpsfParent,
|
||||
lpNameSpaceObject->lpRelativeIDL))
|
||||
{
|
||||
TRACE(_T("COXShellObjectList::OnDblClick: InvokeDefaultCommand() failed"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL COXShellObjectList::Init()
|
||||
{
|
||||
ASSERT_VALID(this);
|
||||
|
||||
if(!::IsWindow(GetSafeHwnd()))
|
||||
return FALSE;
|
||||
|
||||
SetNotifyError(m_bNotifyError);
|
||||
|
||||
// use system image list as tree control's image list
|
||||
//
|
||||
m_mapImageIndex.RemoveAll();
|
||||
|
||||
// large images
|
||||
if((HIMAGELIST)m_imageListLarge!=NULL)
|
||||
m_imageListLarge.DeleteImageList();
|
||||
// retrieve Shell image list
|
||||
if(m_hShellImageListLarge==NULL)
|
||||
{
|
||||
m_hShellImageListLarge=m_navigator.GetShellImageList(FALSE);
|
||||
if(m_hShellImageListLarge==NULL)
|
||||
return FALSE;
|
||||
}
|
||||
IMAGEINFO imageInfo;
|
||||
VERIFY(ImageList_GetImageInfo(m_hShellImageListLarge,0,&imageInfo));
|
||||
CRect rect(imageInfo.rcImage);
|
||||
VERIFY(m_imageListLarge.Create(rect.Width(),rect.Height(),ILC_COLOR32|ILC_MASK,0,0));
|
||||
|
||||
SetImageList(&m_imageListLarge,TVSIL_NORMAL);
|
||||
////////////////////////////////////////////////
|
||||
|
||||
// small images
|
||||
if((HIMAGELIST)m_imageListSmall!=NULL)
|
||||
m_imageListSmall.DeleteImageList();
|
||||
// retrieve Shell image list
|
||||
if(m_hShellImageListSmall==NULL)
|
||||
{
|
||||
m_hShellImageListSmall=m_navigator.GetShellImageList(TRUE);
|
||||
if(m_hShellImageListSmall==NULL)
|
||||
return FALSE;
|
||||
}
|
||||
VERIFY(ImageList_GetImageInfo(m_hShellImageListSmall,0,&imageInfo));
|
||||
rect=imageInfo.rcImage;
|
||||
VERIFY(m_imageListSmall.Create(rect.Width(),rect.Height(),ILC_COLOR32|ILC_MASK,0,0));
|
||||
|
||||
SetImageList(&m_imageListSmall,LVSIL_SMALL);
|
||||
////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Clean up ListCtrl
|
||||
DeleteAllItems();
|
||||
|
||||
// check the columns
|
||||
LVCOLUMN lvc={0};
|
||||
lvc.mask=LVCF_FMT;
|
||||
int nColumnCount=0;
|
||||
while(GetColumn(nColumnCount,&lvc))
|
||||
nColumnCount++;
|
||||
if(nColumnCount!=4)
|
||||
{
|
||||
for(int nIndex=0; nIndex<nColumnCount; nIndex++)
|
||||
DeleteColumn(0);
|
||||
CString sItem;
|
||||
VERIFY(sItem.LoadString(IDS_OX_SHELLOBJECTLISTNAME));
|
||||
InsertColumn(0,sItem,LVCFMT_LEFT,200);
|
||||
VERIFY(sItem.LoadString(IDS_OX_SHELLOBJECTLISTSIZE));
|
||||
InsertColumn(1,sItem,LVCFMT_LEFT,70);
|
||||
VERIFY(sItem.LoadString(IDS_OX_SHELLOBJECTLISTTYPE));
|
||||
InsertColumn(2,sItem,LVCFMT_LEFT,120);
|
||||
VERIFY(sItem.LoadString(IDS_OX_SHELLOBJECTLISTMODIFIED));
|
||||
InsertColumn(3,sItem,LVCFMT_LEFT,120);
|
||||
}
|
||||
|
||||
m_bInitialized=TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void COXShellObjectList::SetRedraw(BOOL bRedraw/*=TRUE*/)
|
||||
{
|
||||
ASSERT(m_nRedraw>=0);
|
||||
|
||||
if(!bRedraw)
|
||||
{
|
||||
if(m_nRedraw==0)
|
||||
{
|
||||
CWnd::SetRedraw(FALSE);
|
||||
}
|
||||
m_nRedraw++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_nRedraw>=1)
|
||||
m_nRedraw--;
|
||||
if(m_nRedraw==0)
|
||||
{
|
||||
CWnd::SetRedraw(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL COXShellObjectList::OnBeginLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
NMLVDISPINFO* plvdi=(NMLVDISPINFO*)pNMHDR;
|
||||
ASSERT(plvdi!=NULL);
|
||||
// TODO: Add your control notification handler code here
|
||||
|
||||
(*pResult)=FALSE;
|
||||
|
||||
// retrieve associated structure
|
||||
LPNAMESPACEOBJECT lpNameSpaceObject=(LPNAMESPACEOBJECT)plvdi->item.lParam;
|
||||
if(lpNameSpaceObject==NULL)
|
||||
{
|
||||
(*pResult)=TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// check if item is allowed to be edited
|
||||
if((lpNameSpaceObject->dwFlags&SFGAO_CANRENAME)!=SFGAO_CANRENAME)
|
||||
{
|
||||
(*pResult)=TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL COXShellObjectList::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
NMLVDISPINFO* plvdi=(NMLVDISPINFO*)pNMHDR;
|
||||
ASSERT(plvdi!=NULL);
|
||||
// TODO: Add your control notification handler code here
|
||||
|
||||
*pResult=TRUE;;
|
||||
|
||||
CString sNewText=plvdi->item.pszText;
|
||||
|
||||
CWaitCursor waitCusor;
|
||||
|
||||
// retrieve associated structure
|
||||
LPNAMESPACEOBJECT lpNameSpaceObject=(LPNAMESPACEOBJECT)plvdi->item.lParam;
|
||||
ASSERT(lpNameSpaceObject!=NULL);
|
||||
|
||||
// rename the item
|
||||
LPITEMIDLIST lpNewRelativeIDL=NULL;
|
||||
if(sNewText.IsEmpty() ||
|
||||
!m_navigator.RenameShellObject(lpNameSpaceObject->lpsfParent,
|
||||
lpNameSpaceObject->lpRelativeIDL,&lpNewRelativeIDL,sNewText))
|
||||
{
|
||||
*pResult=FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(lpNewRelativeIDL!=NULL);
|
||||
lpNameSpaceObject->lpRelativeIDL=lpNewRelativeIDL;
|
||||
*pResult=TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL COXShellObjectList::Refresh()
|
||||
{
|
||||
SetRedraw(FALSE);
|
||||
PopulateList(m_lpsfCurrentParentFolder,m_lpFullIDLCurrentParentFolder);
|
||||
SetRedraw(TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef OXSHELLLIST_WATCHFORDIR
|
||||
|
||||
LRESULT COXShellObjectList::OnDirChangeNotify(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(lParam);
|
||||
|
||||
CString str;
|
||||
|
||||
COXFileWatchNotifier fwNotifier;
|
||||
fwNotifier=m_fileWatcher.GetFileWatchNotifier(wParam);
|
||||
|
||||
// If the wParam is an invalid ID then the notifier is empty
|
||||
if(!fwNotifier.IsEmpty())
|
||||
{
|
||||
CString sDirPath=fwNotifier.GetPath();
|
||||
ASSERT(!sDirPath.IsEmpty());
|
||||
VERIFY(Refresh());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // OXSHELLLIST_WATCHFORDIR
|
||||
|
||||
|
||||
void COXShellObjectList::SetFilter(LPCTSTR lpszExtentions)
|
||||
{
|
||||
m_arrFilter.RemoveAll();
|
||||
|
||||
CString sExtentions=lpszExtentions;
|
||||
if(sExtentions.IsEmpty())
|
||||
return;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int nDelimiterPos=sExtentions.Find(OXSHELLLIST_EXT_DELIMITER);
|
||||
if(nDelimiterPos==-1)
|
||||
{
|
||||
m_arrFilter.Add(sExtentions);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(nDelimiterPos>0)
|
||||
m_arrFilter.Add(sExtentions.Left(nDelimiterPos));
|
||||
sExtentions=sExtentions.Mid(nDelimiterPos+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CString COXShellObjectList::GetFilter() const
|
||||
{
|
||||
TCHAR sDelimiter[2];
|
||||
sDelimiter[0]=OXSHELLLIST_EXT_DELIMITER;
|
||||
sDelimiter[1]=_T('\0');
|
||||
// special case
|
||||
if(m_arrFilter.GetSize()==1 && m_arrFilter[0].IsEmpty())
|
||||
return sDelimiter;
|
||||
|
||||
CString sExtentions(_T(""));
|
||||
for(int nIndex=0; nIndex<m_arrFilter.GetSize(); nIndex++)
|
||||
{
|
||||
sExtentions=(nIndex==0 ? _T("") : sDelimiter)+m_arrFilter[nIndex];
|
||||
}
|
||||
return sExtentions;
|
||||
}
|
||||
|
||||
|
||||
BOOL COXShellObjectList::IsMatchingFilter(LPCTSTR lpszFileName)
|
||||
{
|
||||
ASSERT(lpszFileName!=NULL);
|
||||
|
||||
if(m_arrFilter.GetSize()==0)
|
||||
return TRUE;
|
||||
|
||||
CString sFileName=lpszFileName;
|
||||
CString sExtention(_T(""));
|
||||
int nDelimeterPos=sFileName.Find(_T('.'));
|
||||
if(nDelimeterPos!=0)
|
||||
sExtention=sFileName.Mid(nDelimeterPos+1);
|
||||
|
||||
BOOL bFoundMatch=FALSE;
|
||||
for(int nIndex=0; nIndex<m_arrFilter.GetSize(); nIndex++)
|
||||
{
|
||||
if(sExtention.CompareNoCase(m_arrFilter[nIndex])==0)
|
||||
{
|
||||
bFoundMatch=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bFoundMatch;
|
||||
}
|
||||
|
||||
|
||||
void COXShellObjectList::OnContextMenu(CWnd* pWnd, CPoint pos)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pWnd);
|
||||
|
||||
// TODO: Add your control notification handler code here
|
||||
if(GetEnableContextMenu())
|
||||
{
|
||||
// On right click we display context menu for any item
|
||||
//
|
||||
|
||||
// Get the item that was right clicked in screen coordinates
|
||||
CPoint ptMouseCursor=pos;
|
||||
ScreenToClient(&ptMouseCursor);
|
||||
|
||||
// Use HitTest function to define the list item by coordinate
|
||||
UINT nFlags=NULL;
|
||||
int nItem=HitTest(ptMouseCursor,&nFlags);
|
||||
|
||||
if(nItem!=-1 && (nFlags&LVHT_ONITEM)!=0)
|
||||
{
|
||||
// select the item
|
||||
VERIFY(SetItemState(nItem,LVIS_SELECTED,LVIS_SELECTED));
|
||||
// Get folder info associated with item
|
||||
LPNAMESPACEOBJECT lpNameSpaceObject=
|
||||
(LPNAMESPACEOBJECT)GetItemData(nItem);
|
||||
ASSERT(lpNameSpaceObject!=NULL);
|
||||
|
||||
DWORD dwMenuFlags=CMF_EXPLORE |
|
||||
((((GetStyle()&LVS_EDITLABELS)==LVS_EDITLABELS) &&
|
||||
((lpNameSpaceObject->dwFlags&SFGAO_CANRENAME)==SFGAO_CANRENAME)) ?
|
||||
CMF_CANRENAME : NULL);
|
||||
HMENU hMenu=m_navigator.GetObjectContextMenu(lpNameSpaceObject->lpsfParent,
|
||||
lpNameSpaceObject->lpRelativeIDL,dwMenuFlags);
|
||||
if(hMenu==NULL)
|
||||
{
|
||||
TRACE(_T("COXShellObjectList::OnContextMenu: GetObjectContextMenu() failed\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Display popup menu using Windows API TrackPopupMenu function because
|
||||
// it provides easy way of getting selected menu item. We need to set
|
||||
// screen coordinates of the point where popup menu should be displayed.
|
||||
ClientToScreen(&ptMouseCursor);
|
||||
BOOL nCmdID=::TrackPopupMenu(hMenu,
|
||||
TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON,
|
||||
ptMouseCursor.x,ptMouseCursor.y,0,GetSafeHwnd(),NULL);
|
||||
|
||||
if(nCmdID)
|
||||
{
|
||||
switch(nCmdID)
|
||||
{
|
||||
case IDCMD_RENAME:
|
||||
{
|
||||
EditLabel(nItem);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if(!m_navigator.InvokeCommand(lpNameSpaceObject->lpsfParent,
|
||||
lpNameSpaceObject->lpRelativeIDL,nCmdID,dwMenuFlags))
|
||||
{
|
||||
TRACE(_T("COXShellObjectList::OnContextMenu: InvokeCommand() failed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(nCmdID)
|
||||
{
|
||||
case IDCMD_DELETE:
|
||||
{
|
||||
DeleteItem(nItem);
|
||||
break;
|
||||
}
|
||||
case IDCMD_PASTE:
|
||||
{
|
||||
Refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
::DestroyMenu(hMenu);
|
||||
}
|
||||
else if(m_lpsfCurrentParentFolder!=NULL)
|
||||
{
|
||||
LPITEMIDLIST lpRelativeIDL=NULL;
|
||||
LPSHELLFOLDER pShellFolder= m_navigator.GetParentShellFolder(
|
||||
m_lpFullIDLCurrentParentFolder,&lpRelativeIDL);
|
||||
if(pShellFolder==NULL)
|
||||
{
|
||||
TRACE(_T("COXShellObjectList::OnContextMenu: GetParentShellFolder() failed\n"));
|
||||
return;
|
||||
}
|
||||
ASSERT(lpRelativeIDL!=NULL || m_lpFullIDLCurrentParentFolder==NULL);
|
||||
|
||||
DWORD dwMenuFlags=CMF_EXPLORE;
|
||||
HMENU hMenu=m_navigator.GetObjectContextMenu(
|
||||
pShellFolder,lpRelativeIDL,dwMenuFlags);
|
||||
if(hMenu==NULL)
|
||||
{
|
||||
TRACE(_T("COXShellObjectList::OnContextMenu: GetObjectContextMenu() failed\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
CMenu menuPopup;
|
||||
VERIFY(menuPopup.Attach(hMenu));
|
||||
|
||||
// Display popup menu using Windows API TrackPopupMenu function because
|
||||
// it provides easy way of getting selected menu item. We need to set
|
||||
// screen coordinates of the point where popup menu should be displayed.
|
||||
ClientToScreen(&ptMouseCursor);
|
||||
BOOL nCmdID=::TrackPopupMenu(menuPopup.m_hMenu,
|
||||
TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON,
|
||||
ptMouseCursor.x,ptMouseCursor.y,0,GetSafeHwnd(),NULL);
|
||||
|
||||
if(nCmdID)
|
||||
{
|
||||
switch(nCmdID)
|
||||
{
|
||||
case IDCMD_RENAME:
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if(!m_navigator.InvokeCommand(pShellFolder,lpRelativeIDL,
|
||||
nCmdID,dwMenuFlags))
|
||||
{
|
||||
TRACE(_T("COXShellObjectList::OnContextMenu: InvokeCommand() failed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(nCmdID)
|
||||
{
|
||||
case IDCMD_DELETE:
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
case IDCMD_PASTE:
|
||||
{
|
||||
Refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
VERIFY(menuPopup.DestroyMenu());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue