| 167 | #define HIDA_GetPIDLItem(pida, i) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[i+1]) |
| 168 | |
| 169 | HRESULT GetFileItemsFromIDataObject_ShellIDList(IDataObject *pDataObj, std::vector<String>& root_files) |
| 170 | { |
| 171 | String tmpdir; |
| 172 | FORMATETC fmtetc_filedescriptor = { static_cast<WORD>(RegisterClipboardFormat(CFSTR_SHELLIDLIST)), nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; |
| 173 | STGMEDIUM medium = { 0 }; |
| 174 | HRESULT hr; |
| 175 | if ((hr = pDataObj->GetData(&fmtetc_filedescriptor, &medium)) == S_OK) |
| 176 | { |
| 177 | CIDA *pcida = (CIDA *)GlobalLock(medium.hGlobal); |
| 178 | if (pcida != nullptr) |
| 179 | { |
| 180 | LPCITEMIDLIST pidlParent = HIDA_GetPIDLFolder(pcida); |
| 181 | for (unsigned i = 0; i < pcida->cidl; ++i) |
| 182 | { |
| 183 | IShellItemPtr pShellItem; |
| 184 | if (SUCCEEDED(hr = SHCreateShellItem(pidlParent, nullptr, HIDA_GetPIDLItem(pcida, i), &pShellItem))) |
| 185 | { |
| 186 | SFGAOF sfgaof = 0; |
| 187 | if (SUCCEEDED(hr = pShellItem->GetAttributes(SFGAO_FOLDER, &sfgaof)) && (sfgaof & SFGAO_FOLDER)) |
| 188 | { |
| 189 | // Folder item |
| 190 | wchar_t *pPath = nullptr; |
| 191 | if (SUCCEEDED(hr = pShellItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &pPath))) |
| 192 | { |
| 193 | root_files.push_back(ucr::toTString(pPath)); |
| 194 | CoTaskMemFree(pPath); |
| 195 | } |
| 196 | } |
| 197 | else |
| 198 | { |
| 199 | // File item |
| 200 | IFileOperationPtr pFileOperation; |
| 201 | if (SUCCEEDED(hr = pFileOperation.CreateInstance(CLSID_FileOperation, nullptr, CLSCTX_ALL))) |
| 202 | { |
| 203 | if (tmpdir.empty()) |
| 204 | tmpdir = env::GetTempChildPath(); |
| 205 | pFileOperation->SetOperationFlags(0); |
| 206 | PIDLIST_ABSOLUTE pidlDest; |
| 207 | if (SUCCEEDED(hr = SHParseDisplayName(ucr::toUTF16(tmpdir).c_str(), nullptr, &pidlDest, 0, nullptr))) |
| 208 | { |
| 209 | IShellItemPtr pShellItemDest; |
| 210 | SHCreateShellItem(nullptr, nullptr, pidlDest, &pShellItemDest); |
| 211 | pFileOperation->CopyItem(pShellItem, pShellItemDest, nullptr, nullptr); |
| 212 | if (SUCCEEDED(hr = pFileOperation->PerformOperations())) |
| 213 | { |
| 214 | wchar_t *pName; |
| 215 | if (SUCCEEDED(hr = pShellItem->GetDisplayName(SIGDN_PARENTRELATIVEPARSING, &pName))) |
| 216 | { |
| 217 | root_files.push_back(paths::ConcatPath(tmpdir, ucr::toTString(pName))); |
| 218 | CoTaskMemFree(pName); |
| 219 | } |
| 220 | } |
| 221 | } |
| 222 | } |
| 223 | } |
| 224 | } |
| 225 | } |
| 226 | GlobalUnlock(medium.hGlobal); |
no test coverage detected