Click here to Skip to main content
15,893,381 members
Articles / Desktop Programming / MFC

Enumdesk Clones

Rate me:
Please Sign up or sign in to vote.
4.90/5 (19 votes)
9 May 20036 min read 139.6K   3.9K   41  
Eunumdesk Clones
/************************************************
   THIS CODE AND INFORMATION IS PROVIDED 'AS IS' 
   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO
   THE IMPLIED WARRANTIES OF MERCHANTABILITY 
   AND/OR FITNESS FOR A PARTICULAR PURPOSE.
   Author: Barretto VN  7/2002
*************************************************/


// ShellCtrlClasses.cpp : implementation file
//

#include "stdafx.h"
#include "ShellCtrlClasses.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CShellCtrlClasses

CShellCtrlClasses::CShellCtrlClasses()
{
}

CShellCtrlClasses::~CShellCtrlClasses()
{
}


BEGIN_MESSAGE_MAP(CShellCtrlClasses, CWnd)
	//{{AFX_MSG_MAP(CShellCtrlClasses)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CShellCtrlClasses message handlers


/******************************************
*    List Control Class (CShellListCtrl)
*
*
*
*
*
*******************************************/

/////////////////////////////////////////////////////////////////////////////
// CShellListCtrl

CShellListCtrl::CShellListCtrl()
{
	giCtr = 0;
    // Allocate Shell Memory at start-up 
	// for use in various functions throught
	// the application
	HRESULT hr = SHGetMalloc(&m_pMalloc);
	if(FAILED(hr))
	{
		AfxMessageBox(IDS_MEMORY_ERROR);
	}

}

CShellListCtrl::~CShellListCtrl()
{
}


BEGIN_MESSAGE_MAP(CShellListCtrl, CListCtrl)
	//{{AFX_MSG_MAP(CShellListCtrl)
	ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
	ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
	ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
	// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CShellListCtrl message handlers

BOOL CShellListCtrl::SubclassDlgItem(UINT nID, CWnd* pParent)
{
   return CListCtrl::SubclassDlgItem(nID, pParent);
}

/*******************************************************
*  Function : InitilizeCtrl()
*
*  Parameters : none
*
*  Purpose  : Setup ListView Styles and Add columns 
*             and call to setup ImageList
*
*  Comments : Calls InsertListViewItem(...) to insert
*             individual items
*
*  Return : int
********************************************************/
int CShellListCtrl::InitilizeCtrl() 
{
	ModifyStyle(NULL, LVS_REPORT | LVS_SHAREIMAGELISTS, 0);
	SetupImageLists();
	
	CRect rect;
	GetClientRect(&rect);
	InsertColumn(ID_COL_NAME, "Name", LVCFMT_LEFT  , rect.right/2, -1);
	InsertColumn(ID_COL_TYPE, "Type", LVCFMT_LEFT  , rect.right/5, -1);
	InsertColumn(ID_COL_SIZE, "Size", LVCFMT_RIGHT , rect.right/6, -1);
	InsertColumn(ID_COL_DATE, "Date", LVCFMT_LEFT  , rect.right/6, -1);

	return 0;
}

/*******************************************************
*  Function : LVPopulateFiles(LPTVITEMDATA*)
*
*  Parameters : User-defined structure
*
*  Purpose  : To Delete all existing items and
*             insert new items into the List Control
*             from the structure passed by enumerating
*             the passed user-defined structure
*
*  Comments : Calls InsertListViewItem(...) to insert
*             individual items
*
*  Return : none
********************************************************/
void CShellListCtrl::LVPopulateFiles(LPTVITEMDATA* lptvid) 
{
	HRESULT hr;
    ULONG celtFetched;
    LPITEMIDLIST pidlItems = NULL;
    LPENUMIDLIST ppenum = NULL;
    IShellFolder *psfProgFiles = NULL;

	if(lptvid->bRoot)
		psfProgFiles = lptvid->lpsfParent;
	else
	{
	   hr = lptvid->lpsfParent->BindToObject(lptvid->lpi, NULL, IID_IShellFolder, (LPVOID *) &psfProgFiles);
	   if(FAILED(hr))
			return;
	}

	hr = psfProgFiles->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &ppenum);
	if(FAILED(hr))
		return;

	MyDeleteAllItems();
	SetRedraw(FALSE);
	while( hr = ppenum->Next(1,&pidlItems, &celtFetched) == S_OK && (celtFetched) == 1)
    {
		InsertListViewItem(psfProgFiles , pidlItems, lptvid->lpifq);
    }
	SetRedraw(TRUE);
	return;
}	


/************************************************
*  Virtual Function : OnGetdispinfo(....)
*
*  Purpose : Display Text and Icons "On-Demand",
*            this function is called by the
*            system framework when it needs to
*            display items in the ListView
*
*  Comment : 
*
*************************************************/
void CShellListCtrl::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;


	LPTVITEMDATA* lptvid = NULL;
	lptvid = (LPTVITEMDATA*) m_pMalloc->Alloc (sizeof (LPTVITEMDATA));
	lptvid = (LPTVITEMDATA*)pDispInfo->item.lParam;
	CShellClass csc;
	char szBuff[MAX_PATH];

	DWORD dwStyles = SHGFI_PIDL|SHGFI_TYPENAME;
	SHFILEINFO sfi;
	SHGetFileInfo ((LPCSTR)lptvid->lpi, 0, &sfi, sizeof (SHFILEINFO), dwStyles);
	WIN32_FIND_DATA fd;
	SHGetDataFromIDList(lptvid->lpsfParent , lptvid->lpi, SHGDFIL_FINDDATA , (WIN32_FIND_DATA*)&fd , sizeof(fd));

	if (pDispInfo->item.mask & LVIF_IMAGE)
    {
		pDispInfo->item.iImage = csc.GetNormalIcon(lptvid->lpifq);

		ULONG uAttr = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_GHOSTED | SFGAO_LINK | SFGAO_SHARE;
        lptvid->lpsfParent->GetAttributesOf(1, (LPCITEMIDLIST *) &lptvid->lpi, &uAttr);
		if (uAttr & SFGAO_GHOSTED)
		{
			pDispInfo->item.mask |= LVIF_STATE;
			pDispInfo->item.stateMask = LVIS_CUT;
			pDispInfo->item.state = LVIS_CUT;
		}
		if (uAttr & SFGAO_LINK)
		{
			pDispInfo->item.mask |= LVIF_STATE;
			pDispInfo->item.stateMask = LVIS_OVERLAYMASK;
			pDispInfo->item.state = INDEXTOOVERLAYMASK(2);
		}
		if (uAttr & SFGAO_SHARE)
		{
			pDispInfo->item.mask |= LVIF_STATE;
			pDispInfo->item.stateMask = LVIS_OVERLAYMASK;
			pDispInfo->item.state = INDEXTOOVERLAYMASK(1);
		}

	}

	if (pDispInfo->item.mask & LVIF_TEXT)
	{
		switch(pDispInfo->item.iSubItem)
		{
	
		    case ID_COL_NAME:
			{
				csc.GetName(lptvid->lpsfParent, lptvid->lpi, SHGDN_NORMAL, szBuff);
				_tcscpy(pDispInfo->item.pszText, szBuff);
				break;
			}
		case ID_COL_TYPE:
			{
				SHFILEINFO fileInfo;
				SHGetFileInfo((LPCTSTR)lptvid->lpi, NULL, &fileInfo, sizeof(fileInfo), SHGFI_PIDL|SHGFI_TYPENAME);
				_tcscpy(pDispInfo->item.pszText,fileInfo.szTypeName);
				break;
			}
				case ID_COL_SIZE:
			{
				if(fd.dwFileAttributes != 3435973836)
				{
					char sNumBuff[30];
					if(fd.nFileSizeLow)
					{
						if(fd.nFileSizeLow > 1024)
						{
							ltoa((long)fd.nFileSizeLow/1024,sNumBuff,10);
							strcat(sNumBuff, " KB");
						}
						else
							ltoa((long)fd.nFileSizeLow,sNumBuff,10);
					}
					else
						strcpy(sNumBuff,"");
	
					_tcscpy(pDispInfo->item.pszText,sNumBuff);
				}
				break;
			}

			case ID_COL_DATE:
			{
				if(fd.dwFileAttributes != 3435973836)
				{
					char refTime[20];
					SYSTEMTIME st;
					FileTimeToSystemTime( &fd.ftLastWriteTime, &st );
					wsprintf(refTime, "%02u-%02u-%04u" , st.wMonth, st.wDay, st.wYear ); 
					_tcscpy(pDispInfo->item.pszText, refTime);
				}
				break;
			}
		}
	}
	
	*pResult = 0;
}
/************************************************
*  Virtual Function : OnDblclk(....)
*
*  Purpose : Called by the Framework when the user
*            double-click on a the List Control area
*
*  Comment : if the clicked item is a folder, 
*            SelectThisItem(..) function in the 
*            CShellTreeView class is called to
*            expand the the Treeview after searching
*            for the passed character string
*
*************************************************/
void CShellListCtrl::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) 
{

	// User has double-clicked, get the clicked Item
	// depending on the clicked point
	LVHITTESTINFO lvhInf;
	GetCursorPos(&lvhInf.pt);
	ScreenToClient(&lvhInf.pt);
	int item = ListView_HitTest(m_hWnd, &lvhInf);
	if((LVHT_ONITEMLABEL & lvhInf.flags ) || (LVHT_ONITEMICON & lvhInf.flags))
	{

       LPTVITEMDATA* lptvid = NULL;
       lptvid = (LPTVITEMDATA*) m_pMalloc->Alloc (sizeof (LPTVITEMDATA));

	   LVITEM lvi;
	   lvi.mask = LVIF_PARAM;
	   lvi.iItem = lvhInf.iItem;
       ListView_GetItem(m_hWnd, &lvi);
	   lptvid = (LPTVITEMDATA*)lvi.lParam;

       ULONG uAttr = SFGAO_FOLDER;
       lptvid->lpsfParent->GetAttributesOf(1, (LPCITEMIDLIST *) &lptvid->lpi, &uAttr);

	   // is the item a Folder

	   if(uAttr & SFGAO_FOLDER)
	   {
		   char szBuff[MAX_PATH];
		   CShellClass csc;
		   csc.GetName(lptvid->lpsfParent , lptvid->lpi , SHGDN_NORMAL, szBuff);
//		   this->m_pShellTreeCtrl->SelectThisItem(szBuff);
	   }
       else
       // display a popup-menu
			ShowStdMenu(FALSE, lptvid);

	}

	*pResult = 0;
}

/*******************************************************
*  Function : InsertListViewItem(LPSHELLFOLDER,
*                                LPITEMIDLIST,
*                                LPITEMIDLIST)
*
*  Parameters : Shellfolder, ItemIDList of the selected
*               item , and Fully Qualified ItemIDList of
*               the selected item
*
*  Purpose  : Create a structure and insert the
*               item in the ListView for later retreival
*               and update in OnGetdispinfo Virtual
*               function
* Comments : This function passes the LPARAM to 
*            the ListView but does not itself 
*            display the item, Icons and Text 
*            are inserted and displayed on-demand 
*            in the function OnGetdispinfo() below
*
*  Return : UINT
********************************************************/
BOOL CShellListCtrl::InsertListViewItem(LPSHELLFOLDER lpsf, 
									    LPITEMIDLIST lpi,
									    LPITEMIDLIST lpifq)
{

	UINT uFlags;
	LV_ITEM lvi;
	lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
	CShellClass csc;
	char szBuff[MAX_PATH];
	csc.GetName (lpsf, lpi, SHGDN_NORMAL, szBuff);

	lvi.iItem = giCtr++;
	lvi.iSubItem = ID_COL_NAME;
	lvi.pszText =  LPSTR_TEXTCALLBACK; 
	uFlags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON;
	LPTVITEMDATA* lptvid = NULL;
	lptvid = (LPTVITEMDATA*) m_pMalloc->Alloc (sizeof (LPTVITEMDATA));

	lvi.iImage = I_IMAGECALLBACK; 
	lptvid->lpsfParent = lpsf;
	lptvid->lpi = csc.CopyItemID(m_pMalloc, lpi);
	lptvid->lpifq = csc.Concatenate(m_pMalloc, lpifq,lpi); 
	lvi.lParam = (LPARAM)lptvid;
	// This function passes the LPARAM to the ListView
	// but does not itself display the item
	// Icons and Text are inserted and displayed
	// on-demand in the function OnGetdispinfo() below
	int iItem = InsertItem (&lvi);

	return TRUE;
}

void CShellListCtrl::MyDeleteAllItems()
{
	DeleteAllItems();
	giCtr = 0;
}


/*******************************************************
*  Function : SetupImageLists()
*  
*  Parameters : none
*
*  Purpose  : Get ImageLists of 3 type 
*             (Normal / Small / State)
*             from the CShellClass and
*             add to the ListView
* 
*  Comments : 
*
*  Return : void
********************************************************/
void CShellListCtrl::SetupImageLists()
{
	CShellClass csc;
	HIMAGELIST himlSmall, himlLarge;
	himlSmall = csc.GetImageList(TRUE);
	himlLarge = csc.GetImageList(FALSE);
	SetImageList(m_pImageListL.FromHandle(himlLarge), LVSIL_NORMAL); 
	SetImageList(m_pImageListS.FromHandle(himlSmall), LVSIL_SMALL); 
	SetImageList(m_pImageListS.FromHandle(himlSmall), LVSIL_STATE); 
}

/*******************************************************
*  Function : ShowStdMenu(BOOL, LPTVITEMDATA*)
*
*  Parameters : True if menu should be displayed, User-defined
*               structure
*
*  Purpose  :  Call CShellContextMenuClass class to
*              display the Shells Context-menu depending
*              on the parameter 1
*
*  Comments : 
*
*  Return : none
********************************************************/
void CShellListCtrl::ShowStdMenu(BOOL bShowMenu ,  LPTVITEMDATA* lptvid)
{
   CShellContextMenuClass cmc;
   cmc.ShowMenu(lptvid, bShowMenu, m_hWnd);
   return;
}

/************************************************
*  Virtual Function : OnRclick(....)
*
*  Purpose : Called by the Framework when the user
*            right-click on the client area
*
*  Comment : Calls CShellContextMenuClass class to 
*            display a pop-menu menu to select 
*            ListView Styles like Small Icons, Large 
*            Icons etc...
*
*************************************************/
void CShellListCtrl::OnRclick(NMHDR* pNMHDR, LRESULT* pResult) 
{
    POSITION pos = GetFirstSelectedItemPosition();
	if(pos == NULL)
	{
		CShellContextMenuClass cmc;
		cmc.ShowViewStyleMenu(*this);
	}

	*pResult = 0;
}



/******************************************
*    Tree Control Class (CShellTreeCtrl)
*
*
*
*
*
*******************************************/



/////////////////////////////////////////////////////////////////////////////
// CShellTreeCtrl

CShellTreeCtrl::CShellTreeCtrl()
{
	m_pShellListCtrl = NULL;
	m_pSelectedItem = NULL;
	HRESULT hr = SHGetMalloc(&m_pMalloc);
	if(FAILED(hr))
	{
		AfxMessageBox(IDS_MEMORY_ERROR);
	}

}

CShellTreeCtrl::~CShellTreeCtrl()
{
}


BEGIN_MESSAGE_MAP(CShellTreeCtrl, CTreeCtrl)
	//{{AFX_MSG_MAP(CShellTreeCtrl)
	ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
	ON_NOTIFY_REFLECT(TVN_SELCHANGING, OnSelchanging)
	// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CShellTreeCtrl message handlers


BOOL CShellTreeCtrl::SubclassDlgItem(UINT nID, CWnd* pParent)
{
   return CTreeCtrl::SubclassDlgItem(nID, pParent);
}

/************************************************
*  Function : InitilizeCtrl()
*
*  Purpose : Set the initial Style of the Tree
*            control , create and setup ImageList
*            and Insert the Desktop Item
*
*  Comment : Calls SetImageLists() to setup
*            ImageList for display and the calls
*            InsertDesktopItem(...) to insert the 
*            Desktop Folder Item
*
*************************************************/
void CShellTreeCtrl::InitializeCtrl() 
{

	ModifyStyle(NULL,  TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT, 0);

	SetupImages();

	LPSHELLFOLDER lpsf = NULL;
	HRESULT hr;

	HTREEITEM hParent = NULL;
	hr = SHGetDesktopFolder (&lpsf);
	if (SUCCEEDED (hr))
	{
		hParent = InsertDesktopItem(lpsf);
		lpsf->Release ();
	}
}

/*******************************************************
*  Function : SetupImageList()
*  
*  Parameters : none
*
*  Purpose  : Get ImageList and set it for 
*             use by the Tree when displaying Images
* 
*  Comments : Calls CShellClass to retreive a handle
*             to the Imagelists, we get 2 different
*             Image List one for normal and selected 
*             images and other for State Images (masked
*             type)
*
*  Return : void
********************************************************/
void CShellTreeCtrl::SetupImages()
{
	CShellClass csc;
	HIMAGELIST himagelist;
	himagelist = csc.GetImageList();
	SetImageList(m_pImageList.FromHandle(himagelist), TVSIL_NORMAL); 
	SetImageList(m_pImageList.FromHandle(himagelist), TVSIL_STATE); 
}

/*******************************************************
*  Function : InsertDesktopItem(LPSHELLFOLDER)
*  
*  Parameters : Initial Desktop Shell folder
*
*  Purpose  : To add the Desktop folder to the Tree
* 
*  Comments : Expand the Tree after adding the Desktop
*             item so as to force the Framework to 
*             call OnItemexpanding(..) to add further
*             items.
*
*  Return : HTREEITEM
********************************************************/
HTREEITEM CShellTreeCtrl::InsertDesktopItem(LPSHELLFOLDER lpsf)
{
	LPITEMIDLIST lpi = NULL;
	HTREEITEM hParent = NULL;
	CShellClass csc;
    char szBuff [MAX_PATH];
	TVINSERTSTRUCT tvins;
	SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &lpi);
	csc.InsertTreeItemTE(TRUE, &tvins, szBuff, NULL, NULL , lpsf , NULL, lpi , TRUE, "");
	hParent = InsertItem(&tvins);
	Expand(hParent, TVE_EXPAND);

	return hParent;
}

/*******************************************************
*  Function : PopulateTree(NMHDR*)
*  
*  Parameters : Header of the selected Tree Item,
*               called by virtual function 
*               OnItemexpanding(..)
*
*  Purpose  : To delete all child item of the sent
*             item populate with new items
* 
*  Comments : If we are using a ListView, the items
*             in the Listview are first deleted and
*             new added depening on the LPARAM of the
*             user-defined structure (LPTVITEMDATA*)
*
*  Return : BOOL
********************************************************/
BOOL CShellTreeCtrl::PopulateTree(NMHDR *pNMHDR)
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	HTREEITEM hItem = pNMTreeView->itemNew.hItem;
	LPTVITEMDATA* lptvid = NULL;

	HRESULT hr;
    lptvid = (LPTVITEMDATA*) m_pMalloc->Alloc (sizeof (LPTVITEMDATA));
	if (! lptvid)
	{
		AfxMessageBox(IDS_MEMORY_ERROR);
		return FALSE; // Error - could not allocate memory
	}

	lptvid = (LPTVITEMDATA*)pNMTreeView->itemNew.lParam;
	if(lptvid == NULL)
		return FALSE;

	LPENUMIDLIST lpe = NULL;	
    ULONG celtFetched;
    LPITEMIDLIST pidlItems = NULL;
    LPENUMIDLIST ppenum = NULL;
    IShellFolder *psfProgFiles = NULL;

	CWaitCursor wait;

	if(lptvid->bRoot)
		psfProgFiles = lptvid->lpsfParent;
	else
	{
		hr = lptvid->lpsfParent->BindToObject(lptvid->lpi, NULL, IID_IShellFolder, (LPVOID *) &psfProgFiles);
		if(psfProgFiles == NULL)
				return FALSE;
	}

    hr = psfProgFiles->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN , &ppenum);
	if(ppenum == NULL)
		return FALSE;

	DeleteChildren(hItem);
	
	if(m_pShellListCtrl != NULL)
		m_pShellListCtrl->MyDeleteAllItems();

	while( hr = ppenum->Next(1,&pidlItems, &celtFetched) == S_OK && (celtFetched) == 1)
    {

		char szBuff[MAX_PATH];
		TVINSERTSTRUCT tvins;
		ULONG uAttr = SFGAO_FOLDER;
		psfProgFiles->GetAttributesOf(1, (LPCITEMIDLIST *) &pidlItems, &uAttr);
		CShellClass csc;
		if(m_pShellListCtrl == NULL)
		{
			csc.InsertTreeItemTE(FALSE, &tvins, szBuff, hItem, NULL , psfProgFiles , lptvid->lpifq, pidlItems , TRUE, "");
			HTREEITEM hPrev = InsertItem(&tvins);
		}
		else 
			if(uAttr & SFGAO_FOLDER)
			{
				csc.InsertTreeItemTE(FALSE, &tvins, szBuff, hItem, NULL , psfProgFiles , lptvid->lpifq, pidlItems , TRUE, "");
				HTREEITEM hPrev = InsertItem(&tvins);
			}
    }

	return TRUE;
}

/*******************************************************
*  Function : DeleteChildren(HTREEITEM)
*  
*  Parameters : selected Tree Item
*
*  Purpose  : Delete all child Items of this Item
* 
*  Comments : 
*
*  Return : UINT
********************************************************/
UINT CShellTreeCtrl::DeleteChildren(HTREEITEM hItem)
{

    UINT nCount = 0;
    HTREEITEM hChild = GetChildItem (hItem);

    while (hChild != NULL) {
        HTREEITEM hNextItem = GetNextSiblingItem (hChild);
        DeleteItem (hChild);
        hChild = hNextItem;
        nCount++;
    }
    return nCount;
}

/************************************************
*  Virtual Function : OnItemexpanding(....)
*
*  Purpose : Populate the Tree Item (if Expanding)
*            also populate the ListView depending
*            on the Tree Item clicked
*
*  Comment : 
*
*************************************************/
void CShellTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

	if(PopulateTree(pNMHDR))
		*pResult = 0;
	else
		*pResult = 1;
	
	*pResult = 0;
}

/************************************************
*  Virtual Function : OnSelchanging(....)
*
*  Purpose : User clicked on the Text of a Tree item
*            populate the ListView if it exists else
*            show the Shells pop-up menu for the 
*            clicked item
*
*  Comment : 
*
*************************************************/
void CShellTreeCtrl::OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	HTREEITEM hItem = pNMTreeView->itemNew.hItem;

	if(!(pNMTreeView->action))
		return;
	
	LPTVITEMDATA* lptvid = NULL;
	m_pSelectedItem = hItem;

    lptvid = (LPTVITEMDATA*) m_pMalloc->Alloc (sizeof (LPTVITEMDATA));
	if (! lptvid)
	{
		AfxMessageBox(IDS_MEMORY_ERROR);
		return; // Error - could not allocate memory
	}

	lptvid = (LPTVITEMDATA*)pNMTreeView->itemNew.lParam;
	if(lptvid == NULL)
		return;

	if(pNMTreeView->action != 4096)
		if(m_pShellListCtrl != NULL)
			m_pShellListCtrl->LVPopulateFiles(lptvid);
		else
		{
				ULONG uAttr = SFGAO_FOLDER;
				lptvid->lpsfParent->GetAttributesOf(1, (LPCITEMIDLIST *) &lptvid->lpi, &uAttr);
				if(!(uAttr & SFGAO_FOLDER))
				{
					CShellContextMenuClass cmc;
					cmc.ShowMenu(lptvid, FALSE, m_hWnd);
				}
		}

	*pResult = 0;
}








/******************************************
*    Context Menu Class (CContextMenuClass)
*
*
*
*
*
*******************************************/

CShellContextMenuClass::CShellContextMenuClass()
{
}

CShellContextMenuClass::~CShellContextMenuClass()
{
}


/*******************************************************
*  Function : ShowMenu(LPTVITEMDATA, BOOL, HWND)
*  
*  Parameters : 1) ItemIDList of the selected item
*               2) True if menu should be displayed 
*				   False otherwise
*				3) Handle of the control (could be
*				   List or Tree control)
* 
*  Purpose : Displays a pop-up menu depending on the
*            parameters passed else executes the command
*
*  Comments : 
*
*  Return : void
********************************************************/

void CShellContextMenuClass::ShowMenu(LPTVITEMDATA *lptvid, 
								 BOOL bShowMenu,
								 HWND m_hWnd) 
{

	HRESULT hr;
	HMENU hMenuPopup;
	IContextMenu   *icm;
	IContextMenu2* icm2;
	static POINT point;
	GetCursorPos(&point);
    
	hr = lptvid->lpsfParent->GetUIObjectOf(m_hWnd, 
                               1, 
                               (LPCITEMIDLIST*)&lptvid->lpi,
                               IID_IContextMenu, 
                               NULL, 
                               (LPVOID*)&icm);

	 if(FAILED(hr))
		 return;

     hMenuPopup = CreatePopupMenu();
     if(!hMenuPopup)
		 return;

     hr = icm->QueryContextMenu(hMenuPopup, 0, 1, 0x7fff, CMF_NORMAL | CMF_EXPLORE);
     if(FAILED(hr))
		 return;

     icm->QueryInterface(IID_IContextMenu2, (LPVOID*)&icm2);
     UINT  id;
	 if(bShowMenu)
		id = TrackPopupMenu(hMenuPopup, 
                  TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, 
                  point.x,point.y,0,m_hWnd,NULL);
	else
		id = hr;

	if(!id)
		return;
    
    CMINVOKECOMMANDINFO  ici;
    ici.cbSize = sizeof(CMINVOKECOMMANDINFO);
    ici.fMask = 0;
    ici.hwnd = m_hWnd;
    ici.lpVerb = (LPCSTR)(INT_PTR)(id - 1);
    ici.lpParameters = NULL;
    ici.lpDirectory = NULL;
    ici.nShow = SW_SHOWNORMAL;
    ici.dwHotKey = 0;
    ici.hIcon = NULL;
    hr = icm->InvokeCommand(&ici);

}


/*******************************************************
*  Function : ShowViewStyleMenu(CListCtrl)
*  
*  Parameters : Referance of the ListControl
* 
*  Purpose : Display a popup menu and change the
*            ListView Style depending on the selection
*
*  Comments : 
*
*  Return : void
********************************************************/

void CShellContextMenuClass::ShowViewStyleMenu(CListCtrl& mListCtrl)
{

#define ID_LARGEICONS 5001
#define ID_SMALLICONS 5002
#define ID_LIST       5003
#define ID_DETAILS    5004
#define ID_LINES      5005
	
	CMenu menu;
    menu.CreatePopupMenu();
    menu.AppendMenu(MF_STRING | MF_ENABLED, ID_LARGEICONS, "&Large Icons");
    menu.AppendMenu(MF_STRING | MF_ENABLED, ID_SMALLICONS, "&Small Icons");
    menu.AppendMenu(MF_STRING | MF_ENABLED, ID_LIST      , "L&ist");
    menu.AppendMenu(MF_STRING | MF_ENABLED, ID_DETAILS   , "&Details");

	POINT pt;
	GetCursorPos(&pt);
	UINT mOptionSelected = menu.TrackPopupMenu(TPM_LEFTALIGN |
	   TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, mListCtrl.FromHandle(mListCtrl.m_hWnd));
	
	switch(mOptionSelected)
	{
	case ID_LARGEICONS:
        mListCtrl.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
		break;
	case ID_SMALLICONS:
        mListCtrl.ModifyStyle(LVS_TYPEMASK, LVS_SMALLICON);
		break;
	case ID_LIST:
        mListCtrl.ModifyStyle(LVS_TYPEMASK, LVS_LIST);
		break;
	case ID_DETAILS:
        mListCtrl.ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
		break;
	}

}


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
India India
Nothing to boast about

Comments and Discussions