【第30节】MFC编程:ListCtrl控件和TreeCtrl控件

news2025/3/31 12:52:20

目录

引言

一、高级控件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);
	}
	
}

运行效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2323405.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript 手写 call、apply、bind 和 new

1. 手写 call 方法 核心思路&#xff1a;改变函数的 this 指向并立即执行&#xff0c;通过将函数临时挂载到目标对象上调用。 Function.prototype.myCall function (context, ...args) {// 如果 context 为 null 或 undefined&#xff0c;则默认为 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 文件的请求下载和导出&#xff0c;以下是简明的步骤&#xff0c;帮助你轻松完成任务。首先&#xff0c;我们将从新建接口开始&#xff0c;逐步引导你完成整个过程。 Postman 请求下载/导出 excel/pdf 文件教程

Stereolabs ZED Box Mini:机器人与自动化领域的人工智能视觉新选择

在人工智能视觉技术快速发展的今天&#xff0c;其应用场景正在持续拓宽&#xff0c;从智能安防到工业自动化&#xff0c;从机器人技术到智能交通&#xff0c;各领域都在积极探索如何利用这一先进技术。而 Stereolabs 推出的ZED Box Mini&#xff0c;正是一款专为满足这些多样化…

arm之s3c2440的I2C的用法

基础概念 IC&#xff08;Inter-Integrated Circuit&#xff09;又称I2C&#xff0c;是是IICBus简称&#xff0c;所以中文应该叫集成电路总线。 IIC的总线的使用场景&#xff0c;所有挂载在IIC总线上的设备都有两根信号线&#xff0c;一根是数据线SDA&#xff0c;另一 根是时钟…

redis部署架构

一.redis多实例 如上图所示&#xff0c;我们经常使用实例的端口号来作为实例的安装目录名称。 1.创建实例安装目录 如上图所示&#xff0c;这是创建实例的安装目录&#xff0c; 2.拷贝实例的配置文件 如上图所示&#xff0c;将redis解压目录下的配置文件拷贝到对应的conf目录…

深入理解指针(4)(C语言版)

文章目录 前言一、回调函数是什么&#xff08;一&#xff09;定义&#xff08;二&#xff09;工作原理&#xff08;三&#xff09;应用场景 二、qsort举例&#xff08;一&#xff09;qsort函数简介&#xff08;二&#xff09;比较函数的定义&#xff08;三&#xff09;使用示例…

【HTML】验证与调试工具

个人主页&#xff1a;Guiat 归属专栏&#xff1a;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…

​​SenseGlove与Aeon Robotics携手推出HEART项目,助力机器人培训迈向新台阶

在自动化和机器人技术快速发展的今天&#xff0c;SenseGlove和Aeon Robotics联合推出了一项创新项目——HEART项目。该项目在欧盟资助的MasterXR框架内展开&#xff0c;旨在通过整合虚拟现实&#xff08;VR&#xff09;、力反馈触觉手套&#xff08;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 自动播放功能 技术要点总结项目亮点总…

游戏引擎学习第186天

回顾并规划今天的任务 现在&#xff0c;我们站在了一个关键的时刻&#xff0c;准备突破&#xff0c;拥有一些优秀的性能分析代码。从目前来看&#xff0c;我们已经能够看到时间的消耗情况&#xff0c;我对这一点感到非常兴奋。昨天的直播中我们勉强让一些东西工作了&#xff0…

【redis】持久化之RDB与AOF

在数字世界的脉搏中&#xff0c;数据是流淌的血液&#xff0c;而持久化则是保障系统生命力的核心机制。作为内存数据库的标杆&#xff0c;Redis凭借其高性能特性成为互联网架构的基石&#xff0c;但其「易失性」的天然属性也催生了关键命题&#xff1a;如何在服务重启或故障时保…

Brainstorm绘制功能连接图(matlab)

上篇笔记简单介绍了Brainstorm&#xff0c;本次使用Brainstorm绘制功能连接图。而对于连接矩阵&#xff0c;软件中有几种方法&#xff1a;相关、相干、双变量格兰杰因果关系、相位锁相值、包络相关、相位转移熵。 首先&#xff0c;对数据进行预处理&#xff0c;保存为.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…

LVS的三种工作模式简述

一、引言 在过去的十几年中&#xff0c;Internet从几个研究机构相连为信息共享的网络发展成为拥有大量应用和服务的全球性网络&#xff0c;它正成为人们生活中不可缺少的 一部分。虽然Internet发展速度很快&#xff0c;但建设和维护大型网络服务依然是一项挑战性的任务&#xf…

使用 Layers 扩展你的 Nuxt4 应用

面对一个臃肿的页面或项目&#xff0c;你会如何简化重构、扩展它&#xff1f; 当单个 Vue 文件中界面/业务足够多时&#xff0c;通常我们会把它拆分成多个 components 或 composables 来引入&#xff0c;以此来减少此文件复杂度和增加可维护性。 当一个项目的界面/业务逻辑足…

Excel处理控件Aspose.Cells指南:如何在不使用 Microsoft Excel 的情况下解锁 Excel 工作表

Microsoft Excel 允许用户使用密码保护工作表&#xff0c;以防止未经授权的更改。但是&#xff0c;在某些情况下&#xff0c;您可能需要在不使用 Microsoft Excel 的情况下解锁 Excel 工作表。在本指南中&#xff0c;我们将探讨解锁 Excel 工作表的不同方法&#xff0c;例如使用…

进军场景智能体,云迹机器人又快了一步

&#xff08;图片来源&#xff1a;Pixels&#xff09; 2025年&#xff0c;AI和机器人行业都发生了巨大改变。 数科星球原创 作者丨苑晶 编辑丨大兔 2025年&#xff0c;酒店行业正掀起一股批量采购具备AI功能的软硬一体解决方案的热潮。 在DeepSeek、Manus等国产AI软件的推动…

PHP 应用SQL 注入符号拼接请求方法HTTP 头JSON编码类

#PHP-MYSQL- 数据请求类型 SQL 语句由于在黑盒中是无法预知写法的&#xff0c; SQL 注入能发成功是需要拼接原 SQL 语句&#xff0c; 大部分黑盒能做的就是分析后各种尝试去判断&#xff0c;所以有可能有注入但可能出现无法注入成 功的情况。究其原因大部分都是原 SQL …