HRESULT CComCatCachedCategory::LoadFromComCatMgr() { HRESULT hr; CComPtr<ICatInformation> pCatInformation; CComPtr<IEnumGUID> pEnumGUID; ULONG pFetched; CLSID tmp; // Get component categories manager instance hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(ICatInformation, &pCatInformation)); if (FAILED_UNEXPECTEDLY(hr)) return hr; // Get the proper enumerator hr = pCatInformation->EnumClassesOfCategories(1, &fCategory, NULL, NULL, &pEnumGUID); if (FAILED_UNEXPECTEDLY(hr)) return hr; // Enumerate elements do { pFetched = 0; pEnumGUID->Next(1, &tmp, &pFetched); if (pFetched) { if (DSA_InsertItem(fLocalDsa, DSA_APPEND, &tmp) == E_OUTOFMEMORY) return E_OUTOFMEMORY; } } while (pFetched > 0); return S_OK; }
BOOL CComCatCachedCategory::LoadFromRegistry() { WCHAR bufKey[MAX_PATH]; WCHAR guidStr[MAX_PATH]; DWORD dataSize, i; CComHeapPtr<CATCACHEHDR> buffer; GUID *guidArray; if (!fLocalDsa) return FALSE; dataSize = 0; if (!StringFromGUID2(fCategory, guidStr, MAX_PATH)) return FALSE; wsprintf(bufKey, L"%s\\%s\\%s", REGPATH , guidStr, L"Enum"); // Try to read key and get proper value size if (SHGetValue(HKEY_CURRENT_USER, bufKey, IMPLEMENTING, NULL, NULL, &dataSize)) return FALSE; buffer.Attach((PCATCACHEHDR)CoTaskMemAlloc(dataSize)); SHGetValue(HKEY_CURRENT_USER, bufKey, IMPLEMENTING, NULL, buffer, &dataSize); guidArray = (GUID*)(buffer + 1); for (i = 0; i < buffer->classCount; i++) { // Add class to cache DSA_InsertItem(fLocalDsa, DSA_APPEND, guidArray + i); } return TRUE; }
/* Theme enumeration callback, adds theme to theme list */ static BOOL CALLBACK myEnumThemeProc (LPVOID lpReserved, LPCWSTR pszThemeFileName, LPCWSTR pszThemeName, LPCWSTR pszToolTip, LPVOID lpReserved2, LPVOID lpData) { ThemeFile newEntry; /* fill size/color lists */ create_color_or_size_dsa (&newEntry.colors); fill_theme_string_array (pszThemeFileName, &newEntry.colors, EnumThemeColors); create_color_or_size_dsa (&newEntry.sizes); fill_theme_string_array (pszThemeFileName, &newEntry.sizes, EnumThemeSizes); newEntry.themeFileName = HeapAlloc (GetProcessHeap(), 0, (lstrlenW (pszThemeFileName) + 1) * sizeof(WCHAR)); lstrcpyW (newEntry.themeFileName, pszThemeFileName); newEntry.fancyName = HeapAlloc (GetProcessHeap(), 0, (lstrlenW (pszThemeName) + 1) * sizeof(WCHAR)); lstrcpyW (newEntry.fancyName, pszThemeName); /*list_add_tail (&themeFiles, &newEntry->entry);*/ DSA_InsertItem (themeFiles, themeFilesCount, &newEntry); themeFilesCount++; return TRUE; }
STDAPI SHCoRegisterClassObject( const CLSID *pclsid, LPUNKNOWN pUnk, DWORD dwClsContext, DWORD dwFlags, LPDWORD lpdwRegister) { HRESULT hres = E_OUTOFMEMORY; Assert(dwClsContext == CLSCTX_INPROC_SERVER); Assert(dwFlags == REGCLS_MULTIPLEUSE); if (dwClsContext != CLSCTX_INPROC_SERVER || dwFlags != REGCLS_MULTIPLEUSE) return E_INVALIDARG; // We don't support this other stuff if (!hdsaRegClasses) { hdsaRegClasses = DSA_Create(SIZEOF(SHREGCLASS), 4); } if (hdsaRegClasses) { SHREGCLASS src; src.clsid = *pclsid; src.pUnk = pUnk; pUnk->lpVtbl->AddRef(pUnk); *lpdwRegister = DSA_InsertItem(hdsaRegClasses, 0x7FFF, &src); s_iClasses++; hres = S_OK; } return hres; }
HRESULT CComCatCachedCategory::WriteCacheToDSA(HDSA pDest) { INT i; for(i = 0; i < DSA_GetItemCount(fLocalDsa); i++) { if (DSA_InsertItem(pDest, DSA_APPEND, DSA_GetItemPtr(fLocalDsa, i)) == DSA_ERR) return E_OUTOFMEMORY; } return S_OK; }
static void color_or_size_dsa_add (WrappedDsa* wdsa, const WCHAR* name, const WCHAR* fancyName) { ThemeColorOrSize item; item.name = HeapAlloc (GetProcessHeap(), 0, (lstrlenW (name) + 1) * sizeof(WCHAR)); lstrcpyW (item.name, name); item.fancyName = HeapAlloc (GetProcessHeap(), 0, (lstrlenW (fancyName) + 1) * sizeof(WCHAR)); lstrcpyW (item.fancyName, fancyName); DSA_InsertItem (wdsa->dsa, wdsa->count, &item); wdsa->count++; }
BOOL PASCAL TV_SortCB(PTREE pTree, TV_SORTCB FAR *pSortCB, BOOL bRecurse, PFNDPACOMPARE lpfnDPACompare) { HDPA dpaSort; HDSA dsaCmp; HTREEITEM hItem, hNext, hFirstMoved; LPTVCOMPARE psCompare, FAR *ppsCompare; int i, cKids; HTREEITEM hParent = pSortCB->hParent; #ifdef DEBUG DWORD dwTime = GetTickCount(); nCompares = 0; #endif if (!hParent || hParent == TVI_ROOT) hParent = pTree->hRoot; // Code below assumes at least one kid cKids = TV_CountKids(hParent); if (!cKids) return FALSE; // Create a DSA for all the extra info we'll need dsaCmp = DSA_Create(sizeof(TVCOMPARE), cKids); if (!dsaCmp) goto Error1; // Create a DPA containing all the tree items dpaSort = DPA_Create(cKids); if (!dpaSort) goto Error2; for (hItem = hParent->hKids; hItem; hItem = hItem->hNext) { TVCOMPARE sCompare; int nItem; // If I can't sort all of them, I don't want to sort any of them // We want to cache the text callback for default processing if (!lpfnDPACompare && hItem->lpstr==LPSTR_TEXTCALLBACK) { TV_ITEM sItem; TCHAR szTemp[MAX_PATH]; sItem.pszText = szTemp; sItem.cchTextMax = ARRAYSIZE(szTemp); TV_GetItem(pTree, hItem, TVIF_TEXT, &sItem); sCompare.lpstr = NULL; sCompare.bCallBack = TRUE; Str_Set(&sCompare.lpstr, sItem.pszText); if (!sCompare.lpstr) { goto Error3; } } else { sCompare.lpstr = hItem->lpstr; sCompare.bCallBack = FALSE; } // Create the pointer for this guy and add it to the DPA list sCompare.hItem = hItem; nItem = DSA_InsertItem(dsaCmp, 0x7fff, &sCompare); if (nItem < 0) { if (sCompare.bCallBack) { Str_Set(&sCompare.lpstr, NULL); } goto Error3; } if (DPA_InsertPtr(dpaSort, 0x7fff, DSA_GetItemPtr(dsaCmp, nItem)) < 0) { goto Error3; } } // Sort the DPA, then stick them back under the parent in the new order DPA_Sort(dpaSort, lpfnDPACompare ? (PFNDPACOMPARE)lpfnDPACompare : (PFNDPACOMPARE) TV_DefCompare, (LPARAM)pSortCB); // Look for the first moved item, so we can invalidate a smaller area ppsCompare = (LPTVCOMPARE FAR *)DPA_GetPtrPtr(dpaSort); if (hParent->hKids != (*ppsCompare)->hItem) { hParent->hKids = (*ppsCompare)->hItem; hFirstMoved = hParent->hKids; } else { hFirstMoved = NULL; } // We do n-1 iterations here for (i = DPA_GetPtrCount(dpaSort) - 1; i > 0; --i, ++ppsCompare) { hNext = (*(ppsCompare+1))->hItem; if ((*ppsCompare)->hItem->hNext != hNext && !hFirstMoved) { hFirstMoved = hNext; } (*ppsCompare)->hItem->hNext = hNext; } (*ppsCompare)->hItem->hNext = NULL; TV_UpdateShownIndexes(pTree, hParent); if ((pSortCB->hParent == TVI_ROOT) || !hParent) { if (pTree->cShowing < pTree->cFullVisible) { pTree->hTop = pTree->hRoot->hKids; } } if (hFirstMoved && (hParent->state & TVIS_EXPANDED)) { RECT rcUpdate; TV_GetItemRect(pTree, hFirstMoved, &rcUpdate, FALSE); if (hParent->hNext) { RECT rcTemp; TV_GetItemRect(pTree, hParent->hNext, &rcTemp, FALSE); rcUpdate.bottom = rcTemp.bottom; } else { RECT rcClient; GetClientRect(pTree->ci.hwnd, &rcClient); // Set to maximal positive number, so the whole rest of // the treeview gets invalidated rcUpdate.bottom = rcClient.bottom; } if (pTree->fRedraw) InvalidateRect(pTree->ci.hwnd, &rcUpdate, TRUE); } Error3: DPA_Destroy(dpaSort); Error2: for (i = DSA_GetItemCount(dsaCmp) - 1; i >= 0; --i) { psCompare = DSA_GetItemPtr(dsaCmp, i); if (psCompare->bCallBack) { Str_Set(&(psCompare->lpstr), NULL); } } DSA_Destroy(dsaCmp); Error1: #ifdef DEBUG DebugMsg(DM_TRACE, TEXT("tv.sort: %ld ms; %d cmps"), GetTickCount()-dwTime, nCompares); #endif { int wNewPos; // restore the scroll position if (GetWindowStyle(pTree->ci.hwnd) & WS_VSCROLL) { SCROLLINFO si; si.cbSize = sizeof(SCROLLINFO); si.fMask = SIF_POS; wNewPos = 0; if (GetScrollInfo(pTree->ci.hwnd, SB_VERT, &si)) { wNewPos = si.nPos; } } else { wNewPos = 0; } if (TV_SetTopItem(pTree, wNewPos)) UpdateWindow(pTree->ci.hwnd); } // if the caret is the child of the thing that was sorted, make sure it's // visible (but if we're sorting something completely unrelated, don't bother if (pTree->hCaret) { hItem = pTree->hCaret; do { // do this first. if hParent is hCaret, we don't want to ensure visible... // only if it's an eventual child hItem = hItem->hParent; if (hParent == hItem) { TV_EnsureVisible(pTree, pTree->hCaret); } } while(hItem && hItem != pTree->hRoot); } return TRUE; }