/***************************************************************************** * SIC_Initialize [internal] */ BOOL SIC_Initialize(void) { HICON hSm, hLg; int cx_small, cy_small; int cx_large, cy_large; cx_small = GetSystemMetrics(SM_CXSMICON); cy_small = GetSystemMetrics(SM_CYSMICON); cx_large = GetSystemMetrics(SM_CXICON); cy_large = GetSystemMetrics(SM_CYICON); TRACE("\n"); if (sic_hdpa) /* already initialized?*/ return TRUE; sic_hdpa = DPA_Create(16); if (!sic_hdpa) { return(FALSE); } ShellSmallIconList = ImageList_Create(cx_small,cy_small,ILC_COLOR32|ILC_MASK,0,0x20); ShellBigIconList = ImageList_Create(cx_large,cy_large,ILC_COLOR32|ILC_MASK,0,0x20); ImageList_SetBkColor(ShellSmallIconList, CLR_NONE); ImageList_SetBkColor(ShellBigIconList, CLR_NONE); /* Load the document icon, which is used as the default if an icon isn't found. */ hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), IMAGE_ICON, cx_small, cy_small, LR_SHARED); hLg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), IMAGE_ICON, cx_large, cy_large, LR_SHARED); if (!hSm || !hLg) { FIXME("Failed to load IDI_SHELL_DOCUMENT icon!\n"); return FALSE; } SIC_IconAppend (swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0); SIC_IconAppend (swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0); TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList); return TRUE; }
static HDPA enum_bucket_trashinfos(const TRASH_BUCKET *bucket, int *count) { HDPA ret = DPA_Create(32); struct dirent *entry; DIR *dir = NULL; errno = ENOMEM; *count = 0; if (ret == NULL) goto failed; dir = opendir(bucket->info_dir); if (dir == NULL) goto failed; while ((entry = readdir(dir)) != NULL) { LPSTR filename; int namelen = lstrlenA(entry->d_name); int suffixlen = lstrlenA(trashinfo_suffix); if (namelen <= suffixlen || lstrcmpA(entry->d_name+namelen-suffixlen, trashinfo_suffix) != 0) continue; filename = StrDupA(entry->d_name); if (filename == NULL) goto failed; if (DPA_InsertPtr(ret, DPA_APPEND, filename) == -1) { LocalFree(filename); goto failed; } (*count)++; } closedir(dir); return ret; failed: if (dir) closedir(dir); if (ret) DPA_DestroyCallback(ret, free_item_callback, NULL); return NULL; }
/************************************************************************** * DPA_LoadStream [COMCTL32.9] * * Loads a dynamic pointer array from a stream * * PARAMS * phDpa [O] pointer to a handle to a dynamic pointer array * loadProc [I] pointer to a callback function * pStream [I] pointer to a stream * pData [I] pointer to callback data * * RETURNS * Success: S_OK, S_FALSE - partial success * Failure: HRESULT error code * * NOTES * No more information available yet! */ HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, PFNDPASTREAM loadProc, IStream *pStream, LPVOID pData) { HRESULT errCode; LARGE_INTEGER position; ULARGE_INTEGER initial_pos; STREAMDATA streamData; DPASTREAMINFO streamInfo; ULONG ulRead; HDPA hDpa; PVOID *ptr; TRACE ("phDpa=%p loadProc=%p pStream=%p pData=%p\n", phDpa, loadProc, pStream, pData); if (!phDpa || !loadProc || !pStream) return E_INVALIDARG; *phDpa = NULL; position.QuadPart = 0; errCode = IStream_Seek (pStream, position, STREAM_SEEK_CUR, &initial_pos); if (errCode != S_OK) return errCode; memset(&streamData, 0, sizeof(STREAMDATA)); errCode = IStream_Read (pStream, &streamData, sizeof(STREAMDATA), &ulRead); if (errCode != S_OK) return errCode; TRACE ("dwSize=%u dwData2=%u dwItems=%u\n", streamData.dwSize, streamData.dwData2, streamData.dwItems); if (ulRead < sizeof(STREAMDATA) || streamData.dwSize < sizeof(STREAMDATA) || streamData.dwData2 != 1) { /* back to initial position */ position.QuadPart = initial_pos.QuadPart; IStream_Seek (pStream, position, STREAM_SEEK_SET, NULL); return E_FAIL; } if (streamData.dwItems > (UINT_MAX / 2 / sizeof(VOID*))) /* 536870911 */ return E_OUTOFMEMORY; /* create the dpa */ hDpa = DPA_Create (streamData.dwItems); if (!hDpa) return E_OUTOFMEMORY; if (!DPA_Grow (hDpa, streamData.dwItems)) return E_OUTOFMEMORY; /* load data from the stream into the dpa */ ptr = hDpa->ptrs; for (streamInfo.iPos = 0; streamInfo.iPos < streamData.dwItems; streamInfo.iPos++) { errCode = (loadProc)(&streamInfo, pStream, pData); if (errCode != S_OK) { errCode = S_FALSE; break; } *ptr = streamInfo.pvItem; ptr++; } /* set the number of items */ hDpa->nItemCount = streamInfo.iPos; /* store the handle to the dpa */ *phDpa = hDpa; TRACE ("new hDpa=%p, errorcode=%x\n", hDpa, errCode); return errCode; }
/***************************************************************************** * SIC_Initialize [internal] */ BOOL SIC_Initialize(void) { HICON hSm = NULL, hLg = NULL; INT cx_small, cy_small; INT cx_large, cy_large; HDC hDC; INT bpp; DWORD ilMask; BOOL result = FALSE; TRACE("Entered SIC_Initialize\n"); if (sic_hdpa) { TRACE("Icon cache already initialized\n"); return TRUE; } sic_hdpa = DPA_Create(16); if (!sic_hdpa) { return FALSE; } hDC = CreateICW(L"DISPLAY", NULL, NULL, NULL); if (!hDC) { ERR("Failed to create information context (error %d)\n", GetLastError()); goto end; } bpp = GetDeviceCaps(hDC, BITSPIXEL); DeleteDC(hDC); if (bpp <= 4) ilMask = ILC_COLOR4; else if (bpp <= 8) ilMask = ILC_COLOR8; else if (bpp <= 16) ilMask = ILC_COLOR16; else if (bpp <= 24) ilMask = ILC_COLOR24; else if (bpp <= 32) ilMask = ILC_COLOR32; else ilMask = ILC_COLOR; ilMask |= ILC_MASK; cx_small = GetSystemMetrics(SM_CXSMICON); cy_small = GetSystemMetrics(SM_CYSMICON); cx_large = GetSystemMetrics(SM_CXICON); cy_large = GetSystemMetrics(SM_CYICON); ShellSmallIconList = ImageList_Create(cx_small, cy_small, ilMask, 100, 100); if (!ShellSmallIconList) { ERR("Failed to create the small icon list.\n"); goto end; } ShellBigIconList = ImageList_Create(cx_large, cy_large, ilMask, 100, 100); if (!ShellBigIconList) { ERR("Failed to create the big icon list.\n"); goto end; } /* Load the document icon, which is used as the default if an icon isn't found. */ hSm = (HICON)LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT), IMAGE_ICON, cx_small, cy_small, LR_SHARED | LR_DEFAULTCOLOR); if (!hSm) { ERR("Failed to load small IDI_SHELL_DOCUMENT icon!\n"); goto end; } hLg = (HICON)LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT), IMAGE_ICON, cx_large, cy_large, LR_SHARED | LR_DEFAULTCOLOR); if (!hLg) { ERR("Failed to load large IDI_SHELL_DOCUMENT icon!\n"); goto end; } if(SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0) == INVALID_INDEX) { ERR("Failed to add IDI_SHELL_DOCUMENT icon to cache.\n"); goto end; } if(SIC_IconAppend(swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0) == INVALID_INDEX) { ERR("Failed to add IDI_SHELL_DOCUMENT icon to cache.\n"); goto end; } /* Everything went fine */ result = TRUE; end: /* The image list keeps a copy of the icons, we must destroy them */ if(hSm) DestroyIcon(hSm); if(hLg) DestroyIcon(hLg); /* Clean everything if something went wrong */ if(!result) { if(sic_hdpa) DPA_Destroy(sic_hdpa); if(ShellSmallIconList) ImageList_Destroy(ShellSmallIconList); if(ShellBigIconList) ImageList_Destroy(ShellSmallIconList); sic_hdpa = NULL; ShellSmallIconList = NULL; ShellBigIconList = NULL; } TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList); return result; }
HRESULT CMenuSFToolbar::FillToolbar(BOOL clearFirst) { HRESULT hr; CComPtr<IEnumIDList> eidl; hr = m_shellFolder->EnumObjects(GetToolbar(), SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &eidl); if (FAILED_UNEXPECTEDLY(hr)) return hr; HDPA dpaSort = DPA_Create(10); LPITEMIDLIST item = NULL; hr = eidl->Next(1, &item, NULL); while (hr == S_OK) { if (m_menuBand->_CallCBWithItemPidl(item, 0x10000000, 0, 0) == S_FALSE) { DPA_AppendPtr(dpaSort, ILClone(item)); } hr = eidl->Next(1, &item, NULL); } // If no items were added, show the "empty" placeholder if (DPA_GetPtrCount(dpaSort) == 0) { DPA_Destroy(dpaSort); return AddPlaceholder(); } TRACE("FillToolbar added %d items to the DPA\n", DPA_GetPtrCount(dpaSort)); DPA_Sort(dpaSort, PidlListSort, (LPARAM) m_shellFolder.p); for (int i = 0; i<DPA_GetPtrCount(dpaSort);) { PWSTR MenuString; INT index = 0; INT indexOpen = 0; STRRET sr = { STRRET_CSTR, { 0 } }; item = (LPITEMIDLIST)DPA_GetPtr(dpaSort, i); hr = m_shellFolder->GetDisplayNameOf(item, SIGDN_NORMALDISPLAY, &sr); if (FAILED_UNEXPECTEDLY(hr)) { DPA_Destroy(dpaSort); return hr; } StrRetToStr(&sr, NULL, &MenuString); index = SHMapPIDLToSystemImageListIndex(m_shellFolder, item, &indexOpen); LPCITEMIDLIST itemc = item; SFGAOF attrs = SFGAO_FOLDER; hr = m_shellFolder->GetAttributesOf(1, &itemc, &attrs); DWORD_PTR dwData = reinterpret_cast<DWORD_PTR>(item); // Fetch next item already, so we know if the current one is the last i++; AddButton(i, MenuString, attrs & SFGAO_FOLDER, index, dwData, i >= DPA_GetPtrCount(dpaSort)); CoTaskMemFree(MenuString); } DPA_Destroy(dpaSort); return hr; }
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; }
HRESULT InitShellServices(HDPA * phdpa) { IOleCommandTarget * pOct; HKEY hkey; CLSID clsid; WCHAR name[MAX_PATH]; WCHAR value[MAX_PATH]; DWORD type; LONG ret; HDPA hdpa; HRESULT hr = S_OK; int count = 0; *phdpa = NULL; TRACE("Enumerating Shell Service Ojbect GUIDs...\n"); if (RegOpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad", &hkey)) { ERR("RegOpenKey failed.\n"); return HRESULT_FROM_WIN32(GetLastError()); } hdpa = DPA_Create(5); /* Enumerate */ do { DWORD name_len = MAX_PATH; DWORD value_len = sizeof(value); /* byte count! */ ret = RegEnumValueW(hkey, count, name, &name_len, 0, &type, (LPBYTE) &value, &value_len); if (ret) break; if (type != REG_SZ) { WARN("Value type was not REG_SZ.\n"); continue; } hr = CLSIDFromString(value, &clsid); if (FAILED_UNEXPECTEDLY(hr)) { ERR("CLSIDFromString failed %08x.\n", hr); goto cleanup; } hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IOleCommandTarget, &pOct)); if (FAILED_UNEXPECTEDLY(hr)) { ERR("CoCreateInstance failed %08x.\n", hr); goto cleanup; } DPA_AppendPtr(hdpa, pOct); count++; } while (1); if (ret != ERROR_NO_MORE_ITEMS) { ERR("RegEnumValueW failed %08x.\n", ret); hr = HRESULT_FROM_WIN32(GetLastError()); goto cleanup; } RegCloseKey(hkey); /* Initialize */ DPA_EnumCallback(hdpa, InitializeAllCallback, &hr); if (FAILED_UNEXPECTEDLY(hr)) goto cleanup; *phdpa = hdpa; return count > 0 ? S_OK : S_FALSE; cleanup: *phdpa = NULL; ShutdownShellServices(hdpa); return hr; }