LPITEMIDLIST joinIDlists(LPCITEMIDLIST pidlA, LPCITEMIDLIST pidlB) { LPITEMIDLIST pidl; int cbA, cbB; cbA = GetIDListSize(pidlA); if (cbA) cbA -= sizeof(short); cbB = GetIDListSize(pidlB); pidl = (LPITEMIDLIST)m_alloc(cbA + cbB); if (pidl) { memcpy(pidl, pidlA, cbA); memcpy((BYTE*)pidl + cbA, pidlB, cbB); } return pidl; }
LPITEMIDLIST duplicateIDlist(LPCITEMIDLIST pidl) { LPITEMIDLIST pidlNew; int cb; if (NULL==pidl) return NULL; pidlNew = (LPITEMIDLIST)m_alloc(cb = GetIDListSize(pidl)); memcpy(pidlNew, pidl, cb); return pidlNew; }
STDMETHODIMP CDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { #if 0 LPITEMIDLIST pidl = (LPITEMIDLIST)SendMessage(m_hwnd, BB_DRAGOVER, grfKeyState, (LPARAM)&pt); // ----------------------------------------------------------- // if this is enabled, things are dropped to menu items // rather than to the menu's folder itself int s1 = pidl ? GetIDListSize(pidl) : 0; int s2 = m_pidl ? GetIDListSize(m_pidl) : 0; if (s1 != s2 || (s1 && memcmp(pidl, m_pidl, s1))) { AddRef(); DragLeave(); if (m_pidl) m_free(m_pidl); m_pidl = duplicateIDlist(pidl); DWORD dwEffect = *pdwEffect; DragEnter(m_pDataObject, grfKeyState, pt, &dwEffect); Release(); } // ----------------------------------------------------------- #else SendMessage(m_hwnd, BB_DRAGOVER, grfKeyState, (LPARAM)&pt); #endif // if we have a valid target object, relay the call if(m_pDropTarget) { // mouse pointer information is not really relevant to the shell item... return m_pDropTarget->DragOver(grfKeyState, pt, pdwEffect); } else { *pdwEffect = DROPEFFECT_NONE; // can't accept now return S_OK; } }
STDMETHODIMP CLocateShellExtension::Initialize(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hRegKey) { DebugFormatMessage("CLocateShellExtension::Initialize(%X,%X,%X)",pIDFolder,pDataObj,hRegKey); if (pDataObj==NULL) return E_INVALIDARG; FORMATETC FormatEtc; STGMEDIUM med; FormatEtc.cfFormat=RegisterClipboardFormat(CFSTR_SHELLIDLIST); FormatEtc.ptd=NULL; FormatEtc.dwAspect=DVASPECT_CONTENT; FormatEtc.lindex=-1; FormatEtc.tymed=TYMED_HGLOBAL; if (pDataObj->GetData(&FormatEtc,&med)==S_OK) { // May be computer? IShellFolder *psf; if (!SUCCEEDED(SHGetDesktopFolder(&psf))) { DebugMessage("No IShellFolder interface"); return E_FAIL; } // Retrieving data from item id list BYTE* pData=(BYTE*)GlobalLock(med.hGlobal); UINT nFiles=((int*)pData)[0]; UINT i,nLines=1,nSubIDListLen,nIDListLen; WCHAR szPath[_MAX_PATH]; nSubIDListLen=GetIDListSize((LPITEMIDLIST)(pData+((int*)pData)[1]))-2; for (i=0;i<nFiles;i++) { nIDListLen=GetIDListSize((LPITEMIDLIST)(pData+((int*)pData)[2+i])); // Constructing IDList from parent item and item LPITEMIDLIST pItemIDList=(LPITEMIDLIST)new BYTE[nSubIDListLen+nIDListLen+2]; CopyMemory((BYTE*)pItemIDList,(LPCSTR)(pData+((int*)pData)[1]),nSubIDListLen); CopyMemory((BYTE*)(pItemIDList)+nSubIDListLen,(LPCSTR)(pData+((int*)pData)[2+i]),nIDListLen); if (SHGetPathFromIDListW(pItemIDList,szPath)) { DebugFormatMessage(L"SHGetPathFromIDListW gives %s",szPath); if (IsDirectory(szPath)) { WCHAR szTarget[MAX_PATH]; switch (GetNethoodTarget(szPath,szTarget,MAX_PATH)) { case 1: m_aComputers.Add(alloccopy(szTarget)); break; case 2: m_aDirectories.Add(alloccopy(szTarget)); break; case 0: m_aDirectories.Add(alloccopy(szPath)); break; } } else m_aFiles.Add(alloccopy(szPath)); } else { DebugHexDump("idlist",(BYTE*)pItemIDList,nSubIDListLen+nIDListLen); STRRET str; if (SUCCEEDED(psf->GetDisplayNameOf(pItemIDList,SHGDN_NORMAL|SHGDN_FORPARSING,&str))) { if (SUCCEEDED(StrRetToBufW(&str,pItemIDList,szPath,MAX_PATH))) { if (szPath[0]!='\\' && szPath[1]!='\\') DebugFormatMessage("Cannot add item %s",szPath); else m_aComputers.Add(alloccopy(szPath)); } else DebugMessage("StrRetToStr failed"); } else DebugMessage("GetDisplayNameOf failed"); } delete[] (BYTE*)pItemIDList; } GlobalUnlock(med.hGlobal); if (med.pUnkForRelease==NULL) GlobalFree(med.hGlobal); else med.pUnkForRelease->Release(); psf->Release(); } else { FormatEtc.cfFormat=CF_HDROP; if (m_pDataObj->GetData(&FormatEtc,&med)==S_OK) { LPDROPFILES df=(LPDROPFILES)GlobalLock(med.hGlobal); if (df->fWide) { LPWSTR lpPtr=(LPWSTR)((BYTE*)df+df->pFiles); SIZE_T nLen; while (nLen=wcslen(lpPtr)) { DebugFormatMessage(L"HDROP contains file %s",(LPCSTR)(lpPtr)); if (IsDirectory(lpPtr)) { WCHAR szTarget[MAX_PATH]; switch (GetNethoodTarget(lpPtr,szTarget,MAX_PATH)) { case 1: m_aComputers.Add(alloccopy(szTarget)); break; case 2: m_aDirectories.Add(alloccopy(szTarget)); break; case 0: m_aDirectories.Add(alloccopy(lpPtr,nLen)); break; } } else m_aFiles.Add(alloccopy(lpPtr,nLen)); lpPtr+=nLen+1; } } else { LPSTR lpPtr=(LPSTR)df+df->pFiles; SIZE_T nLen; while (nLen=strlen(lpPtr)) { LPWSTR lpFile=alloccopyAtoW(lpPtr,nLen); if (IsDirectory(lpFile)) m_aDirectories.Add(lpFile); else m_aFiles.Add(lpFile); lpPtr+=nLen+1; } } GlobalUnlock(med.hGlobal); if (med.pUnkForRelease==NULL) GlobalFree(med.hGlobal); else med.pUnkForRelease->Release(); } } // Initialize can be called more than once if (m_pDataObj) m_pDataObj->Release(); // duplicate the object pointer and registry handle if (pDataObj) { m_pDataObj = pDataObj; pDataObj->AddRef(); } return NOERROR; }