我的 MDI 中的拖放被 CRichEditView 拦截并在 CRichEditView::GetDocument 中崩溃 - 我该如何覆盖它?
Drag and drop in my MDI is intercepted by CRichEditView and crashes in CRichEditView::GetDocument - how do I override it?
我在 MFC 中编写了一个 MDI 应用程序,其中一个文档 window 包含一个 CRichEditView 等。
当我将文件拖到文档 window 中时,拖到 CRichEditView 上时,它在此处崩溃(来自 afxrich.inl):
_AFXRICH_INLINE CRichEditDoc* CRichEditView::GetDocument() const
{
AFXASSUME(m_pDocument != NULL);
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CRichEditDoc))); <<< crash!
return (CRichEditDoc*)m_pDocument;
}
发生崩溃是因为 m_pDocument 不是 CRichEditDoc(它是我的 class 由 CDocument 派生的)。
但是,我不关心 RichEditView/Ctrl,我想要的是当我将文件拖放到应用程序中时,它只是作为文档打开。如果我的 MDI 应用程序是空的,这已经发生了:我将一个文件拖放到应用程序中,它被打开了。如果我在文档 window 已打开时尝试相同的拖放操作,它会如上所述崩溃而不是打开它。
我尝试了多种解决方案来覆盖此行为,但 none 有效:
- 从(我的扩展)CRichEditView 拦截 OnDragEnter
- 使用 ON_NOTIFY_REFLECT(EN_DROPFILES, OnEnDropFiles)
- 从 CRichEditView 调用 CRichEditCtrl 上的 DragAcceptFiles(false)
- 在 CRichEditCtrl 和 CRichEditView 句柄上调用 RevokeDragDrop()
- 从 CMainFrame/CMDIFrameWndEx
调用 DragAcceptFiles(true)
其中 none 能够阻止 RichEdit 进行拖放操作(并崩溃),它们似乎根本没有作用。
我想要的只是 CRichEditView/CRichEditCtrl 不拦截丢弃的文件,而是让它从 CMainFrame/CMDIFrameWndEx 拦截。
有人知道怎么解决吗?
一个 CRichEditView
需要一个 CRichEditDoc
。
如果您不需要 CRichEditView
,请使用您自己的 CView
实现并实现您需要的消息。
这是一个很好的MFC drag&drop sample。
还有一个 detailed description.
经过反复试验,这最终对我有用:
- 使用 CRichEditDoc 而不是 xMRI 建议的 CDocument,这消除了一些问题
- 在class扩展CRichEditView
的OnCreate中添加DragAcceptFiles(false)
- 在 class 扩展 CRichEditView 中实现 QueryAcceptData 并让它 return S_FALSE
- 在 class 扩展 CRichEditView (WM_DROPFILES)
中添加一个 OnDropFiles 处理程序
有了所有这些,每当我将文件放入应用程序时,即使它们在 RichEdit 上,它们仍然会被主框架拦截并在 MDI 中作为新文档打开。这也会禁止在您不放置文件的地方进行拖放(例如,您放置了一些从记事本中拖动的文本)。
我在 MFC 中编写了一个 MDI 应用程序,其中一个文档 window 包含一个 CRichEditView 等。 当我将文件拖到文档 window 中时,拖到 CRichEditView 上时,它在此处崩溃(来自 afxrich.inl):
_AFXRICH_INLINE CRichEditDoc* CRichEditView::GetDocument() const
{
AFXASSUME(m_pDocument != NULL);
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CRichEditDoc))); <<< crash!
return (CRichEditDoc*)m_pDocument;
}
发生崩溃是因为 m_pDocument 不是 CRichEditDoc(它是我的 class 由 CDocument 派生的)。
但是,我不关心 RichEditView/Ctrl,我想要的是当我将文件拖放到应用程序中时,它只是作为文档打开。如果我的 MDI 应用程序是空的,这已经发生了:我将一个文件拖放到应用程序中,它被打开了。如果我在文档 window 已打开时尝试相同的拖放操作,它会如上所述崩溃而不是打开它。 我尝试了多种解决方案来覆盖此行为,但 none 有效:
- 从(我的扩展)CRichEditView 拦截 OnDragEnter
- 使用 ON_NOTIFY_REFLECT(EN_DROPFILES, OnEnDropFiles)
- 从 CRichEditView 调用 CRichEditCtrl 上的 DragAcceptFiles(false)
- 在 CRichEditCtrl 和 CRichEditView 句柄上调用 RevokeDragDrop()
- 从 CMainFrame/CMDIFrameWndEx 调用 DragAcceptFiles(true)
none 能够阻止 RichEdit 进行拖放操作(并崩溃),它们似乎根本没有作用。 我想要的只是 CRichEditView/CRichEditCtrl 不拦截丢弃的文件,而是让它从 CMainFrame/CMDIFrameWndEx 拦截。
有人知道怎么解决吗?
一个 CRichEditView
需要一个 CRichEditDoc
。
如果您不需要 CRichEditView
,请使用您自己的 CView
实现并实现您需要的消息。
这是一个很好的MFC drag&drop sample。
还有一个 detailed description.
经过反复试验,这最终对我有用:
- 使用 CRichEditDoc 而不是 xMRI 建议的 CDocument,这消除了一些问题
- 在class扩展CRichEditView 的OnCreate中添加DragAcceptFiles(false)
- 在 class 扩展 CRichEditView 中实现 QueryAcceptData 并让它 return S_FALSE
- 在 class 扩展 CRichEditView (WM_DROPFILES) 中添加一个 OnDropFiles 处理程序
有了所有这些,每当我将文件放入应用程序时,即使它们在 RichEdit 上,它们仍然会被主框架拦截并在 MDI 中作为新文档打开。这也会禁止在您不放置文件的地方进行拖放(例如,您放置了一些从记事本中拖动的文本)。