| Introduction |
One of the primary characteristics of a control is to make its role appear obvious to the user. For example, by default, a button is used to click in order to start an action. Sometimes you may want to display a context menu. That is, if the user right-clicks, instead of a (left) click, you may want to display a particular menu. Many MFC controls don't provide this functionality on their own; you would have to apply the action on the parent control.
- Start Microsoft Visual C++ MFC Application named ControlContext
- Create it as Dialog Box without the AboutBox
- Set the Dialog Title to Context-Sensitive Menu on Controls
- Add a button to dialog box. Change its ID to IDC_SUBMIT_BTN and its Caption to Submit
- Add a check box to the dialog box. Change its ID to IDC_APPROVED_CHK and its Caption to Approved:

- Display the Add Resource dialog box and double-click Menu

- Change the ID of the IDR_MENU1 to IDR_SUBMIT and create it as follows:

- Set their IDs to ID_POPUP_GREEN, ID_POPUP_RED, ID_POPUP_YELLOW, ID_POPUP_BLUE, ID_POPUP_WHITE, and ID_POPUP_FUCHSIA
- Display the dialog box and click its body
- In the Properties window, click the Messages button

- Click the arrow of the WM_CONTEXTMENU combo box and implement the event as follows:
void CControlContextDlg::OnContextMenu(CWnd* /*pWnd*/, CPoint point) { // TODO: Add your message handler code here // Load the desired menu CMenu mnuPopupSubmit; mnuPopupSubmit.LoadMenu(IDR_SUBMIT); // Get a pointer to the button CButton *pButton; pButton = reinterpret_cast<CButton *>(GetDlgItem(IDC_SUBMIT_BTN)); // Find the rectangle around the button CRect rectSubmitButton; pButton->GetWindowRect(&rectSubmitButton); // Get a pointer to the first item of the menu CMenu *mnuPopupMenu = mnuPopupSubmit.GetSubMenu(0); ASSERT(mnuPopupMenu); // Find out if the user right-clicked the button // because we are interested only in the button if( rectSubmitButton.PtInRect(point) ) // Since the user right-clicked the button, display the context menu mnuPopupMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); } - On the dialog box, double-click the Submit button and implement its Click event as follows:
void CControlContextDlg::OnBnClickedSubmitBtn() { // TODO: Add your control notification handler code here AfxMessageBox("You clicked the Submit button but ain't nothin' to do right now!!!"); } - Display the IDR_SUBMIT menu
- Right-click the Green menu item and click Add Event Handler...
- Set the Class List to CControlContextDlg
- Display the IDR_SUBMIT menu
- Right-click the Red menu item and click Add Event Handler
- Set the Class List to CControlContextDlg
- Implement both events as follows:
void CControlContextDlg::OnPopupGreen() { // TODO: Add your command handler code here AfxMessageBox("You selected the Green menu item"); } void CControlContextDlg::OnPopupRed() { // TODO: Add your command handler code here AfxMessageBox("You selected the Red menu item"); } - Execute the application and right-click the Submit button:

- Right-click the Approved check box or one of the other buttons of the dialog box and notice that no context menu appears
- Close the dialog box and return to MSVC
- Display the Add Resource dialog box again. Click Menu and click Add
- Change the menu's ID to IDR_APPROVAL and design it as follows:

- To be able to display the other menu, change the OnContextMenu() event as follows:
void CControlContextDlg::OnContextMenu(CWnd* /*pWnd*/, CPoint point) { // TODO: Add your message handler code here // Load the desired menu CMenu mnuPopupSubmit; CMenu mnuPopupApproval; mnuPopupSubmit.LoadMenu(IDR_SUBMIT); mnuPopupApproval.LoadMenu(IDR_APPROVAL); // Get a pointer to the button CButton *pButton, *chkApproval; pButton = reinterpret_cast<CButton *>(GetDlgItem(IDC_SUBMIT_BTN)); chkApproval = reinterpret_cast<CButton *>(GetDlgItem(IDC_APPROVED_CHK)); // Find the rectangle around the control CRect rectSubmitButton, rectApprovalButton; pButton->GetWindowRect(&rectSubmitButton); chkApproval->GetWindowRect(&rectApprovalButton); // Get a pointer to the first item of the menu CMenu *mnuPopupMenu = mnuPopupSubmit.GetSubMenu(0); CMenu *mnuPopupMenu2 = mnuPopupApproval.GetSubMenu(0); ASSERT(mnuPopupMenu); ASSERT(mnuPopupApproval); // Find out if the user right-clicked a button if( rectSubmitButton.PtInRect(point) ) // Since the user right-clicked a button, display its context menu mnuPopupMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); else if( rectApprovalButton.PtInRect(point) ) mnuPopupMenu2->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); } - Display the IDR_APPROVAL menu
- Right-click each menu item and click Add Event Handler. Set the Class List to CContextMenuDlg
- Implement the events as follows:
void CControlContextDlg::OnPopupUnderreview() { // TODO: Add your command handler code here CheckDlgButton(IDC_APPROVED_CHK, BST_INDETERMINATE); } void CControlContextDlg::OnPopupApproved() { // TODO: Add your command handler code here CheckDlgButton(IDC_APPROVED_CHK, BST_CHECKED); } void CControlContextDlg::OnPopupRejected() { // TODO: Add your command handler code here CheckDlgButton(IDC_APPROVED_CHK, BST_UNCHECKED); } - Test the application
转自:http://www.functionx.com/visualc/howto/contextmenu.htm
本文介绍如何在Microsoft Visual C++ MFC应用程序中为控件添加上下文敏感菜单,包括按钮和复选框等控件,并实现不同菜单项的功能。

951

被折叠的 条评论
为什么被折叠?



