2010-02-12 22 views
3

它有像CRichEditCtrl::Copy(),CRichEditCtrl::Paste()这样的方法,你可以调用,但我不能发现任何控制信息被Windows发送给执行粘贴操作。有谁知道这样的事情是否存在?还是CRichEditCtrl做一些较低层次的监控WM_CHAR事件?如果是这样,我可以重用任何内部方法,或者我只需要自己滚动以覆盖标准粘贴功能?CRichEditCtrl如何知道粘贴操作已执行?

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

我试过到目前为止:

  1. 检查WM_PASTE消息中CMyRichEditCtrl::PreTranslateMessage()
  2. 创建方法virtual void CMyRichEditCtrl::Paste()
  3. 在afxcmn.inl
  4. 把一个断点CRichEditCtrl::Paste()倾销消息通过CMyRichEditCtrl::PreTranslateMessage()

结果:

1:没有见过WM_PASTE消息
2:这是从来没有所谓的
3:这是从来没有打...... 怎么样?
4:控件从不收到任何WM_COMMAND,WM_PASTE或焦点相关的消息。基本上只有鼠标移动和按键消息

看来其他人已经成功地做到了这一点。我想知道如果我的MFC版本或什么东西可能会搞砸了,在这一点上。

回答

1

处理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 
} 
+0

你能解释为什么SetDefaultCharFormat使它工作(它)? 我说它的工作,但这种做法只有_te lls_我的操作发生了,它不会让我重写它。我仍然会给你赏金,如果没有更好的建议,因为即使你回答的部分是非常有帮助的。 – 2010-02-15 15:41:22

+0

或者当然,如果_you_能够告诉我OnProtected方法如何防止/修改发生在受保护的字符上的动作。 – 2010-02-15 15:45:33

+0

是的,我也发现了!但你当然应该得到它,我一直在用不同的方式问同样的问题,一个星期没有成功! – 2010-02-15 15:53:11

0

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

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

+0

不就执行我可以告诉:http://www.codeguru.com/forum/showthread.php?t=58725 – 2010-02-12 09:47:53

+0

从该链接不明确,那是否应该是Richedit控件的窗口过程的一个子类呢? – 2010-02-12 09:57:16

+0

查看我对原文的编辑,应该让它更清楚我所尝试的内容。 – 2010-02-12 11:03:17

0

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

我会去了解这个问题的方法是从派生一个的CRichEditCtrl类,添加一个OnEditPaste方法和消息路由到其与

ON_COMMAND(ID_EDIT_PASTE, OnEditPaste) 

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

顺便说一句,我已经只是有OnEditPaste与

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

这通过发送粘贴消息响应粘贴请求的实施解决了一个非常类似的问题对你(粘贴不带格式)坚持数据格式为纯文本的控件。

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

+0

我试过了(ON_COMMAND和扫描WM_COMMAND消息),当我点击CTRL-V时,文本刚刚出现在编辑框中,EN_CHANGE被触发,我都没有触发,现在我完全混淆了 - 你是怎么得到它的工作但它拒绝为我?! – 2010-02-12 14:14:22

+0

有趣的!这可能是值得尝试的IRichEditOleCallback :: QueryAcceptData方法,如果只是为了看看发生了什么 尝试创建一个实现IRichEditOleCallback的类,并通过调用CRichEditCtrl :: SetOLECallback ()。现在在粘贴时,应该总是调用QueryAcceptData类,不管怎样,通过一个断点,你至少应该得到一个callstack,它可能会知道它响应的消息。 – DavidK 2010-02-13 16:56:25

0

在派生类中使用ON_MESSAGE宏。

ON_MESSAGE(WM_PASTE,OnPaste)

LRESULT CMyRichEditCtrl :: OnPaste(WPARAM,LPARAM)

如果打开RichEdit.h文件,你会发现,一些消息都在范围WM_USER。也许这就是MFC如何处理Rich Edit Control的事件。

+0

这在我执行的任何测试中都不起作用。您是否测试了它,或者您是否注意到WM_PASTE存在并假定它会起作用? – 2010-02-19 08:02:17

+0

我认为这取决于你如何使用它。我假设你有一个利用这个RichEditCtrl派生类的窗口。 在我的情况下,我有一个调用派生类的Paste()函数的对话框,并返回触发上面发布的代码。 – user276690 2010-02-19 11:01:15

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);  
} 
相关问题