MFC - Windows 资源


资源是一种文本文件,允许编译器管理图片、声音、鼠标光标、对话框等对象。Microsoft Visual Studio 通过在用于编程的同一环境中提供必要的工具,使创建资源文件变得特别容易这意味着,您通常不必使用外部应用程序来创建或配置资源文件。以下是与资源相关的一些重要功能。

  • 资源是向用户提供信息的界面元素。

  • 位图、图标、工具栏和光标都是资源。

  • 可以操纵某些资源来执行操作,例如从菜单中选择或在对话框中输入数据。

  • 应用程序可以使用Behave相互独立的各种资源,这些资源被分组到具有 *.rc 扩展名的文本文件中。

  • 大多数资源是通过从“添加资源”对话框中选择所需的资源来创建的。

添加资源
  • “添加资源”对话框提供了可根据要求使用的广泛资源列表,但如果您需要不可用的资源,则可以在执行程序之前将其手动添加到 *.rc 文件中。

身份标识

标识符是一个符号,它是一个常量整数,其名称通常以 ID 开头它由两部分组成 - 映射到整数值(符号​​值)的文本字符串(符号名称)。

  • 符号提供了一种在源代码中以及在资源编辑器中使用资源和用户界面对象时引用资源和用户界面对象的描述性方式。

  • 创建新资源或资源对象时,资源编辑器会为资源提供默认名称(例如 IDC_DIALOG1),并为其分配一个值。

  • 名称加值定义存储在 Resource.h 文件中。

步骤 1 - 让我们看看上一章中的CMFCDialogDemo示例,其中我们创建了一个对话框,其 ID 为IDD_EXAMPLE_DLG

CMFC对话框演示

步骤2 - 转到解决方案资源管理器,您将在头文件下看到resource.h 文件。继续在编辑器中打开此文件,您还将看到对话框标识符及其整数值。

标识符2

图标

图标是窗口上使用的代表应用程序的小图片它用于两个主要场景。

  • 在窗口框架上,它显示在标题栏上窗口名称的左侧。

  • 在 Windows 资源管理器、桌面、我的电脑或控制面板窗口中。

如果您查看我们的 MFCModalDemo 示例,您将看到 Visual Studio 在标题栏上使用默认图标,如以下快照所示。

图标

您可以按照以下步骤创建自己的图标 -

步骤 1 - 右键单击​​您的项目并选择“添加”→“资源”,您将看到“添加资源”对话框。

选择添加资源

步骤 2 - 选择图标并单击新建按钮,您将看到以下图标。

图标

步骤 3 - 在解决方案资源管理器中,转到资源视图并展开 MFCModalDemo > 图标。您将看到两个图标。IDR_MAINFRAME 是默认图标,IDI_ICON1 是新创建的图标。

步骤 4 - 右键单击​​新创建的图标并选择属性。

步骤 5 - IDI_ICON1 是该图标的 ID,现在让我们将此 ID 更改为 IDR_MYICON。

步骤 6 - 您现在可以根据您的要求在设计器中更改此图标。我们将使用相同的图标。

步骤 7 - 保存此图标。

步骤 8 - 转到 CMFCModalDemoDlg.cpp 文件中的 CMFCModalDemoDlg 构造函数,该构造函数将类似于以下代码。

CMFCModalDemoDlg::CMFCModalDemoDlg(CWnd* pParent /* = NULL*/)
   : CDialogEx(IDD_MFCMODALDEMO_DIALOG, pParent) {
   m_hIcon = AfxGetApp() -> LoadIcon(IDR_MAINFRAME);
}

步骤 9 - 您现在可以看到默认图标已加载到构造函数中。让我们将其更改为 IDR_ MYICON,如以下代码所示。

CMFCModalDemoDlg::CMFCModalDemoDlg(CWnd* pParent /* = NULL*/)
   : CDialogEx(IDD_MFCMODALDEMO_DIALOG, pParent) {
   m_hIcon = AfxGetApp() -> LoadIcon(IDR_ MYICON);
}

步骤 10 - 编译并执行上述代码后,您将看到对话框中显示新图标。

模态演示

菜单

菜单允许您以逻辑且易于查找的方式排列命令。使用菜单编辑器,您可以直接使用与已完成的应用程序中的菜单栏非常相似的菜单栏来创建和编辑菜单。要创建菜单,请按照以下步骤操作 -

步骤 1 - 右键单击​​您的项目并选择添加 → 资源。您将看到“添加资源”对话框。

添加资源菜单

步骤 2 - 选择菜单并单击新建。您将在菜单栏上看到包含“在此处键入”的矩形。

在菜单栏上键入此处

步骤 3 - 编写一些菜单选项,如文件、编辑等,如下面的快照所示。

菜单选项

步骤 4 - 如果在资源视图中展开菜单文件夹,您将看到菜单标识符 IDR_MENU1。右键单击该标识符并将其更改为 IDM_MAINMENU。

菜单标识符

步骤 5 - 保存所有更改。

步骤 6 - 我们需要将此菜单附加到我们的对话框中。在解决方案资源管理器中展开对话框文件夹,然后双击对话框标识符。

对话框文件夹

步骤 7 - 您将在属性中看到菜单字段。从下拉列表中选择菜单标识符,如上所示。

步骤 8 - 运行此应用程序,您将看到以下对话框,其中也包含菜单选项。

菜单选项

工具栏

工具是一个 Windows 控件,它允许用户通过单击按钮而不是使用菜单来在窗体上执行某些操作。

  • 工具栏提供了一组方便的按钮,通过将最容易访问的操作作为按钮来简化用户的工作。

  • 工具栏可以使此类常见操作更贴近用户。

  • 工具栏通常显示在主菜单下。

  • 它们可以配备按钮,但有时它们的按钮或某些按钮有标题。

  • 工具栏还可以配备其他类型的控件。

要创建工具栏,请执行以下步骤。

步骤 1 - 右键单击​​您的项目并选择添加 → 资源。您将看到“添加资源”对话框。

工具栏

步骤 2 - 选择工具栏并单击新建。您将看到以下屏幕。

选择工具栏

步骤 3 - 在设计器中设计工具栏,如下面的屏幕截图所示,并指定 ID。

设计工具栏

步骤 4 - 在 CMFCModalDemoDlg 类中添加这两个变量。

   CToolBar m_wndToolBar;
   BOOL butD;

步骤 5 - 以下是 CMFCModalDemoDlg.h 文件中 CMFCModalDemoDlg 的完整实现 -

class CMFCModalDemoDlg : public CDialogEx {
   // Construction
   public:
      CMFCModalDemoDlg(CWnd* pParent = NULL); // standard constructor
   // Dialog Data
   #ifdef AFX_DESIGN_TIME
      enum { IDD = IDD_MFCMODALDEMO_DIALOG };
   #endif

   protected:
      virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
   
   // Implementation
   protected:
      HICON m_hIcon;
      CToolBar m_wndToolBar;
      BOOL butD;
   
      // Generated message map functions
      virtual BOOL OnInitDialog();
      afx_msg void OnPaint();
      afx_msg HCURSOR OnQueryDragIcon();
      DECLARE_MESSAGE_MAP()
	
   public:
      afx_msg void OnBnClickedOk();
};

步骤 6 - 更新 CMFCModalDemoDlg::OnInitDialog(),如以下代码所示。

BOOL CMFCModalDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();
   
   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);       // Set big icon
   SetIcon(m_hIcon, FALSE);      // Set small icon
   
   if (!m_wndToolBar.Create(this)
      || !m_wndToolBar.LoadToolBar(IDR_TOOLBAR1))
      //if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD |
      // WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS |
      // CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
      // !m_wndToolBar.LoadToolBar(IDR_TOOLBAR1)) {
         TRACE0("Failed to Create Dialog Toolbar\n");
         EndDialog(IDCANCEL);
      }
      butD = TRUE;
      CRect rcClientOld; // Old Client Rect
      CRect rcClientNew; // New Client Rect with Tollbar Added
		
      // Retrive the Old Client WindowSize
      // Called to reposition and resize control bars in the client area of a window
      // The reposQuery FLAG does not really traw the Toolbar. It only does the calculations.
      // And puts the new ClientRect values in rcClientNew so we can do the rest of the Math.
      
      GetClientRect(rcClientOld);
      RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0, reposQuery, rcClientNew);
      // All of the Child Windows (Controls) now need to be moved so the Tollbar does not cover them up.
      // Offest to move all child controls after adding Tollbar 
      CPoint ptOffset(rcClientNew.left - rcClientOld.left, rcClientNew.top - rcClientOld.top); 
		 
      CRect rcChild;
      CWnd* pwndChild = GetWindow(GW_CHILD); //Handle to the Dialog Controls
      
      while (pwndChild) // Cycle through all child controls {
         pwndChild -> GetWindowRect(rcChild); // Get the child control RECT
         ScreenToClient(rcChild);
          
         // Changes the Child Rect by the values of the claculated offset
         rcChild.OffsetRect(ptOffset);
         pwndChild -> MoveWindow(rcChild, FALSE); // Move the Child Control
         pwndChild = pwndChild -> GetNextWindow();
      }
       
      CRect rcWindow;
      // Get the RECT of the Dialog
      GetWindowRect(rcWindow);
       
      // Increase width to new Client Width
      rcWindow.right += rcClientOld.Width() - rcClientNew.Width();
       
      // Increase height to new Client Height
       rcWindow.bottom += rcClientOld.Height() - rcClientNew.Height();
      // Redraw Window
      MoveWindow(rcWindow, FALSE);
       
      // Now we REALLY Redraw the Toolbar
      RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
       
   // TODO: Add extra initialization here

   return TRUE; // return TRUE unless you set the focus to a control
}

步骤 7 - 运行此应用程序。您将看到以下对话框,其中也包含工具栏。

工具栏4

加速器

访问是一个字母,允许用户使用键盘而不是鼠标更快地执行菜单操作。这通常更快,因为用户不需要将鼠标放置在任何地方,从而减少了执行操作所需的时间。

步骤 1 - 要创建访问键,请在菜单项左侧键入与号“&”。

创建访问密钥

步骤 2 - 对所有菜单选项重复此步骤。运行此应用程序并按 Alt。您将看到所有菜单选项的第一个字母都带有下划线。

菜单选项

快捷键

快捷键是高级用户用来执行本来要在菜单项上执行的操作的键或键组合。大多数快捷键是同时按下 Ctrl 键和字母键的组合。例如,Ctrl + N、Ctrl + O 或 Ctrl + D。

要创建快捷方式,请在组成菜单标题的字符串的右侧,右键单击菜单项并选择属性。

在“标题”字段中,输入 \t,后跟所需的组合,如下所示,用于“新建”菜单选项。对所有菜单选项重复该步骤。

快捷键

加速表

加速键表是一个项目列表,其中表中的每个项目都包含一个标识符、一个快捷键和一个指定加速键类型的常量。就像其他资源一样,可以在 .rc 文件中手动创建加速器表。以下是创建加速器表的步骤。

步骤 1 - 要创建加速器表,请右键单击解决方案资源管理器中的 *.rc 文件。

加速表

步骤 2 - 选择加速器并单击新建。

选择加速器

步骤 3 - 单击 ID 组合框的箭头并选择菜单项。

加速表

步骤 4 - 从修饰符下拉列表中选择 Ctrl。

步骤 5 - 单击“密钥”框并键入两个菜单选项各自的密钥。

我们还将添加新菜单项事件处理程序进行测试。右键单击“新建”菜单选项。

事件处理程序

步骤 6 - 您可以指定类、消息类型和处理程序名称。现在,让我们保持原样,然后单击“添加和编辑”按钮。

消息类型处理程序名称

步骤 7 - 选择添加事件处理程序。

步骤 8 - 您现在将看到添加在 CMFCModalDemoDlg.cpp 文件末尾的事件。

void CMFCModalDemoDlg::OnFileNew() {
   // TODO: Add your command handler code here
   MessageBox(L"File > New menu option");
}

步骤 9 -现在让我们添加一个消息框,它将显示简单的菜单选项消息。

要在工作中启动加速器表,请添加 HACCEL 变量和 ProcessMessageFilter,如以下 CMFCModalDemoApp 中所示。

class CMFCModalDemoApp : public CWinApp {
   public:
      CMFCModalDemoApp();
   
   // Overrides
   public:
      virtual BOOL InitInstance();
      HACCEL m_hAccelTable;
      
      // Implementation

      DECLARE_MESSAGE_MAP()
      virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);
};

步骤 10 - 加载加速器并在 CMFCModalDemoApp::InitInstance() 中进行以下调用。

m_hAccelTable = LoadAccelerators(AfxGetInstanceHandle(),
   MAKEINTRESOURCE(IDR_ACCELERATOR1));

步骤 11 - 这是 ProcessMessageFilter 的实现。

BOOL CMFCModalDemoApp::ProcessMessageFilter(int code, LPMSG lpMsg) {
   if (code >= 0 && m_pMainWnd && m_hAccelTable) {
      if (::TranslateAccelerator(m_pMainWnd -> m_hWnd, m_hAccelTable, lpMsg))
      return TRUE;
   }
   return CWinApp::ProcessMessageFilter(code, lpMsg);
}

步骤 12 - 编译并执行上述代码后,您将看到以下输出。

加速器结果

步骤 13 - 按 Alt 按钮,然后按 F 键,然后按 N 键或 Ctrl + N。您将看到以下消息。

加速表