📄 childview.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 + -