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
廣告