www.pudn.com > source.rar > ShellList.cpp


// ShellList.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "flashnow.h" 
#include "ShellList.h" 
#include "BrowserList.h" 
#include "BrowserFrame.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CShellList 
 
CShellList::CShellList() 
{ 
    p_Tree=NULL; 
    h_TreeItem=NULL; 
    m_ViewStyle=2; 
    m_Refresh=FALSE; 
    m_ShowFlashOnly=FALSE; 
} 
 
CShellList::~CShellList() 
{ 
    m_LargeList.Detach(); 
    m_SmallList.Detach(); 
} 
 
 
BEGIN_MESSAGE_MAP(CShellList, CListCtrl) 
//{{AFX_MSG_MAP(CShellList) 
ON_NOTIFY_REFLECT(NM_RCLICK, OnRClick) 
ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblClick) 
ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemChanged) 
ON_WM_CREATE() 
ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnDeleteItem) 
ON_WM_CHAR() 
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndLabelEdit) 
ON_WM_KEYUP() 
//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CShellList message handlers 
 
void CShellList::OnRClick(NMHDR* pNMHDR, LRESULT* pResult) 
{ 
    HD_NOTIFY *phdn=(HD_NOTIFY *)pNMHDR; 
    if(phdn->iItem<0) 
    { 
        POINT pt; 
        GetCursorPos(&pt); 
         
        CMenu Menu; 
        Menu.LoadMenu(IDM_LIST_POP); 
        CMenu* pMenu = Menu.GetSubMenu(0); 
        pMenu->TrackPopupMenu(TPM_RIGHTBUTTON,pt.x,pt.y,::theApp.p_Browser); 
    } 
    else 
    { 
        OnItemRClick(phdn->iItem); 
    } 
} 
 
void CShellList::OnDblClick(NMHDR* pNMHDR, LRESULT* pResult) 
{ 
    HD_NOTIFY *phdn=(HD_NOTIFY *)pNMHDR; 
    if(phdn->iItem<0) 
        return; 
    m_SelectedItem=phdn->iItem; 
    OnItemAction(m_SelectedItem); 
    *pResult=0; 
} 
 
void CShellList::OnItemChanged(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
    if(m_Building) 
        return; 
    HD_NOTIFY *phdn=(HD_NOTIFY *)pNMHDR; 
    if(phdn->iItem<0) 
        return; 
    if(!IsSelectedItem(phdn->iItem)) 
        return; 
    m_SelectedItem=phdn->iItem; 
    OnItemSelected(phdn->iItem); 
    *pResult=0; 
} 
 
CString CShellList::GetSelectedItemFullPath() 
{ 
    return GetItemFullPath(m_SelectedItem); 
} 
 
void CShellList::ShowFileInfo(CBrowserList *pList,int Which,CString FullPath) 
{ 
    CString FileInfo;	 
    FileInfo+=""+GetItemText(Which,0); 
    FileInfo+="\n"+GetItemText(Which,2); 
    FileInfo+="\n\n"+GetItemText(Which,1); 
     
    DWORD fa=GetFileAttributes(FullPath); 
    if(fa!=-1) 
    { 
        CString Property; 
        if((fa & FILE_ATTRIBUTE_SYSTEM ) == FILE_ATTRIBUTE_SYSTEM ) 
            Property+=" 系统"; 
        if((fa & FILE_ATTRIBUTE_READONLY ) == FILE_ATTRIBUTE_READONLY ) 
            Property+=" 只读"; 
        if((fa & FILE_ATTRIBUTE_HIDDEN ) == FILE_ATTRIBUTE_HIDDEN ) 
            Property+=" 隐藏"; 
         
        FileInfo+="\n修改时间: "+GetItemText(Which,3); 
        FileInfo+="\n属性:"+(Property.IsEmpty()?" (正常)":Property); 
    } 
     
    pList->SetFileInfo(FileInfo); 
} 
 
void CShellList::AssociateTree(CShellTree *pTree) 
{ 
    p_Tree=pTree; 
} 
 
int CShellList::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
    if (CListCtrl::OnCreate(lpCreateStruct) == -1) 
        return -1; 
     
    InsertColumn(0,"名称",LVCFMT_LEFT,120); 
    InsertColumn(1,"大小",LVCFMT_RIGHT,60); 
    InsertColumn(2,"类型",LVCFMT_LEFT,100); 
    InsertColumn(3,"修改时间",LVCFMT_LEFT,100); 
     
    SetImageList(); 
    return 0; 
} 
 
void CShellList::SetImageList() 
{ 
    CListCtrl::SetImageList(CShell::GetImageList(FALSE),LVSIL_NORMAL); 
    CListCtrl::SetImageList(CShell::GetImageList(TRUE),LVSIL_SMALL); 
} 
 
//函数PopulateList,展开指定目录项 
//参数pParentShellFolder,父目录 
//参数pStid,指定目录项的项数据 
//参数hItem,指定目录项 
//返回操作结果,TRUE/FALSE 
BOOL CShellList::PopulateList(LPSHELLFOLDER pParentShellFolder,CShellTreeItemData * pStid,HTREEITEM hItem) 
{ 
    LV_ITEM lvi; 
    int nPos = 0;  
    LPENUMIDLIST lpe = NULL; 
    LPITEMIDLIST pIDList = NULL,pFullIDList = NULL; 
    LPMALLOC lpMalloc = NULL; 
    ULONG ulFetched; 
    HRESULT hr; 
    TCHAR szBuff[_MAX_PATH]; 
    SHFILEINFO sfi; 
    CShellListItemData * pSlid = NULL; 
    CString FullPath; 
    CString DisplayName; 
     
    m_Building = TRUE; 
     
    SetRedraw(FALSE); 
     
    CBrowserList *pList = (CBrowserList *)GetParent(); 
    pList->Preview(""); 
     
    SetViewStyle(); 
    DeleteAllItems(); 
     
    m_SelectedItem = -1; 
     
    //分配内存 
    hr = SHGetMalloc(&lpMalloc); 
    if (FAILED(hr)) 
        return FALSE; 
     
    //设置显示标志 
    DWORD dwFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS; 
    if( m_ShowHidden ) 
        dwFlags |= SHCONTF_INCLUDEHIDDEN; 
     
    hr = pParentShellFolder->EnumObjects(GetSafeHwnd(), dwFlags, &lpe); 
    h_TreeItem = hItem; 
     
    if (SUCCEEDED(hr)) 
    { 
        //枚举父目录下的文件 
        while (S_OK == lpe->Next(1, &pIDList, &ulFetched)) 
        { 
            pSlid = (CShellListItemData *)lpMalloc->Alloc(sizeof(CShellListItemData)); 
            if (!pSlid) 
                goto Done; 
             
            //获取文件属性 
            ULONG ulAttrs = SFGAO_FOLDER ; 
             
            pParentShellFolder->GetAttributesOf(1, (const struct _ITEMIDLIST **)&pIDList, &ulAttrs); 
            pSlid->m_Attribute = ulAttrs; 
             
            pFullIDList=ConcatPidl(pStid->m_pFullIDList,pIDList); 
             
            pSlid->m_pParentShellFolder = pParentShellFolder; 
            pParentShellFolder->AddRef(); 
             
            pSlid->m_pIDList = CopyPidl(lpMalloc, pIDList); 
             
            GetFileInfo(pFullIDList,SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_TYPENAME | SHGFI_ATTRIBUTES,&sfi); 
            lvi.iImage = sfi.iIcon;  
            pSlid->m_pFullIDList = ConcatPidl(pStid->m_pFullIDList, pIDList); 
             
            SHGetPathFromIDList(pSlid->m_pFullIDList,szBuff); 
            FullPath = szBuff; 
            pSlid->m_Flag = GetItemFlag(sfi,FullPath); 
             
            if (!GetItemName(pParentShellFolder, pIDList, SHGDN_NORMAL, szBuff)) 
                goto Done; 
             
            lvi.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_PARAM; 
            lvi.iItem = nPos; 
            lvi.iSubItem = 0; 
            lvi.pszText = szBuff; 
            lvi.cchTextMax = _MAX_PATH; 
            lvi.lParam = (LPARAM)pSlid; 
            //添加至文件列表 
            nPos = CListCtrl::InsertItem(&lvi); 
             
            if(m_ShowFlashOnly&&(pSlid->m_Attribute & SFGAO_FOLDER) != SFGAO_FOLDER&&!pSlid->m_Flag) 
            { 
                DeleteItem(nPos); 
            } 
            else 
            { 
                InsertSubItems(nPos,sfi,FullPath); 
                nPos++; 
            } 
            lpMalloc->Free(pFullIDList);   
            pFullIDList=0; 
        }		 
    } 
     
Done: 
     
    //释放内存 
    if (lpe)   
        lpe->Release(); 
     
    if (lpMalloc)  
        lpMalloc->Release(); 
     
    m_Building = FALSE; 
     
    if(!m_Refresh) 
        ::theApp.p_Browser->AddHistoryRecord(hItem); 
    SortItems(SortProc, (LPARAM)this); 
     
    SetRedraw(TRUE); 
     
    return TRUE; 
} 
 
void CShellList::OnDeleteItem(NMHDR* pNMHDR, LRESULT* pResult)  
{ 
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 
    HRESULT hr; 
    LPMALLOC lpMalloc; 
    CShellListItemData *   pSlid = (CShellListItemData *)pNMListView->lParam; 
     
    if(!pSlid) 
        return; 
     
    hr=SHGetMalloc(&lpMalloc); 
    if (FAILED(hr))  
        return; 
     
    lpMalloc->Free(pSlid->m_pIDList);   
    lpMalloc->Free(pSlid->m_pFullIDList);   
    lpMalloc->Free(pSlid);   
    lpMalloc->Release(); 
     
    *pResult = 0; 
} 
 
void CShellList::SetViewStyle(int ViewStyle) 
{ 
    if(m_ViewStyle!=ViewStyle) 
    { 
        m_ViewStyle=ViewStyle; 
        Refresh(); 
    } 
} 
 
BOOL CShellList::GetViewStyle(int ViewStyle) 
{ 
    return (m_ViewStyle==ViewStyle); 
} 
 
void CShellList::InsertSubItems(int Which,SHFILEINFO sfi,CString FullPath) 
{ 
    //AssociateTree() should be called before 
    ASSERT(p_Tree); 
     
    CFileFind Finder; 
    CString Path; 
    SetItemText(Which,2,sfi.szTypeName); 
     
    Path=GetItemFullPath(Which); 
    if(Finder.FindFile(Path)) 
    { 
        Finder.FindNextFile(); 
        CString Text; 
        DWORD Size; 
        CTime Time; 
        Size=Finder.GetLength(); 
        if((sfi.dwAttributes & SFGAO_FOLDER) != SFGAO_FOLDER) 
        { 
            Text.Format("%ldKB",(Size+1023)/1024); 
            SetItemText(Which,1,Text); 
        } 
        Finder.GetLastWriteTime(Time); 
        Text.Format("%04d-%02d-%02d %02d:%02d",Time.GetYear(),Time.GetMonth(),Time.GetDay(),Time.GetHour(),Time.GetMinute()); 
        SetItemText(Which,3,Text); 
    } 
} 
 
CString CShellList::GetItemFullPath(int Which) 
{ 
    CString FullPath; 
    CShellListItemData * pSlid=(CShellListItemData *)GetItemData(Which); 
    if(!pSlid) 
        return FullPath; 
    TCHAR szBuff[_MAX_PATH]; 
     
    SHGetPathFromIDList(pSlid->m_pFullIDList,szBuff); 
    FullPath=szBuff; 
    return FullPath; 
} 
 
BOOL CShellList::IsFolder(int Which) 
{ 
    LV_ITEM lvi; 
    lvi.mask = LVIF_PARAM; 
    lvi.iItem = Which; 
    lvi.iSubItem = 0; 
     
    if (!GetItem(&lvi)) 
        return FALSE; 
     
    CShellListItemData * pSlid=(CShellListItemData *)lvi.lParam; 
     
    return ((pSlid->m_Attribute & SFGAO_FOLDER) == SFGAO_FOLDER); 
} 
 
void CShellList::OnItemDblClick(int Which) 
{ 
    if(!IsMovie(Which)) 
    { 
        CString FullPath=GetItemFullPath(Which); 
        ShellExecute(NULL,"open",FullPath,NULL,NULL,SW_SHOW); 
    } 
    else 
        ::theApp.SwitchToViewer(); 
} 
 
void CShellList::OnItemSelected(int Which) 
{ 
    if(!IsWindowVisible()) 
        return; 
    CBrowserList *pList=(CBrowserList *)GetParent(); 
    CString FullPath=GetItemFullPath(Which); 
    ShowFileInfo(pList,Which,FullPath); 
    pList->Preview(IsMovie(Which)?FullPath:""); 
} 
 
int CShellList::SetSelection(CString FullPath) 
{ 
    CString Title=GetFileTitleFromFileName(FullPath); 
    int Which=-1; 
    for(int i=0;i=GetItemCount()) 
        return FALSE; 
    return GetItemFlag(Which); 
} 
 
int CShellList::GetItemFlag(int Which) 
{ 
    CShellListItemData * pSlid=(CShellListItemData *)GetItemData(Which); 
    if(!pSlid) 
        return 0; 
    return pSlid->m_Flag; 
} 
 
BOOL CShellList::IsSelectedItem(int Which) 
{ 
    return(GetItemState(Which,LVIS_SELECTED)==LVIS_SELECTED); 
} 
 
void CShellList::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
    if(nChar==VK_RETURN) 
    { 
        OnItemAction(m_SelectedItem); 
    } 
    CListCtrl::OnChar(nChar, nRepCnt, nFlags); 
} 
 
void CShellList::OnItemAction(int Item) 
{ 
    CShellListItemData * pSlid=(CShellListItemData *)GetItemData(Item); 
     
    if ((pSlid->m_Attribute & SFGAO_FOLDER) == SFGAO_FOLDER)  
    { 
        p_Tree->Expand(h_TreeItem,TVE_EXPAND); 
        HTREEITEM hChildItem=p_Tree->FindChild(h_TreeItem,pSlid); 
        if(hChildItem) 
            p_Tree->SelectItem(hChildItem); 
    } 
    else 
    { 
        OnItemDblClick(Item); 
    } 
} 
 
void CShellList::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)  
{ 
    LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR; 
    CString Text=pDispInfo->item.pszText; 
    HD_NOTIFY *phdn=(HD_NOTIFY *)pNMHDR; 
    if(phdn->iItem<0) 
        return; 
     
    if(!Text.IsEmpty()&&MoveFile(GetSelectedItemFullPath(),p_Tree->GetItemFullPath(h_TreeItem)+Text)) 
    { 
        ::theApp.p_Browser->OnViewRefresh(); 
    } 
    *pResult = 0; 
} 
 
void CShellList::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
    if(m_SelectedItem!=-1&&nChar==VK_DELETE)	 
    { 
        ::theApp.p_Browser->OnFileDelete(); 
    } 
    CListCtrl::OnKeyUp(nChar, nRepCnt, nFlags); 
} 
 
void CShellList::Refresh() 
{ 
    if(!h_TreeItem) 
        return; 
    m_Refresh=TRUE; 
    p_Tree->PopulateList(h_TreeItem);	 
    m_Refresh=FALSE; 
} 
 
void CShellList::SetViewStyle() 
{ 
    DWORD Style; 
    switch(m_ViewStyle) 
    { 
    case 0:Style=LVS_ICON; 
        break; 
    case 3:Style=LVS_REPORT; 
        break; 
    case 2:Style=LVS_LIST; 
        break; 
    case 1:Style=LVS_SMALLICON; 
        break; 
    } 
    ModifyStyle(LVS_TYPEMASK,Style); 
} 
 
void CShellList::OnItemRClick(int Item) 
{ 
    POINT pt; 
    GetCursorPos(&pt); 
     
    CMenu Menu; 
    Menu.LoadMenu(IDM_ITEM_POP); 
    CMenu* pMenu = Menu.GetSubMenu(0); 
    pMenu->TrackPopupMenu(TPM_RIGHTBUTTON,pt.x,pt.y,::theApp.p_Browser); 
}