【第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_TIMEenum { IDD = IDD_MY01LISTTREE_DIALOG };
#endifprotected: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;// 初始化listvoid 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"
END2 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"
END3 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
BEGINICON IDR_MAINFRAME,IDC_STATIC,14,14,21,20LTEXT "01.ListTree,1.0 版",IDC_STATIC,42,14,114,8,SS_NOPREFIXLTEXT "Copyright (C) 2018",IDC_STATIC,42,26,114,8DEFPUSHBUTTON "确定",IDOK,113,41,50,14,WS_GROUP
ENDIDD_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
BEGINCONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,136,7,177,72CONTROL "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_HSCROLL | WS_TABSTOP,7,7,129,71CONTROL "",IDC_MFCSHELLTREE1,"MfcShellTree",WS_BORDER | WS_HSCROLL | WS_TABSTOP,7,79,128,114CONTROL "",IDC_MFCSHELLLIST1,"MfcShellList",WS_BORDER | WS_TABSTOP | 0x841,135,79,178,114
END/
//
// Version
//VS_VERSION_INFO VERSIONINFOFILEVERSION 1,0,0,1PRODUCTVERSION 1,0,0,1FILEFLAGSMASK 0x3fL
#ifdef _DEBUGFILEFLAGS 0x1L
#elseFILEFLAGS 0x0L
#endifFILEOS 0x40004LFILETYPE 0x1LFILESUBTYPE 0x0L
BEGINBLOCK "StringFileInfo"BEGINBLOCK "080404B0"BEGINVALUE "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"ENDENDBLOCK "VarFileInfo"BEGINVALUE "Translation", 0x804, 1200END
END/
//
// DESIGNINFO
//#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGINIDD_ABOUTBOX, DIALOGBEGINLEFTMARGIN, 7RIGHTMARGIN, 163TOPMARGIN, 7BOTTOMMARGIN, 55ENDIDD_MY01LISTTREE_DIALOG, DIALOGBEGINLEFTMARGIN, 7RIGHTMARGIN, 313TOPMARGIN, 7BOTTOMMARGIN, 193END
END
#endif // APSTUDIO_INVOKED/
//
// AFX_DIALOG_LAYOUT
//IDD_MY01LISTTREE_DIALOG AFX_DIALOG_LAYOUT
BEGIN0
END/
//
// Dialog Info
//IDD_MY01LISTTREE_DIALOG DLGINIT
BEGINIDC_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
BEGINIDS_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// CMy01ListTreeAppBEGIN_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 _AFXDLLControlBarCleanUp();
#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_TIMEenum { IDD = IDD_ABOUTBOX };
#endifprotected: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);}}
运行效果:

相关文章:
【第30节】MFC编程:ListCtrl控件和TreeCtrl控件
目录 引言 一、高级控件ListCtrl 二、高级控件TreeCtrl 三、Shell控件 四、CImageList 五、综合代码示例 引言 在MFC编程里,高级控件能大幅提升应用程序的交互性与功能性。接下来,咱们会详细讲讲ListCtrl和TreeCtrl这两个高级控件。不仅会介绍它们…...
kotlin知识体系(四) : inline、noinline、crossinline 关键字对应编译后的代码是怎样的 ?
1. inline、noinline、crossinline 的作用 在 Kotlin 里,inline、noinline 和 crossinline 这几个关键字和高阶函数紧密相关,它们能够对高阶函数的行为进行优化和控制。本文接下来会详细介绍它们的作用和原理。 1.1 inline 关键字 inline 关键字用于修…...
JavaScript 手写 call、apply、bind 和 new
1. 手写 call 方法 核心思路:改变函数的 this 指向并立即执行,通过将函数临时挂载到目标对象上调用。 Function.prototype.myCall function (context, ...args) {// 如果 context 为 null 或 undefined,则默认为 windowcontext context |…...
睡眠健康领域的智能硬件设备未来的发展趋势
随着社会节奏的不断加快,人们的睡眠问题愈发多了起来,主要表现有以下几个方面: 睡眠质量下降 浅睡眠增多:现代生活中,人们面临着各种压力源,如工作压力、生活琐事、经济压力等,这些压力会导致大…...
计算机网络基础:量子通信技术在网络中的应用前景
计算机网络基础:量子通信技术在网络中的应用前景 一、前言二、量子通信技术基础2.1 量子通信的基本概念2.2 量子通信的主要原理2.2.1 量子密钥分发(QKD)原理2.2.2 量子隐形传态原理三、量子通信技术的特点3.1 绝对安全性3.2 超高通信速率潜力3.3 抗干扰能力强四、量子通信技…...
Postman 下载文件指南:如何请求 Excel/PDF 文件?
在 Postman 中进行 Excel/PDF 文件的请求下载和导出,以下是简明的步骤,帮助你轻松完成任务。首先,我们将从新建接口开始,逐步引导你完成整个过程。 Postman 请求下载/导出 excel/pdf 文件教程...
Stereolabs ZED Box Mini:机器人与自动化领域的人工智能视觉新选择
在人工智能视觉技术快速发展的今天,其应用场景正在持续拓宽,从智能安防到工业自动化,从机器人技术到智能交通,各领域都在积极探索如何利用这一先进技术。而 Stereolabs 推出的ZED Box Mini,正是一款专为满足这些多样化…...
arm之s3c2440的I2C的用法
基础概念 IC(Inter-Integrated Circuit)又称I2C,是是IICBus简称,所以中文应该叫集成电路总线。 IIC的总线的使用场景,所有挂载在IIC总线上的设备都有两根信号线,一根是数据线SDA,另一 根是时钟…...
安装node,配置npm, yarn, pnpm, bun
文章目录 安装node, 配置 npm, yarn, pnpm, bun配置node配置 npm, yarn, pnpm, bunnpmyarnpnpmbun 安装node, 配置 npm, yarn, pnpm, bun 配置node 输入网址:Node.js,包含各种安装方式以及多版本管理方式。也可以直接下载安装包。 安装包的安装过程…...
redis部署架构
一.redis多实例 如上图所示,我们经常使用实例的端口号来作为实例的安装目录名称。 1.创建实例安装目录 如上图所示,这是创建实例的安装目录, 2.拷贝实例的配置文件 如上图所示,将redis解压目录下的配置文件拷贝到对应的conf目录…...
深入理解指针(4)(C语言版)
文章目录 前言一、回调函数是什么(一)定义(二)工作原理(三)应用场景 二、qsort举例(一)qsort函数简介(二)比较函数的定义(三)使用示例…...
【HTML】验证与调试工具
个人主页:Guiat 归属专栏:HTML CSS JavaScript 文章目录 1. HTML 验证工具概述1.1 验证的重要性1.2 常见 HTML 错误类型 2. W3C 验证服务2.1 W3C Markup Validation Service2.2 使用 W3C 验证器2.3 验证结果解读 3. 浏览器开发者工具3.1 Chrome DevTools…...
【Mysql】SQL 优化全解析
文章目录 一、理解执行计划1.1 执行计划的作用1.2 查看执行计划 二、查询优化2.1 避免全表扫描2.2 使用覆盖索引2.3 合理使用 JOIN 三、索引优化3.1 索引设计原则3.2 索引维护 在数据驱动的当今时代,MySQL 作为应用广泛的开源关系型数据库&…...
SenseGlove与Aeon Robotics携手推出HEART项目,助力机器人培训迈向新台阶
在自动化和机器人技术快速发展的今天,SenseGlove和Aeon Robotics联合推出了一项创新项目——HEART项目。该项目在欧盟资助的MasterXR框架内展开,旨在通过整合虚拟现实(VR)、力反馈触觉手套(SenseGlove项目Rembrandt&am…...
mapbox进阶,仿照百度,加载marker点位,移入marker点切换图标,点击展示气泡,气泡和marker联动
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️marker 标注点位 api1.3.1 ☘️构造函数…...
使用HTML5和CSS3实现3D旋转相册效果
使用HTML5和CSS3实现3D旋转相册效果 这里写目录标题 使用HTML5和CSS3实现3D旋转相册效果项目介绍技术栈核心功能实现思路1. HTML结构2. CSS样式解析2.1 基础样式设置2.2 3D效果核心样式2.3 卡片样式 3. JavaScript交互实现3.1 旋转控制3.2 自动播放功能 技术要点总结项目亮点总…...
HTML5 新的 Input 类型学习笔记
HTML5 引入了多种新的表单输入类型,这些新特性不仅增强了输入控制,还提供了更强大的验证功能,使表单设计更加灵活和便捷。以下是 HTML5 新的 Input 类型的详细学习笔记。 一、color 类型 功能:用于选取颜色。 使用场景ÿ…...
游戏引擎学习第186天
回顾并规划今天的任务 现在,我们站在了一个关键的时刻,准备突破,拥有一些优秀的性能分析代码。从目前来看,我们已经能够看到时间的消耗情况,我对这一点感到非常兴奋。昨天的直播中我们勉强让一些东西工作了࿰…...
NDK CMake工程中引入其他C++三方库
在Android NDK CMake工程中引入其他C三方库时,有以下几种常见的依赖方式: 1. 源码依赖 如果三方库的源代码包含在你的项目目录中,并且它有自己的CMake配置,可以使用add_subdirectory将三方库的构建过程集成到你的项目中。 示例…...
【redis】持久化之RDB与AOF
在数字世界的脉搏中,数据是流淌的血液,而持久化则是保障系统生命力的核心机制。作为内存数据库的标杆,Redis凭借其高性能特性成为互联网架构的基石,但其「易失性」的天然属性也催生了关键命题:如何在服务重启或故障时保…...
Brainstorm绘制功能连接图(matlab)
上篇笔记简单介绍了Brainstorm,本次使用Brainstorm绘制功能连接图。而对于连接矩阵,软件中有几种方法:相关、相干、双变量格兰杰因果关系、相位锁相值、包络相关、相位转移熵。 首先,对数据进行预处理,保存为.set&…...
华为HG532路由器RCE漏洞 CVE-2017-17215 复现
华为HG532路由器RCE漏洞 CVE-2017-17215 CVE-Description Huawei HG532 with some customized versions has a remote code execution vulnerability. An authenticated attacker could send malicious packets to port 37215 to launch attacks. Successful exploit could l…...
CSS3学习教程,从入门到精通,CSS3 弹性盒子(Flexbox)布局全面指南(20)
CSS3 弹性盒子(Flexbox)布局全面指南 一、Flexbox 概述 Flexbox(弹性盒子)是 CSS3 提供的一种一维布局模型,可以轻松实现各种复杂的页面布局。它特别适合处理不同屏幕尺寸下的元素排列和对齐问题。 主要优势: 简单实现垂直居中…...
Redis 性能数据解读与问题排查优化版
目录标题 Redis 性能数据解读与问题排查优化版一、Redis 性能数据解读二、常见问题排查与解决(一)CPU 使用率高(二)内存使用异常(三)集群状态异常(四)数据库状态问题 三、综合优化建…...
新能源动力电池测试设备深度解析:充放电设备与电池模拟器的差异及技术趋势
一、技术原理对比与核心技术创新 充放电设备 核心原理与硬件架构 充放电设备的核心功能是通过电力电子技术精确控制电池的充放电过程,其硬件架构包括高精度电源模块、双向DC/DC变换器、数据采集系统和温控单元。例如,在放电阶段,设备通过双向…...
LVS的三种工作模式简述
一、引言 在过去的十几年中,Internet从几个研究机构相连为信息共享的网络发展成为拥有大量应用和服务的全球性网络,它正成为人们生活中不可缺少的 一部分。虽然Internet发展速度很快,但建设和维护大型网络服务依然是一项挑战性的任务…...
Ribbon负载均衡的深度解析与应用
在微服务架构中,服务之间的调用频繁且复杂,因此负载均衡显得尤为重要。Spring Cloud生态系统中,Ribbon作为一个客户端负载均衡器,扮演着关键的角色。它不仅能提高系统的响应速度,还能确保系统的稳定性和可用性。接下来…...
使用 Layers 扩展你的 Nuxt4 应用
面对一个臃肿的页面或项目,你会如何简化重构、扩展它? 当单个 Vue 文件中界面/业务足够多时,通常我们会把它拆分成多个 components 或 composables 来引入,以此来减少此文件复杂度和增加可维护性。 当一个项目的界面/业务逻辑足…...
Excel处理控件Aspose.Cells指南:如何在不使用 Microsoft Excel 的情况下解锁 Excel 工作表
Microsoft Excel 允许用户使用密码保护工作表,以防止未经授权的更改。但是,在某些情况下,您可能需要在不使用 Microsoft Excel 的情况下解锁 Excel 工作表。在本指南中,我们将探讨解锁 Excel 工作表的不同方法,例如使用…...
进军场景智能体,云迹机器人又快了一步
(图片来源:Pixels) 2025年,AI和机器人行业都发生了巨大改变。 数科星球原创 作者丨苑晶 编辑丨大兔 2025年,酒店行业正掀起一股批量采购具备AI功能的软硬一体解决方案的热潮。 在DeepSeek、Manus等国产AI软件的推动…...
