/************************************************
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
*************************************************/
// FilesView.cpp : implementation file
//
#include "stdafx.h"
#include "Shell.h"
#include "FilesView.h"
#include "ShellDoc.h"
#include "ShellClass.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
UINT gnFormat = TYMED_HGLOBAL;
typedef struct tagDROPDATA {
char cPathName[MAX_PATH];
} DROPDATA;
/////////////////////////////////////////////////////////////////////////////
// CFilesView
IMPLEMENT_DYNCREATE(CFilesView, CListView)
CFilesView::CFilesView()
{
gbSetCursor=FALSE;
ghCurrentCursor=NULL;
giCtr = -1;
HRESULT hr = SHGetMalloc(&m_pMalloc);
if (FAILED (hr))
{
AfxMessageBox(IDS_MEMORY_ERROR);
return;
}
}
CFilesView::~CFilesView()
{
}
BEGIN_MESSAGE_MAP(CFilesView, CListView)
//{{AFX_MSG_MAP(CFilesView)
ON_WM_CREATE()
ON_WM_SIZE()
ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
ON_WM_LBUTTONDOWN()
ON_WM_SETCURSOR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFilesView drawing
void CFilesView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
}
/////////////////////////////////////////////////////////////////////////////
// CFilesView diagnostics
#ifdef _DEBUG
void CFilesView::AssertValid() const
{
CListView::AssertValid();
}
void CFilesView::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CFilesView message handlers
BOOL CFilesView::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= LVS_REPORT | LVS_SHAREIMAGELISTS;
return CListView::PreCreateWindow(cs);
}
int CFilesView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListView::OnCreate(lpCreateStruct) == -1)
return -1;
m_DropTarget.Register(this);
CShellDoc* pDoc = (CShellDoc*)GetDocument();
pDoc->m_FilesView = this;
GetListCtrl().InsertColumn(0, "Name", LVCFMT_LEFT , 0, -1);
GetListCtrl().InsertColumn(1, "Type", LVCFMT_LEFT , 0, -1);
SetupImageLists();
return 0;
}
void CFilesView::OnSize(UINT nType, int cx, int cy)
{
CListView::OnSize(nType, cx, cy);
if(GetSafeHwnd())
{
GetListCtrl().SetColumnWidth(0, cx/2);
GetListCtrl().SetColumnWidth(1, cx/2);
}
}
BOOL CFilesView::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 = 0 ; //COL_NAME;
lvi.pszText = szBuff; // LPSTR_TEXTCALLBACK;
lvi.cchTextMax = MAX_PATH;
uFlags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON;
LPMALLOC lpMalloc;
SHGetMalloc(&lpMalloc);
LPTVITEMDATA* lptvid = NULL;
lptvid = (LPTVITEMDATA*) lpMalloc->Alloc (sizeof (LPTVITEMDATA));
LPITEMIDLIST pidl = csc.Concatenate(lpMalloc, lpifq,lpi);
lvi.iImage = csc.GetNormalIcon(pidl); //I_IMAGECALLBACK;
lptvid->lpsfParent = lpsf;
lptvid->lpi = csc.CopyItemID(lpMalloc, lpi);
lptvid->lpifq = pidl; //csc.CopyItemID(lpMalloc, pidl);
lvi.lParam = (LPARAM)lptvid;
int iItem = GetListCtrl().InsertItem (&lvi);
lpMalloc->Release();
return TRUE;
DWORD dwStyles = SHGFI_PIDL|SHGFI_TYPENAME;
SHFILEINFO sfi;
SHGetFileInfo ((LPCSTR)lpi, 0, &sfi, sizeof (SHFILEINFO), dwStyles);
WIN32_FIND_DATA fd;
SHGetDataFromIDList(lpsf , lpi, SHGDFIL_FINDDATA , (WIN32_FIND_DATA*)&fd , sizeof(fd));
if(fd.dwFileAttributes == 3435973836)
return FALSE;
lvi.mask = LVIF_TEXT;
lvi.iItem = iItem;
lvi.iSubItem = 1; //COL_TYPE;
lvi.pszText = sfi.szTypeName;
GetListCtrl().SetItem(&lvi); //iItem, 1 , LVIF_TEXT, sfi.szTypeName , 0, LVIF_STATE,LVIF_STATE, NULL);
if(fd.nFileSizeLow)
{
char sNumBuff[30];
if(fd.nFileSizeLow != 0)
ltoa((long)fd.nFileSizeLow,sNumBuff,10);
else
strcpy(sNumBuff,"");
lvi.mask = LVIF_TEXT;
lvi.iItem = iItem;
lvi.iSubItem = 2; //COL_SIZE;
lvi.pszText = sNumBuff;
GetListCtrl().SetItem(&lvi);
}
// Add Time column
CTime refTime;
// if(fd.ftCreationTime != -1)
{
refTime = fd.ftLastWriteTime; //.ftCreationTime;
CString sText = refTime.Format( "%b-%d-%Y" );
lvi.mask = LVIF_TEXT;
lvi.iItem = iItem;
lvi.iSubItem = 3; //COL_DATE;
lvi.pszText = sText.GetBuffer(sText.GetLength());
GetListCtrl().SetItem(&lvi);
}
return TRUE;
}
void CFilesView::MyDeleteAllItems()
{
if(giCtr != -1)
GetListCtrl().DeleteAllItems();
giCtr = -1;
}
void CFilesView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
{
POSITION pos = GetListCtrl().GetFirstSelectedItemPosition();
if(pos == NULL)
return;
LPTVITEMDATA* lptvid = NULL;
lptvid = (LPTVITEMDATA*) m_pMalloc->Alloc (sizeof (LPTVITEMDATA));
LV_ITEM lvi;
int iItem = GetListCtrl().GetNextSelectedItem(pos);
memset(&lvi,0,sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
lvi.iItem = iItem;
lvi.iSubItem = 0;
GetListCtrl().GetItem(&lvi);
lptvid = (LPTVITEMDATA*)lvi.lParam;
ULONG uAttr = SFGAO_FOLDER;
lptvid->lpsfParent->GetAttributesOf(1, (LPCITEMIDLIST *) &lptvid->lpi, &uAttr);
if(uAttr & SFGAO_FOLDER)
{
CShellDoc* pDoc = (CShellDoc*)GetDocument();
pDoc->m_HTMLView->ShowIt(lptvid->lpifq);
PopulateFiles(lptvid->lpsfParent, lptvid->lpi, lptvid->lpifq);
}
else
SetupPopupmenu(FALSE);
*pResult = 0;
}
void CFilesView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)
{
SetupPopupmenu(TRUE);
*pResult = 0;
}
void CFilesView::SetupPopupmenu(BOOL bShowMenu)
{
POSITION pos = GetListCtrl().GetFirstSelectedItemPosition();
if(pos == NULL)
ShowViewStyleMenu();
else
ShowStdMenu(bShowMenu, pos);
}
void CFilesView::ShowMenu(LPSHELLFOLDER lpsfParent, LPITEMIDLIST lpi, LPITEMIDLIST lpifq, BOOL bShowMenu)
{
CShellDoc* pDoc = (CShellDoc*)GetDocument();
HRESULT hr;
HMENU hMenuPopup;
IContextMenu *icm;
IContextMenu2* icm2;
static POINT point;
GetCursorPos(&point);
hr = lpsfParent->GetUIObjectOf(this->m_hWnd,
1,
(LPCITEMIDLIST*)&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,
this->m_hWnd,NULL);
else
{
char szBuff[MAX_PATH];
SHGetPathFromIDList(lpi, szBuff);
if(IsViewableFile(szBuff))
{
pDoc->m_TreeView->m_pRightPane->SwitchToView(1);
pDoc->m_TreeView->m_pRightPane->m_pWebView->Navigate2Site(lpifq);
return;
}
else
id = hr;
}
if(!id)
return;
CMINVOKECOMMANDINFO ici;
ici.cbSize = sizeof(CMINVOKECOMMANDINFO);
ici.fMask = 0;
ici.hwnd = this->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);
}
void CFilesView::PopulateFiles(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, LPITEMIDLIST lpifq)
{
HRESULT hr;
ULONG celtFetched;
LPITEMIDLIST pidlItems = NULL;
LPENUMIDLIST ppenum = NULL;
IShellFolder *psfProgFiles = NULL;
MyDeleteAllItems();
hr = lpsf->BindToObject(lpi, NULL, IID_IShellFolder, (LPVOID *) &psfProgFiles);
if(FAILED(hr))
return;
hr = psfProgFiles->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &ppenum);
if(FAILED(hr))
return;
GetListCtrl().SetRedraw(FALSE);
while( hr = ppenum->Next(1,&pidlItems, &celtFetched) == S_OK && (celtFetched) == 1)
{
InsertListViewItem(psfProgFiles , pidlItems, lpifq);
}
GetListCtrl().SetRedraw(TRUE);
}
void CFilesView::ShowViewStyleMenu()
{
CMenu menu;
VERIFY(menu.LoadMenu(IDR_FILESVIEW_POPUPMENU));
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
POINT pt;
GetCursorPos(&pt);
UINT mOptionSelected = pPopup->TrackPopupMenu(TPM_LEFTALIGN |
TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, this);
switch(mOptionSelected)
{
case ID_LARGEICONS:
GetListCtrl().ModifyStyle(LVS_TYPEMASK, LVS_ICON);
break;
case ID_SMALLICONS:
GetListCtrl().ModifyStyle(LVS_TYPEMASK, LVS_SMALLICON);
break;
case ID_LIST:
GetListCtrl().ModifyStyle(LVS_TYPEMASK, LVS_LIST);
break;
case ID_DETAILS:
GetListCtrl().ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
break;
}
}
void CFilesView::SetupImageLists()
{
CShellClass csc;
HIMAGELIST himlSmall, himlLarge;
himlSmall = csc.GetImageList(TRUE);
himlLarge = csc.GetImageList(FALSE);
GetListCtrl().SetImageList(m_pImageListL.FromHandle(himlLarge), LVSIL_NORMAL);
GetListCtrl().SetImageList(m_pImageListS.FromHandle(himlSmall), LVSIL_SMALL);
}
void CFilesView::GetLVItemData(POSITION pos, LPTVITEMDATA* lptvid)
{
LV_ITEM lvi;
int iItem = GetListCtrl().GetNextSelectedItem(pos);
memset(&lvi,0,sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
lvi.iItem = iItem;
lvi.iSubItem = 0;
GetListCtrl().GetItem(&lvi);
lptvid = (LPTVITEMDATA*)lvi.lParam;
return;
}
void CFilesView::ShowStdMenu(BOOL bShowMenu , POSITION pos)
{
LPTVITEMDATA* lptvid = NULL;
LV_ITEM lvi;
int iItem = GetListCtrl().GetNextSelectedItem(pos);
memset(&lvi,0,sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
lvi.iItem = iItem;
lvi.iSubItem = 0;
GetListCtrl().GetItem(&lvi);
lptvid = (LPTVITEMDATA*) m_pMalloc->Alloc (sizeof (LPTVITEMDATA));
if (! lptvid)
{
AfxMessageBox(IDS_MEMORY_ERROR);
return; // Error - could not allocate memory
}
lptvid = (LPTVITEMDATA*)lvi.lParam;
if(lptvid->lpsfParent)
ShowMenu(lptvid->lpsfParent, lptvid->lpi, lptvid->lpifq, bShowMenu);
}
void CFilesView::OnLButtonDown(UINT nFlags, CPoint point)
{
LVHITTESTINFO pinfo;
pinfo.pt.x = point.x;
pinfo.pt.y = point.y;
if(GetListCtrl().HitTest(&pinfo) == -1)
return;
LPTVITEMDATA* lptvid = NULL;
lptvid = (LPTVITEMDATA*) m_pMalloc->Alloc (sizeof (LPTVITEMDATA));
LV_ITEM lvi;
memset(&lvi,0,sizeof(lvi));
lvi.mask = LVIF_PARAM;
lvi.iItem = pinfo.iItem;
lvi.iSubItem = 0;
GetListCtrl().GetItem(&lvi);
lptvid = (LPTVITEMDATA*)lvi.lParam;
COleDataSource ods;
HANDLE hData = ::GlobalAlloc (GMEM_MOVEABLE | GMEM_SHARE, sizeof (LPTVITEMDATA));
DROPDATA* pItemData = (DROPDATA*)::GlobalLock(hData);
char strPath[MAX_PATH];
SHGetPathFromIDList(lptvid->lpifq, strPath);
strncpy(pItemData->cPathName, strPath, strlen(strPath));
::GlobalUnlock (hData);
gnFormat = TYMED_HGLOBAL;
ods.CacheGlobalData(gnFormat, hData);
DROPEFFECT de = ods.DoDragDrop (DROPEFFECT_COPY | DROPEFFECT_MOVE);
CListView::OnLButtonDown(nFlags, point);
}
BOOL CFilesView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if(gbSetCursor)
{
gbSetCursor = FALSE;
return TRUE;
}
return FALSE;
}
BOOL CFilesView::IsViewableFile(char filename[MAX_PATH])
{
CString file, ext;
file = filename;
ext = file.Mid(file.ReverseFind('.')+1);
ext.MakeLower();
if((ext == "cpp") ||
(ext == "c") ||
(ext == "h") ||
(ext == "clw") ||
(ext == "dsp") ||
(ext == "dsw") ||
(ext == "plg") ||
(ext == "txt") ||
(ext == "htm") || (ext == "html") ||
(ext == "gif") ||
(ext == "jpg") || (ext == "jpeg") ||
(ext == "png")
)
return TRUE;
else
return FALSE;
}
DROPEFFECT CFilesView::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
return CListView::OnDragEnter(pDataObject, dwKeyState, point);
}
void CFilesView::OnDragLeave()
{
CListView::OnDragLeave();
}
DROPEFFECT CFilesView::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
return CListView::OnDragOver(pDataObject, dwKeyState, point);
}
BOOL CFilesView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
{
return CListView::OnDrop(pDataObject, dropEffect, point);
}
BOOL CFilesView::OnScrollBy(CSize sizeScroll, BOOL bDoScroll)
{
return CListView::OnScrollBy(sizeScroll, bDoScroll);
}