📄 leftview.cpp
字号:
// LeftView.cpp : implementation of the CLeftView class
//
//
//
#include "stdafx.h"
#include "MTrickster.h"
#include "MTricksterDoc.h"
#include "LeftView.h"
#include "MTListView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define ILI_CDDRV 0
#define ILI_CLSDFLD 1
#define ILI_DRIVE 2
#define ILI_FLOPPYDRV 3
#define ILI_MYCOMP 4
#define ILI_OPENFLD 5
#define ILI_TEXTFILE 6
#define MYCOMPUTER "My Computer"
/////////////////////////////////////////////////////////////////////////////
// CLeftView
IMPLEMENT_DYNCREATE(CLeftView, CTreeView)
BEGIN_MESSAGE_MAP(CLeftView, CTreeView)
//{{AFX_MSG_MAP(CLeftView)
ON_WM_DESTROY()
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
ON_NOTIFY_REFLECT(TVN_SELCHANGING, OnSelchanging)
ON_WM_RBUTTONDBLCLK()
//}}AFX_MSG_MAP
// Standard printing commands
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLeftView construction/destruction
CLeftView::CLeftView()
{
// TODO: add construction code here
}
CLeftView::~CLeftView()
{
}
BOOL CLeftView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style |= TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES;
return CTreeView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CLeftView drawing
void CLeftView::OnDraw(CDC* pDC)
{
CDriveExplorerDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
void CLeftView::OnInitialUpdate()
{
CTreeView::OnInitialUpdate();
CTreeView::OnInitialUpdate();
m_pImageList = new CImageList();
CWinApp* pApp = AfxGetApp();
// ASSERT(m_pImageList != NULL); // serious allocation failure checking
m_pImageList->Create(16, 16, ILC_COLOR8 | ILC_MASK, 9, 9);
m_pImageList->Add(pApp->LoadIcon(ICO_CDDRV));
m_pImageList->Add(pApp->LoadIcon(IDI_ICON3));
m_pImageList->Add(pApp->LoadIcon(IDI_ICON4));
m_pImageList->Add(pApp->LoadIcon(IDI_ICON2));
m_pImageList->Add(pApp->LoadIcon(ICO_MYCOMP));
m_pImageList->Add(pApp->LoadIcon(ICO_OPENFLD));
GetTreeCtrl().SetImageList(m_pImageList , TVSIL_NORMAL);
GetTreeCtrl().ModifyStyle(0,TVS_HASLINES|TVS_HASBUTTONS|TVS_SHOWSELALWAYS|TVS_SINGLEEXPAND|TVSIL_NORMAL);
HTREEITEM hParent = GetTreeCtrl().InsertItem(MYCOMPUTER, ILI_MYCOMP, ILI_MYCOMP);
InitTreeView(hParent);
GetTreeCtrl().Expand(hParent, TVE_EXPAND);
hDevice = CreateFile( "\\\\.\\explorer",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(hDevice==INVALID_HANDLE_VALUE )
{
hDevice = CreateFile( "\\\\.\\explorer",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(hDevice==INVALID_HANDLE_VALUE )
{
MessageBox("加载内核失败!");
ExitProcess(0);
}
}
// TODO: You may populate your TreeView with items by directly accessing
// its tree control through a call to GetTreeCtrl().
}
/////////////////////////////////////////////////////////////////////////////
// CLeftView diagnostics
#ifdef _DEBUG
void CLeftView::AssertValid() const
{
CTreeView::AssertValid();
}
void CLeftView::Dump(CDumpContext& dc) const
{
CTreeView::Dump(dc);
}
CMTricksterDoc* CLeftView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMTricksterDoc)));
return (CMTricksterDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CLeftView message handlers
void CLeftView::InitTreeView(HTREEITEM hParent)
{
int nPos = 0;
UINT nCount = 0;
CString strDrive = "?:\\";
DWORD dwDriveList = ::GetLogicalDrives ();
CString cTmp;
while (dwDriveList) {
if (dwDriveList & 1) {
cTmp = strDrive;
strDrive.SetAt (0, 0x41 + nPos);
if (AddDrives(strDrive , hParent))
nCount++;
}
dwDriveList >>= 1;
nPos++;
}
return;
}
BOOL CLeftView::AddDrives(CString strDrive, HTREEITEM hParent)
{
HTREEITEM hItem;
UINT nType = ::GetDriveType ((LPCTSTR) strDrive);
UINT nDrive = (UINT) strDrive[0] - 0x41;
switch (nType) {
case DRIVE_REMOVABLE:
strDrive=strDrive;
hItem = GetTreeCtrl().InsertItem(strDrive, ILI_FLOPPYDRV, ILI_FLOPPYDRV, hParent);
if (HasSubdirectory (strDrive))
{
AddDummyNode(hItem);
}
break;
case DRIVE_FIXED:
strDrive=strDrive;
hItem = GetTreeCtrl().InsertItem(strDrive, ILI_DRIVE, ILI_DRIVE, hParent);
if (HasSubdirectory (strDrive))
{
AddDummyNode(hItem);
}
break;
case DRIVE_REMOTE:
hItem = GetTreeCtrl().InsertItem(strDrive, ILI_DRIVE, ILI_DRIVE, hParent);
if (HasSubdirectory (strDrive))
{
AddDummyNode(hItem);
}
break;
case DRIVE_CDROM:
strDrive=strDrive;
hItem = GetTreeCtrl().InsertItem(strDrive, ILI_CDDRV, ILI_CDDRV, hParent);
if (HasSubdirectory (strDrive))
{
AddDummyNode(hItem);
}
break;
case DRIVE_RAMDISK:
hItem = GetTreeCtrl().InsertItem(strDrive, ILI_CDDRV, ILI_CDDRV, hParent);
if (HasSubdirectory (strDrive))
{
AddDummyNode(hItem);
}
break;
default:
return FALSE;
}
return true;
}
BOOL CLeftView::HasSubdirectory(CString &strPathName)
{
HANDLE hFind;
WIN32_FIND_DATA fd;
BOOL bResult = FALSE;
CString strFileSpec = strPathName;
if (strFileSpec.Right (1) != "\\")
strFileSpec += "\\";
strFileSpec += "*.*";
if ((hFind = ::FindFirstFile ((LPCTSTR) strFileSpec, &fd)) !=
INVALID_HANDLE_VALUE) {
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
CString strFileName = (LPCTSTR) &fd.cFileName;
if ((strFileName != ".") && (strFileName != ".."))
bResult = TRUE;
}
} while (::FindNextFile (hFind, &fd) && !bResult);
::FindClose (hFind);
}
return bResult;
}
void CLeftView::AddDummyNode(HTREEITEM hItem)
{
GetTreeCtrl().InsertItem ("", 0, 0, hItem);
}
CString CLeftView::GetPathFromItem(HTREEITEM hItem)
{
CString strPathName;
while (hItem != NULL)
{
CString string = GetTreeCtrl().GetItemText (hItem);
if ((string.Right (1) != "\\") && !strPathName.IsEmpty ())
string += "\\";
strPathName = string + strPathName;
hItem = GetTreeCtrl().GetParentItem (hItem);
}
if(strPathName.Left(11) == MYCOMPUTER && strPathName.GetLength() > 11)
strPathName = strPathName.Mid(12);
return strPathName;
}
BOOL CLeftView::IsPathValid(CString &strPathName)
{
if (strPathName.GetLength () == 3)
return TRUE;
HANDLE hFind;
WIN32_FIND_DATA fd;
BOOL bResult = FALSE;
if ((hFind = ::FindFirstFile ((LPCTSTR) strPathName, &fd)) !=
INVALID_HANDLE_VALUE) {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
bResult = TRUE;
::CloseHandle (hFind);
}
return bResult;
}
BOOL CLeftView::IsMediaValid(CString &strPathName)
{
// Return TRUE if the drive doesn't support removable media.
UINT nDriveType = GetDriveType ((LPCTSTR) strPathName);
if ((nDriveType != DRIVE_REMOVABLE) && (nDriveType != DRIVE_CDROM))
return TRUE;
else
return FALSE;
}
HTREEITEM CLeftView::GetDriveNode(HTREEITEM hItem)
{
HTREEITEM hParent;
do {
hParent = GetTreeCtrl().GetParentItem (hItem);
if (hParent != NULL)
hItem = hParent;
} while (hParent != NULL);
return hItem;
}
UINT CLeftView::DeleteChildren(HTREEITEM hItem)
{
UINT nCount = 0;
HTREEITEM hChild = GetTreeCtrl().GetChildItem (hItem);
while (hChild != NULL) {
HTREEITEM hNextItem = GetTreeCtrl().GetNextSiblingItem (hChild);
GetTreeCtrl().DeleteItem (hChild);
hChild = hNextItem;
nCount++;
// dwTreeItemCount--;
}
return nCount;
}
UINT CLeftView::AddDirectoryNodes(HTREEITEM hItem, CString &strPathName)
{
DWORD bytesReturned;
ULONG num;
PDIRECTORY_INFO temp;
DIRECTORY_INFO_EX b;
CString str,str1,strFileSpec = strPathName;
if (strFileSpec.Right (1) != "\\")
strFileSpec += "\\";
char a[MAX_PATH];
str1=strFileSpec;
strcpy(a,strFileSpec.GetBuffer(strFileSpec.GetLength()));
strFileSpec += "*.*";
DeviceIoControl(hDevice,(DWORD)IOCTL_MT_GETDIRNUMINF,a,sizeof(a),&num,sizeof(ULONG),&bytesReturned,NULL);
if(num==0)
{
return 0;
}
temp=(PDIRECTORY_INFO)calloc(num,sizeof(DIRECTORY_INFO));
if(temp==NULL)
{
return 0;
}
DeviceIoControl(hDevice,(DWORD)IOCTL_MT_GETDIRINF,a,sizeof(a),temp,num*sizeof(DIRECTORY_INFO),&bytesReturned,NULL);
CWaitCursor wait;
CMTricksterDoc* pDoc = (CMTricksterDoc*)GetDocument();
pDoc->m_MTListView->DeleteAllItems();
pDoc->m_MTListView->SetPath(str1,hDevice);
for(ULONG i=0;i<num;i++)
{
str.Format("%s",temp[i].FileName);
str=str1+str;
CString strFileName = (LPCTSTR) &temp[i].FileName;
if(PathIsDirectory(str))
{
if(strcmp(temp[i].FileName,"."))
{
if(strcmp(temp[i].FileName,".."))
{
HTREEITEM hChild =
GetTreeCtrl().InsertItem ((LPCTSTR) temp[i].FileName,//&fd.cFileName,
ILI_CLSDFLD , ILI_OPENFLD , hItem , TVI_SORT);
CString strNewPathName = strPathName;
if (strNewPathName.Right (1) != "\\")
strNewPathName += "\\";
strNewPathName += (LPCTSTR) temp[i].FileName;//fd.cFileName;
SetButtonState (hChild, strNewPathName);
}
}
}
else
{
b.DirectoryInfo=temp[i];
b.path=str1;
pDoc->m_MTListView->AddToListView(&b);
}
}
delete temp;
return num;
}
void CLeftView::SetButtonState(HTREEITEM hItem, CString &strPathName)
{
if (HasSubdirectory (strPathName))
AddDummyNode (hItem);
}
BOOL CLeftView::IsDriveNode(HTREEITEM hItem)
{
return (GetTreeCtrl().GetParentItem (hItem) == NULL) ? TRUE : FALSE;
}
void CLeftView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
CString strPathName = GetPathFromItem (hItem);
if (!IsMediaValid (strPathName))
{
HTREEITEM hRoot = GetDriveNode (hItem);
GetTreeCtrl().Expand (hRoot, TVE_COLLAPSE);
DeleteChildren (hRoot);
AddDummyNode (hRoot);
*pResult = TRUE;
return;
}
// Delete the item if strPathName no longer specifies a valid path.
if (!IsPathValid (strPathName))
{
if(strPathName != MYCOMPUTER && strPathName != "")
{
GetTreeCtrl().DeleteItem (hItem);
*pResult = TRUE;
return;
}
}
CWaitCursor wait;
// If the item is expanding, delete the dummy item attached to it
// and add folder items. If the item is collapsing instead, delete
// its folder items and add a dummy item if appropriate.
if (pNMTreeView->action == TVE_EXPAND)
{
if(strPathName != MYCOMPUTER)
{
DeleteChildren (hItem);
if (!AddDirectoryNodes (hItem, strPathName))
*pResult = TRUE;
}
}
else {
if(strPathName != MYCOMPUTER)
{
DeleteChildren (hItem);
if (IsDriveNode (hItem))
AddDummyNode (hItem);
else
SetButtonState (hItem, strPathName);
}
}
m_LocalPath = strPathName;
*pResult = 0;
}
void CLeftView::OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
CString strPathName = GetPathFromItem (hItem);
*pResult = FALSE;
if(strPathName == MYCOMPUTER)
return;
CWaitCursor wait;
if (!AddDirectoryNodes (hItem, strPathName))
*pResult = TRUE;
m_LocalPath = strPathName;
*pResult = 0;
}
void CLeftView::OnDestroy()
{
CTreeView::OnDestroy();
// TODO: Add your message handler code here
if(m_pImageList != NULL)
m_pImageList = NULL;
CloseHandle(hDevice);
//UnloadDeviceDriver("Explorer");
delete m_pImageList;
}
void CLeftView::OnRButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CTreeView::OnRButtonDblClk(nFlags, point);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -