MFC - Windows 资源



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

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

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

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

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

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

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

标识符

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

  • 符号提供了一种描述性方式来引用资源和用户界面对象,无论是在源代码中还是在使用资源编辑器处理它们时。

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

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

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

CMFCDialogDemo

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

Identifiers2

图标

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

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

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

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

Icons

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

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

Select Add Resources

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

Icon

步骤 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 -编译并执行上述代码后,您将看到新的图标显示在对话框上。

Modal Demo

菜单

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

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

Add Resources Menu

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

Type Here on Menu Bar

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

Menu Options

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

Menu Identifier

步骤 5 -保存所有更改。

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

Dialog Folder

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

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

Menu Option

工具栏

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

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

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

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

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

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

要创建工具栏,请按照以下步骤操作。

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

Toolbar

步骤 2 -选择“工具栏”,然后单击“新建”。您将看到以下屏幕。

Select Toolbar

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

Design Toolbar

步骤 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 -运行此应用程序。您将看到以下对话框,其中还包含工具栏。

Toolbar4

加速键

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

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

Create an Access Key

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

Menu Option

快捷键

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

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

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

Shortcut Key

加速器表

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

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

Accelerator Table

步骤 2 -选择“加速器”,然后单击“新建”。

Select Accelerator

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

Accelerator Table

步骤 4 -从“修饰符”下拉菜单中选择 Ctrl。

步骤 5 -单击“键”框,然后为这两个菜单选项键入相应的键。

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

Event Handler

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

Message Type  Handler Name

步骤 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 -编译并执行上述代码后,您将看到以下输出。

Accelerator Result

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

Accelerator Table
广告
© . All rights reserved.