
通常这样的界面,是看树形列表中是否选取了节点,如果选取了,就以选中的为父节点,否则就是默认根为父节点,这样一个一个增加就可以了,不会出现歧义,录入错误也会少些。
很简单:第一步:在向导中给你的树形控件关联一个CTreeCtrl的变量(就像你代码中的m_Mess)
第二步:在向导中,添加该树形控件的NM_Click消息(就是鼠标单击消息,以下假设函数名为OnClickTree)
第三步:在代码中添加你的数据(主要是在初始化树形控件的数据的函数中,如你代码中的OnInitDialog()就可以)
HTREEITEM hRoot = m_ctrlTree.InsertItem("北京")
m_ctrlTree.SetItemData(hRoot, 1)
HTREEITEM hChild = m_ctrlTree.InsertItem("朝阳区", hRoot)
m_ctrlTree.SetItemData(hChild, 2)
hChild = m_ctrlTree.InsertItem("海淀区", hRoot)
m_ctrlTree.SetItemData(hChild, 3)
注意:我在上面用了SetItemData函数,主要是给不同的节点添加不同的标记
,在下面的单击消息函数中就可以看出它的作用
第四步:在OnClickTree函数中添加鼠标单击消息响应代码
CPoint pt = GetCurrentMessage()->pt //获取当前鼠标点击消息的坐标点
m_ctrlTree.ScreenToClient(&pt) //将鼠标的屏幕坐标,转换成树形控件的客户区坐标
UINT uFlags = 0
HTREEITEM hItem = m_ctrlTree.HitTest(pt, &uFlags)//然后做点击测试
if ((hItem != NULL) &&(TVHT_ONITEM &uFlags))//如果点击的位置是在节点位置上面
{
m_ctrlTree.SelectItem(hItem)
//获取开始我们设置的数据,注意这就是我为什么开始要每个节点设置不同的数据的原因。当然,如果你的数据节点比较少,你也可以通过获取节点的文字,如上面设置的"海淀区",然后通过字符串比较来判断点击了哪个节点
int nDat = m_ctrlTree.GetItemData(hItem)
//然后根据不同的节点,你完成不同的动作即可
switch (nDat)
{
case 1:
AfxMessageBox("北京")
break
case 2:
AfxMessageBox("北京->朝阳区")
break
case 3:
AfxMessageBox("北京->海淀区")
break
default:
AfxMessageBox("ERROR")
}
// TreeCtrlTestDlg.h : 头文件//
#pragma once
#include "afxcmn.h"
#include "afxwin.h"
// CTreeCtrlTestDlg 对话框
class CTreeCtrlTestDlg : public CDialog
{
// 构造
public:
CTreeCtrlTestDlg(CWnd* pParent = NULL)// 标准构造函数
// 对话框数据
enum { IDD = IDD_TREECTRLTEST_DIALOG }
protected:
virtual void DoDataExchange(CDataExchange* pDX)// DDX/DDV 支持
// 实现
public:
CString GetSelectedDir()
protected:
HICON m_hIcon
// 生成的消息映射函数
virtual BOOL OnInitDialog()
afx_msg void OnSysCommand(UINT nID, LPARAM lParam)
afx_msg void OnPaint()
afx_msg HCURSOR OnQueryDragIcon()
DECLARE_MESSAGE_MAP()
public:
CTreeCtrl m_tree
void OutTreeToList(HTREEITEM node)
CImageList m_ImageList
afx_msg void OnNMDblclkTreeFile(NMHDR *pNMHDR, LRESULT *pResult)
afx_msg void OnBnClickedButton1()
CListBox m_name_lst
afx_msg void OnBnClickedButton2()
CString m_dir_str
afx_msg void OnNMClickTreeFile(NMHDR *pNMHDR, LRESULT *pResult)
}
// TreeCtrlTestDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "TreeCtrlTest.h"
#include "TreeCtrlTestDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg()
// 对话框数据
enum { IDD = IDD_ABOUTBOX }
protected:
virtual void DoDataExchange(CDataExchange* pDX) // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
}
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX)
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CTreeCtrlTestDlg 对话框
CTreeCtrlTestDlg::CTreeCtrlTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTreeCtrlTestDlg::IDD, pParent)
, m_dir_str(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME)
}
void CTreeCtrlTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX)
DDX_Control(pDX, IDC_TREE_FILE, m_tree)
DDX_Control(pDX, IDC_LIST1, m_name_lst)
DDX_Text(pDX, IDC_DIR_STR, m_dir_str)
}
BEGIN_MESSAGE_MAP(CTreeCtrlTestDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_NOTIFY(NM_DBLCLK, IDC_TREE_FILE, &CTreeCtrlTestDlg::OnNMDblclkTreeFile)
ON_BN_CLICKED(IDC_BUTTON1, &CTreeCtrlTestDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CTreeCtrlTestDlg::OnBnClickedButton2)
ON_NOTIFY(NM_CLICK, IDC_TREE_FILE, &CTreeCtrlTestDlg::OnNMClickTreeFile)
END_MESSAGE_MAP()
// CTreeCtrlTestDlg 消息处理程序
BOOL CTreeCtrlTestDlg::OnInitDialog()
{
CDialog::OnInitDialog()
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX &0xFFF0) == IDM_ABOUTBOX)
ASSERT(IDM_ABOUTBOX <0xF000)
CMenu* pSysMenu = GetSystemMenu(FALSE)
if (pSysMenu != NULL)
{
CString strAboutMenu
strAboutMenu.LoadString(IDS_ABOUTBOX)
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR)
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu)
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此 *** 作
SetIcon(m_hIcon, TRUE) // 设置大图标
SetIcon(m_hIcon, FALSE) // 设置小图标
// TODO: 在此添加额外的初始化代码
/*TVINSERTSTRUCT tvInsert
tvInsert.hParent = NULL
tvInsert.hInsertAfter = NULL
tvInsert.item.mask = TVIF_TEXT
tvInsert.item.pszText = TEXT("United States")
HTREEITEM hCountry = m_tree.InsertItem(&tvInsert)
// Insert subitems of that root. Pennsylvania is
// a state in the United States, so its item will be a child
// of the United States item. We won't set any image or states,
// so we supply only the TVIF_TEXT mask flag. This
// override provides nearly complete control over the
// insertion operation without the tedium of initializing
// a structure. If you're going to add lots of items
// to a tree, you might prefer the structure override
// as it affords you a performance win by allowing you
// to initialize some fields of the structure only once,
// outside of your insertion loop.
HTREEITEM hPA = m_tree.InsertItem(TVIF_TEXT,
TEXT("Pennsylvania"), 0, 0, 0, 0, 0, hCountry, NULL)
// Insert the "Washington" item and assure that it is
// inserted after the "Pennsylvania" item. This override is
// more appropriate for conveniently inserting items with
// images.
HTREEITEM hWA = m_tree.InsertItem(_T("Washington"),
0, 0, hCountry, hPA)
// We'll add some cities under each of the states.
// The override used here is most appropriate
// for inserting text-only items.
m_tree.InsertItem(TEXT("Pittsburgh"), hPA, TVI_SORT)
m_tree.InsertItem(TEXT("Harrisburg"), hPA, TVI_SORT)
m_tree.InsertItem(TEXT("Altoona"), hPA, TVI_SORT)
m_tree.InsertItem(TEXT("Seattle"), hWA, TVI_SORT)
m_tree.InsertItem(TEXT("Kalaloch"), hWA, TVI_SORT)
m_tree.InsertItem(TEXT("Yakima"), hWA, TVI_SORT)*/
m_ImageList.Create(16,16,ILC_COLOR32|ILC_MASK,0,0)//图形列表
//关联树形控件与图标控件
m_tree.SetImageList(&m_ImageList,TVSIL_NORMAL)
m_tree.ModifyStyle(0L,TVS_HASLINES|TVS_LINESATROOT)
size_t alldriver=::GetLogicalDriveStrings(0,NULL)//获得逻辑驱动器字串长度
TCHAR *driverstr=NULL
driverstr=new TCHAR[alldriver+sizeof(TCHAR)]
if(GetLogicalDriveStrings(alldriver,driverstr)!=alldriver-1)//获得逻辑驱动器字串
{
return FALSE
}
TCHAR *pdriverstr=driverstr
size_t driversize=wcslen(pdriverstr)
HTREEITEM disktree
SHFILEINFO fileinfo
memset(&fileinfo,0,sizeof(SHFILEINFO))
while(driversize>0)
{
//用盘符获得驱动器类型
UINT tType=::GetDriveType(pdriverstr)
//用盘符得到驱动器信息
SHGetFileInfo(pdriverstr,0,&fileinfo,sizeof(SHFILEINFO),SHGFI_ICON)
//判断驱动器类型
if(tType!=DRIVE_REMOVABLE&&tType!=DRIVE_CDROM )
{
//把图标加入图形控件列表
int imindex=m_ImageList.Add(fileinfo.hIcon)
//增加树形控件列表节点
disktree=m_tree.InsertItem(pdriverstr,imindex,imindex,TVI_ROOT,TVI_LAST)
}
pdriverstr+=driversize+1
driversize=wcslen(pdriverstr)
}
return TRUE // 除非将焦点设置到控件,否则返回 TRUE
}
void CTreeCtrlTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID &0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout
dlgAbout.DoModal()
}
else
{
CDialog::OnSysCommand(nID, lParam)
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CTreeCtrlTestDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this)// 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0)
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON)
int cyIcon = GetSystemMetrics(SM_CYICON)
CRect rect
GetClientRect(&rect)
int x = (rect.Width() - cxIcon + 1) / 2
int y = (rect.Height() - cyIcon + 1) / 2
// 绘制图标
dc.DrawIcon(x, y, m_hIcon)
}
else
{
CDialog::OnPaint()
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CTreeCtrlTestDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon)
}
void CTreeCtrlTestDlg::OnNMDblclkTreeFile(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
CFileFind filefd
HTREEITEM parent
//当前选中节点
HTREEITEM item=m_tree.GetSelectedItem()
//是否有字节点 可用ItemHasChildren(hmyItem)判断
HTREEITEM h=m_tree.GetChildItem(item)
//如果已经有根节点,说明遍历过了,不再遍历
if(h)
{
return
}
parent =item
//得到当前节点的名字串
CString rootstr=m_tree.GetItemText(item)
CString temp
CString lstr
if(rootstr.Find(TEXT("\\"))==2)//判断是否是盘根目录
{
lstr.Format(TEXT("%s*.*"),rootstr)
}
else
{
//非根目录要重组查找字串
CString strparent
while(1)
{
parent=m_tree.GetParentItem(parent)
strparent=m_tree.GetItemText(parent)
if(strparent.Find(TEXT("\\"))==2)
{
break
}
temp+=strparent
temp+=TEXT("\\")
}
CString root=m_tree.GetItemText(parent)
lstr.Format(TEXT("%s%s%s\\*.*"),root,temp,rootstr)
}
//遍历文件
SHFILEINFO fileinfo
BOOL bfind=filefd.FindFile(lstr)
while(bfind)
{
bfind=filefd.FindNextFile()
CString filepath
//是目录,并且 不是 .和..文件夹
if(filefd.IsDirectory() &&!filefd.IsDots())
{
//文件图标信息
SHGetFileInfo(filefd.GetFilePath(),0,&fileinfo,sizeof(SHFILEINFO),SHGFI_ICON)
//加入到图标列表
int imindex=m_ImageList.Add(fileinfo.hIcon)
//加入到树形控件中
m_tree.InsertItem(filefd.GetFileName(),imindex,imindex,item)
}
}
*pResult = 0
}
void CTreeCtrlTestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CString StrDisktype
switch( ::GetDriveType(TEXT("G:")) )
{
case DRIVE_REMOVABLE:
StrDisktype=TEXT("软驱")
break
case DRIVE_FIXED:
StrDisktype=TEXT("固定硬盘")
break
case DRIVE_REMOTE:
StrDisktype=TEXT("网络驱动器")
break
case DRIVE_CDROM:
StrDisktype=TEXT("光驱")
break
case DRIVE_RAMDISK:
StrDisktype=TEXT("RAM驱动器")
break
default:
StrDisktype=TEXT("未知")
break
}
MessageBox(TEXT("G:盘为:")+StrDisktype,TEXT("信息提示"),MB_OK)
}
void CTreeCtrlTestDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
m_name_lst.ResetContent()
HTREEITEM hChild
CString Str
//HTREEITEM node=m_tree.GetRootItem()
HTREEITEM node=m_tree.GetSelectedItem()
if(node)
{
Str=m_tree.GetItemText(node)
m_name_lst.AddString(Str)
OutTreeToList(node)
}
}
CString CTreeCtrlTestDlg::GetSelectedDir()
{
CString Str
//HTREEITEM node2=m_tree.GetSelectedItem()//用这个不稳定
CPoint pt
GetCursorPos(&pt)
m_tree.ScreenToClient(&pt)
HTREEITEM node2 = m_tree.HitTest(pt)//下当于得到当前选中项
Str=m_tree.GetItemText(node2)
node2=m_tree.GetParentItem(node2)
while(node2!=NULL)
{
CString tStr
tStr=m_tree.GetItemText(node2)
if(tStr.Find('\\')>=0)
{
Str=tStr+Str
}
else
{
Str=tStr+TEXT("\\")+Str
}
node2=m_tree.GetParentItem(node2)
}
return Str
}
void CTreeCtrlTestDlg::OutTreeToList(HTREEITEM node)
{
HTREEITEM child
CString Str
node=m_tree.GetChildItem(node)
if(node)
{
while(node)
{
Str=m_tree.GetItemText(node)
m_name_lst.AddString(Str)
child=node
OutTreeToList(child)//递归调用
node=m_tree.GetNextItem(node,TVGN_NEXT)
}
}
}
void CTreeCtrlTestDlg::OnNMClickTreeFile(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
m_dir_str=GetSelectedDir()
m_name_lst.ResetContent()
CFileFind fFind
CString Str
Str=m_dir_str+TEXT("\\*.wdf")
BOOL bMore=fFind.FindFile(Str)
while(bMore)
{
bMore=fFind.FindNextFile()
m_name_lst.AddString(fFind.GetFileName())
}
UpdateData(FALSE)
/*CPoint pt
GetCursorPos(&pt)
m_tree.ScreenToClient(&pt)
HTREEITEM node = m_tree.HitTest(pt)
m_dir_str=m_tree.GetItemText(node)
UpdateData(FALSE)*/
*pResult = 0
}
以上代码是用树形控件来显示磁盘文件,你拿去研究下吧
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)