Ejemplo n.º 1
0
HRESULT inline CShellBrowser::AddItemInternal(LPITEMIDLIST pidlDirectory,
LPITEMIDLIST pidlRelative,TCHAR *szFileName,int iItemIndex,BOOL bPosition)
{
	int uItemId;

	uItemId = SetItemInformation(pidlDirectory,pidlRelative,szFileName);

	return AddItemInternal(iItemIndex,uItemId,bPosition);
}
void CMyTreeView::AddItem(const TCHAR *szFullFileName)
{
	TCHAR			szDirectory[MAX_PATH];
	HTREEITEM		hParent;
	HTREEITEM		hDeskParent;

	/* If the specified item is a drive, it
	will need to be handled differently,
	as it is a child of my computer (and
	as such is not a regular file). */
	if(PathIsRoot(szFullFileName))
	{
		AddDrive(szFullFileName);
	}
	else
	{
		StringCchCopy(szDirectory, SIZEOF_ARRAY(szDirectory), szFullFileName);
		PathRemoveFileSpec(szDirectory);

		// Check if it is a desktop (sub)child
		hDeskParent = LocateItemOnDesktopTree(szDirectory);

		hParent = LocateExistingItem(szDirectory);

		/* If this items' parent isn't currently shown on the
		treeview and the item is not on the desktop, exit without
		doing anything further. */
		if(hParent == NULL && hDeskParent == NULL)
			return;

		AddItemInternal(hParent,szFullFileName);

		if(hDeskParent != NULL)
		{
			/* If the item is on the desktop, it is a special
			case. We need to update the treeview also starting
			from the root item. */
			AddItemInternal(hDeskParent,szFullFileName);
		}
	}
}
void CMyTreeView::AddDrive(const TCHAR *szDrive)
{
	LPITEMIDLIST	pidlMyComputer = NULL;
	HTREEITEM		hMyComputer;
	HRESULT			hr;

	hr = SHGetFolderLocation(NULL,CSIDL_DRIVES,NULL,0,&pidlMyComputer);

	if(hr == S_OK)
	{
		hMyComputer = LocateExistingItem(pidlMyComputer);

		if(hMyComputer != NULL)
		{
			AddItemInternal(hMyComputer,szDrive);
		}

		CoTaskMemFree(pidlMyComputer);
	}
}
void CShellBrowser::OnFileActionAdded(const TCHAR *szFileName)
{
	IShellFolder	*pShellFolder = NULL;
	LPITEMIDLIST	pidlFull = NULL;
	LPITEMIDLIST	pidlRelative = NULL;
	Added_t			Added;
	TCHAR			FullFileName[MAX_PATH];
	TCHAR			szDisplayName[MAX_PATH];
	STRRET			str;
	BOOL			bFileAdded = FALSE;
	HRESULT hr;

	StringCchCopy(FullFileName,SIZEOF_ARRAY(FullFileName),m_CurDir);
	PathAppend(FullFileName,szFileName);

	hr = GetIdlFromParsingName(FullFileName,&pidlFull);

	/* It is possible that by the time a file is registered here,
	it will have already been renamed. In this the following
	check will fail.
	If the file is not added, store its filename. */
	if(SUCCEEDED(hr))
	{
		hr = SHBindToParent(pidlFull, IID_PPV_ARGS(&pShellFolder), (LPCITEMIDLIST *)&pidlRelative);

		if(SUCCEEDED(hr))
		{
			/* If this is a virtual folder, only use SHGDN_INFOLDER. If this is
			a real folder, combine SHGDN_INFOLDER with SHGDN_FORPARSING. This is
			so that items in real folders can still be shown with extensions, even
			if the global, Explorer option is disabled. */
			if(m_bVirtualFolder)
				hr = pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_INFOLDER,&str);
			else
				hr = pShellFolder->GetDisplayNameOf(pidlRelative,SHGDN_INFOLDER|SHGDN_FORPARSING,&str);

			if(SUCCEEDED(hr))
			{
				StrRetToBuf(&str,pidlRelative,szDisplayName,SIZEOF_ARRAY(szDisplayName));

				std::list<DroppedFile_t>::iterator itr;
				BOOL bDropped = FALSE;

				if(!m_DroppedFileNameList.empty())
				{
					for(itr = m_DroppedFileNameList.begin();itr != m_DroppedFileNameList.end();itr++)
					{
						if(lstrcmp(szDisplayName,itr->szFileName) == 0)
						{
							bDropped = TRUE;
							break;
						}
					}
				}

				/* Only insert the item in its sorted position if it
				wasn't dropped in. */
				if(m_bInsertSorted && !bDropped)
				{
					int iItemId;
					int iSorted;

					iItemId = SetItemInformation(m_pidlDirectory,pidlRelative,szDisplayName);

					iSorted = DetermineItemSortedPosition(iItemId);

					AddItemInternal(iSorted,iItemId,TRUE);
				}
				else
				{
					/* Just add the item to the end of the list. */
					AddItemInternal(m_pidlDirectory,pidlRelative,szDisplayName,-1,FALSE);
				}
				
				InsertAwaitingItems(m_bShowInGroups);

				bFileAdded = TRUE;
			}

			pShellFolder->Release();
		}

		CoTaskMemFree(pidlFull);
	}
	
	if(!bFileAdded)
	{
		/* The file does not exist. However, it is possible
		that is was simply renamed shortly after been created.
		Record the filename temporarily (so that it can later
		be added). */
		StringCchCopy(Added.szFileName,SIZEOF_ARRAY(Added.szFileName),szFileName);
		m_FilesAdded.push_back(Added);
	}
}
Ejemplo n.º 5
0
void CShellBrowser::BrowseVirtualFolder(LPITEMIDLIST pidlDirectory)
{
	IShellFolder	*pShellFolder = NULL;
	IEnumIDList		*pEnumIDList = NULL;
	LPITEMIDLIST	rgelt = NULL;
	STRRET			str;
	SHCONTF			EnumFlags;
	TCHAR			szFileName[MAX_PATH];
	ULONG			uFetched;
	HRESULT			hr;

	DetermineFolderVirtual(pidlDirectory);

	hr = BindToIdl(pidlDirectory, IID_PPV_ARGS(&pShellFolder));

	if(SUCCEEDED(hr))
	{
		m_pidlDirectory = ILClone(pidlDirectory);

		EnumFlags = SHCONTF_FOLDERS|SHCONTF_NONFOLDERS;

		if(m_bShowHidden)
			EnumFlags |= SHCONTF_INCLUDEHIDDEN;

		hr = pShellFolder->EnumObjects(m_hOwner,EnumFlags,&pEnumIDList);

		if(SUCCEEDED(hr) && pEnumIDList != NULL)
		{
			uFetched = 1;
			while(pEnumIDList->Next(1,&rgelt,&uFetched) == S_OK && (uFetched == 1))
			{
				ULONG uAttributes = SFGAO_FOLDER;

				pShellFolder->GetAttributesOf(1,(LPCITEMIDLIST *)&rgelt,&uAttributes);

				/* If this is a virtual folder, only use SHGDN_INFOLDER. If this is
				a real folder, combine SHGDN_INFOLDER with SHGDN_FORPARSING. This is
				so that items in real folders can still be shown with extensions, even
				if the global, Explorer option is disabled.
				Also use only SHGDN_INFOLDER if this item is a folder. This is to ensure
				that specific folders in Windows 7 (those under C:\Users\Username) appear
				correctly. */
				if(m_bVirtualFolder || (uAttributes & SFGAO_FOLDER))
					hr = pShellFolder->GetDisplayNameOf(rgelt,SHGDN_INFOLDER,&str);
				else
					hr = pShellFolder->GetDisplayNameOf(rgelt,SHGDN_INFOLDER|SHGDN_FORPARSING,&str);

				if(SUCCEEDED(hr))
				{
					StrRetToBuf(&str,rgelt,szFileName,MAX_PATH);

					AddItemInternal(pidlDirectory,rgelt,szFileName,-1,FALSE);
				}

				CoTaskMemFree((LPVOID)rgelt);
			}

			pEnumIDList->Release();
		}

		pShellFolder->Release();
	}
}