⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 childview.cpp

📁 类似 windows explorer的工具
💻 CPP
字号:
// ChildView.cpp : implementation of the CChildView class
//

#include "stdafx.h"
#include "MMXShell2.h"
#include "ChildView.h"
#include "MainFrm.h"

#include "MMXShellGenelal.h"

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

#define IDM_FIRST_SHELLMENUID	20000
#define IDM_LAST_SHELLMENUID	(IDM_FIRST_SHELLMENUID+1000)

/////////////////////////////////////////////////////////////////////////////
// CChildView
IMPLEMENT_DYNCREATE(CChildView, CWnd)

CChildView::CChildView()
{
    m_bIsUDisk = FALSE;
    m_nViewStyle = DETAILINFO;
}

CChildView::~CChildView()
{
}


BEGIN_MESSAGE_MAP(CChildView,CWnd )
//{{AFX_MSG_MAP(CChildView)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_CONTEXTMENU()
ON_NOTIFY(NM_RCLICK, IDC_TREE_FOLDER, OnRclickTree1)
ON_WM_CLOSE()
ON_WM_PAINT()
//}}AFX_MSG_MAP
ON_COMMAND_RANGE(IDM_FIRST_SHELLMENUID, IDM_LAST_SHELLMENUID, OnShellCommand)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_FOLDER, OnSelchangedTree1)
ON_NOTIFY(NM_CLICK, IDC_LIST_FILE, OnClickListItem)
ON_NOTIFY(NM_RCLICK, IDC_LIST_FILE, OnRclickList1)

ON_NOTIFY(NM_SETFOCUS, IDC_TREE_FOLDER, OnSetfocusTree1)
ON_NOTIFY(NM_SETFOCUS, IDC_LIST_FILE, OnSetfocusList1)    
ON_NOTIFY(NM_DBLCLK, IDC_LIST_FILE, OnDblclkList)

ON_MESSAGE(WM_EXPANDEDTREEITEM,OnItemexpandedTreeItem)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CChildView message handlers

BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
{
    if (!CWnd::PreCreateWindow(cs))
        return FALSE;
    
    cs.dwExStyle |= WS_EX_CLIENTEDGE;
    cs.style &= ~WS_BORDER;
    cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
       ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);
    
    return TRUE;
}

int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    DWORD dwExStyle;
    
    // 创建目录树
    // 提醒:App 类中要调用 AfxOleInit ,否则下面创建要失败。
    UINT nID = IDC_TREE_FOLDER;
    DWORD dwStyle = TVS_LINESATROOT | TVS_HASBUTTONS | TVS_HASLINES
        | TVS_SHOWSELALWAYS;

    //dwExStyle = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
    dwExStyle = WS_EX_CLIENTEDGE;
    
    if (!m_TreeCtrl.CreateEx(dwExStyle, WC_TREEVIEW, _T("ShellTree Control"),
        WS_VISIBLE|WS_CHILD|dwStyle, CRect(0,0,0,0), this, nID, NULL)
        )
    {
        return -1;
    }
    
    
    // 创建 ListCtrl
    // 不要边框 WS_EX_CLIENTEDGE
    dwExStyle = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR
        | WS_EX_NOPARENTNOTIFY;
    dwStyle = WS_CHILD | WS_VISIBLE | LVS_LIST | LVS_AUTOARRANGE
        | LVS_SHOWSELALWAYS | LVS_REPORT;

    if (!m_ListCtrl.CreateEx(dwExStyle, WC_LISTVIEW, NULL, dwStyle,
        CRect(0,0,0,0),this, IDC_LIST_FILE))
    {
        return -1 ;
    }
    //failed,why??
    //VERIFY( m_ListCtrl.m_ctlHeader.SubclassWindow(
    //    m_ListCtrl.GetHeaderCtrl()->GetSafeHwnd()));

    // 设置图像列表及表头
    m_ListCtrl.SetImageList(&CMMXShell2App::m_ImgList,LVSIL_SMALL);
    m_ListCtrl.SetImageList(&CMMXShell2App::m_ImgBigList,LVSIL_NORMAL);

    // 创建拆分窗口
    if (!m_wndSplitter.Create(this))
    {
        return -1;
    }
    m_TreeCtrl.MoveWindow(0, 0, 300, 0, FALSE);
    m_wndSplitter.AddWindow(IDC_TREE_FOLDER, SIDE_LEFT);
    m_wndSplitter.AddWindow(IDC_LIST_FILE, SIDE_RIGHT);
    m_wndSplitter.SetMoveDirection(MD_HORIZONTAL);

    return 0;
}

void CChildView::Initialize(BOOL bIsUDisk)
{
    m_bIsUDisk = bIsUDisk;
    m_TreeCtrl.SetUDiskTag(bIsUDisk);
    m_ListCtrl.SetUDiskTag(bIsUDisk);
    
    m_ListCtrl.InitColumns();
    RefreshTree();
}

void CChildView::OnSize(UINT nType, int cx, int cy) 
{
    CWnd::OnSize(nType, cx, cy);
    
    /*
    int nWidth = (int)(cx * 0.3);

    m_TreeCtrl.MoveWindow(0, 0, nWidth, cy);	
    m_ListCtrl.MoveWindow(nWidth, 0, cx - nWidth, cy);	
    */
    // 第一次初始化拆分条
    m_wndSplitter.RelayWindows();
}

void CChildView::OnRclickTree1(NMHDR* pNMHDR, LRESULT* pResult) 
{
    *pResult = 0;
    
    // 得到鼠标右键单击的项目
    CPoint point;
    
    GetCursorPos(&point);
    UINT nFlags = 0;
    ScreenToClient(&point);
    HTREEITEM hItem = m_TreeCtrl.HitTest(point, &nFlags);
    
    if (!(nFlags & TVHT_ONITEM))
    {
        return;
    }
    TVITEMDATA* pData = (TVITEMDATA*)m_TreeCtrl.GetItemData(hItem);
    ShowShellMenu(pData, point);
}

void CChildView::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult) 
{
    *pResult = 0;
    
    // 得到鼠标右键单击的项目
    CPoint point;
    
    GetCursorPos(&point);
    ScreenToClient(&point);

    int nItem = m_ListCtrl.GetNextItem(-1, LVNI_SELECTED);
    
    if (nItem < 0)
    {
        return;
    }
    DWORD dwData = m_ListCtrl.GetItemData(nItem);
    ASSERT(dwData > 0);
    
    if (dwData == 0)
    {
        return;
    }
    
    TVITEMDATA* pData = (TVITEMDATA*)dwData;
    ASSERT(pData != NULL);
    ShowShellMenu(pData, point);
}

void CChildView::ShowShellMenu(TVITEMDATA* pData, CPoint& point) 
{
    ASSERT(pData != NULL);
    
    CMenu menu;
    menu.LoadMenu(IDR_TESTMENU);
    CMenu *pPopupMenu = menu.GetSubMenu(0);
    
    pPopupMenu->DeleteMenu(0, MF_BYPOSITION);
    
    CMMXShellGenelal::GetItemContextMenu(pData, m_shellMenu);
    if (!m_shellMenu.FillMenu(pPopupMenu, 0, IDM_FIRST_SHELLMENUID,
        IDM_LAST_SHELLMENUID, CMF_NODEFAULT|CMF_EXPLORE))
    {
        ASSERT(FALSE); // 未知
    }
    
    // display menu
    m_shellMenu.SetOwner(this);
    ClientToScreen(&point);
    pPopupMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
        point.x, point.y, this);
    m_shellMenu.SetOwner(NULL);
}

void CChildView::OnContextMenu(CWnd* pWnd, CPoint point) 
{
    if (pWnd->GetSafeHwnd() != m_hWnd)
    {
        Default();
        return;
    }
    
}
void CChildView::OnShellCommand(UINT nID) 
{
    // shell command
    m_shellMenu.InvokeCommand(nID);
}

void CChildView::OnItemexpandedTreeItem(HTREEITEM hParent) 
{
}

void CChildView::OnClose() 
{
    CWnd::OnClose();
}

// 刷新 TreeView 和 ListView
void CChildView::RefreshAll() 
{
    RefreshTree();
    RefreshFileList();
}

void CChildView::RefreshTree()
{
    m_TreeCtrl.DeleteAllItems();
    if (!m_bIsUDisk)
    {
        // 显示桌面上所有对象(包含隐藏对象)
        m_TreeCtrl.AddRootFolderContent(NULL, STCF_INCLUDEHIDDEN);
    }
    else
    {
        CShellPidl pidlMyComputer((UINT)CSIDL_DRIVES);
        m_TreeCtrl.AddRootItem(pidlMyComputer);
        
        m_TreeCtrl.SetItemText(m_TreeCtrl.GetRootItem(), "移动硬盘");
    }
    
    // 展开树节点
    m_TreeCtrl.Expand(m_TreeCtrl.GetRootItem(),TVE_EXPAND);
}

// 刷新ListCtrl的内容
void CChildView::RefreshFileList()
{
    HTREEITEM hParent = m_TreeCtrl.GetSelectedItem();
    if (hParent == NULL)
    {
        return;
    }
    
    DWORD dwData = m_TreeCtrl.GetItemData(hParent);
    if (dwData != 0)
    {
        TVITEMDATA* pData = (TVITEMDATA*)dwData;
        CShellPidl& pidlParent = pData->pidlAbs;
        
        m_ListCtrl.EnumFolderItems(pData->pParentFolder, pidlParent);
    }
}

void CChildView::OnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult) 
{
    RefreshFileList();
    
    *pResult = 0;
}


void CChildView::OnClickListItem(NMHDR* pNMHDR, LRESULT* pResult) 
{
    int nItem = m_ListCtrl.GetNextItem(-1, LVNI_SELECTED);
    
    if (nItem < 0)
    {
        return;
    }
    *pResult = 0;
}

// 跳到上级目录
void CChildView::OnUpFolder()
{
    HTREEITEM hItem = m_TreeCtrl.GetSelectedItem();
    
    if (hItem != NULL)
    {
        HTREEITEM hItemParent = m_TreeCtrl.GetParentItem(hItem);
        
        if (hItemParent != NULL)
        {
            m_TreeCtrl.SelectItem(hItemParent);
        }
    }
}

void CChildView::OnSetfocusTree1(NMHDR* pNMHDR, LRESULT* pResult) 
{
    *pResult = 0;
}

void CChildView::OnSetfocusList1(NMHDR* pNMHDR, LRESULT* pResult) 
{
    // Release版本 通过发消息居然有异常,晕!
    //AfxGetMainWnd()->PostMessage(WM_ACTIVECHILDVIEW, (WPARAM)this,0);
    ((CMainFrame*)AfxGetMainWnd())->OnActiveListView(this);
    
    *pResult = 0;
}

VIEWSTYLE CChildView::GetViewStyle() 
{
    return m_nViewStyle;
}

void CChildView::ChangeViewStyle(VIEWSTYLE nViewStyle)
{
    DWORD style = m_ListCtrl.GetStyle();
    
    m_nViewStyle = nViewStyle;
    switch (nViewStyle)
    {
    case BIGICON:
        style &= ~LVS_REPORT;
        style &= ~LVS_LIST;
        style &= ~LVS_SMALLICON;
        
        style |= LVS_ICON;
        break;
    case SMALLICON:
        style &= ~LVS_ICON;
        style &= ~LVS_REPORT;
        style &= ~LVS_LIST;
        
        style |= LVS_SMALLICON;
        break;
    case LIST:
        style &= ~LVS_ICON;
        style &= ~LVS_REPORT;
        style &= ~LVS_SMALLICON;
        
        style |= LVS_LIST;
        break;
    case DETAILINFO:
        style &= ~LVS_ICON;
        style &= ~LVS_LIST;
        style &= ~LVS_SMALLICON;
        
        style |= LVS_REPORT;
        break;
    }
    
    SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,style);	
}

// 双击ListCtrl
void CChildView::OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult) 
{
    *pResult = 0;
   
    LPNMLISTVIEW pLVItem = (LPNMLISTVIEW)pNMHDR;

    ASSERT(pLVItem);

    int nItem = pLVItem->iItem; 
    
    if (nItem != -1)
    {
        CString strItemName = m_ListCtrl.GetItemText(nItem,0);
        
        if (m_ListCtrl.IsFolder(nItem))
        {
            m_TreeCtrl.GotoSubFolder(strItemName);
        }
        else // 如果双击的是个文件
        {
            if (!m_bIsUDisk)
            {
                // 调用 ShellExecute 打开该对象
                ShellExecute(NULL, _T("open"), 
                    m_ListCtrl.GetSelectedFileName(),
                    NULL,NULL, SW_SHOW);
            }
        } // end if (m_ListCtrl.IsFolder(nItem))
    }
    
}

// 取得当前的路径(最后有‘\’)
CString CChildView::GetCurrentPath()
{
    HTREEITEM hTreeItem = m_TreeCtrl.GetSelectedItem();
    
    if (hTreeItem == NULL)
    {
        return "";
    }
    
    CString strPath;
    DWORD dwData = m_TreeCtrl.GetItemData(hTreeItem);
    
    if (dwData != 0)
    {
        TVITEMDATA* pData = (TVITEMDATA*)dwData;
        strPath = pData->pidlAbs.GetPath();    
        
        // 判断目录未尾是否已有"\"符
        if (!strPath.IsEmpty() && (strPath.Right(1) != '\\'))
        {
            
            strPath += '\\';
        }
    }
    
    return strPath;
}
// vFileNames; 存储选择的文件名
void CChildView::GetSelectedFiles(vector<CString>& vFileNames)
{
    vFileNames.clear();
    
    CString strName;
    CString strPath = GetCurrentPath();
    int nItem = m_ListCtrl.GetNextItem(-1, LVNI_SELECTED);
    
    // 将所有选择的文件名保存在 vFileNames 中
    while (nItem != -1)
    {
        strName = m_ListCtrl.GetItemText(nItem,0);
        
        // 判断是否是快捷方式
        if (m_ListCtrl.IsShortcut(nItem))
        {
            strName += ".lnk";
        }
        
        vFileNames.push_back(strPath + strName); // 路径 + 文件名
        
        nItem = m_ListCtrl.GetNextItem(nItem, LVNI_SELECTED);   
    }
}

BOOL CChildView::PreTranslateMessage(MSG* pMsg) 
{
    if (pMsg->hwnd==m_ListCtrl.m_hWnd && pMsg->message==WM_KEYDOWN)
    {
        // 实现全选功能 ctrl+A
        if (pMsg->wParam == 65 && (::GetKeyState(VK_CONTROL) & 0x8000)) //'A'
        {
            for(int i = 0; i < m_ListCtrl.GetItemCount(); ++i)
            {
                m_ListCtrl.SetItemState(i,LVNI_SELECTED,LVNI_SELECTED);
            }
        }
    }
    
    return CWnd::PreTranslateMessage(pMsg);
}

void CChildView::ListCtrl_SubclassWindow()
{
    VERIFY( m_ListCtrl.m_ctlHeader.SubclassWindow(
        m_ListCtrl.GetHeaderCtrl()->GetSafeHwnd()));

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -