演练:使用新的 MFC Shell 控件

在本演练中,你将创建一个类似于文件资源管理器的应用程序。 你将创建包含两个窗格的窗口。 左侧窗格包含一个 CMFCShellTreeCtrl 对象,该对象在分层视图中显示桌面。 右侧窗格包含一个 CMFCShellListCtrl,该对象显示左侧窗格中选择的文件夹中的文件。

先决条件

  • 在 Visual Studio 2017 和更高版本中,MFC 支持是一个可选组件。 若要安装它,请从 Windows“开始”菜单打开 Visual Studio 安装程序。 找到你正在使用的 Visual Studio 版本,然后选择“修改”按钮。 确保选中“使用 C++ 的桌面开发”磁贴。 在“可选组件”下,选中“MFC 支持”按钮

  • 本演练假设已将 Visual Studio 设置为使用“常规开发设置”。 如果你使用其他开发设置,在本演练中使用的某些 Visual Studio 窗口默认可能不会显示。

使用 MFC 应用程序向导创建新的 MFC 应用程序

这些步骤根据你使用的 Visual Studio 版本而有所不同。 若要查看 Visual Studio 首选项的文档,请使用“版本”选择器控件。 它位于此页面上目录表的顶部。

在 Visual Studio 中创建 MFC 项目

  1. 在主菜单中,选择“文件”>“新建”>“项目”,打开“创建新项目”对话框

  2. 在顶部的搜索框中键入“MFC”,然后从结果列表中选择“MFC 应用”

  3. 单击“下一步”。 在下一页中,输入项目的名称,并根据需要指定项目位置。

  4. 选择“创建”按钮创建项目。

    显示“MFC 应用程序向导”后,使用以下选项

    1. 选择左侧的“应用程序类型”。 然后依次选择“单个文档”和“文档/查看体系结构支持”。 在“项目样式”下选择“Visual Studio”,然后从“视觉样式和颜色”下拉列表中选择“Office 2007 (蓝色主题)”

    2. 在“复合文档支持”窗格中选择“无”

    3. 不要对“文档模板属性”窗格进行任何更改

    4. 在“用户界面功能”窗格中,确保选择了“使用菜单栏和工具栏”选项。 将所有其他选项保留原样。

    5. 在“高级功能”窗格中,选择“ActiveX 控件”、“通用控件清单”和“导航窗格”选项。 其他所有内容保持原样。 “导航窗格”选项会使向导在窗口左侧创建已嵌入 CMFCShellTreeCtrl 的窗格

    6. 我们不会对“生成的类”窗格进行任何更改,因此请单击“完成”以创建新的 MFC 项目

在 Visual Studio 2017 或更低版本中创建 MFC 项目

  1. 使用“MFC 应用程序向导”创建新的 MFC 应用程序。 若要运行该向导,请从“文件”菜单中选择“新建”,然后选择“项目”。 此时会显示“新建项目”对话框

  2. 在“新建项目”对话框中,展开“项目类型”窗格中的“Visual C++”节点并选择“MFC”。 然后,在“模板”窗格中选择“MFC 应用程序”。 键入项目的名称(例如 MFCShellControls),然后单击“确定”

    显示“MFC 应用程序向导”后,使用以下选项

    1. 在“应用程序类型”窗格中的“应用程序类型”下,清除“选项卡式文档”选项。 接下来,依次选择“单个文档”和“文档/查看体系结构支持”。 在“项目样式”下选择“Visual Studio”,然后从“视觉样式和颜色”下拉列表中选择“Office 2007 (蓝色主题)”

    2. 在“复合文档支持”窗格中选择“无”

    3. 不要对“文档模板字符串”窗格进行任何更改

    4. 在“数据库支持”窗格(Visual Studio 2015 和更低版本)中选择“无”,因为该应用程序不使用数据库

    5. 在“用户界面功能”窗格中,确保选择了“使用菜单栏和工具栏”选项。 将所有其他选项保留原样。

    6. 在“高级功能”窗格中的“高级功能”下,仅选择“ActiveX 控件”和“通用控件清单”。 在“高级框架窗格”下,仅选择“导航窗格”选项。 该选项会使向导在窗口左侧创建已嵌入 CMFCShellTreeCtrl 的窗格。

    7. 我们不会对“生成的类”窗格进行任何更改,因此请单击“完成”以创建新的 MFC 项目

通过生成并运行应用程序来验证其是否已成功创建。 若要生成应用程序,请从“生成”菜单中选择“生成解决方案”。 如果成功生成了该应用程序,请在“调试”菜单中选择“开始调试”来运行该应用程序

向导会自动创建一个应用程序,该应用程序带有标准的菜单栏、标准的工具栏、标准的状态栏和位于窗口左侧的 Outlook 栏,其中包含“文件夹”视图和“日历”视图

将 shell 列表控件添加到文档视图

  1. 在本部分,你会将一个 CMFCShellListCtrl 实例添加到向导创建的视图。 在“解决方案资源管理器”中双击“MFCShellControlsView.h”打开视图头文件

    找到靠近头文件顶部的 #pragma once 指令。 紧接在此指令的下方添加以下代码以包含 CMFCShellListCtrl 的头文件:

    #include <afxShellListCtrl.h>
    

    现在添加一个类型为 CMFCShellListCtrl 的成员变量。 首先,在头文件中找到以下注释:

    // Generated message map functions
    

    紧靠在该注释的上方添加以下代码:

    private:
    CMFCShellListCtrl m_wndList;
    
  2. “MFC 应用程序向导”已在 CMainFrame 类中创建了一个 CMFCShellTreeCtrl 对象,但该对象是一个受保护的成员。 我们稍后将访问该对象,因此现在请为它创建一个访问器。 在“解决方案资源管理器”中双击 MainFrm.h 头文件以将它打开。 找到以下注释:

    // Attributes
    

    紧接在该注释的下方添加以下方法声明:

    public:
        CMFCShellTreeCtrl& GetShellTreeCtrl();
    

    接下来,在“解决方案资源管理器”中双击 MainFrm.cpp 源文件以将它打开。 在该文件的底部添加以下方法定义:

    CMFCShellTreeCtrl& CMainFrame::GetShellTreeCtrl()
    {
         return m_wndTree;
    }
    
  3. 现在我们更新 CMFCShellControlsView 类以处理 WM_CREATE 窗口消息。 打开“类视图”窗口并选择 CMFCShellControlsView 类。 右键单击并选择 “属性”

    接下来,在类向导中单击“消息”选项卡。向下滚动,直到看到 WM_CREATE 消息。 在 WM_CREATE 旁边的下拉菜单中,选择“<Add> OnCreate”。 该命令创建一个消息处理程序并自动更新 MFC 消息映射。

    现在,我们在 OnCreate 方法中创建 CMFCShellListCtrl 对象。 在 MFCShellControlsView.cpp 源文件中找到 OnCreate 方法定义,并将其实现替换为以下代码:

    int CMFCShellControlsView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if (CView::OnCreate(lpCreateStruct) == -1)
            return -1;
    
        CRect rectDummy (0, 0, 0, 0);
    
        m_wndList.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT,
            rectDummy, this, 1);
    
        return 0;
    }
    
  4. 针对 WM_SIZE 消息重复上一步骤。 这样,每当用户更改应用程序窗口的大小时,应用程序视图就会重绘。 将 OnSize 方法的定义替换为以下代码:

    void CMFCShellControlsView::OnSize(UINT nType, int cx, int cy)
    {
        CView::OnSize(nType, cx, cy);
    
        m_wndList.SetWindowPos(NULL, -1, -1, cx, cy,
            SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
    }
    
  5. 最后一步是使用 CMFCShellTreeCtrl::SetRelatedList 方法连接 CMFCShellTreeCtrlCMFCShellListCtrl 对象。 调用 CMFCShellTreeCtrl::SetRelatedList 后,CMFCShellListCtrl 将自动显示 CMFCShellTreeCtrl 中所选项的内容。 我们在通过 CView::OnActivateView 重写的 OnActivateView 方法中连接对象。

    在 MFCShellControlsView.h 头文件中的 CMFCShellControlsView 类声明内添加以下方法声明:

    protected:
    virtual void OnActivateView(BOOL bActivate,
        CView* pActivateView,
        CView* pDeactiveView);
    

    接下来,将该方法的定义添加到 MFCShellControlsView.cpp 源文件中:

    void CMFCShellControlsView::OnActivateView(BOOL bActivate,
        CView* pActivateView,
        CView* pDeactiveView)
    {
        if (bActivate&& AfxGetMainWnd() != NULL)
        {
            ((CMainFrame*)AfxGetMainWnd())->GetShellTreeCtrl().SetRelatedList(&m_wndList);
        }
    
        CView::OnActivateView(bActivate,
            pActivateView,
            pDeactiveView);
    }
    

    由于我们要从 CMainFrame 类调用方法,因此必须在 MFCShellControlsView.cpp 源文件的顶部添加一个 #include 指令:

    #include "MainFrm.h"
    
  6. 通过生成并运行应用程序来验证其是否已成功创建。 若要生成应用程序,请从“生成”菜单中选择“生成解决方案”。 如果成功生成了该应用程序,请在“调试”菜单中选择“开始调试”来运行该应用程序

    现在应会在视图窗格中看到 CMFCShellTreeCtrl 中所选项的详细信息。 单击 CMFCShellTreeCtrl 中的节点时,CMFCShellListCtrl 会自动更新。 同样,如果双击 CMFCShellListCtrl 中的文件夹,CMFCShellTreeCtrl 应会自动更新。

    右键单击树控件或列表控件中的任何项。 你将看到一个上下文菜单,它与使用真正的“文件资源管理器”时显示的菜单相同

后续步骤

  • 向导创建了一个包含“文件夹”窗格和“日历”窗格的 Outlook 栏。 在“资源管理器”窗口中包含“日历”窗格可能没有意义,因此现在请删除该窗格

  • CMFCShellListCtrl 支持以不同的模式查看文件,例如“大图标”、“小图标”、“列表”和“详细信息”。 更新应用程序以实现此功能。 提示:参阅 Visual C++ 示例

另请参阅

演练