santosh kumar
santosh kumar

Reputation: 585

Popup menu in MFC from button click handler not working

// CMFCApplication1Dlg dialog
CMFCApplication1Dlg::CMFCApplication1Dlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(CMFCApplication1Dlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMFCApplication1Dlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_BUTTON1, &CMFCApplication1Dlg::OnBnClickedButton1)
END_MESSAGE_MAP()

// CMFCApplication1Dlg message handlers
BOOL CMFCApplication1Dlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // Add "About..." menu item to system menu.

    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // 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

    // TODO: Add extra initialization here

    return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMFCApplication1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialogEx::OnSysCommand(nID, lParam);
    }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMFCApplication1Dlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialogEx::OnPaint();
    }
}

// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMFCApplication1Dlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}

void CMFCApplication1Dlg::OnBnClickedButton1()
{
    //Simulating the similar code as product
    CFrameWnd *pFrame = GetParentFrame();
    CMenu popup;
    popup.CreatePopupMenu();

    LPCWSTR pszMenuItem2 = L"Korean with wchar_t: 기존 운";
    AppendMenuW(popup.m_hMenu, MF_STRING, 1, pszMenuItem2);

    TCHAR* pszMenuItem3 = "|| Korean without wchar_t: 또는 차량 삽입";
    AppendMenu(popup.m_hMenu, MF_STRING, 2, pszMenuItem3);

    UINT nCmd = popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
                                    14, 20, pFrame, 0);
}

I have written above piece of code to generate popup menu in the screen on button click but it doesn't show any menu at all? Am I missing something?

As you asked here is the complete code. Actually I have placed one static button through GUI and on button click trying to generate the popup menu.

These button is not created dynamically. Also, the entire code here is generated by wizard except the last portion of the code about the button click.

Upvotes: 1

Views: 1272

Answers (1)

santosh kumar
santosh kumar

Reputation: 585

The problem was in the handle, if I use the right API to get the handle, it shows the popup menu. Here is the updated code.

void CMFCApplication1Dlg::OnBnClickedButton1()
{
    //Simulating the similar code as product
    HWND wnd= GetSafeHwnd();//<---- this had to change  
    CMenu popup;
    popup.CreatePopupMenu();

    LPCWSTR pszMenuItem2 = L"Korean with wchar_t: 기존 운";
    AppendMenuW(popup.m_hMenu, MF_STRING, 1, pszMenuItem2);

    TCHAR* pszMenuItem3 = "|| Korean without wchar_t: 또는 차량 삽입";
    AppendMenu(popup.m_hMenu, MF_STRING, 2, pszMenuItem3);

    UINT nCmd = popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
                                    14, 20, CWnd::FromHandle(wnd)/*need this api to get the CWnd from HWND*/, 0);


Upvotes: 1

Related Questions