akif
akif

Reputation: 12344

List box context menu

How do I add a context menu in a list box in MFC? I don't see any WM_CONTEXTMENU handler in list box's properties. Any ideas?

EDIT: I followed this tutorial MFC List Control: How to use a context menu in a list control?. The tutorial says to derive my own class from CListBox which I did, but now how do I add list box of my derived class to the dialog?

Upvotes: 2

Views: 7091

Answers (5)

Michael Haephrati
Michael Haephrati

Reputation: 4245

You need to take the following steps:

  1. Add
ON_WM_CONTEXTMENU()

to

BEGIN_MESSAGE_MAP()

So you will have something like

BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_QUERYDRAGICON()
    ON_WM_CONTEXTMENU()
END_MESSAGE_MAP()
  1. Add the Context Menu function in the header file:
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point)
  1. Then add the Context Menu function, as suggested in the article:
void CMyDialog::OnContextMenu(CWnd* pWnd, CPoint point)
{
    CListCtrl* pList = (CListCtrl*)GetDlgItem( ID_YOUR_LIST );

    if ( (CWnd*)pList == pWnd )
    {
        CMenu menu;
        // Create your menu items.

        int retVal  = menu.TrackPopupMenu( TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD, point.x, point.y, this );

        // Handle your returns here.
    }
}

Upvotes: 2

Goz
Goz

Reputation: 62333

Put an OnContextMenu handler in the parent class. Then add a popup menu

Edit To add the OnContextMenu handler, add an event handler to the PARENT window (ie not the list class). This is most easily done through the resource editor. Go to the properties page then go to the messages section. Then add a function for WM_CONTEXTMENU.

void CYourDialog::OnContextMenu(CWnd* pWnd, CPoint point)
{
    CListCtrl* pList = (CListCtrl*)GetDlgItem( ID_YOUR_LIST );

    if ( (CWnd*)pList == pWnd )
    {
        CMenu menu;
        // Create your menu items.

        int retVal  = menu.TrackPopupMenu( TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD, point.x, point.y, this );
        
        // Handle your returns here.
    }
}

Upvotes: 3

Igor Levicki
Igor Levicki

Reputation: 1613

Since my edit was rejected with the rationale of "changing too much", I will put my proposal here because in my opinion the original code promotes bad coding practices.

void CYourDialog::OnContextMenu(CWnd* pWnd, CPoint point)
{
    int CtrlID = pWnd->GetDlgCtrlID();

    if (CtrlID == ID_YOUR_LIST) {
        CMenu menu;
        // Create your menu items...
        int retVal = menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD, point.x, point.y, this);
        // Handle selected options here...
    }
}

Upvotes: 3

djeidot
djeidot

Reputation: 4642

If you followed the tutorial to derive you own class, make sure ON_WM_CONTEXTMENU() is added to the new class message map.

To add a list box of your derived class, you simply add a variable for your ListBox control and specify the variable class as your derived class.

However I think @Goz's answer is also a valid solution, and a simpler one.

Upvotes: -1

Nick Dandoulakis
Nick Dandoulakis

Reputation: 43140

Add a handler for your dialog window. That will generate this:

void YourDialogClass::OnContextMenu(CWnd* pWnd, CPoint point) {
  ...
}

pWnd will point to the window/control in which the user right clicked the mouse.

Upvotes: 0

Related Questions