diff options
author | George Hazan <george.hazan@gmail.com> | 2023-12-16 12:48:19 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2023-12-16 12:48:19 +0300 |
commit | 5ab6d9ae15f81fe1784ae34f0eab3e611e4330c7 (patch) | |
tree | 5f1c77d72fc93b48a173e39d4bb746202182f978 | |
parent | effb19fea7c74535cd0e44f547879a5651c4a44e (diff) |
malfunctioning double linked list replaced with the standard OBJLIST
-rw-r--r-- | libs/mTextControl/src/ImageDataObjectHlp.cpp | 168 |
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; } |