#include "headers.h" class CREOleCallback: public IRichEditOleCallback { private: unsigned refCount; IStorage *pictStg; int nextStgId; public: CREOleCallback() { refCount = 1; pictStg = 0; nextStgId = 0; } HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID * ppvObj) { if (IsEqualIID(riid, IID_IRichEditOleCallback)) { *ppvObj = this; this->AddRef(); return S_OK; } *ppvObj = NULL; return E_NOINTERFACE; } ULONG STDMETHODCALLTYPE AddRef() { if (this->refCount == 0) { if (S_OK != StgCreateDocfile(NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &this->pictStg)) this->pictStg = NULL; this->nextStgId = 0; } return ++this->refCount; } ULONG STDMETHODCALLTYPE Release() { if (--this->refCount == 0) { if (this->pictStg) this->pictStg->Release(); } return this->refCount; } HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode) { return S_OK; } HRESULT STDMETHODCALLTYPE DeleteObject(LPOLEOBJECT lpoleobj) { return S_OK; } HRESULT STDMETHODCALLTYPE GetClipboardData(CHARRANGE * lpchrg, DWORD reco, LPDATAOBJECT * lplpdataobj) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE GetContextMenu(WORD seltype, LPOLEOBJECT lpoleobj, CHARRANGE * lpchrg, HMENU * lphmenu) { return E_INVALIDARG; } HRESULT STDMETHODCALLTYPE GetDragDropEffect(BOOL fDrag, DWORD grfKeyState, LPDWORD pdwEffect) { return S_OK; } HRESULT STDMETHODCALLTYPE GetInPlaceContext(LPOLEINPLACEFRAME * lplpFrame, LPOLEINPLACEUIWINDOW * lplpDoc, LPOLEINPLACEFRAMEINFO lpFrameInfo) { return E_INVALIDARG; } HRESULT STDMETHODCALLTYPE GetNewStorage(LPSTORAGE * lplpstg) { WCHAR szwName[64]; char szName[64]; wsprintfA(szName, "s%u", this->nextStgId); MultiByteToWideChar(CP_ACP, 0, szName, -1, szwName, sizeof(szwName) / sizeof(szwName[0])); if (this->pictStg == NULL) return STG_E_MEDIUMFULL; #ifdef UNICODE return this->pictStg->CreateStorage(szwName, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, lplpstg); #else return this->pictStg->CreateStorage(szName, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, lplpstg); #endif } HRESULT STDMETHODCALLTYPE QueryAcceptData(LPDATAOBJECT lpdataobj, CLIPFORMAT * lpcfFormat, DWORD reco, BOOL fReally, HGLOBAL hMetaPict) { return S_OK; } HRESULT STDMETHODCALLTYPE QueryInsertObject(LPCLSID lpclsid, LPSTORAGE lpstg, LONG cp) { return S_OK; } HRESULT STDMETHODCALLTYPE ShowContainerUI(BOOL fShow) { return S_OK; } }; IRichEditOleCallback *reOleCallback = 0; void InitRichEdit(ITextServices *ts) { LRESULT lResult; ts->TxSendMessage(EM_SETOLECALLBACK, 0, (LPARAM)reOleCallback, &lResult); } LRESULT CALLBACK RichEditProxyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ITextServices *ts = (ITextServices *)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (ts && (msg != WM_DESTROY)) { LRESULT lResult; ts->TxSendMessage(msg, wParam, lParam, &lResult); return lResult; } return 1; } void LoadRichEdit() { OleInitialize(NULL); // LoadLibrary("riched20.dll"); reOleCallback = new CREOleCallback; // CoInitializeEx(NULL,COINIT_MULTITHREADED); WNDCLASSEX wcl; wcl.cbSize = sizeof(wcl); wcl.lpfnWndProc = RichEditProxyWndProc; wcl.style = CS_GLOBALCLASS; wcl.cbClsExtra = 0; wcl.cbWndExtra = 0; wcl.hInstance = hInst; wcl.hIcon = NULL; wcl.hCursor = LoadCursor(NULL, IDC_ARROW); wcl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wcl.lpszMenuName = NULL; wcl.lpszClassName = _T("NBRichEditProxyWndClass"); wcl.hIconSm = 0; RegisterClassEx(&wcl); } void UnloadRichEdit() { delete reOleCallback; OleUninitialize(); } HWND CreateProxyWindow(ITextServices *ts) { HWND hwnd = CreateWindow(_T("NBRichEditProxyWndClass"), _T(""), 0, 0, 0, 0, 0, 0, 0, hInst, 0); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)ts); return hwnd; }