diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/mTextControl/mtextcontrol.vcxproj | 1 | ||||
-rw-r--r-- | libs/mTextControl/mtextcontrol.vcxproj.filters | 3 | ||||
-rw-r--r-- | libs/mTextControl/src/FormattedTextDraw.cpp | 3 | ||||
-rw-r--r-- | libs/mTextControl/src/FormattedTextDraw.h | 1 | ||||
-rw-r--r-- | libs/mTextControl/src/ImageDataObjectHlp.cpp | 196 | ||||
-rw-r--r-- | libs/mTextControl/src/ImageDataObjectHlp.h | 5 | ||||
-rw-r--r-- | libs/mTextControl/src/dataobject.cpp | 123 | ||||
-rw-r--r-- | libs/mTextControl/src/dataobject.h | 65 | ||||
-rw-r--r-- | libs/mTextControl/src/fancy_rtf.cpp | 8 | ||||
-rw-r--r-- | libs/mTextControl/src/services.cpp | 30 | ||||
-rw-r--r-- | libs/mTextControl/src/textcontrol.cpp | 2 |
11 files changed, 284 insertions, 153 deletions
diff --git a/libs/mTextControl/mtextcontrol.vcxproj b/libs/mTextControl/mtextcontrol.vcxproj index 360adeabf6..b015728e23 100644 --- a/libs/mTextControl/mtextcontrol.vcxproj +++ b/libs/mTextControl/mtextcontrol.vcxproj @@ -39,6 +39,7 @@ </ClCompile> <ClCompile Include="src\textcontrol.cpp" /> <ClCompile Include="src\textusers.cpp" /> + <ClInclude Include="src\dataobject.h" /> <ClInclude Include="src\FormattedTextDraw.h" /> <ClInclude Include="src\ImageDataObjectHlp.h" /> <ClInclude Include="src\services.h" /> diff --git a/libs/mTextControl/mtextcontrol.vcxproj.filters b/libs/mTextControl/mtextcontrol.vcxproj.filters index 8bba4a0916..e05342e6d8 100644 --- a/libs/mTextControl/mtextcontrol.vcxproj.filters +++ b/libs/mTextControl/mtextcontrol.vcxproj.filters @@ -52,5 +52,8 @@ <ClInclude Include="src\textusers.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="src\dataobject.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> </Project>
\ No newline at end of file diff --git a/libs/mTextControl/src/FormattedTextDraw.cpp b/libs/mTextControl/src/FormattedTextDraw.cpp index e093048160..16008cc7c3 100644 --- a/libs/mTextControl/src/FormattedTextDraw.cpp +++ b/libs/mTextControl/src/FormattedTextDraw.cpp @@ -6,6 +6,7 @@ #include "stdafx.h" #include "FormattedTextDraw.h" +#include "ImageDataObjectHlp.h" const IID IID_ITextServices = { // 8d33f740-cf58-11ce-a89d-00aa006cadc5 0x8d33f740, @@ -54,6 +55,8 @@ CFormattedTextDraw::CFormattedTextDraw() CFormattedTextDraw::~CFormattedTextDraw() { + if (m_hwndParent) + CleanupEmfCache(m_hwndParent); if (m_spTextServices != nullptr) m_spTextServices->Release(); if (m_spTextDocument != nullptr) diff --git a/libs/mTextControl/src/FormattedTextDraw.h b/libs/mTextControl/src/FormattedTextDraw.h index edfcac0d2f..82993e903a 100644 --- a/libs/mTextControl/src/FormattedTextDraw.h +++ b/libs/mTextControl/src/FormattedTextDraw.h @@ -48,6 +48,7 @@ public: __forceinline bool isNative() const { return m_bNative; } __forceinline void setParentWnd(HWND hwnd, RECT rect) { m_hwndParent = hwnd; m_rcClient = rect; } + __forceinline HWND getParentWnd() { return m_hwndParent; } // IUnknown HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void __RPC_FAR *__RPC_FAR *ppvObject) override diff --git a/libs/mTextControl/src/ImageDataObjectHlp.cpp b/libs/mTextControl/src/ImageDataObjectHlp.cpp index 71f5824d82..eac28e6c6d 100644 --- a/libs/mTextControl/src/ImageDataObjectHlp.cpp +++ b/libs/mTextControl/src/ImageDataObjectHlp.cpp @@ -22,11 +22,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "stdafx.h" #include "ImageDataObjectHlp.h" +#include "dataobject.h" + +// cache up to 1000 objects +#define MAX_CACHE_SIZE 2000 struct EMFCACHE { - HENHMETAFILE hEmf; + CEMFObject *pEmfObj; + IStorage *pStorage; + IOleObject *pOleObject; HICON hIcon; + HWND hwnd; EMFCACHE *prev; EMFCACHE *next; } *emfCache = nullptr; @@ -37,133 +44,150 @@ void UnloadEmfCache() { while (emfCache) { EMFCACHE *tmp = emfCache->next; + emfCache->pEmfObj->Release(); + emfCache->pStorage->Release(); delete emfCache; emfCache = tmp; } } -HENHMETAFILE CacheIconToEmf(HICON hIcon) +void CleanupEmfCache(HWND hwnd) +{ + EMFCACHE *p = emfCache; + while (p) { + if (p->hwnd == hwnd) { + EMFCACHE *tmp = p; + if (p->prev) p->prev->next = p->next; + if (p->next) p->next->prev = p->prev; + p = p->next; + if (tmp == emfCache) emfCache = p; + tmp->pEmfObj->Release(); + tmp->pOleObject->Release(); + tmp->pStorage->Release(); + delete tmp; + emfCacheSize--; + } + else { + p = p->next; + } + } +} + +IDataObject *CacheIconToIDataObject(HWND hwnd, HICON hIcon, IOleClientSite *pOleClientSite, IStorage **ppStorage, IOleObject **ppOleObject) { - HENHMETAFILE result = nullptr; + IDataObject *result = nullptr; + static const FORMATETC lc_format[] = + { + { CF_ENHMETAFILE, nullptr, DVASPECT_CONTENT, -1, TYMED_ENHMF } + }; + mir_cslock lck(csEmfCache); for (EMFCACHE *p = emfCache; p; p = p->next) - if (p->hIcon == hIcon) { - if (p->prev) { - p->prev->next = p->next; - if (p->next) p->next->prev = p->prev; - p->prev = nullptr; - emfCache->prev = p; - p->next = emfCache; - emfCache = p; - result = CopyEnhMetaFile(emfCache->hEmf, nullptr); - break; - } + if (p->hIcon == hIcon && p->hwnd == hwnd) { + if (p->prev) p->prev->next = p->next; + if (p->next) p->next->prev = p->prev; + p->prev = nullptr; + emfCache->prev = p; + p->next = emfCache; + emfCache = p; + result = emfCache->pEmfObj; + *ppStorage = emfCache->pStorage; + *ppOleObject = emfCache->pOleObject; + break; } // cache new item if (!result) { EMFCACHE *newItem = new EMFCACHE; + + LPLOCKBYTES lpLockBytes = nullptr; + SCODE sc = CreateILockBytesOnHGlobal(nullptr, TRUE, &lpLockBytes); + if (sc != S_OK) { + delete newItem; + return nullptr; + } + + sc = StgCreateDocfileOnILockBytes(lpLockBytes, + STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &newItem->pStorage); + + lpLockBytes->Release(); + + if (sc != S_OK) { + delete newItem; + return nullptr; + } + + HDC emfdc = CreateEnhMetaFile(nullptr, nullptr, nullptr, L"icon"); + DrawIconEx(emfdc, 0, 0, (HICON)hIcon, 16, 16, 0, nullptr, DI_NORMAL); + newItem->pEmfObj = new CEMFObject(CloseEnhMetaFile(emfdc)); + newItem->hIcon = hIcon; + newItem->hwnd = hwnd; + + sc = OleCreateStaticFromData(newItem->pEmfObj, IID_IOleObject, OLERENDER_FORMAT, + (LPFORMATETC)lc_format, pOleClientSite, newItem->pStorage, (void **)&newItem->pOleObject); + + if (sc != S_OK) { + newItem->pStorage->Release(); + newItem->pEmfObj->Release(); + delete newItem; + return nullptr; + } + + OleSetContainedObject(newItem->pOleObject, TRUE); + newItem->prev = nullptr; newItem->next = emfCache; if (emfCache) emfCache->prev = newItem; emfCache = newItem; emfCacheSize++; - HDC emfdc = CreateEnhMetaFile(nullptr, nullptr, nullptr, L"icon"); - DrawIconEx(emfdc, 0, 0, (HICON)hIcon, 16, 16, 0, nullptr, DI_NORMAL); - emfCache->hIcon = hIcon; - emfCache->hEmf = CloseEnhMetaFile(emfdc); - result = CopyEnhMetaFile(emfCache->hEmf, nullptr); + result = emfCache->pEmfObj; + *ppStorage = emfCache->pStorage; + *ppOleObject = emfCache->pOleObject; } - // tail cutoff - if (emfCacheSize > 20) { + // tail cutoff - cache up to MAX_CACHE_SIZE data sources (smaller than 1/2 of 10000 GDI objects) + if (emfCacheSize > MAX_CACHE_SIZE) { int n = 0; EMFCACHE *p; for (p = emfCache; p; p = p->next) - if (++n > 20) + if (++n > MAX_CACHE_SIZE) break; + while (p->next) { EMFCACHE *tmp = p->next; p->next = p->next->next; + tmp->pEmfObj->Release(); + tmp->pStorage->Release(); delete tmp; } - if (p->next) p->next->prev = p; - emfCacheSize = 20; + if (p->next) + p->next->prev = p; + emfCacheSize = MAX_CACHE_SIZE; } return result; } -HRESULT CreateDataObject(const FORMATETC *fmtetc, const STGMEDIUM *stgmed, UINT count, IDataObject **ppDataObject); - // returns true on success, false on failure -//bool InsertBitmap(IRichEditOle* pRichEditOle, HBITMAP hBitmap, HGLOBAL hGlobal) -bool InsertBitmap(IRichEditOle *pRichEditOle, HENHMETAFILE hEmf) +bool InsertBitmap(HWND hwnd, IRichEditOle *pRichEditOle, HICON hIcon) { - SCODE sc; - - // Get the image data object - // - static const FORMATETC lc_format[] = - { - { CF_ENHMETAFILE, nullptr, DVASPECT_CONTENT, -1, TYMED_ENHMF }//, - // { CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, - // { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } - }; - - STGMEDIUM lc_stgmed[] = - { - { TYMED_ENHMF, { (HBITMAP)hEmf }, nullptr }//, - // { TYMED_GDI, { hBitmap }, 0 }, - // { TYMED_HGLOBAL, { (HBITMAP)hGlobal }, 0 } - }; - - IDataObject *pods; - CreateDataObject(lc_format, lc_stgmed, 1, &pods); - // Get the RichEdit container site - // IOleClientSite *pOleClientSite; pRichEditOle->GetClientSite(&pOleClientSite); - // Initialize a Storage Object - // - LPLOCKBYTES lpLockBytes = nullptr; - sc = CreateILockBytesOnHGlobal(nullptr, TRUE, &lpLockBytes); - if (sc != S_OK) { - pOleClientSite->Release(); - return false; - } - IStorage *pStorage; - sc = StgCreateDocfileOnILockBytes(lpLockBytes, - STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage); - if (sc != S_OK) { - lpLockBytes->Release(); - pOleClientSite->Release(); - pods->Release(); - return false; - } - - // The final ole object which will be inserted in the richedit control - // IOleObject *pOleObject; - sc = OleCreateStaticFromData(pods, IID_IOleObject, OLERENDER_FORMAT, - (LPFORMATETC)lc_format, pOleClientSite, pStorage, (void **)&pOleObject); - if (sc != S_OK) { - pStorage->Release(); - lpLockBytes->Release(); + IDataObject *pods = CacheIconToIDataObject(hwnd, hIcon, pOleClientSite, &pStorage, &pOleObject); + if (pods == nullptr) { pOleClientSite->Release(); return false; } // all items are "contained" -- this makes our reference to this object // weak -- which is needed for links to embedding silent update. - OleSetContainedObject(pOleObject, TRUE); // Now Add the object to the RichEdit - // REOBJECT reobject = { 0 }; reobject.cbStruct = sizeof(REOBJECT); @@ -174,26 +198,12 @@ bool InsertBitmap(IRichEditOle *pRichEditOle, HENHMETAFILE hEmf) reobject.pstg = pStorage; reobject.dwFlags = REO_BELOWBASELINE; - sc = pOleObject->GetUserClassID(&reobject.clsid); - if (sc != S_OK) { - pOleObject->Release(); - pStorage->Release(); - lpLockBytes->Release(); - pOleClientSite->Release(); + SCODE sc = pOleObject->GetUserClassID(&reobject.clsid); + if (sc != S_OK) return false; - } // Insert the bitmap at the current location in the richedit control - // sc = pRichEditOle->InsertObject(&reobject); - // Release all unnecessary interfaces - // - pOleObject->Release(); - pStorage->Release(); - lpLockBytes->Release(); - pOleClientSite->Release(); - pods->Release(); - return sc == S_OK; } diff --git a/libs/mTextControl/src/ImageDataObjectHlp.h b/libs/mTextControl/src/ImageDataObjectHlp.h index fdc395aa48..312e4bc72c 100644 --- a/libs/mTextControl/src/ImageDataObjectHlp.h +++ b/libs/mTextControl/src/ImageDataObjectHlp.h @@ -21,8 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define _IMAGEDATAOBJECTHLP_ void UnloadEmfCache(); -HENHMETAFILE CacheIconToEmf(HICON hIcon); - -bool InsertBitmap(IRichEditOle* pRichEditOle, HENHMETAFILE hEmf); +void CleanupEmfCache(HWND hwnd); +bool InsertBitmap(HWND hwnd, IRichEditOle* pRichEditOle, HICON hIcon); #endif diff --git a/libs/mTextControl/src/dataobject.cpp b/libs/mTextControl/src/dataobject.cpp index cc05369021..121922f72f 100644 --- a/libs/mTextControl/src/dataobject.cpp +++ b/libs/mTextControl/src/dataobject.cpp @@ -11,57 +11,14 @@ //#define STRICT #include "stdafx.h" +#include "dataobject.h" const ULONG MAX_FORMATS = 100; HRESULT CreateEnumFormatEtc(UINT nNumFormats, FORMATETC *pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc); -class CDataObject : public IDataObject -{ -public: - // - // IUnknown members - // - HRESULT __stdcall QueryInterface(REFIID iid, void ** ppvObject); - ULONG __stdcall AddRef(void); - ULONG __stdcall Release(void); - - // - // IDataObject members - // - HRESULT __stdcall GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium); - HRESULT __stdcall GetDataHere(FORMATETC *pFormatEtc, STGMEDIUM *pMedium); - HRESULT __stdcall QueryGetData(FORMATETC *pFormatEtc); - HRESULT __stdcall GetCanonicalFormatEtc(FORMATETC *pFormatEct, FORMATETC *pFormatEtcOut); - HRESULT __stdcall SetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium, BOOL fRelease); - HRESULT __stdcall EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc); - HRESULT __stdcall DAdvise(FORMATETC *pFormatEtc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection); - HRESULT __stdcall DUnadvise(DWORD dwConnection); - HRESULT __stdcall EnumDAdvise(IEnumSTATDATA **ppEnumAdvise); - - // - // Constructor / Destructor - // - CDataObject(const FORMATETC *fmt, const STGMEDIUM *stgmed, int count); - ~CDataObject(); - -private: - - int LookupFormatEtc(FORMATETC *pFormatEtc); - - // - // any private members and functions - // - LONG m_lRefCount; - - FORMATETC *m_pFormatEtc; - STGMEDIUM *m_pStgMedium; - LONG m_nNumFormats; - -}; - // -// Constructor +// Constructors // CDataObject::CDataObject(const FORMATETC *fmtetc, const STGMEDIUM *stgmed, int count) { @@ -77,18 +34,40 @@ CDataObject::CDataObject(const FORMATETC *fmtetc, const STGMEDIUM *stgmed, int c } } +CDataObject::CDataObject() +{ + m_lRefCount = 1; + m_nNumFormats = 0; + + m_pFormatEtc = nullptr; + m_pStgMedium = nullptr; +} + // // Destructor // CDataObject::~CDataObject() { - // cleanup - for (int i = 0; i < m_nNumFormats; i++) { - // ReleaseStgMedium(&m_pStgMedium[i]); - } + if (m_pFormatEtc) delete[] m_pFormatEtc; + if (m_pStgMedium) delete[] m_pStgMedium; +} + +// for use in child's +void CDataObject::UpdateData(const FORMATETC *fmtetc, const STGMEDIUM *stgmed, int count) +{ + m_lRefCount = 1; + m_nNumFormats = count; if (m_pFormatEtc) delete[] m_pFormatEtc; if (m_pStgMedium) delete[] m_pStgMedium; + + m_pFormatEtc = new FORMATETC[count]; + m_pStgMedium = new STGMEDIUM[count]; + + for (int i = 0; i < count; i++) { + m_pFormatEtc[i] = fmtetc[i]; + m_pStgMedium[i] = stgmed[i]; + } } // @@ -135,7 +114,7 @@ HRESULT __stdcall CDataObject::QueryInterface(REFIID iid, void **ppvObject) int CDataObject::LookupFormatEtc(FORMATETC *pFormatEtc) { for (int i = 0; i < m_nNumFormats; i++) { - if ((pFormatEtc->tymed & m_pFormatEtc[i].tymed) && + if ((pFormatEtc->tymed & m_pFormatEtc[i].tymed) && pFormatEtc->cfFormat == m_pFormatEtc[i].cfFormat && pFormatEtc->dwAspect == m_pFormatEtc[i].dwAspect) { return i; @@ -155,9 +134,8 @@ HRESULT __stdcall CDataObject::GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium // // try to match the requested FORMATETC with one of our supported formats // - if ((idx = LookupFormatEtc(pFormatEtc)) == -1) { + if ((idx = LookupFormatEtc(pFormatEtc)) == -1) return DV_E_FORMATETC; - } // // found a match! transfer the data into the supplied storage-medium @@ -169,7 +147,6 @@ HRESULT __stdcall CDataObject::GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium case TYMED_HGLOBAL: case TYMED_GDI: case TYMED_ENHMF: - // pMedium->hBitmap = (HBITMAP)OleDuplicateData(m_pStgMedium[idx].hBitmap, pFormatEtc->cfFormat, 0); pMedium->hBitmap = m_pStgMedium[idx].hBitmap; break; @@ -274,3 +251,43 @@ HRESULT CreateDataObject(const FORMATETC *fmtetc, const STGMEDIUM *stgmeds, UINT return (*ppDataObject) ? S_OK : E_OUTOFMEMORY; } + + +// CEMFObject + +// Constructor +CEMFObject::CEMFObject(HENHMETAFILE hEmf) +{ + static const FORMATETC lc_format[] = + { + { CF_ENHMETAFILE, nullptr, DVASPECT_CONTENT, -1, TYMED_ENHMF } + }; + + STGMEDIUM lc_stgmed[] = + { + { TYMED_ENHMF, { (HBITMAP)hEmf }, nullptr } + }; + + UpdateData(lc_format, lc_stgmed, 1); + + m_hEmf = hEmf; +} + +// Destructor +CEMFObject::~CEMFObject() +{ + DeleteEnhMetaFile(m_hEmf); +} + +// GetData +HRESULT __stdcall CEMFObject::GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium) +{ + HRESULT hr; + hr = CDataObject::GetData(pFormatEtc, pMedium); + if (hr == S_OK) { + // we are responsible for releasing EMF object, not OLE client, so set pointer to IUnknown to us and Add a new reference + pMedium->pUnkForRelease = this; + AddRef(); + } + return hr; +} diff --git a/libs/mTextControl/src/dataobject.h b/libs/mTextControl/src/dataobject.h new file mode 100644 index 0000000000..b0547367c0 --- /dev/null +++ b/libs/mTextControl/src/dataobject.h @@ -0,0 +1,65 @@ +#pragma once + +class CDataObject : public IDataObject +{ +public: + // + // IUnknown members + // + HRESULT __stdcall QueryInterface(REFIID iid, void** ppvObject); + ULONG __stdcall AddRef(void); + ULONG __stdcall Release(void); + + // + // IDataObject members + // + HRESULT __stdcall GetData(FORMATETC* pFormatEtc, STGMEDIUM* pMedium); + HRESULT __stdcall GetDataHere(FORMATETC* pFormatEtc, STGMEDIUM* pMedium); + HRESULT __stdcall QueryGetData(FORMATETC* pFormatEtc); + HRESULT __stdcall GetCanonicalFormatEtc(FORMATETC* pFormatEct, FORMATETC* pFormatEtcOut); + HRESULT __stdcall SetData(FORMATETC* pFormatEtc, STGMEDIUM* pMedium, BOOL fRelease); + HRESULT __stdcall EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC** ppEnumFormatEtc); + HRESULT __stdcall DAdvise(FORMATETC* pFormatEtc, DWORD advf, IAdviseSink* pAdvSink, DWORD* pdwConnection); + HRESULT __stdcall DUnadvise(DWORD dwConnection); + HRESULT __stdcall EnumDAdvise(IEnumSTATDATA** ppEnumAdvise); + + // + // Constructor / Destructor + // + CDataObject(); + CDataObject(const FORMATETC* fmt, const STGMEDIUM* stgmed, int count); + ~CDataObject(); + +protected: + void UpdateData(const FORMATETC* pFormatEtc, const STGMEDIUM* pMedium, int count); + +private: + + int LookupFormatEtc(FORMATETC* pFormatEtc); + + // + // any private members and functions + // + LONG m_lRefCount; + + FORMATETC* m_pFormatEtc; + STGMEDIUM* m_pStgMedium; + LONG m_nNumFormats; + +}; + +class CEMFObject : public CDataObject +{ +public: + // IDataObject members + HRESULT __stdcall GetData(FORMATETC* pFormatEtc, STGMEDIUM* pMedium); + + // Constructor / Destructor + CEMFObject(HENHMETAFILE hEmf); + ~CEMFObject(); + +private: + HENHMETAFILE m_hEmf; + +}; + diff --git a/libs/mTextControl/src/fancy_rtf.cpp b/libs/mTextControl/src/fancy_rtf.cpp index 7c82bad0cd..e6193f63af 100644 --- a/libs/mTextControl/src/fancy_rtf.cpp +++ b/libs/mTextControl/src/fancy_rtf.cpp @@ -93,10 +93,12 @@ static bool bbCodeImageFunc(CFormattedTextDraw *ftd, CHARRANGE range, wchar_t *t if (!swscanf(txt, L"%p", &hIcon)) return false; - bool res = InsertBitmap(RichEditOle, CacheIconToEmf(hIcon)); + bool res = InsertBitmap(ftd->getParentWnd(), RichEditOle, hIcon); + if (!res) + ts->TxSendMessage(EM_REPLACESEL, 0, (LPARAM)L"!E!", &lResult); + td->Unfreeze(&cnt); - RichEditOle->Release(); - return res; + return true; } static BBCodeInfo bbCodes[] = diff --git a/libs/mTextControl/src/services.cpp b/libs/mTextControl/src/services.cpp index 8c6e06d165..35efa5f5f7 100644 --- a/libs/mTextControl/src/services.cpp +++ b/libs/mTextControl/src/services.cpp @@ -113,6 +113,36 @@ MTEXTCONTROL_DLL(TextObject *) MTextCreateEx(HANDLE userHandle, const void *text } ///////////////////////////////////////////////////////////////////////////////////////// +// allocate text object (more advanced) + +MTEXTCONTROL_DLL(TextObject *) MTextCreateEx2(HWND hwnd, HANDLE userHandle, const void *text, uint32_t flags) +{ + TextObject *result = new TextObject; + result->options = TextUserGetOptions(userHandle); + result->ftd = new CFormattedTextDraw(); + if (hwnd) { + RECT rc; + GetClientRect(hwnd, &rc); + result->ftd->setParentWnd(hwnd, rc); + } + InitRichEdit(result->ftd->getTextService()); + + MText_InitFormatting0(result->ftd, result->options); + if (flags & MTEXT_FLG_RTF) { + result->ftd->putRTFText((char *)text); + } + else { + if (flags & MTEXT_FLG_WCHAR) + result->ftd->putTextW((wchar_t *)text); + else + result->ftd->putTextA((char *)text); + } + MText_InitFormatting1(result); + return result; +} + + +///////////////////////////////////////////////////////////////////////////////////////// // measure text object MTEXTCONTROL_DLL(int) MTextMeasure(HDC dc, SIZE *sz, TextObject *text) diff --git a/libs/mTextControl/src/textcontrol.cpp b/libs/mTextControl/src/textcontrol.cpp index 2391ecc1ac..f261094307 100644 --- a/libs/mTextControl/src/textcontrol.cpp +++ b/libs/mTextControl/src/textcontrol.cpp @@ -132,7 +132,7 @@ static LRESULT CALLBACK MTextControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, if (data->mtext) MTextDestroy(data->mtext); - data->mtext = MTextCreateEx(data->htu, (char*)lParam, wParam); + data->mtext = MTextCreateEx2(hwnd, data->htu, (char *)lParam, wParam); MTextSetParent(data->mtext, hwnd); InvalidateRect(hwnd, nullptr, TRUE); return TRUE; |