summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/mTextControl/mtextcontrol.vcxproj1
-rw-r--r--libs/mTextControl/mtextcontrol.vcxproj.filters3
-rw-r--r--libs/mTextControl/src/FormattedTextDraw.cpp3
-rw-r--r--libs/mTextControl/src/FormattedTextDraw.h1
-rw-r--r--libs/mTextControl/src/ImageDataObjectHlp.cpp196
-rw-r--r--libs/mTextControl/src/ImageDataObjectHlp.h5
-rw-r--r--libs/mTextControl/src/dataobject.cpp123
-rw-r--r--libs/mTextControl/src/dataobject.h65
-rw-r--r--libs/mTextControl/src/fancy_rtf.cpp8
-rw-r--r--libs/mTextControl/src/services.cpp30
-rw-r--r--libs/mTextControl/src/textcontrol.cpp2
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;