diff options
Diffstat (limited to 'libs/mTextControl/src/richeditutils.cpp')
-rw-r--r-- | libs/mTextControl/src/richeditutils.cpp | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/libs/mTextControl/src/richeditutils.cpp b/libs/mTextControl/src/richeditutils.cpp new file mode 100644 index 0000000000..c8867eb17a --- /dev/null +++ b/libs/mTextControl/src/richeditutils.cpp @@ -0,0 +1,140 @@ +#include "stdafx.h" + +class CREOleCallback : public IRichEditOleCallback +{ +private: + unsigned refCount = 1; + IStorage *pictStg = nullptr; + int nextStgId = 0; + +public: + CREOleCallback() {} + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID * ppvObj) + { + if (IsEqualIID(riid, IID_IRichEditOleCallback)) { + *ppvObj = this; + this->AddRef(); + return S_OK; + } + *ppvObj = nullptr; + return E_NOINTERFACE; + } + + ULONG STDMETHODCALLTYPE AddRef() + { + if (this->refCount == 0) { + if (S_OK != StgCreateDocfile(nullptr, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &this->pictStg)) + this->pictStg = nullptr; + 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) + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE DeleteObject(LPOLEOBJECT) + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE GetClipboardData(CHARRANGE *, DWORD, LPDATAOBJECT *) + { + return E_NOTIMPL; + } + + HRESULT STDMETHODCALLTYPE GetContextMenu(WORD, LPOLEOBJECT, CHARRANGE *, HMENU *) + { + return E_INVALIDARG; + } + + HRESULT STDMETHODCALLTYPE GetDragDropEffect(BOOL, DWORD, LPDWORD) + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE GetInPlaceContext(LPOLEINPLACEFRAME *, LPOLEINPLACEUIWINDOW *, LPOLEINPLACEFRAMEINFO) + { + return E_INVALIDARG; + } + + HRESULT STDMETHODCALLTYPE GetNewStorage(LPSTORAGE * lplpstg) + { + wchar_t sztName[64]; + mir_snwprintf(sztName, L"s%u", this->nextStgId); + if (this->pictStg == nullptr) + return STG_E_MEDIUMFULL; + + return this->pictStg->CreateStorage(sztName, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, lplpstg); + + } + + HRESULT STDMETHODCALLTYPE QueryAcceptData(LPDATAOBJECT, CLIPFORMAT *, DWORD, BOOL, HGLOBAL) + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE QueryInsertObject(LPCLSID, LPSTORAGE, LONG) + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE ShowContainerUI(BOOL) + { + return S_OK; + } +}; + +static CREOleCallback reOleCallback; + +void InitRichEdit(ITextServices *ts) +{ + LRESULT lResult; + ts->TxSendMessage(EM_SETOLECALLBACK, 0, (LPARAM)&reOleCallback, &lResult); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static ATOM winClass = 0; + +static 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; +} + +HWND CreateProxyWindow(ITextServices *ts) +{ + if (winClass == 0) { + WNDCLASSEX wcl = {}; + wcl.cbSize = sizeof(wcl); + wcl.lpfnWndProc = RichEditProxyWndProc; + wcl.style = CS_GLOBALCLASS; + wcl.hInstance = g_hInst; + wcl.hCursor = LoadCursor(nullptr, IDC_ARROW); + wcl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); + wcl.lpszClassName = L"NBRichEditProxyWndClass"; + winClass = RegisterClassEx(&wcl); + } + + HWND hwnd = CreateWindow(L"NBRichEditProxyWndClass", L"", 0, 0, 0, 0, 0, nullptr, nullptr, g_hInst, nullptr); + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)ts); + return hwnd; +} |