C++ CRICHEDITCRL如何知道已执行粘贴操作?

C++ CRICHEDITCRL如何知道已执行粘贴操作?,c++,mfc,clipboard,C++,Mfc,Clipboard,它有一些方法,如CRichEditCtrl::Copy(),CRichEditCtrl::Paste(),您可以调用这些方法,但我无法发现Windows向控件发送的任何消息,告诉它执行粘贴操作。有人知道这样的事情是否存在吗?或者CRichEditCtrl是否做了一些较低级别的事情,比如监视WM_CHAR事件?如果是这样的话,我可以重用任何内部方法吗?或者我只需要使用自己的方法来覆盖标准的粘贴功能吗 我实际上希望自定义子类(CMyRichEditCtrl:CRichEditCtrl)忽略粘贴到控件

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

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

到目前为止我所尝试的:

  • CMyRichEditCtrl::PreTranslateMessage()中检查消息的WM_粘贴
  • 创建方法
    virtualvoid CMyRichEditCtrl::Paste()
  • 在afxcmn.inl中的
    CRichEditCtrl::Paste()
    上放置断点
  • 转储通过的每条消息
    CMyRichEditCtrl::PreTranslateMessage()
  • 结果:

    1:未看到WM_粘贴消息
    2:从来没有人叫过它
    3:从来没有打过怎么做?
    4:控件从不接收任何WM_命令、WM_粘贴或焦点相关消息。基本上只有鼠标移动和按键信息


    似乎其他人已经成功地做到了这一点。我想知道我的MFC版本或其他东西是否会把它搞砸。

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


    它可能会响应这些消息,而不是WM_CHAR消息,以了解何时执行剪贴板操作。

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

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

    ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
    
    声明,这应该是有效的。或者,在预翻译消息中,您可以查找wParam为ID_EDIT_PASTE的WM_命令

    顺便说一句,我解决了一个与您的问题非常类似的问题(粘贴而不格式化),方法是使用

    void MyRichEdit::OnEditPaste()
    {
      SendMessage(EM_PASTESPECIAL,CF_UNICODETEXT);
    }
    
    这通过向坚持数据格式为纯文本的控件发送粘贴消息来响应粘贴请求


    最后,我应该指出,上述技术足以捕获从用户界面触发的所有粘贴。但是,当您的代码将WM_粘贴发送到编辑控件时,它不会捕获编程触发的粘贴。在这种情况下,只需更改代码就可以了。然而,如果你真的想截获这种情况,你必须用COM和IRichEditOleCallback::QueryAcceptData弄脏你的手。但您几乎肯定不想去那里:-)

    处理受保护的消息

    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
    }
    

    在派生类上使用ON_MESSAGE宏

    ON_消息(WM_粘贴,ON粘贴)

    LRESULT CMyRichEditCtrl::OnPaste(WPARAM,LPARAM)


    如果打开RichEdit.h文件,您会注意到一些消息位于WM_用户的范围内。也许这就是MFC处理富编辑控件事件的方式。

    我必须执行如下操作

    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);    
    }
    
    void MyRichEcit::OnKeyDown(UINT nChar、UINT nRepCnt、UINT nFlags)
    {
    
    如果((GetKeyState)(VK_控件)没有从该链接中清除,那么这应该是richedit控件的window proc的子类吗?请参阅我对原始帖子的编辑,应该可以更清楚地了解我在尝试什么。我已经尝试过了(无论是在_命令还是扫描WM_命令消息。当我点击CTRL-V时,两者都不会被触发,文本只是出现在编辑框中,而EN_更改被触发。我现在完全困惑了-你是如何让它工作的,但它拒绝为我工作的?!有趣!可能值得尝试IRichEditOleCallback::QueryAcceptData方法,如果只是为了看看正在进行。请尝试创建一个实现IRichEditOleCallback的类,并通过调用CRichEditCtrl::SetOLECallback()进行安装。现在,在粘贴时,无论发生什么情况,都应始终调用类“QueryAcceptData”。如果在该类上有断点,则至少应获得一个callstack,其中可能有关于它响应的消息的线索。您能否解释为什么SetDefaultCharFormat可以工作(它可以)?我说它是有效的,但这种方法只告诉我操作已经发生,它不允许我重写它。如果没有更好的建议,我仍然会给你奖金,因为即使你回答的部分也非常有用。或者,如果你能告诉我OnProtected方法如何阻止/修改发生在受保护字符上的操作,我当然会立即给你。是的我也发现了!但这是你应得的,我用不同的方式问了同样的问题一周都没有成功!文档说明:此消息返回零以允许操作。此消息返回非零值以防止操作。这在我执行的任何测试中都不起作用。你测试过它吗?或者你只是没有tice WM_PASTE存在并假设它会工作?我想这取决于你如何使用它。我假设你有一个窗口,它利用了你拥有的这个RichEditCtrl派生类。在我的例子中,我有一个对话框,它调用派生类的PASTE()函数,并反过来触发我上面发布的代码。