MCPcopy Create free account
hub / github.com/clechasseur/pathcopycopy / Initialize

Method Initialize

PathCopyCopy/src/PathCopyCopyContextMenuExt.cpp:221–281  ·  view source on GitHub ↗

IShellExtInit::Initialize Called by the shell to initialize our contextual menu extension. We need to use this opportunity to look at the files/folders to act upon. @param p_pFolderPIDL Pointer to ITEMIDLIST representing selected folder. @param p_pDataObject Pointer to data object containing information about selected files/folders. @param p_hKeyFileClass Handle to file class key; unused. @retur

Source from the content-addressed store, hash-verified

219// @return S_OK if successful, otherwise an error code.
220//
221[[gsl::suppress(c.128)]]
222STDMETHODIMP CPathCopyCopyContextMenuExt::Initialize(
223 PCIDLIST_ABSOLUTE p_pFolderPIDL,
224 IDataObject *p_pDataObject,
225 HKEY /*p_hKeyFileClass*/)
226{
227 HRESULT hRes = S_OK;
228
229 try {
230 // Make sure we have a data object.
231 if (p_pDataObject != nullptr) {
232 // Extract HDROP from data object.
233 StStgMedium stgMedium;
234 FORMATETC formatEtc = {CF_HDROP, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
235 if (SUCCEEDED(p_pDataObject->GetData(&formatEtc, &stgMedium))) {
236 // Get number of files included in the selection.
237 const UINT fileCount = ::DragQueryFileW(
238 static_cast<HDROP>(stgMedium.Get().hGlobal), 0xFFFFFFFF, 0, 0);
239 if (fileCount > 0) {
240 // Pre-allocate space in vector to store files.
241 m_vFiles.reserve(fileCount);
242
243 // Get each file in turn.
244 for (UINT i = 0; i < fileCount; ++i) {
245 const auto bufferSize = ::DragQueryFileW(static_cast<HDROP>(stgMedium.Get().hGlobal), i, nullptr, 0);
246 std::wstring buffer(bufferSize + 1, L'\0');
247 ::DragQueryFileW(static_cast<HDROP>(stgMedium.Get().hGlobal), i, &*buffer.begin(), gsl::narrow<UINT>(buffer.size()));
248 m_vFiles.emplace_back(buffer.c_str());
249 }
250 } else {
251 // It's difficult to display a menu item without files to act upon.
252 hRes = E_FAIL;
253 }
254 }
255 } else if (p_pFolderPIDL != nullptr) {
256 // No data object, but maybe it's because user clicked on a folder's
257 // background. Get the folder path from the ID list.
258 std::wstring buffer(MAX_PATH + 1, L'\0');
259 if (::SHGetPathFromIDList(p_pFolderPIDL, &*buffer.begin()) != FALSE) {
260 m_vFiles.emplace_back(buffer.c_str());
261 } else {
262 // Nothing like that either, problem.
263 hRes = E_FAIL;
264 }
265 } else {
266 hRes = E_POINTER;
267 }
268 } catch (...) {
269 hRes = E_UNEXPECTED;
270 }
271
272 if (SUCCEEDED(hRes)) {
273 // Check if files and/or folders are selected.
274 m_FilesSelected = std::any_of(m_vFiles.cbegin(), m_vFiles.cend(),
275 [](const auto& path) { return !PCC::PluginUtils::IsDirectory(path); });
276 m_FoldersSelected = std::any_of(m_vFiles.cbegin(), m_vFiles.cend(),
277 [](const auto& path) { return PCC::PluginUtils::IsDirectory(path); });
278 }

Callers

nothing calls this directly

Calls 6

GetDataMethod · 0.80
GetMethod · 0.45
beginMethod · 0.45
sizeMethod · 0.45
cbeginMethod · 0.45
cendMethod · 0.45

Tested by

no test coverage detected