CRichEditCtrl如何知道粘贴操作?

时间:2010-02-12 09:28:30

标签: c++ mfc clipboard

它可以调用CRichEditCtrl::Copy()CRichEditCtrl::Paste()之类的方法,但我无法发现Windows发送控件的任何消息,告诉它执行粘贴操作。有谁知道这样的事情是否存在?或者CRichEditCtrl做一些低级的事情,比如监视WM_CHAR事件?如果是这样,我可以重用任何内部方法,还是只需要自己滚动以覆盖标准粘贴功能?

我真正想要的是我的自定义子类(CMyRichEditCtrl : CRichEditCtrl)忽略在中粘贴到控件上的文本的任何格式。通过以不同的剪贴板格式获取剪贴板数据,或者正常粘贴剪贴板数据并立即删除插入文本的格式。

到目前为止我尝试了什么:

  1. CMyRichEditCtrl::PreTranslateMessage()
  2. 中查看WM_PASTE的消息
  3. 创建方法virtual void CMyRichEditCtrl::Paste()
  4. 在afxcmn.inl
  5. CRichEditCtrl::Paste()上设置断点
  6. 转发每条消息,通过CMyRichEditCtrl::PreTranslateMessage()
  7. 结果:

    1:没有看到WM_PASTE消息 2:它永远不会被称为 3:从来没有打过...... 怎么样?
    4:控件从不接收任何WM_COMMAND,WM_PASTE或焦点相关的消息。基本上只有鼠标移动和按键消息

    似乎其他人已经成功地做到了这一点。我想知道我的MFC版本或其他什么东西可能会搞砸了。

5 个答案:

答案 0 :(得分:2)

处理EN_PROTECTED消息。

ON_NOTIFY_REFLECT(EN_PROTECTED, &YourClass::OnProtected)

// call this from the parent class
void YourClass::Initialize()
{
    CHARFORMAT format = { sizeof(CHARFORMAT) };
    format.dwEffects = CFE_PROTECTED; 
    format.dwMask = CFM_PROTECTED;

    SetDefaultCharFormat(format);
    SetEventMask(ENM_PROTECTED);
}

void YourClass::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)
{
    *pResult = 0; 

    ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;
    if (pEP->msg == WM_PASTE)
        pResult = 1; // prevent paste
}

答案 1 :(得分:0)

Windows定义了剪切/复制/粘贴的消息。见WM_CUT

它可能会响应这些消息而不是WM_CHAR消息来知道何时进行剪贴板操作。

答案 2 :(得分:0)

当用户请求粘贴操作时,通常会将带有标识符ID_EDIT_PASTE的WM_COMMAND消息发送到富编辑控件。默认情况下,它在MFC中由CRichEditCtrl :: OnEditPaste()处理,它在编辑控件本身上调用Paste()。

我的方法是从CRichEditCtrl派生一个类,添加一个OnEditPaste方法并使用

将消息路由到它
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)

声明,应该有效。或者,在PreTranslateMessage中,您可以使用ID_EDIT_PASTE的wParam查找WM_COMMAND。

顺便说一句,我已经解决了一个非常类似的问题(粘贴没有格式化)只需要实现OnEditPaste

void MyRichEdit::OnEditPaste()
{
  SendMessage(EM_PASTESPECIAL,CF_UNICODETEXT);
}

这通过向控件发送粘贴消息来响应粘贴请求,该消息坚持数据格式是纯文本。

最后,我应该指出,上述技术足以捕获从用户界面触发的所有粘贴。但是,当您的代码将WM_PASTE发送到编辑控件时,它不会捕获以编程方式触发的粘贴。在这些情况下,最简单的方法是更改​​代码。但是,如果你真的想拦截这种情况,你必须弄清楚COM和IRichEditOleCallback :: QueryAcceptData。但你几乎肯定不想去那里: - )

答案 3 :(得分:0)

在派生类上使用ON_MESSAGE宏。

ON_MESSAGE(WM_PASTE,OnPaste)

LRESULT CMyRichEditCtrl :: OnPaste(WPARAM,LPARAM)

如果打开RichEdit.h文件,您会注意到某些消息在WM_USER范围内。也许这就是MFC如何处理Rich Edit Control的事件。

答案 4 :(得分:0)

我必须执行如下

void MyRichEcit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{


if( ( GetKeyState(VK_CONTROL)<0 && nChar==88 ) || (nChar==VK_DELETE && GetKeyState(VK_SHIFT) < 0) ) //cut
    {

    }

if( ( GetKeyState(VK_CONTROL)<0 && nChar==86 ) || (nChar==VK_INSERT && GetKeyState(VK_SHIFT) < 0) ) //paste
    {

    }


    CWnd::OnKeyDown(nChar, nRepCnt, nFlags);    
}