【第30节】MFC编程:ListCtrl控件和TreeCtrl控件
目录
引言
一、高级控件ListCtrl
二、高级控件TreeCtrl
三、Shell控件
四、CImageList
五、综合代码示例
引言
在MFC编程里,高级控件能大幅提升应用程序的交互性与功能性。接下来,咱们会详细讲讲ListCtrl和TreeCtrl这两个高级控件。不仅会介绍它们的功能、操作方法,还会分享创建与使用时的实操步骤,助力大家掌握这些控件的开发技巧 。
一、高级控件ListCtrl
ListCtrl控件可以把字符串内容,用列表形式展示出来。这种展示方法既整齐又直观,在实际使用过程中,能让用户更方便。
一般情况下,使用ListCtrl控件时,需要将它和CListCtrl类,或者从CListCtrl派生出来的类所创建的对象进行绑定。
常见函数如下:
具体每个消息的含义,可在控件属性栏中选择消息查看中文解释,也可查阅MSDN。
ListCtrl控件的创建步骤
1. 添加变量:为ListCtrl控件添加变量。
2. 添加类:右键点击list控件,选择“添加类”,类名设为CMyListCtrl,基类选择CListCtrl(该类继承于CListCtrl)。
3. 绑定变量生成代码:绑定变量完成后会在当前对话框类的相应位置生成代码。
头文件中:
protected:
virtual void DoDataExchange(CDataExchange*pDX);
DECLARE_MESSAGE_MAP()
// 该窗口类对应的h类中
public:
CListCtrl mListCtrl;
CPP文件中:
void CListCtrlDlg::DoDataExchange(CDataExchange*pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, mListCtrl);
}
4. 初始化:在该窗口类的OnInitDialog()中对ListCtrl初始化。
//获取当前控件的扩展风格
DWORD dwOldStyle = mListCtrl.GetExtendedStyle(); //获取原风格
//设置当前控件的扩展风格
mListCtrl.SetExtendedStyle(dwOldStyle |
LVS_EX_FULLROWSELECT| //报表视图形式
LVS_EX_GRIDLINES //网格线(只适用与report风格的listctrl)
LVS_EX_CHECKBOXES); //item前生成checkbox控件
//获取list的宽度
CRect rc;
mListCtrl.GetClientRect(rc);
int nWidth = rc.Width();
//为List插入列信息
mListCtrl.InsertColumn(0, L"姓名", 0, nWidth/3); //当前列编号、要求插入的信息、风格、列的宽度
mListCtrl.InsertColumn(1, L"性别", 0, nWidth /3);
mListCtrl.InsertColumn(2, L"年龄", 0, nWidth/3);
//插入生信息
mListCtrl.InsertItem(0, L"张三"); //行号
mListCtrl.SetItemText(0, 1, L"男"); //行号、列号
mListCtrl.SetItemText(0, 2, L"20");
mListCtrl.InsertItem(1, L"李四");
mListCtrl.SetItemText(1, 1, L"男");
mListCtrl.SetItemText(1, 2, L"22");
运行之后,列表框会显示相应内容。
5. 响应选中行:为新添加的List类添加点击事件,通过类向导选择“消息”中的NM_CLICK消息。
头文件中:
public :
afx_msg void OnNMGIick(NMHDR *pNMHDR, LRESULT *pResult);
CPP文件中:
// 消息映射宏中添加的代码
BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
ON_NOTIFY_REFLECT(NM_CLICK, &CMyListCtrl::OnNMClicK)
END_MESSAGE_MAP()
// 函数实现部分
void CMyListCtrl::OnNMClicK(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
//TODO:在此添加控件通知处理程序代码
*pResult = 0;
}
可以在注释下面添加相应代码。
二、高级控件TreeCtrl
树控件是较为复杂的控件,这里先简要介绍其基本使用方法,后续课程会介绍一些使用技巧。树控件的每个节点都由一个HTREEITEM类型的句柄标识,在插入或查找树节点时会用到。
CTree类的常见函数
重点函数详解
HTREEITEM InsertItem(
LPCTSTR lpszItem,
int nImage,
int nSelectedImage,
HTREEITEM hParent =TVI_ROOT,
HTREEITEM hInsertAfter =TVI_LAST);
- lpszItem:为新节点的标签文本字符串的指针。
- nImage:为新节点的图标在树形控件图像序列中的索引。
- nSelectedImage:为新节点被选中时的图标在图像序列中的索引。
- hParent:为插入节点的父节点的句柄。
- hInsertAfter:为新节点的前一个节点的句柄,即新节点将被插入到hInsertAfter节点之后。
与其他控件使用方法相同,需要为Tree控件绑定一个控件类型的变量。
通知消息
Tree控件和所有控件一样,都有针对父窗口的通知消息,可通过类向导查看,如:TVN_SELCHANGED、TVN_BEGINDRAG、TVN_BEGINLABELEDIT、TVN_BEGINRDRAG、TVN_DELETEITEM、TVN_ENDLABELEDIT、TVN_GETDISPINFO、TVN_ITEMEXPANDED等。
我们可测试其中的TVN_SELCHANGED消息(被选择的树节点改变的消息),与tab控件一样,这个消息也有对应的发给自身的反射消息,在类向导中添加其处理程序即可。
三、Shell控件
Shell控件主要用于实现与Windows Shell相关的功能,例如文件资源管理器的树形视图和列表视图。以下是关于MFC中Shell控件用法的详细介绍:
1. Shell控件概述
MFC提供了两个主要的Shell控件:
- `CMFCShellTreeCtrl`:用于显示文件系统的树形结构,类似于Windows资源管理器的左侧树形视图。
- `CMFCShellListCtrl`:用于显示指定文件夹中的文件列表,类似于Windows资源管理器的右侧文件列表。
这两个控件可以结合使用,创建一个类似于文件资源管理器的应用程序。
2. 创建Shell控件
以下是如何在MFC应用程序中使用Shell控件的步骤:
2.1 创建MFC项目
- 使用Visual Studio的MFC应用程序向导创建一个新的MFC项目。在向导中,选择“单个文档”或“对话框”应用程序类型,并确保勾选“ActiveX控件”和“导航窗格”选项。导航窗格选项会自动在窗口左侧嵌入一个`CMFCShellTreeCtrl`控件。
2.2 添加Shell控件
- `CMFCShellTreeCtrl`:通常由向导自动创建,嵌入在主窗口的左侧窗格中。
- `CMFCShellListCtrl`:需要在视图类中手动添加。首先在视图头文件中包含`afxShellListCtrl.h`,然后声明一个`CMFCShellListCtrl`类型的成员变量。接着,在`OnCreate`方法中初始化并创建该控件。
示例代码:
#include <afxShellListCtrl.h>
class CMFCShellControlsView : public CView {
private:
CMFCShellListCtrl m_wndList;
};
在`OnCreate`方法中:
int CMFCShellControlsView::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
CRect rect;
GetClientRect(&rect);
m_wndList.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT, rect, this, 2);
return 0;
}
3. Shell控件的交互
- 树形控件与列表控件的联动:当用户在`CMFCShellTreeCtrl`中选择一个文件夹时,`CMFCShellListCtrl`应显示该文件夹中的内容。可以通过处理树形控件的`TVN_SELCHANGED`消息来实现这一功能。
示例代码:
void CMFCShellControlsView::OnTvnSelchangedTree(NMHDR *pNMHDR, LRESULT *pResult) {
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
CString strPath;
m_wndTree.GetItemPath(strPath, pNMTreeView->itemNew.hItem);
m_wndList.SetFolder(strPath);
*pResult = 0;
}
4. Shell控件的扩展功能
- 文件操作:可以通过`CMFCShellListCtrl`实现文件的复制、移动、删除等操作。
- 自定义显示:可以自定义列表控件的显示方式,例如图标视图、详细信息视图等。
5. 注意事项
- 路径处理:Shell控件使用PIDL(指向项目标识符列表的指针)来唯一标识文件和文件夹。可以使用`CMFCShellManager`类来管理PIDL和路径之间的转换。
- 权限问题:某些系统文件夹可能需要管理员权限才能访问,需确保应用程序有足够的权限。
通过以上步骤和代码示例,您可以在MFC应用程序中实现类似文件资源管理器的功能,并充分利用Shell控件的强大功能。
四、CImageList
`CImageList` 是 MFC(Microsoft Foundation Classes)中的一个类,用于管理相同大小的图像集合,通常用于为其他控件(如列表控件、树控件、标签控件等)提供图标资源。以下是 `CImageList` 的用法详细介绍:
1. 创建 `CImageList` 对象
`CImageList` 的创建通过 `Create` 方法实现,该方法有多个重载版本,常用的形式如下:
BOOL Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow);
BOOL Create(UINT nBitmapID, int cx, int nGrow, COLORREF crMask);
BOOL Create(LPCTSTR lpszBitmapID, int cx, int nGrow, COLORREF crMask);
- 参数说明:
- `cx` 和 `cy`:图像的宽度和高度(以像素为单位)。
- `nFlags`:指定图像列表的类型,如 `ILC_COLOR4`(16色)、`ILC_COLOR8`(256色)、`ILC_COLOR32`(真彩色)等。
- `nInitial`:初始图像数量。
- `nGrow`:当图像列表需要扩展时,每次增加的图像数量。
- `nBitmapID` 或 `lpszBitmapID`:位图资源的 ID 或路径。
- `crMask`:用于生成透明掩码的颜色。
示例:
CImageList m_ImageList;
m_ImageList.Create(32, 32, ILC_COLOR32 | ILC_MASK, 0, 4);
2. 添加图像
`CImageList` 支持从资源文件或外部文件添加图像:
// 从资源文件添加图标
m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
// 从资源文件添加位图
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);
m_ImageList.Add(&bmp, RGB(0, 0, 0)); // RGB(0, 0, 0) 为透明色
bmp.DeleteObject();
// 从外部文件添加位图
HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, _T("e:\\TIME.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
CBitmap* pBitmap = new CBitmap;
pBitmap->Attach(hBitmap);
m_ImageList.Add(pBitmap, RGB(0, 0, 0));
delete pBitmap;
3. 关联控件
`CImageList` 通常与其他控件(如 `CListCtrl`、`CTreeCtrl`)一起使用,通过 `SetImageList` 方法关联:
// 关联列表控件
CListCtrl m_ListCtrl;
m_ListCtrl.SetImageList(&m_ImageList, LVSIL_NORMAL);
// 关联树控件
CTreeCtrl m_TreeCtrl;
m_TreeCtrl.SetImageList(&m_ImageList, TVSIL_NORMAL);
4. 绘制图像
可以通过 `Draw` 方法将图像绘制到设备上下文(DC)中:
CDC* pDC = GetDC();
CPoint pt(30, 50);
for (int i = 0; i < m_ImageList.GetImageCount(); i++) {
m_ImageList.Draw(pDC, i, pt, ILD_NORMAL);
pt.x += 60;
}
ReleaseDC(pDC);
5. 常用操作
- 获取图像数量:`int GetImageCount()`
- 删除图像:`BOOL Remove(int nImage)`
- 设置背景颜色:`COLORREF SetBkColor(COLORREF cr)`
- 删除图像列表:`BOOL DeleteImageList()`
- 提取图标:`HICON ExtractIcon(int nImage)`
6. 应用示例
以下是一个完整的示例,展示如何创建 `CImageList` 并关联到 `CListCtrl`:
// 在对话框类中定义成员变量
CImageList m_ImageList;
CListCtrl m_ListCtrl;
// 在 OnInitDialog 中初始化
m_ImageList.Create(32, 32, ILC_COLOR32 | ILC_MASK, 0, 4);
m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
m_ListCtrl.SetImageList(&m_ImageList, LVSIL_NORMAL);
m_ListCtrl.InsertItem(0, _T("Item 1"), 0);
m_ListCtrl.InsertItem(1, _T("Item 2"), 1);
7. 注意事项
- `CImageList` 本身不可见,必须与其他控件结合使用。
- 图像列表中的图像大小必须一致。
- 使用透明色时,确保 `ILC_MASK` 标志被设置。
通过以上方法,可以有效地在 MFC 应用程序中使用 `CImageList` 来管理和显示图像资源。
五、综合代码示例
该项目是一个演示 MFC 中列表控件(CListCtrl)和树形控件(CTreeCtrl)使用的示例程序。主要功能包括:
1. 列表控件(CListCtrl)功能:
- 使用网格线样式和整行选择
- 包含3列数据展示
- 每行显示3个数据项
- 支持图标显示
- 点击列表项会弹出消息框显示选中内容
2. 树形控件(CTreeCtrl)功能:
- 支持图标显示
- 包含两级树形结构:
- 第一级:SDK、MFC
- 第二级:SDK001/SDK002、MFC001/MFC002
- 支持节点选择和点击事件
- 点击树节点会弹出消息框显示节点文本
3. Shell控件功能:
- 使用 CMFCShellTreeCtrl 和 CMFCShellListCtrl 实现文件系统浏览
- 树形控件显示文件夹结构
- 列表控件显示当前文件夹内容
- 两个控件联动,选择文件夹时自动更新列表内容
4. 界面特点:
- 使用图标列表(CImageList)管理界面图标
- 包含4个图标资源(1.ico ~ 4.ico)
- 支持对话框最小化时的图标显示
5. 其他功能:
- 包含"关于"对话框
- 支持系统菜单
- 使用 Unicode 字符集
- 支持 Windows 视觉样式
这个项目主要用于演示 MFC 中常用控件的使用方法和基本功能,包括列表控件、树形控件、Shell控件等。
// 01.ListTree.h : PROJECT_NAME 应用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif
#include "resource.h" // 主符号
// CMy01ListTreeApp:
// 有关此类的实现,请参阅 01.ListTree.cpp
//
class CMy01ListTreeApp : public CWinApp
{
public:
CMy01ListTreeApp();
// 重写
public:
virtual BOOL InitInstance();
// 实现
DECLARE_MESSAGE_MAP()
};
extern CMy01ListTreeApp theApp;
// 01.ListTreeDlg.h : 头文件
//
#pragma once
#include "afxcmn.h"
#include "afxshelltreectrl.h"
#include "afxshelllistctrl.h"
// CMy01ListTreeDlg 对话框
class CMy01ListTreeDlg : public CDialogEx
{
// 构造
public:
CMy01ListTreeDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MY01LISTTREE_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
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:
CListCtrl m_list;
// 初始化list
void InitList();
// 初始化图标数组
CImageList m_img;
void InitImgList();
afx_msg void OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult);
// 初始化树控件
CTreeCtrl m_tree;
void InitTree();
afx_msg void OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnNMClickTree1(NMHDR *pNMHDR, LRESULT *pResult);
CMFCShellTreeCtrl m_mfcTree;
CMFCShellListCtrl m_mfcList;
};
//resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 01.ListTree.rc 使用
//
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_MY01LISTTREE_DIALOG 102
#define IDR_MAINFRAME 128
#define IDI_ICON1 130
#define IDI_ICON2 131
#define IDI_ICON3 132
#define IDI_ICON4 133
#define IDC_LIST1 1000
#define IDC_TREE1 1001
#define IDC_MFCSHELLTREE1 1002
#define IDC_MFCSHELLLIST1 1003
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 135
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1004
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
//01.ListTree.rc
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#include "afxres.h"
#include "verrsrc.h"
/
#undef APSTUDIO_READONLY_SYMBOLS
/
// 中文(简体,中国) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#ifdef APSTUDIO_INVOKED
/
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#ifndef APSTUDIO_INVOKED\r\n"
"#include ""targetver.h""\r\n"
"#endif\r\n"
"#include ""afxres.h""\r\n"
"#include ""verrsrc.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
"LANGUAGE 4, 2\r\n"
"#include ""res\\My01ListTree.rc2"" // 非 Microsoft Visual C++ 编辑的资源\r\n"
"#include ""l.CHS\\afxres.rc"" // 标准组件\r\n"
"#if !defined(_AFXDLL)\r\n"
"#include ""l.CHS\\afxribbon.rc"" // MFC 功能区和控制条资源\r\n"
"#endif\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON "res\\01.ListTree.ico"
IDI_ICON1 ICON "res\\1.ico"
IDI_ICON2 ICON "res\\2.ico"
IDI_ICON3 ICON "res\\3.ico"
IDI_ICON4 ICON "res\\4.ico"
/
//
// Dialog
//
IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "关于 01.ListTree"
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,14,14,21,20
LTEXT "01.ListTree,1.0 版",IDC_STATIC,42,14,114,8,SS_NOPREFIX
LTEXT "Copyright (C) 2018",IDC_STATIC,42,26,114,8
DEFPUSHBUTTON "确定",IDOK,113,41,50,14,WS_GROUP
END
IDD_MY01LISTTREE_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "01.ListTree"
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,136,7,177,72
CONTROL "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_HSCROLL | WS_TABSTOP,7,7,129,71
CONTROL "",IDC_MFCSHELLTREE1,"MfcShellTree",WS_BORDER | WS_HSCROLL | WS_TABSTOP,7,79,128,114
CONTROL "",IDC_MFCSHELLLIST1,"MfcShellList",WS_BORDER | WS_TABSTOP | 0x841,135,79,178,114
END
/
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080404B0"
BEGIN
VALUE "CompanyName", "TODO: <公司名>"
VALUE "FileDescription", "01.ListTree"
VALUE "FileVersion", "1.0.0.1"
VALUE "InternalName", "01.ListTree.exe"
VALUE "LegalCopyright", "TODO: (C) <公司名>。 保留所有权利。"
VALUE "OriginalFilename", "01.ListTree.exe"
VALUE "ProductName", "TODO: <产品名>"
VALUE "ProductVersion", "1.0.0.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x804, 1200
END
END
/
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 163
TOPMARGIN, 7
BOTTOMMARGIN, 55
END
IDD_MY01LISTTREE_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 313
TOPMARGIN, 7
BOTTOMMARGIN, 193
END
END
#endif // APSTUDIO_INVOKED
/
//
// AFX_DIALOG_LAYOUT
//
IDD_MY01LISTTREE_DIALOG AFX_DIALOG_LAYOUT
BEGIN
0
END
/
//
// Dialog Info
//
IDD_MY01LISTTREE_DIALOG DLGINIT
BEGIN
IDC_MFCSHELLTREE1, 0x37c, 88, 0
0x4d3c, 0x4346, 0x6853, 0x6c65, 0x546c, 0x6572, 0x4365, 0x7274, 0x5f6c,
0x6e45, 0x6261, 0x656c, 0x6853, 0x6c65, 0x436c, 0x6e6f, 0x6574, 0x7478,
0x654d, 0x756e, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x5343, 0x6568,
0x6c6c, 0x7254, 0x6565, 0x7443, 0x6c72, 0x455f, 0x616e, 0x6c62, 0x5365,
0x6568, 0x6c6c, 0x6f43, 0x746e, 0x7865, 0x4d74, 0x6e65, 0x3e75,
IDC_MFCSHELLLIST1, 0x37c, 88, 0
0x4d3c, 0x4346, 0x6853, 0x6c65, 0x4c6c, 0x7369, 0x4374, 0x7274, 0x5f6c,
0x6e45, 0x6261, 0x656c, 0x6853, 0x6c65, 0x436c, 0x6e6f, 0x6574, 0x7478,
0x654d, 0x756e, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x5343, 0x6568,
0x6c6c, 0x694c, 0x7473, 0x7443, 0x6c72, 0x455f, 0x616e, 0x6c62, 0x5365,
0x6568, 0x6c6c, 0x6f43, 0x746e, 0x7865, 0x4d74, 0x6e65, 0x3e75,
0
END
/
//
// String Table
//
STRINGTABLE
BEGIN
IDS_ABOUTBOX "关于 01.ListTree(&A)..."
END
#endif // 中文(简体,中国) resources
/
#ifndef APSTUDIO_INVOKED
/
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE 4, 2
#include "l.CHS\afxres.rc" // 标准组件
#if !defined(_AFXDLL)
#include "l.CHS\afxribbon.rc" // MFC 功能区和控制条资源
#endif
#endif
/
#endif // not APSTUDIO_INVOKED
// 01.ListTree.cpp : 定义应用程序的类行为。
//
#include "stdafx.h"
#include "01.ListTree.h"
#include "01.ListTreeDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMy01ListTreeApp
BEGIN_MESSAGE_MAP(CMy01ListTreeApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CMy01ListTreeApp 构造
CMy01ListTreeApp::CMy01ListTreeApp()
{
// 支持重新启动管理器
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CMy01ListTreeApp 对象
CMy01ListTreeApp theApp;
// CMy01ListTreeApp 初始化
BOOL CMy01ListTreeApp::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。 否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// 创建 shell 管理器,以防对话框包含
// 任何 shell 树视图控件或 shell 列表视图控件。
CShellManager *pShellManager = new CShellManager;
// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
CMy01ListTreeDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
// “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
// “取消”来关闭对话框的代码
}
else if (nResponse == -1)
{
TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
}
// 删除上面创建的 shell 管理器。
if (pShellManager != NULL)
{
delete pShellManager;
}
#ifndef _AFXDLL
ControlBarCleanUp();
#endif
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}
// 01.ListTreeDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "01.ListTree.h"
#include "01.ListTreeDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CMy01ListTreeDlg 对话框
CMy01ListTreeDlg::CMy01ListTreeDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_MY01LISTTREE_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMy01ListTreeDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_list);
DDX_Control(pDX, IDC_TREE1, m_tree);
DDX_Control(pDX, IDC_MFCSHELLTREE1, m_mfcTree);
DDX_Control(pDX, IDC_MFCSHELLLIST1, m_mfcList);
}
BEGIN_MESSAGE_MAP(CMy01ListTreeDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_NOTIFY(NM_CLICK, IDC_LIST1, &CMy01ListTreeDlg::OnNMClickList1)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, &CMy01ListTreeDlg::OnTvnSelchangedTree1)
ON_NOTIFY(NM_CLICK, IDC_TREE1, &CMy01ListTreeDlg::OnNMClickTree1)
END_MESSAGE_MAP()
// CMy01ListTreeDlg 消息处理程序
BOOL CMy01ListTreeDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
InitImgList();
InitList();
InitTree();
m_mfcTree.SetRelatedList(&m_mfcList);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CMy01ListTreeDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CMy01ListTreeDlg::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
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMy01ListTreeDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CMy01ListTreeDlg::InitList()
{
// 设置扩展风格 带网格 整行选中
m_list.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
// 设置list的关联图标数组
m_list.SetImageList(&m_img, LVSIL_SMALL);
// 设置行列信息
// 1. 先设置列标题
m_list.InsertColumn(0, L"第1列", 0, 80);
m_list.InsertColumn(1, L"第2列", 0, 80);
m_list.InsertColumn(2, L"第3列", 0, 80);
// 2. 再插入行信息 行标题 行内容
for (int i=0;i<20;i++)
{
TCHAR szShow[20] = {};
swprintf_s(szShow, 20, L"第%d行",i+1);
// 行标题
m_list.InsertItem(i, szShow,i%4);
// 行内容
swprintf_s(szShow, 20, L"第%d行%d列", i + 1,1);
m_list.SetItemText(i, 1, szShow);
swprintf_s(szShow, 20, L"第%d行%d列", i + 1, 2);
m_list.SetItemText(i, 2, szShow);
}
}
void CMy01ListTreeDlg::InitImgList()
{
// 每个icon的信息 大小等
// 创建一成员为32*32大小使用32位色的icon数组,
// 数组初始空间大小为4个,满了之后按1递增
m_img.Create(32, 32, ILC_COLOR32, 4, 1);
m_img.Add(AfxGetApp()->LoadIconW(IDI_ICON1));
m_img.Add(AfxGetApp()->LoadIconW(IDI_ICON2));
m_img.Add(AfxGetApp()->LoadIconW(IDI_ICON3));
m_img.Add(AfxGetApp()->LoadIconW(IDI_ICON4));
}
void CMy01ListTreeDlg::OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
CString str = m_list.GetItemText(pNMItemActivate->iItem, pNMItemActivate->iSubItem);
MessageBox(str.GetBuffer());
}
void CMy01ListTreeDlg::InitTree()
{
// 设置关联图标
m_tree.SetImageList(&m_img, TVSIL_NORMAL);
// 1级节点
HTREEITEM hParent = m_tree.InsertItem(
L"SDK",// 插入文本
0,// 正常情况下显示的图标在数组中的索引
3,// 该节点被点击的时候显示的图标在数组中的索引
TVI_ROOT,// 父节点
TVI_LAST// 插入方式
);
// 2级节点
m_tree.InsertItem(L"SDK001", 1,3,hParent, TVI_LAST);
m_tree.InsertItem(L"SDK002", 2,3,hParent, TVI_LAST);
// 1级节点
hParent = m_tree.InsertItem(L"MFC", 0,3,TVI_ROOT, TVI_LAST);
m_tree.InsertItem(L"MFC001", 1, 3, hParent, TVI_LAST);
m_tree.InsertItem(L"MFC002", 2, 3, hParent, TVI_LAST);
}
void CMy01ListTreeDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
m_tree.Invalidate();
}
void CMy01ListTreeDlg::OnNMClickTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
CPoint pt;
GetCursorPos(&pt);
// 屏幕坐标转客户区坐标
m_tree.ScreenToClient(&pt);
UINT uFlags = 0;
//TVHT_ONITEMLABEL
HTREEITEM hTree = m_tree.HitTest(pt, &uFlags);
if (uFlags == TVHT_ONITEMLABEL ||
uFlags == TVHT_ONITEMICON)
{
CString str = m_tree.GetItemText(hTree);
MessageBox(str);
}
}
运行效果: