.NET中的RichTextEdit
控件执行我需要为我的应用程序执行的操作的99%,除了一些小事情:
据我所知,微软没有在你可以使用的控件上提供任何类型的“无图像”属性,这是理想的。
我的想法是我可以回复“textChanged
”事件,然后删除图像和/或重置文本样式,然后再将其渲染到屏幕上。当然这将是一个完全黑客。一方面,用户的拖放鼠标图标表示图像可以放置,而实际上并非如此。
要简短地提一个问题,有没有办法设置一个过滤器,RichTextEdit
控件可以通过复制和粘贴,拖放和拖放来导入哪种类型的数据类型?
答案 0 :(得分:0)
这是可能的;但是,您必须离开.NET RichTextBox接口的范围来执行此操作,因为回调需要存在于IRichEditOleCallback COM接口中。
为了让您了解ATL C ++中涉及的内容(不保证这会起作用,但是您必须对其进行调整,但是您需要创建一个简单的OL&#COM; COM对象无论你在哪种语言中工作:
#include <windows.h>
#include <Richole.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlcomcli.h>
#include <string>
struct RattyRichEditOleCallbackImpl: public CComObjectRoot, public IRichEditOleCallback
{
HWND* hRichEdit;
RattyRichEditOleCallbackImpl(): hRichEdit(NULL) {}
HRESULT SetRichEditCtl(HWND *hCtl)
{
hRichEdit = hCtl;
return S_OK;
}
HRESULT QueryAcceptData(LPDATAOBJECT lpdataobj, CLIPFORMAT* lpcfFormat, DWORD reco, BOOL fReally, HGLOBAL hMetaPict)
{
// This list of image formats covers all the standard ones listed in
// the [MSDN docs](https://msdn.microsoft.com/en-us/library/ff729168.aspx)
// if there are more CF_blahs that correspond to images, add them here
if (*lpcfFormat == CF_DIB || *lpcfFormat == CF_DIBV5
|| *lpcfFormat == CF_BITMAP || *lpcfFormat == CF_TIFF
|| *lpcfFormat == CF_ENHMETAFILE || *lpcfFormat == CF_METAFILEPICT
|| *lpcfFormat == CF_PALETTE || *lpcfFormat == CF_DSPBITMAP
|| *lpcfFormat == CF_DSPMETAFILEPICT || *lpcfFormat == CF_DSPENHMETAFILE
|| *lpcfFormat >= CF_GDIOBJECTFIRST || *lpcfFormat <= CF_GDIOBJECTLAST)
{
// Bail out with an error HRESULT because we don't want some stinkin' image in our rich edit control!
return E_NOTIMPL;
}
// Try to convert anything else to plain ol' Unicode text
else
{
*lpcfFormat = CF_UNICODETEXT;
// Are we being asked to paste this?
if (fReally)
{
// Insert the data as text with the default style
FORMATETC fmt = {*lpcfFormat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM stg;
HRESULT res = E_UNEXPECTED;
if (hRichEdit && (res = lpdataobj->GetData(fmt, stg)) == S_OK)
{
// Lock the HGLOBAL as it might not be ordinary heap mem
WCHAR* pText = GlobalLock(stg.hGlobal);
if (!pText)
{
ReleaseStgMedium(stg);
return res;
}
std::wstring text(pText);
// Do a bit of selection trickiness to ensure we have the default text style -- we can't just EM_PASTESPECIAL due to recursion issues
DWORD cursorPos, selPos;
SendMessageW(hRichEdit, EM_GETSEL, &cursorPos, &selPos);
if (cursorPos == selPos)
{
// No selection, so select the character after the cursor, fetch it, and append it to the text
SendMessageW(hRichEdit, EM_SETSEL, cursorPos, cursorPos + 1);
WCHAR buffer[2];
TEXTRANGEW tr = {{cursorPos, cursorPos + 1}, buffer};
SendMessageW(hRichEdit, EM_GETTEXTRANGE, 0, &tr);
text.append(buffer[0]);
}
// Now that we have ourselves a selection -- we can unformat it then replace it
CHARFORMAT2 cf;
cf.cbSize = sizeof(CHARFORMAT2);
SendMessageW(hRichEdit, EM_GETCHARFORMAT, SCF_DEFAULT, &cf);
SendMessageW(hRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, &cf);
SendMessageW(hRichEdit, EM_REPLACESEL, TRUE, text.c_str());
GlobalUnlock(stg.hGlobal);
ReleaseStgMedium(stg);
// We did the work ourselves, so don't ask the control to do anything for us, unless something broke that is
res = S_FALSE;
}
return res;
}
else
{
// Have the control check for us to see if it can coerce what's on the clipboard to CF_UNICODETEXT
return S_OK;
}
}
}
};
typedef CComObject<RattyRichEditOleCallbackImpl> RattyRichEditOleCallback;
inline void AttachRattyCallbackToRichEdit(HWND *hRichEdit)
{
RattyRichEditOleCallback* pCb;
if (RattyRichEditOleCallback::CreateInstance(&pCb) == S_OK)
{
CComPtr cb(pCb);
cb->SetRichEditCtl(hRichEdit);
SendMessage(hRichEdit, EM_SETOLECALLBACK, 0, cb);
}
}