MFC – Popup Menu

Pop-up menu

Context menu (còn được gọi là shortcut, pop-up menu) là menu xuất hiện trên GUI khi user thực hiện thao tác như thực hiện right-click chuột.
Chúng ta sẽ sử dụng source code base tại bài viết Dialog-based để add thêm menu bar.

Tạo Menu Resource

  • Chọn [View] -> [Other Windows] -> [View Resources]
  • Click chuột phải vào folder [MFCApp.rc], chọn [Add Resource…]
  • Resource type: Menu
  • Click [New]

Màn hình để bạn design menu xuất hiện, bạn chỉ cần đánh tên các item mong muốn của menu vào ô [Type Here].
ID của menu là IDR_MENU1

Tôi sẽ tạo 1 menu gồm có item [File] và các sub-item là [New], [Open], [Save] và [Exit]. Và giữa [Save] và [Exit] có separator line.

Mỗi sub-item [New], [Open], [Save] và [Exit] có 1 ID (định danh) riêng. Dựa vào ID này, application biết được sự kiện (select sub-item) đang xảy ra trên sub-item nào, để đưa ra các phương thức xử lí sự kiện tương ứng.
Visual Studio tự đồng đặt tên ID và giá trị của ID cho mỗi sub-item. Đôi khi, tên ID là không có ý nghĩa, chúng ta cần rename ID. Để rename của ID, chúng ta làm như sau

– Chuột phải vào sub-item cần rename ID, chọn [Edit IDs]

– Edit ID của các sub-item như sau

Sub-item ID name
New IDM_FILE_NEW
Open IDM_FILE_OPEN
Save IDM_FILE_SAVE
Exit IDM_FILE_EXIT

Giá trị của các ID được Visual Studio define trong file Resource.h

#define ID_FILE_EXIT                    32774
#define IDM_FILE_NEW                    32775
#define IDM_FILE_OPEN                   32776
#define IDM_FILE_SAVE                   32777

Hiển thị shortcut menu khi right-click chuột

Định nghĩa function bắt sự kiện right-click

void CMFCAppDlg::OnRButtonDown(UINT nFlags, CPoint point)
{

    CMenu m_lMenu; // A pointer to the menu
    CMenu *hmenuTrackPopup;
    CPoint m_pPoint; // A copy of the mouse position
    m_pPoint = point; // Copy mouse position to a local variable
    ClientToScreen(&m_pPoint); // Convert to an absolute screen position

    m_lMenu.LoadMenuW(IDR_MENU1);
    ASSERT(m_lMenu);

    hmenuTrackPopup = m_lMenu.GetSubMenu(0);
    hmenuTrackPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, m_pPoint.x, m_pPoint.y, this, NULL);

    m_lMenu.DestroyMenu();
}
BEGIN_MESSAGE_MAP(CMFCAppDlg, CDialogEx)
    ...
    ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()

Khi right-click chuột, phương thức OnRButtonDown() được gọi và tham số đầu vào point chứa tọa độ điểm (x0, y0) right-click chuột. (x0, y0 là tọa độ tương đối – lấy (Top, Left) là gốc tọa độ).
Hàm ClientToScreen() convert tọa độ tương đối (x0, y0) sang tọa độ tuyệt đối (x, y). (x, y là tọa độ so với gốc (0,0) của màn hình PC.

Tọa độ tương đối và tuyệt đối
Tọa độ tương đối và tuyệt đối

Phương thức LoadMenuW(IDR_MENU1)load menu với ID = IDR_MENU1 được tạo trên. Chú ý phải free menu resource khi không sử dụng nữa.
Phương thức GetSubMenu() lấy CMenu object của menu ID = IDR_MENU1
Phương thức TrackPopupMenu() hiển thị menu tại vị trí right-click chuột
Phương thức DestroyMenu() free menu resource.

Source Code

Download

Demo

Pop-up Demo

Be the first to comment

Leave a Reply