📜  MFC-Windows资源

📅  最后修改于: 2020-11-20 06:25:52             🧑  作者: Mango


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

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

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

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

  • 应用程序可以使用各种行为彼此独立的资源,这些资源被分组为扩展名为* .rc的文本文件。

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

添加资源

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

身份标识

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

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

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

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

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

CMFCDialogDemo

步骤2-转到解决方案资源管理器,您将在Header Files下看到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-我们需要将此菜单附加到对话框。在解决方案资源管理器中展开Dialog文件夹,然后双击对话框标识符。

对话框文件夹

步骤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-单击键框,然后为两个菜单选项键入相应的键。

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

事件处理程序

步骤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()中加载Accelerator和以下调用。

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。您将看到以下消息。

加速表