summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2023-12-16 12:48:19 +0300
committerGeorge Hazan <george.hazan@gmail.com>2023-12-16 12:48:19 +0300
commit5ab6d9ae15f81fe1784ae34f0eab3e611e4330c7 (patch)
tree5f1c77d72fc93b48a173e39d4bb746202182f978
parenteffb19fea7c74535cd0e44f547879a5651c4a44e (diff)
malfunctioning double linked list replaced with the standard OBJLIST
-rw-r--r--libs/mTextControl/src/ImageDataObjectHlp.cpp168
1 files changed, 58 insertions, 110 deletions
diff --git a/libs/mTextControl/src/ImageDataObjectHlp.cpp b/libs/mTextControl/src/ImageDataObjectHlp.cpp
index eac28e6c6d..b755060dfc 100644
--- a/libs/mTextControl/src/ImageDataObjectHlp.cpp
+++ b/libs/mTextControl/src/ImageDataObjectHlp.cpp
@@ -29,144 +29,94 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
struct EMFCACHE
{
- CEMFObject *pEmfObj;
- IStorage *pStorage;
- IOleObject *pOleObject;
- HICON hIcon;
HWND hwnd;
- EMFCACHE *prev;
- EMFCACHE *next;
-} *emfCache = nullptr;
-int emfCacheSize = 0;
+ HICON hIcon;
+ CEMFObject *pEmfObj = 0;
+ IStorage *pStorage = 0;
+ IOleObject *pOleObject = 0;
+
+ ~EMFCACHE()
+ {
+ if (pEmfObj)
+ pEmfObj->Release();
+ if (pStorage)
+ pStorage->Release();
+ if (pOleObject)
+ pOleObject->Release();
+ }
+};
+
mir_cs csEmfCache;
+static OBJLIST<EMFCACHE> g_arCache(50);
void UnloadEmfCache()
{
- while (emfCache) {
- EMFCACHE *tmp = emfCache->next;
- emfCache->pEmfObj->Release();
- emfCache->pStorage->Release();
- delete emfCache;
- emfCache = tmp;
- }
+ g_arCache.destroy();
}
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;
- }
- }
+ for (auto &it : g_arCache.rev_iter())
+ if (it->hwnd == hwnd)
+ g_arCache.remove(g_arCache.indexOf(&it));
}
-IDataObject *CacheIconToIDataObject(HWND hwnd, HICON hIcon, IOleClientSite *pOleClientSite, IStorage **ppStorage, IOleObject **ppOleObject)
+IDataObject* CacheIconToIDataObject(HWND hwnd, HICON hIcon, IOleClientSite *pOleClientSite, IStorage **ppStorage, IOleObject **ppOleObject)
{
- 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 && 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;
+ for (auto &it : g_arCache.rev_iter())
+ if (it->hwnd == hwnd && it->hIcon == hIcon) {
+ *ppStorage = it->pStorage;
+ *ppOleObject = it->pOleObject;
+ return it->pEmfObj;
}
// 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();
+ EMFCACHE *newItem = new EMFCACHE();
- if (sc != S_OK) {
- delete newItem;
- return nullptr;
- }
+ LPLOCKBYTES lpLockBytes = nullptr;
+ SCODE sc = CreateILockBytesOnHGlobal(nullptr, TRUE, &lpLockBytes);
+ 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 = StgCreateDocfileOnILockBytes(lpLockBytes,
+ STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &newItem->pStorage);
- sc = OleCreateStaticFromData(newItem->pEmfObj, IID_IOleObject, OLERENDER_FORMAT,
- (LPFORMATETC)lc_format, pOleClientSite, newItem->pStorage, (void **)&newItem->pOleObject);
+ lpLockBytes->Release();
- if (sc != S_OK) {
- newItem->pStorage->Release();
- newItem->pEmfObj->Release();
- delete newItem;
- return nullptr;
- }
+ if (sc != S_OK) {
+ delete newItem;
+ return nullptr;
+ }
- OleSetContainedObject(newItem->pOleObject, TRUE);
+ 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;
- newItem->prev = nullptr;
- newItem->next = emfCache;
- if (emfCache) emfCache->prev = newItem;
- emfCache = newItem;
- emfCacheSize++;
+ sc = OleCreateStaticFromData(newItem->pEmfObj, IID_IOleObject, OLERENDER_FORMAT,
+ (LPFORMATETC)lc_format, pOleClientSite, newItem->pStorage, (void **)&newItem->pOleObject);
- result = emfCache->pEmfObj;
- *ppStorage = emfCache->pStorage;
- *ppOleObject = emfCache->pOleObject;
+ if (sc != S_OK) {
+ delete newItem;
+ return nullptr;
}
- // 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 > 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 = MAX_CACHE_SIZE;
- }
+ OleSetContainedObject(newItem->pOleObject, TRUE);
- return result;
+ g_arCache.insert(newItem);
+
+ *ppStorage = newItem->pStorage;
+ *ppOleObject = newItem->pOleObject;
+ return newItem->pEmfObj;
}
// returns true on success, false on failure
@@ -188,8 +138,7 @@ bool InsertBitmap(HWND hwnd, IRichEditOle *pRichEditOle, HICON hIcon)
// weak -- which is needed for links to embedding silent update.
// Now Add the object to the RichEdit
- REOBJECT reobject = { 0 };
-
+ REOBJECT reobject = {};
reobject.cbStruct = sizeof(REOBJECT);
reobject.cp = REO_CP_SELECTION;
reobject.dvaspect = DVASPECT_CONTENT;
@@ -204,6 +153,5 @@ bool InsertBitmap(HWND hwnd, IRichEditOle *pRichEditOle, HICON hIcon)
// Insert the bitmap at the current location in the richedit control
sc = pRichEditOle->InsertObject(&reobject);
-
return sc == S_OK;
}