- 不能够自动初始化
- 不能够接受TAB键
- 不能够通过属性设置自动换行
- 不能显示图片等其他OLE对象
- 不能够使用Ctrl+C来实现拷贝
不能够自动初始化 当我第一次将Rich Edit控件放在资源窗体上的时候,发现程序根本就不能运行。后来才找到原因,原来Rich Edit 控件是Ole类型的控件。在加载Rich Edit 控件的时候,必须进行初始化。代码如下: BOOLCTestApp::InitInstance(){ ..... AfxInitRichEdit(); } 不能够接受TAB键 将 RichEdit控件放到资源窗体上的时候,发现它的属性页中并没有设置接受TAB键的设置,导致当把焦点放到Rich Edit 控件上的时候,一按tab键,焦点就移动到下一个控件上面去了。 具体解决方法就是重载Rich Edit控件的OnGetDlgCode: 例子代码: .h文件: class CMyRichEdit : public CRichEditCtrl{ ........ afx_msg UINT OnGetDlgCode( ); ........ } .cpp文件: BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl) ON_WM_GETDLGCODE( ) END_MESSAGE_MAP() UINT COleRichEditCtrl::OnGetDlgCode( ){ return DLGC_WANTTAB; } 不能够通过属性设置自动换行 当把Rich Edit控件放到资源窗体上的时候,发现在它的属性窗体中并没有设置Rich Edit控件自动换行的属性设置。要达到这一目的,例子代码如下: BOOL CTestDlg::InitDialog(){ ............. //m_RichEdit为窗体类的成员变量 this->m_RichEdit.SetTargetDevice(NULL,0); ............ } 不能显示图片等其他OLE对象 MFC提供的CRichEditCtrl没有提供直接显示图片等OLE对象的属性或方法设置,但是提供了一个接口SetOLECallback( IRichEditOleCallback* pCallback ); 要让CRichEditCtrl显示图片,就得在IRichEditOleCallback上下功夫。 IRichEditOleCallback是windows中的接口,它的定义如下: ContextSensitiveHelp: 通过该方法通知应用程序它将以上下文关联方式调度帮助。 DeleteObject: 通过该方法发出通知:一个对象即将从RichEdit控件中删除 GetClipboardData: 通过该方法允许RichEdit的客户端(调用程序)提供自己的粘贴对象 GetContextMenu: 通过该方法向应用程序提出通过鼠标右键事件来获取上下文菜单的请求 GetDragDropEffect: 通过该方法允许RichEdit的客户端(调用程序)设置拖动操作的效果 GetInPlaceContext: 通过该方法提供了应用程序级和文档级接口,以及必要的支持In-place激活的信息 GetNewStrorage: 通过该方法存储从粘贴板或超文本流(RTF)中读取的新对象 QueryAcceptData: 通过该方法决定在粘贴操作或拖放操作中引入的数据是否可以被接受。 QueryInsertObject: 通过该方法向应用程序询问某个对象是否可以被插入 ShowContainerUI: 通过该方法告知应用程序是否显示自己的操作界面 大致了解了IRichEditOleCallback接口后,就应该清楚,要显示图片等ole对象,至少应该实现GetNewStorage方法,因为该方法是存储ole对象的接口方法。 以下是接口声明的代码: interface IExRichEditOleCallback : IRichEditOleCallback { public: IExRichEditOleCallback(); virtual ~IExRichEditOleCallback(); int m_iNumStorages; IStorage* pStorage; DWORD m_dwRef; virtual HRESULT STDMETHODCALLTYPE GetNewStorage(LPSTORAGE* lplpstg); virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject); virtual ULONG STDMETHODCALLTYPE AddRef(); virtual ULONG STDMETHODCALLTYPE Release(); virtual HRESULT STDMETHODCALLTYPE GetInPlaceContext(LPOLEINPLACEFRAME FAR *lplpFrame, LPOLEINPLACEUIWINDOW FAR *lplpDoc, LPOLEINPLACEFRAMEINFO lpFrameInfo); virtual HRESULT STDMETHODCALLTYPE ShowContainerUI(BOOL fShow); virtual HRESULT STDMETHODCALLTYPE QueryInsertObject(LPCLSID lpclsid, LPSTORAGE lpstg, LONG cp); virtual HRESULT STDMETHODCALLTYPE DeleteObject(LPOLEOBJECT lpoleobj); virtual HRESULT STDMETHODCALLTYPE QueryAcceptData(LPDATAOBJECT lpdataobj, CLIPFORMAT FAR *lpcfFormat, DWORD reco, BOOL fReally, HGLOBAL hMetaPict); virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode); virtual HRESULT STDMETHODCALLTYPE GetClipboardData(CHARRANGE FAR *lpchrg, DWORD reco, LPDATAOBJECT FAR *lplpdataobj); virtual HRESULT STDMETHODCALLTYPE GetDragDropEffect(BOOL fDrag, DWORD grfKeyState, LPDWORD pdwEffect); virtual HRESULT STDMETHODCALLTYPE GetContextMenu(WORD seltyp, LPOLEOBJECT lpoleobj, CHARRANGE FAR *lpchrg, HMENU FAR *lphmenu); } 关于接口的实现,将被附在最后的附录中。 不能够使用Ctrl+C来实现拷贝 实际上,CRichEditCtrl本身是支持Ctrl+C实现拷贝功能的,但是当我在CRichiEditCtrl的继承类中使用了IRichiEditCallback接口后,它就不在支持Ctrl+C实现拷贝功能了。我想问题就出在IRichEditCallback接口上。 仔细看了一遍它的帮助文档,我发现问题就出在GetClipboardData上,我没有在它的实现方法中写代码,只是返回了S_OK,如果要处理Ctrl+C,就必须返回E_NOTIMPL。 以上是我近几天的开发经历,与大家分享,还希望路过的高手多多指教。 在以下关于RichEdit的代码例子中,我参考了Mike O'Neill 的代码,再次谢谢他的贡献。 http://dqifa.blog.163.com/blog/static/492583652008425103543391/ |