summaryrefslogtreecommitdiff
path: root/libs/mTextControl/src/richeditutils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/mTextControl/src/richeditutils.cpp')
-rw-r--r--libs/mTextControl/src/richeditutils.cpp140
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;
+}