📄 resexplorertree.cpp
字号:
// ResExplorerTree.cpp : implementation file
//
#include "stdafx.h"
#include "resExplorer.h"
#include "ResExplorerTree.h"
#include "MainFrm.h"
#include "resExplorerView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CResExplorerTree
IMPLEMENT_DYNCREATE(CResExplorerTree, CView)
CResExplorerTree::CResExplorerTree()
{
//建立图象列表
HIMAGELIST hSystemSmallImageList, hSystemLargeImageList;
SHFILEINFO ssfi, lsfi;
//获得指向系统小图标的句柄
//把它分配给小图象列表
//不要忘了在你的析构函数里执行m_smallImageList.Detach()操作
hSystemSmallImageList = (HIMAGELIST)SHGetFileInfo( (LPCTSTR)_T("C:\\"), 0,&ssfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
m_smallImageList.Attach(hSystemSmallImageList);
//对大图标做同样的工作
hSystemLargeImageList = (HIMAGELIST)SHGetFileInfo( (LPCTSTR)_T("C:\\"),0, &lsfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_ICON);
m_largeImageList.Attach(hSystemLargeImageList);
//初始化树形控件节点的lparam值,该值将用于转换成CString 型ID值
m_tvlparam=0;
isSetting=false;
}
CResExplorerTree::~CResExplorerTree()
{
m_smallImageList.Detach();
m_largeImageList.Detach();
}
BEGIN_MESSAGE_MAP(CResExplorerTree, CView)
//{{AFX_MSG_MAP(CResExplorerTree)
ON_WM_CREATE()
ON_WM_SIZE()
//}}AFX_MSG_MAP
ON_NOTIFY(TVN_ITEMEXPANDING, IDC_TREE_VIEW, OnItemexpandingTreeView)
ON_NOTIFY(NM_RCLICK, IDC_TREE_VIEW, OnRclickTreeView)
ON_NOTIFY(TVN_SELCHANGING, IDC_TREE_VIEW, OnSelchangingTreeView)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CResExplorerTree drawing
void CResExplorerTree::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/////////////////////////////////////////////////////////////////////////////
// CResExplorerTree diagnostics
#ifdef _DEBUG
void CResExplorerTree::AssertValid() const
{
CView::AssertValid();
}
void CResExplorerTree::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CResExplorerTree message handlers
int CResExplorerTree::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
//创建"文件夹"标签
if (!m_wndCaption.Create( _T("文件夹"), WS_VISIBLE|WS_EX_LEFT|WS_DLGFRAME ,
CRect(0,0,0,0), this,IDC_CAPT_BUTTON ))
{
TRACE0( "Unable to create caption.\n" );
return -1;
}
//创建树控件
if( !this->m_TreeCtrl.Create((WS_VISIBLE|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT)/*|TVS_CHECKBOXES*/, CRect(0,0,0,0), this, IDC_TREE_VIEW))
{
TRACE0( "Unable to create tree control.\n" );
return -1;
}
m_TreeCtrl.SetImageList(&m_smallImageList, TVSIL_NORMAL);
//创建状态图标列表对象
if(!m_ImageState.Create(IDB_STATE, 11, 1, RGB(255,255,255)))//创建ImageList
{ TRACE0("Failed to create ImageList\n"); return -1; }
m_TreeCtrl.SetImageList(&m_ImageState, TVSIL_STATE );//在TreeList中加入表示状态的ImageList
/*
char * CJ[3]={"Visual C++","TanXin","TanZongRen"};//根数据名称
char * PM[3][4]={
{"Visual C++","Version 6.0","language C++","UseByTanXin"},//产品数据项
{"1979","March","Twenty-two","Visual C++"},
{"HuNan","HengYang","HengDong","www.xtu.edu.cn"}};
HTREEITEM hRoot;//树控制项目句柄
TVINSERTSTRUCTA TCItem;//插入数据项数据结构
TCItem.hInsertAfter=TVI_LAST;//在最后项之后
TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_STATE;//设屏蔽
TCItem.item.lParam=0;//序号
TCItem.item.iImage=1;//正常图标
TCItem.item.iImage=this->GetIconIndex("folder");//得到文件夹图标
TCItem.item.iSelectedImage=this->GetIconIndex("folderOpened");//得到文件夹打开图标
TCItem.item.state=INDEXTOSTATEIMAGEMASK(1);
TCItem.item.stateMask=TVIS_STATEIMAGEMASK;
for(int i=0;i<3;i++)
{
TCItem.hParent=TVI_ROOT;
TCItem.item.pszText=CJ[i];
char* tmpChr=new char[255];
TCItem.item.lParam=i*10;//子项序号
hRoot=m_TreeCtrl.InsertItem(&TCItem);
for(int j=0;j<4;j++)
{
TCItem.hParent=hRoot;
TCItem.item.pszText=PM[i][j];
TCItem.item.lParam=i*10+j;//子项序号
HTREEITEM hroot1=m_TreeCtrl.InsertItem(&TCItem);
for(int k=0;k<5;k++){
TCItem.hParent=hroot1;
TCItem.item.pszText=PM[i][j];
TCItem.item.lParam=i*10+j+100*k;//子项序号
m_TreeCtrl.InsertItem(&TCItem);
}
}
}
*/
this->InsertXMLItem(m_ResDataProvider.GetResLibs());
m_TreeCtrl.m_pTree=this;
return 0;
}
void CResExplorerTree::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if( m_wndCaption.GetSafeHwnd()) {
m_wndCaption.MoveWindow( 0, 0, cx, 19 );
}
if( this->m_TreeCtrl.GetSafeHwnd()) {
this->m_TreeCtrl.MoveWindow( 0, 19, cx, cy-19 );
}
}
int CResExplorerTree::GetIconIndex(const CString &csFileName)
{
SHFILEINFO sfi;
//获取主程序所在路径,存在sPath中
CString sPath;
GetModuleFileName(NULL,sPath.GetBufferSetLength (MAX_PATH+1),MAX_PATH);
sPath.ReleaseBuffer ();
int nPos;
nPos=sPath.ReverseFind ('\\');
sPath=sPath.Left (nPos);
CString tmpStr=sPath+"\\icon\\local";
if(csFileName=="folder"){//关闭的文件夹图标
SHGetFileInfo((LPCTSTR)tmpStr,0,&sfi,sizeof(SHFILEINFO),SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
}else if(csFileName=="folderOpened"){//打开文件夹图标
SHGetFileInfo((LPCTSTR)tmpStr,0,&sfi,sizeof(SHFILEINFO),SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_OPENICON);
}else if(csFileName=="disk"){//硬盘驱动器图标
tmpStr="c:\\";
SHGetFileInfo((LPCTSTR)tmpStr,0,&sfi,sizeof(SHFILEINFO),SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
}else{ //其他给定的文件在本地机器上正常显示的图标
tmpStr+="\\local."+csFileName;
//检查文件的存在性,若不存在,创建该文件
CFileFind finder;
BOOL bFind=finder.FindFile(tmpStr);
if(!bFind){//如果文件不存在,创建该文件
CFile file(tmpStr,CFile::modeCreate);
file.Close();//关闭文件句柄
}
SHGetFileInfo((LPCTSTR)tmpStr,0,&sfi,sizeof(SHFILEINFO),SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
}
return sfi.iIcon;
}
BOOL CResExplorerTree::InsertXMLItem(MSXML::IXMLDOMElement *node)
{
MSXML::IXMLDOMNodeListPtr pNodeList;
pNodeList=node->getElementsByTagName("item");
long count=pNodeList->Getlength();
for(long i=0;i<count;i++){
MSXML::IXMLDOMNodePtr pNode=pNodeList->Getitem(i);
MSXML::IXMLDOMNamedNodeMap* namedNodeMap = NULL;
HRESULT hr = S_OK;
hr = pNode->get_attributes(&namedNodeMap);
HTREEITEM hItem;//树控制项目句柄
TVINSERTSTRUCTA TCItem;//插入数据项数据结构
TCItem.hInsertAfter=TVI_LAST;//在最后项之后
//TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;//设屏蔽
if(isSetting){
TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_STATE;//设屏蔽
}else{
TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;//设屏蔽
}
TCItem.item.lParam=0;//序号
TCItem.item.iImage=1;//正常图标
TCItem.item.iImage=this->GetIconIndex("folder");
TCItem.item.iSelectedImage=this->GetIconIndex("folderOpened");
TCItem.item.state=INDEXTOSTATEIMAGEMASK(1);
TCItem.item.stateMask=TVIS_STATEIMAGEMASK;
if (SUCCEEDED(hr) && namedNodeMap != NULL) {
//得到节点名称
MSXML::IXMLDOMNodePtr pTextNode=namedNodeMap->getNamedItem("text");
BSTR text;
hr=pTextNode->get_text(&text);
//得到节点ID
MSXML::IXMLDOMNodePtr pIDNode=namedNodeMap->getNamedItem("id");
BSTR id;
hr=pIDNode->get_text(&id);
//得到父节点ID
MSXML::IXMLDOMNodePtr pPIDNode=namedNodeMap->getNamedItem("pid");
BSTR pid;
hr=pPIDNode->get_text(&pid);
//得到节点图标类型
MSXML::IXMLDOMNodePtr pIconNode=namedNodeMap->getNamedItem("icon");
BSTR icon;
hr=pIconNode->get_text(&icon);
CString tmpIconStr(icon);
if(tmpIconStr!="" && tmpIconStr!="folder"){
//得到图标索引号
TCItem.item.iImage=this->GetIconIndex(tmpIconStr);
TCItem.item.iSelectedImage=TCItem.item.iImage;
}
//设置节点插入的父节点句柄
/* if(CString(pid)=="root"){
TCItem.hParent=TVI_ROOT;
}else{
long tmpID=GetLParamByID(CString(pid));
TCItem.hParent=(HTREEITEM)(m_hTreeItems[tmpID]);
}
*/
if(CString(pid)=="root"){
TCItem.hParent=TVI_ROOT;
int nState=this->m_ResDataProvider.GetDispalySetting(CString(id));
TCItem.item.state=INDEXTOSTATEIMAGEMASK(nState);
if(nState==2){
if(!isSetting){//隐藏该节点
continue;
}
}
}else{
long tmpID=GetLParamByID(CString(pid));
TCItem.hParent=(HTREEITEM)(m_hTreeItems[tmpID]);
int nPState=this->m_ResDataProvider.GetDispalySetting(CString(pid));
int nState=this->m_ResDataProvider.GetDispalySetting(CString(id));
if(nPState==2){
TCItem.item.state=INDEXTOSTATEIMAGEMASK(2);
this->m_ResDataProvider.SetDispalySetting(CString(id),2);
}else if(nPState==4){
TCItem.item.state=INDEXTOSTATEIMAGEMASK(4);
this->m_ResDataProvider.SetDispalySetting(CString(id),4);
}else{
TCItem.item.state=INDEXTOSTATEIMAGEMASK(nState);
if(!isSetting&&nState==2){//隐藏该节点
continue;
}
}
}
//增加节点
CString tmpStr(text);
TCItem.item.pszText=tmpStr.GetBuffer(tmpStr.GetLength());
//得到与该节点ID相对的合适的子项序号
long l_id=GetLParamByID(CString(id));
TCItem.item.lParam=l_id;//子项序号
hItem=m_TreeCtrl.InsertItem(&TCItem);
//保存节点的hItem,方便以后通过节点ID查找相应的节点属性
m_hTreeItems.SetAtGrow(l_id,(hItem));
//以下插入一空节点,便于用于依次展开树节点
TCItem.hParent=hItem;
TCItem.item.pszText="";
TCItem.item.lParam=-1;
hItem=m_TreeCtrl.InsertItem(&TCItem);
}
}
return true;
}
long CResExplorerTree::GetLParamByID(CString strID)
{
//检查ID的重复性
if(m_tvlparam==0){
m_TVItemIDs.RemoveAll();
m_hTreeItems.RemoveAll();
}
long maxJ=m_TVItemIDs.GetSize();
for(long j=0;j<maxJ;j++){
if(m_TVItemIDs[j]==strID){
return j;
}
}
m_TVItemIDs.Add(strID);
m_tvlparam=m_TVItemIDs.GetUpperBound();
// m_TVItemIDs[m_tvlparam]=strID;
return m_tvlparam++;
}
CString CResExplorerTree::GetIDByLParam(long lparam)
{
/* if(m_tvlparam==0){
m_TVItemIDs.RemoveAll();
m_hTreeItems.RemoveAll();
}*/
long maxJ=m_TVItemIDs.GetSize();
if(lparam>=maxJ){
return "error";
}
return m_TVItemIDs[lparam];
}
void CResExplorerTree::OnItemexpandingTreeView(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
CString nodeID;
nodeID=GetIDByLParam(pNMTreeView->itemNew.lParam);
HTREEITEM hChildrenItem=m_TreeCtrl.GetChildItem(pNMTreeView->itemNew.hItem);
CString itemText=m_TreeCtrl.GetItemText(hChildrenItem);
if(itemText==""){
m_TreeCtrl.DeleteItem(hChildrenItem);
this->InsertXMLItem(m_ResDataProvider.GetChildren(nodeID));
}
*pResult = 0;
}
BOOL CResExplorerTree::SetItemState(HTREEITEM hItem,int nState)
{
// CMainFrame* MainFrame1=(CMainFrame*)this->GetParent()->GetParent();
TVITEM Item;
Item.hItem=hItem;
m_TreeCtrl.GetItem(&Item);
int lparam=Item.lParam;
if(lparam<0){//去掉不需要保存状态的节点
return false;
}
CMainFrame* MainFrame1=((CMainFrame*)(AfxGetApp()->m_pMainWnd));
CResExplorerTree* pView=(CResExplorerTree*)(MainFrame1->m_wndSplitter.GetPane(0,0));
CString strID;
strID=pView->GetIDByLParam(lparam);
pView->m_ResDataProvider.SetDispalySetting(strID,nState);
return TRUE;
}
void CResExplorerTree::OnRclickTreeView(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
CMenu t_Menu;
CMenu* t_pSubMenu;
CPoint m_Point;
GetCursorPos(&m_Point);
m_TreeCtrl.ScreenToClient(&m_Point);//转换为Client
UINT flag;
HTREEITEM hItem;
//测试是否有节点右键选中
hItem=m_TreeCtrl.HitTest(m_Point,&flag);
if(flag&TVHT_ONITEM){
//右键选中
t_Menu.LoadMenu (IDR_TREECTRL_CONTEXTMENU);
t_pSubMenu=t_Menu.GetSubMenu(0);
m_TreeCtrl.SelectItem(hItem);
}else{
t_Menu.LoadMenu (IDR_TREECTRL_CONTEXTMENU);
t_pSubMenu=t_Menu.GetSubMenu(0);
}
/*
CString menuText;
if(isSetting){
menuText="切换到常规状态";
}else{
menuText="切换到设置状态";
}
t_pSubMenu->ModifyMenu(0,MF_STRING|MF_BYPOSITION,ID_FILE_FOLDER_SETTING,menuText);
*/
m_TreeCtrl.ClientToScreen(&m_Point);
CMainFrame* MainFrame1=(CMainFrame*)this->GetParent()->GetParent();
HWND safeHwnd=(MainFrame1->GetSafeHwnd());
t_pSubMenu->TrackPopupMenu(TPM_RIGHTBUTTON, m_Point.x,m_Point.y,MainFrame1);
*pResult = 0;
}
void CResExplorerTree::OnSelchangingTreeView(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
CString nodeID;
nodeID=GetIDByLParam(pNMTreeView->itemNew.lParam);
CMainFrame* MainFrame1=(CMainFrame*)this->GetParent()->GetParent();
CResExplorerView* pView=(CResExplorerView*)(MainFrame1->m_wndSplitter.GetPane(0,1));
pView->InsertXMLItem(m_ResDataProvider.GetChildrenList(nodeID));
*pResult = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -