小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

數(shù)CRichEditCtrl的先天不足及進(jìn)化方法_VC文摘_開發(fā)文摘_軟件開發(fā)_天新網(wǎng)

 wangzai117 2007-01-25
數(shù)CRichEditCtrl的先天不足及進(jìn)化方法
http://dev. 2006年06月14日 火狐設(shè)計

今天一位同事要離開公司到電腦報去做事,中午大家為他舉行了一個歡送會,大家都喝得挺多。
送走那位同事之后,我回到了辦公室,覺得頭有點暈,不想做事,于是就把集聚在心中,這幾天對MFC框架中的CRichEditCtrl的不滿,發(fā)泄在這篇blog上,希望前輩們能夠多指教,也希望能夠為后來者掃除一些MFC開發(fā)歷程中的障礙。

  1. 不能夠自動初始化
  2. 不能夠接受TAB鍵
  3. 不能夠通過屬性設(shè)置自動換行
  4. 不能顯示圖片等其他OLE對象
  5. 不能夠使用Ctrl+C來實現(xiàn)拷貝

不能夠自動初始化

當(dāng)我第一次將Rich Edit控件放在資源窗體上的時候,發(fā)現(xiàn)程序根本就不能運行。后來才找到原因,原來Rich Edit 控件是Ole類型的控件。在加載Rich Edit 控件的時候,必須進(jìn)行初始化。代碼如下:
BOOLCTestApp::InitInstance(){

          .....
          AfxInitRichEdit();

}

 不能夠接受TAB鍵

將 RichEdit控件放到資源窗體上的時候,發(fā)現(xiàn)它的屬性頁中并沒有設(shè)置接受TAB鍵的設(shè)置,導(dǎo)致當(dāng)把焦點放到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;


}

 不能夠通過屬性設(shè)置自動換行

當(dāng)把Rich Edit控件放到資源窗體上的時候,發(fā)現(xiàn)在它的屬性窗體中并沒有設(shè)置Rich Edit控件自動換行的屬性設(shè)置。要達(dá)到這一目的,例子代碼如下:
BOOL CTestDlg::InitDialog(){

          .............
          //m_RichEdit為窗體類的成員變量
          this->m_RichEdit.SetTargetDevice(NULL,0);
          ............

}

不能顯示圖片等其他OLE對象

MFC提供的CRichEditCtrl沒有提供直接顯示圖片等OLE對象的屬性或方法設(shè)置,但是提供了一個接口SetOLECallback( IRichEditOleCallback* pCallback );
要讓CRichEditCtrl顯示圖片,就得在IRichEditOleCallback上下功夫。
IRichEditOleCallback是Windows中的接口,它的定義如下:
ContextSensitiveHelp:
    通過該方法通知應(yīng)用程序它將以上下文關(guān)聯(lián)方式調(diào)度幫助。
DeleteObject:
    通過該方法發(fā)出通知:一個對象即將從RichEdit控件中刪除
GetCliPBoardData:
    通過該方法允許RichEdit的客戶端(調(diào)用程序)提供自己的粘貼對象
GetContextMenu:
    通過該方法向應(yīng)用程序提出通過鼠標(biāo)右鍵事件來獲取上下文菜單的請求
GetDragDropEffect:
    通過該方法允許RichEdit的客戶端(調(diào)用程序)設(shè)置拖動操作的效果
GetInPlaceContext:
    通過該方法提供了應(yīng)用程序級和文檔級接口,以及必要的支持In-place激活的信息
GetNewStrorage:
    通過該方法存儲從粘貼板或超文本流(RTF)中讀取的新對象
QueryAcceptData:
    通過該方法決定在粘貼操作或拖放操作中引入的數(shù)據(jù)是否可以被接受。
QueryInsertObject:
    通過該方法向應(yīng)用程序詢問某個對象是否可以被插入
ShowContainerUI:
   
通過該方法告知應(yīng)用程序是否顯示自己的操作界面

大致了解了IRichEditOleCallback接口后,就應(yīng)該清楚,要顯示圖片等ole對象,至少應(yīng)該實現(xiàn)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);

}
關(guān)于接口的實現(xiàn),將被附在最后的附錄中。


不能夠使用Ctrl+C來實現(xiàn)拷貝

實際上,CRichEditCtrl本身是支持Ctrl+C實現(xiàn)拷貝功能的,但是當(dāng)我在CRichiEditCtrl的繼承類中使用了IRichiEditCallback接口后,它就不在支持Ctrl+C實現(xiàn)拷貝功能了。我想問題就出在IRichEditCallback接口上。
仔細(xì)看了一遍它的幫助文檔,我發(fā)現(xiàn)問題就出在GetClipboardData上,我沒有在它的實現(xiàn)方法中寫代碼,只是返回了S_OK,如果要處理Ctrl+C,就必須返回E_NOTIMPL。

以上是我近幾天的開發(fā)經(jīng)歷,與大家分享,還希望路過的高手多多指教。
在以下關(guān)于RichEdit的代碼例子中,我參考了Mike O‘Neill 的代碼,再次謝謝他的貢獻(xiàn)。

附錄
.h文件

#if !defined(AFX_OLERICHEDITCTRL_H__3DFF15EE_7336_4297_9620_7F00B611DAA1__INCLUDED_)
#define AFX_OLERICHEDITCTRL_H__3DFF15EE_7336_4297_9620_7F00B611DAA1__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// OleRichEditCtrl.h : header file
//


#include <richole.h>


/////////////////////////////////////////////////////////////////////////////
// COleRichEditCtrl window

class COleRichEditCtrl : public CRichEditCtrl
{
// Construction
public:
 COleRichEditCtrl();
 virtual ~COleRichEditCtrl();

 long StreamInFromResource(int iRes, LPCTSTR sType);

 

protected:
 
 static DWORD CALLBACK readFunction(DWORD dwCookie,
   LPBYTE lpBuf,   // the buffer to fill
   LONG nCount,   // number of bytes to read
   LONG* nRead);   // number of bytes actually read

 interface IExRichEditOleCallback; // forward declaration (see below in this header file)

 IExRichEditOleCallback* m_pIRichEditOleCallback;
 BOOL m_bCallbackSet;
 
 
 interface IExRichEditOleCallback : public 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);
 };
 

public:

// Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(COleRichEditCtrl)
 protected:
 virtual void PreSubclassWindow();
 //}}AFX_VIRTUAL

// Implementation
public:


 // Generated message map functions
protected:
 //{{AFX_MSG(COleRichEditCtrl)
 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
 
 //}}AFX_MSG
 afx_msg UINT OnGetDlgCode( );
 DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_OLERICHEDITCTRL_H__3DFF15EE_7336_4297_9620_7F00B611DAA1__INCLUDED_)

 

.cpp文件

// OleRichEditCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "OleRichEditCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// COleRichEditCtrl

COleRichEditCtrl::COleRichEditCtrl()
{
 m_bCallbackSet = FALSE;
}

COleRichEditCtrl::~COleRichEditCtrl()
{
 // IExRichEditOleCallback class is a reference-counted class 
 // which deletes itself and for which delete should not be called

 // delete m_pIRichEditOleCallback;
}


BEGIN_MESSAGE_MAP(COleRichEditCtrl, CRichEditCtrl)
 //{{AFX_MSG_MAP(COleRichEditCtrl)
 ON_WM_CREATE()
 //}}AFX_MSG_MAP
 ON_WM_GETDLGCODE( )
END_MESSAGE_MAP()
//


int COleRichEditCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CRichEditCtrl::OnCreate(lpCreateStruct) == -1)
   return -1;
  
 // m_pIRichEditOleCallback should have been created in PreSubclassWindow

  ASSERT( m_pIRichEditOleCallback != NULL ); 

 // set the IExRichEditOleCallback pointer if it wasn‘t set
 // successfully in PreSubclassWindow

 if ( !m_bCallbackSet )
 {
  SetOLECallback( m_pIRichEditOleCallback );
 }
  
  return 0;
}

void COleRichEditCtrl::PreSubclassWindow()
{
 // base class first
 CRichEditCtrl::PreSubclassWindow(); 

 m_pIRichEditOleCallback = NULL;
 m_pIRichEditOleCallback = new IExRichEditOleCallback;
 ASSERT( m_pIRichEditOleCallback != NULL );

 m_bCallbackSet = SetOLECallback( m_pIRichEditOleCallback );
}


long COleRichEditCtrl::StreamInFromResource(int iRes, LPCTSTR sType)
{
 HINSTANCE hInst = AfxGetInstanceHandle();
 HRSRC hRsrc = ::FindResource(hInst,
  MAKEINTRESOURCE(iRes), sType);
 
 DWORD len = SizeofResource(hInst, hRsrc);
 BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
 ASSERT(lpRsrc);
 
 CMemFile mfile;
 mfile.Attach(lpRsrc, len);

 EDITSTREAM es;
 es.pfnCallback = readFunction;
 es.dwError = 0;
 es.dwCookie = (DWORD) &mfile;

 return StreamIn( SF_RTF, es );
}


/* static */
DWORD CALLBACK COleRichEditCtrl::readFunction(DWORD dwCookie,
   LPBYTE lpBuf,   // the buffer to fill
   LONG nCount,   // number of bytes to read
   LONG* nRead)   // number of bytes actually read
{
 CFile* fp = (CFile *)dwCookie;
 *nRead = fp->Read(lpBuf,nCount);
 return 0;
}

/////////////////////////////////////////////////////////////////////////////

COleRichEditCtrl::IExRichEditOleCallback::IExRichEditOleCallback()
{
 pStorage = NULL;
 m_iNumStorages = 0;
 m_dwRef = 0;

 // set up OLE storage

 HRESULT hResult = ::StgCreateDocfile(NULL,
  STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE /*| STGM_DELETEONRELEASE */|STGM_CREATE ,
  0, &pStorage );

 if ( pStorage == NULL ||
  hResult != S_OK )
 {
  AfxThrowOleException( hResult );
 }
}

COleRichEditCtrl::IExRichEditOleCallback::~IExRichEditOleCallback()
{
}

HRESULT STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::GetNewStorage(LPSTORAGE* lplpstg)
{
 m_iNumStorages++;
 WCHAR tName[50];
 swprintf(tName, L"REOLEStorage%d", m_iNumStorages);

 HRESULT hResult = pStorage->CreateStorage(tName,
  STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE ,
  0, 0, lplpstg );

 if (hResult != S_OK )
 {
  ::AfxThrowOleException( hResult );
 }

 return hResult;
}

HRESULT STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::QueryInterface(REFIID iid, void ** ppvObject)
{

 HRESULT hr = S_OK;
 *ppvObject = NULL;
 
 if ( iid == IID_IUnknown ||
  iid == IID_IRichEditOleCallback )
 {
  *ppvObject = this;
  AddRef();
  hr = NOERROR;
 }
 else
 {
  hr = E_NOINTERFACE;
 }

 return hr;
}

 

ULONG STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::AddRef()
{
 return ++m_dwRef;
}

 

ULONG STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::Release()
{
 if ( --m_dwRef == 0 )
 {
  delete this;
  return 0;
 }

 return m_dwRef;
}


HRESULT STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::GetInPlaceContext(LPOLEINPLACEFRAME FAR *lplpFrame,
 LPOLEINPLACEUIWINDOW FAR *lplpDoc, LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
 return S_OK;
}


HRESULT STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::ShowContainerUI(BOOL fShow)
{
 return S_OK;
}

 

HRESULT STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::QueryInsertObject(LPCLSID lpclsid, LPSTORAGE lpstg, LONG cp)
{
 return S_OK;
}


HRESULT STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::DeleteObject(LPOLEOBJECT lpoleobj)
{
 return S_OK;
}

 

HRESULT STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::QueryAcceptData(LPDATAOBJECT lpdataobj, CLIPFORMAT FAR *lpcfFormat,
 DWORD reco, BOOL fReally, HGLOBAL hMetaPict)
{
 return S_OK;
}


HRESULT STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::ContextSensitiveHelp(BOOL fEnterMode)
{
 return S_OK;
}

 

HRESULT STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::GetClipboardData(CHARRANGE FAR *lpchrg, DWORD reco, LPDATAOBJECT FAR *lplpdataobj)
{
 return E_NOTIMPL;
}


HRESULT STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::GetDragDropEffect(BOOL fDrag, DWORD grfKeyState, LPDWORD pdwEffect)
{
 return S_OK;
}

HRESULT STDMETHODCALLTYPE
COleRichEditCtrl::IExRichEditOleCallback::GetContextMenu(WORD seltyp, LPOLEOBJECT lpoleobj, CHARRANGE FAR *lpchrg,
 HMENU FAR *lphmenu)
{
 return S_OK;
}

// TabRichEditCtrl 消息處理程序
UINT COleRichEditCtrl::OnGetDlgCode( ){

 return DLGC_WANTTAB;
}

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多