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; }
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; }