演练:更新 MFC Scribble 应用程序(第 2 部分)

本演练的第 1 部分演示了如何将 Office Fluent 功能区添加到经典 Scribble 应用程序。 此部分演示如何添加用户可以使用的功能区面板和控件,而不是菜单和命令。

先决条件

视觉C++示例

章节

本演练的这一部分包含以下部分:

向功能区添加新面板

这些步骤演示如何添加一个 视图 面板,其中包含两个复选框来控制工具栏和状态栏的可见性,以及一个 窗口 面板,其中包含垂直方向的拆分按钮,用于控制多文档界面(MDI)窗口的创建和排列。

向功能区栏添加“视图”面板和“窗口”面板

  1. 创建一个名为 View的面板,其中包含两个用于切换状态栏和工具栏的复选框。

    1. 工具箱中,将 面板 拖到 “开始 ”类别。 然后将两个 复选框 拖到面板。

    2. 单击面板可修改其属性。 将 标题 更改为 View.

    3. 单击第一个复选框可修改其属性。 将 ID 更改为 ID_VIEW_TOOLBAR标题 更改为 Toolbar

    4. 单击第二个复选框可修改其属性。 将 ID 更改为 ID_VIEW_STATUS_BAR标题 更改为 Status Bar

  2. 创建一个名为 Window 具有拆分按钮的面板。 当用户单击拆分按钮时,快捷菜单会显示已在 Scribble 应用程序中定义的三个命令。

    1. 工具箱中,将 面板 拖到 “开始 ”类别。 然后将 按钮 拖到面板。

    2. 单击面板可修改其属性。 将 标题 更改为 Window.

    3. 单击该按钮。 将 标题 更改为 Windowsw大型图像索引 更改为 1,并将 拆分模式 更改为 False。 然后单击菜单项旁边的省略号(...),打开“项编辑器”对话框。

    4. 单击“ 添加 三次”以添加三个按钮。

    5. 单击第一个按钮,然后将标题New Window更改为,ID 更改为ID_WINDOW_NEW

    6. 单击第二个按钮,然后将 Caption 更改为Cascade,ID 更改为ID_WINDOW_CASCADE

    7. 单击第三个按钮,然后将 Caption 更改为 Tile,并将 ID 更改为 ID_WINDOW_TILE_HORZ

  3. 保存更改,然后生成并运行应用程序。 应显示 “视图 ”和 “窗口 ”面板。 单击这些按钮以确认它们正常运行。

向功能区添加帮助面板

现在,可以将 Scribble 应用程序中定义的两个菜单项分配给名为 “帮助主题 ”和“ 关于Scribble”的功能区按钮。 这些按钮将添加到名为 “帮助”的新面板中。

添加帮助面板

  1. 工具箱中,将 面板 拖到 “开始 ”类别。 然后将两 个按钮 拖到面板上。

  2. 单击面板可修改其属性。 将 标题 更改为 Help.

  3. 单击第一个按钮。 将 标题 更改为 Help TopicsID 更改为 ID_HELP_FINDER

  4. 单击第二个按钮。 将 标题 更改为 About Scribble...ID 更改为 ID_APP_ABOUT

  5. 保存更改,然后生成并运行应用程序。 应显示包含两个功能区按钮的 帮助 面板。

    重要

    单击“帮助主题”按钮时,Scribble 应用程序将打开名为 your_project_name.chm 的压缩 HTML (.chm) 帮助文件。 因此,如果项目未命名为 Scribble,则必须将帮助文件重命名为项目名称。

将笔面板添加到功能区

现在,添加一个面板以显示用于控制笔粗细和颜色的按钮。 此面板包含一个复选框,用于在粗笔和细笔之间切换。 其功能类似于 Scribble 应用程序中 粗线 菜单项的功能。

原始 Scribble 应用程序允许用户从当用户单击菜单上的笔宽时出现的对话框中选择 笔宽 。 由于功能区栏具有充足的新控件空间,因此可以使用功能区上的两个组合框替换对话框。 一个组合框调整细笔的宽度,另一个组合框调整粗笔的宽度。

向功能区添加触控笔面板和组合框

  1. 工具箱中,将 面板 拖到 “开始 ”类别。 然后将一个 复选框 和两个 组合框 拖到面板上。

  2. 单击面板可修改其属性。 将 标题 更改为 Pen.

  3. 单击复选框。 将 标题 更改为 Use ThickID 更改为 ID_PEN_THICK_OR_THIN

  4. 单击第一个组合框。 将标题更改为,ID 更改为ID_PEN_THIN_WIDTHThin Pen键入Drop List数据1;2;3;4;5;6;7;8;9;文本更改为2

  5. 单击第二个组合框。 将标题更改为,ID 更改为ID_PEN_THICK_WIDTHThick Pen键入Drop List数据5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;文本更改为5

  6. 新的组合框与任何现有菜单项不对应,因此必须为每个笔选项创建一个菜单项。

    1. “资源视图 ”窗口中,打开 IDR_SCRIBBTYPE 菜单资源。

    2. 单击 “笔 ”打开笔菜单。 然后单击“ 在此处键入 ”,然后键入 Thi&n Pen

    3. 右键单击键入的文本以打开 “属性” 窗口,然后将 ID 属性更改为 ID_PEN_THIN_WIDTH

    4. 为每个笔菜单项创建事件处理程序。 右键单击创建的 Thi&n Pen 菜单项,然后单击“ 添加事件处理程序”。 显示 事件处理程序向导

    5. 在向导中的 “类列表 ”框中,选择 “CScribbleDoc ”,然后单击“ 添加和编辑”。 该命令将创建名为 CScribbleDoc::OnPenThinWidth..

    6. 将以下代码添加到 CScribbleDoc::OnPenThinWidth

      // Get a pointer to the ribbon bar
      CMFCRibbonBar* pRibbon = ((CMDIFrameWndEx*) AfxGetMainWnd())->GetRibbonBar();
      ASSERT_VALID(pRibbon);
      
      // Get a pointer to the Thin Width combo box
      CMFCRibbonComboBox* pThinComboBox = DYNAMIC_DOWNCAST(
      CMFCRibbonComboBox, pRibbon->FindByID(ID_PEN_THIN_WIDTH));
      
      //Get the selected value
      int nCurSel = pThinComboBox->GetCurSel();
      if (nCurSel>= 0)
      {
          m_nThinWidth = atoi(CStringA(pThinComboBox->GetItem(nCurSel)));
      }
      
      // Create a new pen using the selected width
      ReplacePen();
      
  7. 接下来,为粗笔创建菜单项和事件处理程序。

    1. “资源视图 ”窗口中,打开 IDR_SCRIBBTYPE 菜单资源。

    2. 单击 “笔 ”打开笔菜单。 然后单击“ 在此处键入 ”,然后键入 Thic&k Pen

    3. 右键单击键入的文本以显示 “属性” 窗口。 将 ID 属性更改为 ID_PEN_THICK_WIDTH.

    4. 右键单击创建的 粗笔 菜单项,然后单击“ 添加事件处理程序”。 显示 事件处理程序向导

    5. 在向导的 “类列表 ”框中,选择 “CScribbleDoc ”,然后单击“ 添加和编辑”。 该命令将创建名为 CScribbleDoc::OnPenThickWidth..

    6. 将以下代码添加到 CScribbleDoc::OnPenThickWidth

      // Get a pointer to the ribbon bar
      CMFCRibbonBar* pRibbon = ((CMDIFrameWndEx *) AfxGetMainWnd())->GetRibbonBar();
      ASSERT_VALID(pRibbon);
      
      CMFCRibbonComboBox* pThickComboBox = DYNAMIC_DOWNCAST(
          CMFCRibbonComboBox, pRibbon->FindByID(ID_PEN_THICK_WIDTH));
      // Get the selected value
      int nCurSel = pThickComboBox->GetCurSel();
      if (nCurSel>= 0)
      {
          m_nThickWidth = atoi(CStringA(pThickComboBox->GetItem(nCurSel)));
      }
      
      // Create a new pen using the selected width
      ReplacePen();
      
  8. 保存更改,然后生成并运行应用程序。 应显示新按钮和组合框。 请尝试使用不同的笔宽进行涂鸦。

向笔面板添加颜色按钮

接下来,添加 一个 CMFCRibbonColorButton 对象,该对象允许用户以颜色进行涂鸦。

向“笔”面板添加颜色按钮

  1. 在添加颜色按钮之前,请为其创建菜单项。 在 “资源视图 ”窗口中,打开 IDR_SCRIBBTYPE 菜单资源。 单击 “笔 ”菜单项以打开笔菜单。 然后单击“ 在此处键入 ”,然后键入 &Color。 右键单击键入的文本以显示 “属性” 窗口。 将 ID 更改为 ID_PEN_COLOR

  2. 现在添加颜色按钮。 从 工具箱中,将 颜色按钮 拖到 触控笔 面板。

  3. 单击颜色按钮。 将标题更改为ColorID 更改为ID_PEN_COLOR简单查找True大型图像索引更改为1,并将拆分模式更改为False

  4. 保存更改,然后生成并运行应用程序。 “ ”面板上应显示新的颜色按钮。 但是,它不能使用,因为它还没有事件处理程序。 后续步骤演示如何为颜色按钮添加事件处理程序。

向文档类添加颜色成员

由于原始 Scribble 应用程序没有彩色笔,因此必须为其编写实现。 若要存储文档的笔颜色,请将新成员添加到文档类。 CscribbleDoc

向文档类添加颜色成员

  1. 在 scribdoc.h 的类中 CScribbleDoc ,找到该 // Attributes 节。 在数据成员的定义 m_nThickWidth 后添加以下代码行。

    // Current pen color
    COLORREF m_penColor;
    
  2. 每个文档都包含用户已绘制的点数列表。 每个笔划都由对象 CStroke 定义。 该 CStroke 类不包含有关笔色的信息,因此必须修改该类。 在类中的 scribdoc.h 中 CStroke ,在数据成员的定义 m_nPenWidth 后添加以下代码行。

    // Pen color for the stroke
    COLORREF m_penColor;
    
  3. 在 scribdoc.h 中,添加一个新的 CStroke 构造函数,其参数指定宽度和颜色。 在语句后面 CStroke(UINT nPenWidth); 添加以下代码行。

    CStroke(UINT nPenWidth, COLORREF penColor);
    
  4. 在scribdoc.cpp中,添加新 CStroke 构造函数的实现。 在构造函数的 CStroke::CStroke(UINT nPenWidth) 实现后添加以下代码。

    // Constructor that uses the document's current width and color
    CStroke::CStroke(UINT nPenWidth, COLORREF penColor)
    {
        m_nPenWidth = nPenWidth;
        m_penColor = penColor;
        m_rectBounding.SetRectEmpty();
    }
    
  5. 按如下所示更改方法的第 CStroke::DrawStroke 二行。

    if (!penStroke.CreatePen(PS_SOLID, m_nPenWidth, m_penColor))
    
  6. 设置文档类的默认笔颜色。 在scribdoc.cpp中,将以下行 CScribbleDoc::InitDocument添加到语句后面 m_nThickWidth = 5;

    // default pen color is black
    m_penColor = RGB(0, 0, 0);
    
  7. 在scribdoc.cpp中,将 CScribbleDoc::NewStroke 方法的第一行更改为以下内容。

    CStroke* pStrokeItem = new CStroke(m_nPenWidth, m_penColor);
    
  8. CScribbleDoc::ReplacePen 方法的最后一行更改为以下内容。

    m_penCur.CreatePen(PS_SOLID, m_nPenWidth, m_penColor);
    
  9. 在上一步中添加了该 m_penColor 成员。 现在,为设置成员的颜色按钮创建事件处理程序。

    1. “资源视图 ”窗口中,打开IDR_SCRIBBTYPE菜单资源。

    2. 右键单击 “颜色” 菜单项,然后单击“ 添加事件处理程序”。 此时会显示 事件处理程序向导

    3. 在向导的 “类列表 ”框中,选择 “CScribbleDoc ”,然后单击“ 添加和编辑 ”按钮。 该命令创建 CScribbleDoc::OnPenColor 事件处理程序存根。

  10. 将事件处理程序的 CScribbleDoc::OnPenColor 存根替换为以下代码。

    void CScribbleDoc::OnPenColor()
    {
        // Change pen color to reflect color button's current selection
        CMFCRibbonBar* pRibbon = ((CMDIFrameWndEx*) AfxGetMainWnd())->GetRibbonBar();
        ASSERT_VALID(pRibbon);
    
        CMFCRibbonColorButton* pColorBtn = DYNAMIC_DOWNCAST(
            CMFCRibbonColorButton, pRibbon->FindByID(ID_PEN_COLOR));
    
        m_penColor = pColorBtn->GetColor();
        // Create new pen using the selected color
        ReplacePen();
    }
    
  11. 保存更改,然后生成并运行应用程序。 现在可以按颜色按钮并更改笔的颜色。

初始化笔和保存首选项

接下来,初始化笔的颜色和宽度。 最后,保存并加载文件中的颜色绘图。

初始化功能区栏上的控件

  1. 初始化功能区栏上的笔。

    将以下代码添加到语句后面的m_sizeDoc = CSize(200,200)方法中CScribbleDoc::InitDocumentscribdoc.cpp。

    // Reset the ribbon UI to its initial values
    CMFCRibbonBar* pRibbon =
        ((CMDIFrameWndEx*) AfxGetMainWnd())->GetRibbonBar();
    ASSERT_VALID(pRibbon);
    
    CMFCRibbonColorButton* pColorBtn = DYNAMIC_DOWNCAST(
        CMFCRibbonColorButton,
        pRibbon->FindByID(ID_PEN_COLOR));
    
    // Set ColorButton to black
    pColorBtn->SetColor(RGB(0, 0, 0));
    
    CMFCRibbonComboBox* pThinComboBox = DYNAMIC_DOWNCAST(
        CMFCRibbonComboBox,
        pRibbon->FindByID(ID_PEN_THIN_WIDTH));
    
    // Set Thin pen combobox to 2
    pThinComboBox->SelectItem(1);
    
    CMFCRibbonComboBox* pThickComboBox = DYNAMIC_DOWNCAST(
        CMFCRibbonComboBox,
        pRibbon->FindByID(ID_PEN_THICK_WIDTH));
    
    // Set Thick pen combobox to 5
    pThickComboBox->SelectItem(0);
    
  2. 将颜色绘图保存到文件中。 将以下语句添加到方法中的 CStroke::Serialize scribdoc.cpp语句后面 ar << (WORD)m_nPenWidth;

    ar << (COLORREF)m_penColor;
    
  3. 最后,从文件加载颜色绘图。 在方法中,在 CStroke::Serialize 语句后面 m_nPenWidth = w; 添加以下代码行。

    ar >> m_penColor;
    
  4. 现在,用颜色进行涂鸦,并将绘图保存到文件中。

结论

已更新 MFC Scribble 应用程序。 修改现有应用程序时,请使用本演练作为指南。

另请参阅

演练
演练:更新 MFC Scribble 应用程序(第 1 部分)