bool sh_get_uiobject( const _ITEMIDLIST * pidl, _ITEMIDLIST ** ppidlPath, _ITEMIDLIST ** ppidlItem, struct IShellFolder **ppsfFolder, const struct _GUID riid, void **pObject ) { *ppidlItem = NULL; *ppsfFolder = NULL; *pObject = NULL; LPITEMIDLIST p = *ppidlPath = duplicateIDlist(pidl); if (NULL == p) return false; //get last shit.emid - the file while (NextID(p)->mkid.cb) p = NextID(p); *ppidlItem = duplicateIDlist(p); p->mkid.cb=0; if (NULL == (*ppsfFolder = sh_get_folder_interface(*ppidlPath))) return false; //fake ITEMIDLIST - array for 1 file object HRESULT hr = (*ppsfFolder)->GetUIObjectOf((HWND)NULL, 1, (LPCITEMIDLIST*)ppidlItem, riid, NULL, pObject); return SUCCEEDED(hr) && NULL != *pObject; }
LPITEMIDLIST sh_getpidl (IShellFolder *pSF, const char *path) { HRESULT hr; WCHAR wpath[MAX_PATH]; ULONG chEaten; LPITEMIDLIST pIDFolder; if (NULL == pSF) { hr = SHGetDesktopFolder(&pSF); if (NOERROR!=hr) return NULL; } char temp[MAX_PATH]; replace_slashes(temp, path); MultiByteToWideChar(CP_ACP, 0, temp, -1, wpath, MAX_PATH); hr = pSF->ParseDisplayName( NULL, NULL, wpath, &chEaten, &pIDFolder, NULL); pSF->Release(); if (NOERROR!=hr) return NULL; LPITEMIDLIST pID = duplicateIDlist(pIDFolder); SHMalloc_Free(pIDFolder); return pID; }
//================================================ struct pidl_node *copy_pidl_list(const struct pidl_node *old_pidl_list) { const struct pidl_node *p; struct pidl_node *new_pidl_list = NULL; dolist (p, old_pidl_list) append_node(&new_pidl_list, new_node(duplicateIDlist(p->v))); return new_pidl_list; }
CDropTarget(HWND hwnd, LPCITEMIDLIST pidl) { m_dwRef = 1; m_pDropTarget = NULL; m_hwnd = hwnd; m_pidl = duplicateIDlist(pidl); m_pDataObject = NULL; //dbg_printf("CDropTarget created %d", ++objcount); };
LPITEMIDLIST get_folder_pidl (const char *rawpath) { if (NULL==rawpath) return NULL; char path [MAX_PATH]; char temp [MAX_PATH]; unquote(temp, rawpath); if (false == is_relative_path(temp)) { if (is_alpha(temp[0]) && temp[1] == ':' && temp[2] == 0) temp[2] = '\\', temp[3] = 0; return sh_getpidl(NULL, temp); } const char *p = temp; int id = get_csidl(&p); if (NO_CSIDL == id || CSIDL_BLACKBOX == id || CSIDL_CURTHEME == id) { GetBlackboxPath(path, MAX_PATH); if (NO_CSIDL != id) path[strlen(path)-1] = 0; if (p) strcat(path, p); return sh_getpidl(NULL, path); } // special folders, like CONTROLS LPITEMIDLIST pID1, pID; if (NOERROR != SHGetSpecialFolderLocation(NULL, id, &pID1)) return sh_getpidl(NULL, temp); if (NULL == p) { pID = duplicateIDlist(pID1); } else { pID = NULL; // a subdirectory is specified, like APPDATA\microsoft // so get its local pidl and append it IShellFolder* pThisFolder = sh_get_folder_interface(pID1); if (pThisFolder) { LPITEMIDLIST pID2 = sh_getpidl(pThisFolder, p+1); if (pID2) { pID = joinIDlists(pID1, pID2); m_free(pID2); } } } SHMalloc_Free(pID1); return pID; }
//=========================================================================== // SpecialFolder //=========================================================================== SpecialFolder::SpecialFolder(const TCHAR *pszTitle, const struct pidl_node *pidl_list, const TCHAR *optional_command) : Menu(pszTitle) { m_MenuID = MENU_ID_SF; // ID m_pidl_list = NULL; // the list of pidl m_notify = 0; // create a copy of the SpecialFolderItem's pidl-list m_pidl_list = copy_pidl_list(pidl_list); m_pszExtra = new_str(optional_command); // attach a copy of the (first) pidl to the TitleItem (for // "shift - right - click on title" - context menu. if (m_pidl_list) m_pMenuItems->m_pidl = duplicateIDlist(m_pidl_list->v); // fill menu UpdateFolder(); }
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; } }