if (IID_IUnknown == riid) { *ppv = (LPUNKNOWN) this; } else if (IID_IRichEditOleCallback == riid) { *ppv = (LPRICHEDITOLECALLBACK)this; } if (NULL == *ppv) return ResultFromScode(E_NOINTERFACE); ((LPUNKNOWN) *ppv)->AddRef(); return NOERROR; }ULONG CRichEditOleCallback::AddRef(void) { m_cRef++; return m_cRef; }ULONG CRichEditOleCallback::Release(void) { m_cRef--; if (0 == m_cRef) delete this; return m_cRef; }//关键是这里 HRESULT CRichEditOleCallback::GetNewStorage(LPSTORAGE* ppStg) { if (!ppStg) return E_INVALIDARG; *ppStg = NULL; // // We need to create a new storage for an object to occupy. We're going // to do this the easy way and just create a storage on an HGLOBAL and let // OLE do the management. When it comes to saving things we'll just let // the RichEdit control do the work. Keep in mind this is not efficient, // but this program is just for demonstration. // LPLOCKBYTES pLockBytes; HRESULT hr = CreateILockBytesOnHGlobal(NULL, TRUE, &pLockBytes); if (FAILED(hr)) return hr; hr = StgCreateDocfileOnILockBytes(pLockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, ppStg); pLockBytes->Release(); return (hr); }HRESULT CRichEditOleCallback::GetInPlaceContext(LPOLEINPLACEFRAME*, LPOLEINPLACEUIWINDOW*, LPOLEINPLACEFRAMEINFO) { return S_OK; }HRESULT CRichEditOleCallback::ShowContainerUI(BOOL) { return S_OK; }HRESULT CRichEditOleCallback::QueryInsertObject(LPCLSID /* pclsid */, LPSTORAGE /* pStg */, LONG /* cp */) { return S_OK; }HRESULT CRichEditOleCallback::DeleteObject(LPOLEOBJECT pOleObj) { return S_OK; } HRESULT CRichEditOleCallback::QueryAcceptData(LPDATAOBJECT, CLIPFORMAT*, DWORD, BOOL, HGLOBAL) { return S_OK; }HRESULT CRichEditOleCallback::ContextSensitiveHelp(BOOL) { return E_NOTIMPL; }HRESULT CRichEditOleCallback::GetClipboardData(CHARRANGE*, DWORD, LPDATAOBJECT*){ return E_NOTIMPL; }HRESULT CRichEditOleCallback::GetDragDropEffect(BOOL /* fDrag */, DWORD /* grfKeyState */, LPDWORD /* pdwEffect */) { return E_NOTIMPL; }HRESULT CRichEditOleCallback::GetContextMenu(WORD, LPOLEOBJECT, CHARRANGE*, HMENU*) { return S_OK; }
m_pCallback = new CRichEditOleCallback;
m_pCallback ->AddRef();
m_cRich.SetOLECallback(m_pCallback);RichEditOleCallback.h: interface for the CRichEditOleCallback class.
//
//////////////////////////////////////////////////////////////////////#if !defined(AFX_RICHEDITOLECALLBACK_H__F3691242_2C6E_4A88_A01C_F8C06D6641A5__INCLUDED_)
#define AFX_RICHEDITOLECALLBACK_H__F3691242_2C6E_4A88_A01C_F8C06D6641A5__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000#include <richole.h>
class CRichEditOleCallback : public IRichEditOleCallback
{
protected:
ULONG m_cRef; // Object Reference Count
public:
CRichEditOleCallback();
virtual ~CRichEditOleCallback();
public: // IRichEditOleCallback Interface Members
STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppv);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void); // IRichEditOleCallback Interface Members
STDMETHODIMP GetNewStorage(LPSTORAGE* ppStg);
STDMETHODIMP GetInPlaceContext(LPOLEINPLACEFRAME* ppFrame,
LPOLEINPLACEUIWINDOW* ppDoc,
LPOLEINPLACEFRAMEINFO pFrameInfo);
STDMETHODIMP ShowContainerUI(BOOL fShow);
STDMETHODIMP QueryInsertObject(LPCLSID pclsid, LPSTORAGE pStg, LONG cp);
STDMETHODIMP DeleteObject(LPOLEOBJECT pOleObj);
STDMETHODIMP QueryAcceptData(LPDATAOBJECT pDataObj, CLIPFORMAT* pcfFormat,
DWORD reco, BOOL fReally, HGLOBAL hMetaPict);
STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
STDMETHODIMP GetClipboardData(CHARRANGE* pchrg, DWORD reco,
LPDATAOBJECT* ppDataObject);
STDMETHODIMP GetDragDropEffect(BOOL fDrag, DWORD grfKeyState,
LPDWORD pdwEffect);
STDMETHODIMP GetContextMenu(WORD seltype, LPOLEOBJECT pOleObj,
CHARRANGE* pchrg, HMENU* phMenu);
};#endif // !defined(AFX_RICHEDITOLECALLBACK_H__F3691242_2C6E_4A88_A01C_F8C06D6641A5__INCLU#include "stdafx.h"
#include <ole2.h>
#include <richedit.h>
#include "RichEditOleCallback.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endifCRichEditOleCallback::CRichEditOleCallback()
{
m_cRef = 0;
}CRichEditOleCallback::~CRichEditOleCallback()
{}HRESULT CRichEditOleCallback::QueryInterface(REFIID riid, LPVOID* ppv)
{
*ppv = NULL;
if (IID_IUnknown == riid)
{
*ppv = (LPUNKNOWN) this;
}
else if (IID_IRichEditOleCallback == riid)
{
*ppv = (LPRICHEDITOLECALLBACK)this;
} if (NULL == *ppv)
return ResultFromScode(E_NOINTERFACE); ((LPUNKNOWN) *ppv)->AddRef();
return NOERROR;
}ULONG CRichEditOleCallback::AddRef(void)
{
m_cRef++;
return m_cRef;
}ULONG CRichEditOleCallback::Release(void)
{
m_cRef--; if (0 == m_cRef)
delete this; return m_cRef;
}//关键是这里
HRESULT CRichEditOleCallback::GetNewStorage(LPSTORAGE* ppStg)
{
if (!ppStg)
return E_INVALIDARG; *ppStg = NULL; //
// We need to create a new storage for an object to occupy. We're going
// to do this the easy way and just create a storage on an HGLOBAL and let
// OLE do the management. When it comes to saving things we'll just let
// the RichEdit control do the work. Keep in mind this is not efficient,
// but this program is just for demonstration.
// LPLOCKBYTES pLockBytes;
HRESULT hr = CreateILockBytesOnHGlobal(NULL, TRUE, &pLockBytes);
if (FAILED(hr))
return hr; hr = StgCreateDocfileOnILockBytes(pLockBytes,
STGM_SHARE_EXCLUSIVE | STGM_CREATE |
STGM_READWRITE,
0,
ppStg);
pLockBytes->Release();
return (hr);
}HRESULT CRichEditOleCallback::GetInPlaceContext(LPOLEINPLACEFRAME*,
LPOLEINPLACEUIWINDOW*, LPOLEINPLACEFRAMEINFO)
{
return S_OK;
}HRESULT CRichEditOleCallback::ShowContainerUI(BOOL)
{ return S_OK;
}HRESULT CRichEditOleCallback::QueryInsertObject(LPCLSID /* pclsid */,
LPSTORAGE /* pStg */,
LONG /* cp */)
{
return S_OK;
}HRESULT CRichEditOleCallback::DeleteObject(LPOLEOBJECT pOleObj)
{
return S_OK;
}
HRESULT CRichEditOleCallback::QueryAcceptData(LPDATAOBJECT, CLIPFORMAT*,
DWORD, BOOL, HGLOBAL)
{
return S_OK;
}HRESULT CRichEditOleCallback::ContextSensitiveHelp(BOOL)
{
return E_NOTIMPL;
}HRESULT CRichEditOleCallback::GetClipboardData(CHARRANGE*, DWORD, LPDATAOBJECT*){
return E_NOTIMPL;
}HRESULT CRichEditOleCallback::GetDragDropEffect(BOOL /* fDrag */,
DWORD /* grfKeyState */,
LPDWORD /* pdwEffect */)
{
return E_NOTIMPL;
}HRESULT CRichEditOleCallback::GetContextMenu(WORD,
LPOLEOBJECT,
CHARRANGE*,
HMENU*)
{
return S_OK;
}