Search code examples
c++mfcsdi

C++ MFC SDI Copy/Paste did not work


I have created a simple MFC SDI Application with an Ribbon. The View for the Document is a FormView with on Edit Control.

If I now use CTRL+V to paste some Text in the Edit Control nothing happens. Same goes with CTRL+C to copy the Text inside the Edit Control. I could use the Context Menu if i right click inside the Edit Control. But how can i enable the Shortcuts? The CTRL + C etc is inside the Accelerator List. If i add the following to the MainForm

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
    ON_COMMAND(ID_EDIT_COPY, &CMainFrame::onCopy)
END_MESSAGE_MAP()

and the Function itself

void CMainFrame::onCopy() {
    AfxMessageBox(L"Copy");
}

If i now press CTRL+C the MessageBox Pops up. But i could not copy the text of the Edit Control to the Clipboard. How could I chose between copy text from an Edit Text and doing something else if a different control is selected and CTRL+C is pressed(e.g. if i select text inside the Edit Control it should be copied to the clipboard. If i select e.g. an Item from a Tree View only a popup should shown)?


Solution

  • Use ON_UPDATE_COMMAND_UI to enable/disable command. Use ON_COMMAND to respond to the same command.

    You then have to forward the message to the edit control (m_edit.Copy()). You can do this directly in CMyView class (remove the handler from CMainFrame)

    If there are more than one edit control, GetFocus will report which edit control has focus.

    CEdit::GetSel will report if selection is available.

    Do the same with paste. Use m_edit.CanPaste() to see if paste is available. Use m_edit.Paste() for paste command.

    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
        //ON_COMMAND(ID_EDIT_COPY, &CMainFrame::onCopy)
    END_MESSAGE_MAP()
    
    BEGIN_MESSAGE_MAP(CMyView, CView)
        ON_COMMAND(ID_EDIT_COPY, &CMyView::OnEditCopy)
        ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, &CMyView::OnUpdateEditCopy)
        ...
    END_MESSAGE_MAP()
    
    class CMyView : public CView
    {
        CEdit m_edit1, m_edit2;
        ...
    };
    
    void CMyView::OnEditCopy()
    {
        CWnd *wnd = GetFocus();
        if(wnd == &m_edit1)
            m_edit1.Copy();
        else if(wnd == &m_edit2)
            m_edit2.Copy();
    }
    
    void CMyView::OnUpdateEditCopy(CCmdUI *pCmdUI)
    {
        CWnd *wnd = GetFocus();
        int start, end;
        if(wnd == &m_edit1)
        {
            m_edit1.GetSel(start, end);
            pCmdUI->Enable(end > start);
        }
        else if(wnd == &m_edit2)
        {
            m_edit2.GetSel(start, end);
            pCmdUI->Enable(end > start);
        }
    }
    

    Or you can do this in CMainFrame, you have to find the handle to the view class and edit control.

    Also make sure accelerator key is added.