Пример #1
0
std::wstring OsShell::toolTip(std::wstring itemPath)
{
	ComInitializer comInitializer;

	std::replace(itemPath.begin(), itemPath.end(), '/', '\\');
	std::wstring tipString;
	ITEMIDLIST * id = 0;
	HRESULT result = SHParseDisplayName(itemPath.c_str(), 0, &id, 0, 0);
	if (!SUCCEEDED(result) || !id)
		return tipString;
	CItemIdListReleaser idReleaser (id);

	LPCITEMIDLIST child = 0;
	IShellFolder * ifolder = 0;
	result = SHBindToParent(id, IID_IShellFolder, (void**)&ifolder, &child);
	if (!SUCCEEDED(result) || !child)
		return tipString;

	IQueryInfo* iQueryInfo = 0;
	if (SUCCEEDED(ifolder->GetUIObjectOf(NULL, 1, &child, IID_IQueryInfo, 0, (void**)&iQueryInfo)) && iQueryInfo)
	{
		LPWSTR lpszTip = 0;
		CComInterfaceReleaser releaser (iQueryInfo);
		if (SUCCEEDED(iQueryInfo->GetInfoTip(0, &lpszTip)) && lpszTip)
		{
			tipString = lpszTip;
			CoTaskMemFree(lpszTip);
		}
	}

	std::replace(tipString.begin(), tipString.end(), '\r', '\n');
	return tipString;
}
Пример #2
0
 /*
  * Class:     sun_awt_shell_Win32ShellFolder
  * Method:    getIcon
  * Signature: (JJZ)J
  */
 JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder_getIcon__JJZ
 (JNIEnv* env, jobject folder, jlong parentIShellFolder, jlong relativePIDL,
  jboolean getLargeIcon)
 {
     IShellFolder* pParent = (IShellFolder*)parentIShellFolder;
     if (pParent == NULL) {
         return 0;
     }
     LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL;
     if (pidl == NULL) {
         return 0;
     }
     IExtractIcon* pIcon;
     if (pParent->GetUIObjectOf(NULL, 1, const_cast<LPCITEMIDLIST*>(&pidl),
                                IID_IExtractIcon, NULL, (void**)&pIcon) != S_OK) {
         return 0;
     }
     CHAR szBuf[MAX_PATH];
     INT index;
     UINT flags;
     if (pIcon->GetIconLocation(
                 GIL_FORSHELL, szBuf, MAX_PATH, &index, &flags)
             != S_OK) {
         pIcon->Release();
         return 0;
     }
     HICON hIcon;
     HICON hIconLarge;
     if (pIcon->Extract(szBuf, index, &hIconLarge, &hIcon, (16 << 16) + 32) != S_OK) {
         pIcon->Release();
         return 0;
     }
     return (jlong)(getLargeIcon ? hIconLarge : hIcon);
 }
Пример #3
0
// Retrieves the UIObject interface for the specified full PIDL
STDAPI SHGetUIObjectFromFullPIDL(LPITEMIDLIST pidl, HWND hwnd, REFIID riid, void **ppv)
{
    LPCITEMIDLIST pidlChild;
    IShellFolder* psf;

    *ppv = NULL;

    HRESULT hr = SHBindToParent(pidl, IID_IShellFolder, (void**)(&psf), &pidlChild);
    if (SUCCEEDED(hr)) {
        hr = psf->GetUIObjectOf(hwnd, 1, &pidlChild, riid, NULL, ppv);
        psf->Release();
    }
    return hr;
}
Пример #4
0
HRESULT CContextMenuHelper::SHGetContextMenu(std::vector<LPCTSTR> files) {
    HRESULT hr;
    IMalloc *pm = NULL;
    IShellFolder *pDesktop = NULL;
    IShellFolder *psf = NULL;
    LPITEMIDLIST pidl = NULL;
    WCHAR fwname[MAX_PATH + 1];

    if (SUCCEEDED(hr = SHGetMalloc(&pm))) {
        if (SUCCEEDED(hr = SHGetDesktopFolder(&pDesktop))) {
            std::vector<LPITEMIDLIST> pidls;
            IShellFolder* psfFolder = NULL;
            for (UINT i = 0; SUCCEEDED(hr) && i < files.size(); i++) {
                LPCTSTR lpszFilePath = files[i];

                ULONG cch;
                ULONG attrs;

                // Convert to Unicode
                memset(fwname, L'\0', (MAX_PATH + 1) * sizeof(WCHAR));
                MultiByteToWideChar(CP_THREAD_ACP, 0, lpszFilePath, -1, fwname, MAX_PATH);
                if (SUCCEEDED(hr = pDesktop->ParseDisplayName(m_hWnd, NULL, fwname, &cch, &pidl, &attrs))) {
                    LPITEMIDLIST pidlItem = NULL;
                    if (SUCCEEDED(hr = SHBindToParentEx((LPCITEMIDLIST)pidl, IID_IShellFolder, (void **)&psf, (LPCITEMIDLIST *) &pidlItem, pDesktop, pm))) {
                        pidls.push_back(CopyPIDL(pidlItem, pm));
                        pm->Free(pidlItem);
                        if (psfFolder == NULL) {
                            // Remember first folder and we wiil show menu for this one
                            // All other folder will be ignored
                            psfFolder = psf;
                        } else {
                            psf->Release();
                        }
                    }
                    pm->Free(pidl);
                }
            }
            if (SUCCEEDED(hr) && psfFolder != NULL) {
                hr = psfFolder->GetUIObjectOf(m_hWnd, pidls.size(), const_cast<LPCITEMIDLIST*>(pidls.begin()), IID_IContextMenu, NULL, (void**)&m_lpcm);
                psfFolder->Release();
            }
            FreeItemIDList(pidls, pm);
            pDesktop->Release();
        }
        pm->Release();
    }

    return hr;
}
Пример #5
0
bool prepareContextMenuForObjects(std::vector<std::wstring> objects, void * parentWindow, HMENU& hmenu, IContextMenu*& imenu)
{
	ComInitializer comInitializer;

	if (objects.empty())
		return false;

	std::vector<ITEMIDLIST*> ids;
	std::vector<LPCITEMIDLIST> relativeIds;
	IShellFolder * ifolder = 0;
	for (size_t i = 0; i < objects.size(); ++i)
	{
		std::replace(objects[i].begin(), objects[i].end(), '/', '\\');
		ids.push_back(0);
		HRESULT result = SHParseDisplayName(objects[i].c_str(), 0, &ids.back(), 0, 0);
		if (!SUCCEEDED(result) || !ids.back())
		{
			ids.pop_back();
			continue;
		}

		relativeIds.push_back(0);
		result = SHBindToParent(ids.back(), IID_IShellFolder, (void**)&ifolder, &relativeIds.back());
		if (!SUCCEEDED(result) || !relativeIds.back())
			relativeIds.pop_back();
		else if (i < objects.size() - 1 && ifolder)
		{
			ifolder->Release();
			ifolder = nullptr;
		}
	}

	CItemIdArrayReleaser arrayReleaser(ids);

	assert_r(parentWindow);
	assert_and_return_message_r(ifolder, "Error getting ifolder", false);
	assert_and_return_message_r(!relativeIds.empty(), "RelativeIds is empty", false);

	imenu = 0;
	HRESULT result = ifolder->GetUIObjectOf((HWND)parentWindow, (UINT)relativeIds.size(), (const ITEMIDLIST **)relativeIds.data(), IID_IContextMenu, 0, (void**)&imenu);
	if (!SUCCEEDED(result) || !imenu)
		return false;

	hmenu = CreatePopupMenu();
	if (!hmenu)
		return false;
	return (SUCCEEDED(imenu->QueryContextMenu(hmenu, 0, 1, 0x7FFF, CMF_NORMAL)));
}
Пример #6
0
bool OsShell::recycleBinContextMenu(int xPos, int yPos, void *parentWindow)
{
	ComInitializer comInitializer;

	PIDLIST_ABSOLUTE idlist = 0;
	if (!SUCCEEDED(SHGetFolderLocation(0, CSIDL_BITBUCKET, 0, 0, &idlist)))
		return false;

	IShellFolder * iFolder = 0;
	LPCITEMIDLIST list;
	HRESULT result = SHBindToParent(idlist, IID_IShellFolder, (void**)&iFolder, &list);
	if (!SUCCEEDED(result) || !list || !iFolder)
		return false;

	IContextMenu * imenu = 0;
	result = iFolder->GetUIObjectOf((HWND)parentWindow, 1u, &list, IID_IContextMenu, 0, (void**)&imenu);
	CoTaskMemFree(idlist);
	if (!SUCCEEDED(result) || !imenu)
		return false;
	CComInterfaceReleaser menuReleaser(imenu);

	HMENU hMenu = CreatePopupMenu();
	if (!hMenu)
		return false;
	if (SUCCEEDED(imenu->QueryContextMenu(hMenu, 0, 1, 0x7FFF, CMF_NORMAL)))
	{
		int iCmd = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, xPos, yPos, (HWND)parentWindow, NULL);
		if (iCmd > 0)
		{
			CMINVOKECOMMANDINFOEX info = { 0 };
			info.cbSize = sizeof(info);
			info.fMask = CMIC_MASK_UNICODE;
			info.hwnd = (HWND)parentWindow;
			info.lpVerb  = MAKEINTRESOURCEA(iCmd - 1);
			info.lpVerbW = MAKEINTRESOURCEW(iCmd - 1);
			info.nShow = SW_SHOWNORMAL;
			imenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
		}
	}
	DestroyMenu(hMenu);
	return true;
}
Пример #7
0
/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    extractIcon
 * Signature: (JJZ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_extractIcon
    (JNIEnv* env, jclass cls, jlong pIShellFolderL, jlong relativePIDL, jboolean getLargeIcon)
{
    IShellFolder* pIShellFolder = (IShellFolder*)pIShellFolderL;
    LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL;
    if (pIShellFolder == NULL || pidl == NULL) {
        return 0;
    }

    HICON hIcon = NULL;

    HRESULT hres;
    IExtractIconW* pIcon;
    hres = pIShellFolder->GetUIObjectOf(NULL, 1, const_cast<LPCITEMIDLIST*>(&pidl),
                                        IID_IExtractIconW, NULL, (void**)&pIcon);
    if (SUCCEEDED(hres)) {
        WCHAR szBuf[MAX_PATH];
        INT index;
        UINT flags;
        hres = pIcon->GetIconLocation(GIL_FORSHELL, szBuf, MAX_PATH, &index, &flags);
        if (SUCCEEDED(hres)) {
            HICON hIconLarge;
            hres = pIcon->Extract(szBuf, index, &hIconLarge, &hIcon, (16 << 16) + 32);
            if (SUCCEEDED(hres)) {
                if (getLargeIcon) {
                    fn_DestroyIcon((HICON)hIcon);
                    hIcon = hIconLarge;
                } else {
                    fn_DestroyIcon((HICON)hIconLarge);
                }
            }
        }
        pIcon->Release();
    }
    return (jlong)hIcon;
}
Пример #8
0
void CContextMenu::LoadShellMenu(HMENU hMenu, UINT indexMenu)
{
	if(m_pContextMenu)
	{
		m_pContextMenu->Release();
		m_pContextMenu = NULL;
	}

	CPidl cpidl( m_aPidls[0] );
	LPPIDLDATA pData = cpidl.GetData();

	IShellFolder *psfParent; //A pointer to the parent folder object's IShellFolder interface
	LPITEMIDLIST pidlItem = pData->fileData.pidlFS; //the item's PIDL
	LPITEMIDLIST pidlRelative; //the item's PIDL relative to the parent folder
	HRESULT hr;

	hr = ::SHBindToParent
	(
		(LPCITEMIDLIST)pidlItem,
		IID_IShellFolder,
		(void **)&psfParent,
		(LPCITEMIDLIST*)&pidlRelative
	);

	if(S_OK == hr)
	{
		int nCount;
		for(nCount=0; m_aPidls[nCount]; nCount++) {}
		LPITEMIDLIST *pPidls;
		pPidls = (LPITEMIDLIST*)m_pMalloc->Alloc((nCount+1) * sizeof(LPITEMIDLIST));
		ZeroMemory(pPidls, (nCount+1) * sizeof(LPITEMIDLIST));
		for(int i=0; m_aPidls[i]; i++)
		{
			CPidl cpidl( m_aPidls[i] );
			LPPIDLDATA pData = cpidl.GetData();
			if(i == 0)
				pPidls[i] = pidlRelative;
			else
				pPidls[i] = pData->fileData.pidlFS;
		}
		
		LPCONTEXTMENU icm1 = NULL;

		psfParent->GetUIObjectOf
		(
			NULL,
			nCount,
			(LPCITEMIDLIST*)pPidls,
			IID_IContextMenu,
			NULL,
			(void**)&icm1
		);

		m_pMalloc->Free(pPidls);

		int iMenuType = 0;
		
		if(icm1)
		{
			if(icm1->QueryInterface(IID_IContextMenu3, (void**)&m_pContextMenu) == NOERROR)
			{
				iMenuType = 3;
			}
			else if(icm1->QueryInterface(IID_IContextMenu2, (void**)&m_pContextMenu) == NOERROR)
			{
				iMenuType = 2;
			}
			
			if(m_pContextMenu)
			{
				icm1->Release();
			}
			else 
			{	
				iMenuType = 1;
				m_pContextMenu = icm1;
			}

			AddMenuItem(hMenu, NULL, indexMenu++); // Separator

			m_pContextMenu->QueryContextMenu(
				hMenu,
				indexMenu,
				MIN_ID,
				MAX_ID,
				CMF_NORMAL | CMF_EXPLORE);
		}

		psfParent->Release();
	}
}
Пример #9
0
void CFileTreeCtrl::doItemMenu (HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen)
{
	TVITEM   tvItem;

	ZeroMemory(&tvItem, sizeof(tvItem));
	tvItem.mask = TVIF_PARAM;
	tvItem.hItem = hItem;

	if(TreeView_GetItem(hwndTreeView, &tvItem))
	{
		HWND           hwndParent = ::GetParent(hwndTreeView);
	    HRESULT        hr;
	    CTreeItemInfo*     pInfo = (CTreeItemInfo*)tvItem.lParam;
	    IContextMenu   *pcm;
	    IShellFolder   *psfFolder = pInfo->pParentFolder;

		if(!psfFolder)
		{
			SHGetDesktopFolder(&psfFolder);
		}
		else
		{
			psfFolder->AddRef();
		}

		if(psfFolder)
		{
		hr = psfFolder->GetUIObjectOf(   hwndParent, 
                                       1, 
                                       (LPCITEMIDLIST*)&pInfo->pidlSelf,
                                       IID_IContextMenu, 
                                       NULL, 
                                       (LPVOID*)&pcm);

		if(SUCCEEDED(hr))
        {
			HMENU hPopup;

			hPopup = CreatePopupMenu();
			if(hPopup)
			{
	            hr = pcm->QueryContextMenu(hPopup, 0, 1, 0x7fff, CMF_NORMAL | CMF_EXPLORE);

				if(SUCCEEDED(hr))
				{
					IContextMenu2* pcm2;
					pcm->QueryInterface(IID_IContextMenu2, (LPVOID*)&pcm2);

					UINT  idCmd;

					idCmd = TrackPopupMenu( hPopup, 
                                       TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, 
                                       pptScreen->x,
                                       pptScreen->y,
                                       0,
                                       hwndParent,
                                       NULL);
            
					if(pcm2)
					{
						pcm2->Release();
						pcm2 = NULL;
					}

					if(idCmd)
					{
						CMINVOKECOMMANDINFO  cmi;
					  cmi.cbSize = sizeof(CMINVOKECOMMANDINFO);
					  cmi.fMask = 0;
					  cmi.hwnd = hwndParent;
					  cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - 1);
					  cmi.lpParameters = NULL;
					  cmi.lpDirectory = NULL;
					  cmi.nShow = SW_SHOWNORMAL;
					  cmi.dwHotKey = 0;
					  cmi.hIcon = NULL;
					  hr = pcm->InvokeCommand(&cmi);
                  }
               }
            }
	         pcm->Release();
		}
		psfFolder->Release();
      }
   }
}
Пример #10
0
HRESULT AddContextMenu(WCHAR* file)
{
  HRESULT hr = E_UNEXPECTED;
  LPVOID lpVoid;
  HMENU fileMenu = CreatePopupMenu();
  IShellFolder* deskFolder = NULL;
  IShellFolder* appObject = NULL;
  LPITEMIDLIST pidlLocal = NULL;
  LPITEMIDLIST pidlRelative = NULL;
  IContextMenu* contextMenu = NULL;
  CONTEXTINFO contextInfo;

  wcscpy(contextInfo.value, file);

  hr = SHGetDesktopFolder(&deskFolder);
  if (FAILED(hr))
  {
    return hr;
  }

  hr = deskFolder->ParseDisplayName(NULL, NULL, file, NULL, &pidlLocal, NULL);
  if (FAILED(hr))
  {
    deskFolder->Release();
    return hr;
  }

  pidlRelative = ILClone(ILFindLastID(pidlLocal));
  ILRemoveLastID(pidlLocal);

  hr = deskFolder->BindToObject(pidlLocal, NULL, IID_IShellFolder, &lpVoid);
  if (FAILED(hr))
  {
    deskFolder->Release();
    ILFree(pidlLocal);
    return hr;
  }
  appObject = reinterpret_cast <IShellFolder*> (lpVoid);

  deskFolder->Release();
  ILFree(pidlLocal);

  hr = appObject->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidlRelative,
                                IID_IContextMenu, NULL, &lpVoid);
  if (FAILED(hr))
  {
    appObject->Release();
    ILFree(pidlRelative);
    return hr;
  }
  contextMenu = reinterpret_cast <IContextMenu*> (lpVoid);

  ILFree(pidlRelative);
  appObject->Release();

  contextMenu->QueryInterface(IID_IContextMenu2, &lpVoid);
  if (FAILED(hr))
  {
    contextMenu->Release();
    return hr;
  }
  contextInfo.ic2 = reinterpret_cast <IContextMenu2*> (lpVoid);

  contextMenu->Release();

  hr = contextInfo.ic2->QueryContextMenu(fileMenu, 0, SYSMENUMIN, SYSMENUMAX, CMF_NORMAL);
  if (FAILED(hr))
  {
    contextInfo.ic2->Release();
    return hr;
  }

  if (!ELIsDirectory(file))
  {
    AppendMenu(fileMenu, MF_SEPARATOR, 0x8000, NULL);
    AppendMenu(fileMenu, MF_STRING, 0x8001, TEXT("Open Folder"));
  }

  contextMap.insert(std::pair<HMENU, CONTEXTINFO>(fileMenu, contextInfo));

  return hr;
}
Пример #11
0
bool SelectFolder(HWND hOwner)
{
	BROWSEINFO info;
	LPITEMIDLIST pidlist;
	TCHAR path[MAX_PATH];

	if (FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
	{
		return false;
	}
	
	info.hwndOwner = hOwner;
	info.pidlRoot = NULL;
	info.pszDisplayName = path;
	info.lpszTitle = _T("Select a game/mod folder");
	info.ulFlags = BIF_EDITBOX | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
	info.lpfn = NULL;
	info.lParam = 0;
	info.iImage = 0;

	if ((pidlist = SHBrowseForFolder(&info)) == NULL)
	{
		CoUninitialize();
		return false;
	}

	/* This hellish code is from MSDN and translate shortcuts to real targets.
	 * God almighty, I wish Window used real symlinks.
	 */
	bool acquire_success = false;
	bool is_link = false;
	IShellFolder *psf = NULL;
	LPCITEMIDLIST new_item_list;
	HRESULT hr;
	
	hr = SHBindToParent(pidlist, IID_IShellFolder, (void **)&psf, &new_item_list);
	if (SUCCEEDED(hr))
	{
		IShellLink *psl = NULL;

		hr = psf->GetUIObjectOf(hOwner, 1, &new_item_list, IID_IShellLink, NULL, (void **)&psl);
		if (SUCCEEDED(hr))
		{
			LPITEMIDLIST new_item_list;

			hr = psl->GetIDList(&new_item_list);
			if (SUCCEEDED(hr))
			{
				is_link = true;

				hr = SHGetPathFromIDList(new_item_list, method_path);
				if (SUCCEEDED(hr))
				{
					acquire_success = true;
				}

				CoTaskMemFree(new_item_list);
			}
			psl->Release();
		}
		psf->Release();
	}

	if (!acquire_success && !is_link)
	{
		hr = SHGetPathFromIDList(pidlist, method_path);
		if (SUCCEEDED(hr))
		{
			acquire_success = true;
		}
	}

	/* That was awful.  shoo, shoo, COM */
	CoTaskMemFree(pidlist);
	CoUninitialize();

	return acquire_success;
}
Пример #12
0
BOOL CImageUtility::PrintImage(wchar_t* path, wchar_t* file_name )
{
	IShellFolder* pDesktop = NULL;
	HRESULT hr =  ::SHGetDesktopFolder( &pDesktop );
	if( !SUCCEEDED( hr ) )
		return FALSE;

	LPITEMIDLIST pidl = NULL;
	hr = pDesktop->ParseDisplayName(NULL, NULL, path, NULL, &pidl, NULL);
	if( !SUCCEEDED( hr ) )
	{
		pDesktop->Release();
		return FALSE;
	}

	IShellFolder* pPath = NULL;
	hr = pDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (void**)(&pPath) );
	if( !SUCCEEDED( hr ) )
	{
		pDesktop->Release();
		CoTaskMemFree( pidl );
		return FALSE;
	}

	LPITEMIDLIST pidl2 = NULL;
	hr = pPath->ParseDisplayName(NULL, NULL, file_name, NULL, &pidl2, NULL);
	if( !SUCCEEDED( hr ) )
	{
		pDesktop->Release();
		CoTaskMemFree( pidl );
		pPath->Release();
		return FALSE;
	}

	IContextMenu* contextMenu_ptr = NULL;
	hr = pPath->GetUIObjectOf( GetActiveWindow(), 1, (LPCITEMIDLIST*)(&pidl2), IID_IContextMenu, NULL,(void**)(&contextMenu_ptr) );
	if( !SUCCEEDED( hr ) )
	{
		pDesktop->Release();
		CoTaskMemFree( pidl );
		pPath->Release();
		CoTaskMemFree( pidl2 );
		return FALSE;
	}

	HMENU hMenu = CreatePopupMenu();
	if( hMenu == NULL )
	{
		pDesktop->Release();
		CoTaskMemFree( pidl );
		pPath->Release();
		CoTaskMemFree( pidl2 );
		contextMenu_ptr->Release();
		return FALSE;
	}
	contextMenu_ptr->QueryContextMenu( hMenu, 0, 1, 0x7FFF, CMF_NORMAL );
	CMINVOKECOMMANDINFO cmdInfo;
	::memset( &cmdInfo, 0, sizeof(CMINVOKECOMMANDINFO) );
	cmdInfo.cbSize = sizeof(CMINVOKECOMMANDINFO);
	cmdInfo.lpVerb = "print";//"properties";"Print"
	cmdInfo.nShow = SW_SHOW;
	cmdInfo.hwnd = GetActiveWindow();
	hr = contextMenu_ptr->InvokeCommand( &cmdInfo );
	pDesktop->Release();
	CoTaskMemFree( pidl );
	pPath->Release();
	CoTaskMemFree( pidl2 );
	contextMenu_ptr->Release();
	DestroyMenu( hMenu );
	if( SUCCEEDED( hr ) )
		return TRUE;
	else
		return FALSE;
}
Пример #13
0
void CDisplayWindow::ExtractThumbnailImageInternal(ThumbnailEntry_t *pte)
{
	IExtractImage *pExtractImage = NULL;
	IShellFolder *pShellDesktop = NULL;
	IShellFolder *pShellFolder = NULL;
	LPITEMIDLIST pidlParent = NULL;
	LPITEMIDLIST pidlFull = NULL;
	LPITEMIDLIST pridl = NULL;
	HBITMAP hBitmap;
	BITMAP bm;
	RECT rc;
	SIZE size;
	TCHAR szImage[MAX_PATH];
	DWORD dwPriority;
	DWORD dwFlags;
	HRESULT hr;

	m_bThumbnailExtracted = TRUE;
	m_bThumbnailExtractionFailed = TRUE;

	hr = GetIdlFromParsingName(m_ImageFile,&pidlFull);

	if(SUCCEEDED(hr))
	{
		pidlParent = ILClone(pidlFull);
		ILRemoveLastID(pidlParent);

		pridl = ILClone(ILFindLastID(pidlFull));

		hr = SHGetDesktopFolder(&pShellDesktop);

		if(SUCCEEDED(hr))
		{
			hr = pShellDesktop->BindToObject(pidlParent,NULL,IID_IShellFolder,(void **)&pShellFolder);

			if(SUCCEEDED(hr))
			{
				hr = pShellFolder->GetUIObjectOf(NULL,1,(LPCITEMIDLIST *)&pridl,
					IID_IExtractImage,NULL,(void **)&pExtractImage);

				if(SUCCEEDED(hr))
				{
					GetClientRect(m_hDisplayWindow,&rc);

					/* First, query the thumbnail so that its actual aspect
					ratio can be calculated. */
					dwFlags = IEIFLAG_OFFLINE|IEIFLAG_QUALITY|IEIFLAG_ORIGSIZE;
					size.cx = GetRectHeight(&rc) - THUMB_HEIGHT_DELTA;
					size.cy = GetRectHeight(&rc) - THUMB_HEIGHT_DELTA;

					hr = pExtractImage->GetLocation(szImage,MAX_PATH,
						&dwPriority,&size,32,&dwFlags);

					if(SUCCEEDED(hr))
					{
						hr = pExtractImage->Extract(&hBitmap);

						if(SUCCEEDED(hr))
						{
							/* Get bitmap information (including height and width). */
							GetObject(hBitmap,sizeof(BITMAP),&bm);

							/* Delete the original bitmap. */
							DeleteObject(hBitmap);

							/* ...now query the thumbnail again, this time adjusting
							the width of the suggested area based on the actual aspect
							ratio. */
							dwFlags = IEIFLAG_OFFLINE|IEIFLAG_QUALITY|IEIFLAG_ASPECT|IEIFLAG_ORIGSIZE;
							size.cy = GetRectHeight(&rc) - THUMB_HEIGHT_DELTA;
							size.cx = (LONG)((double)size.cy * ((double)bm.bmWidth / (double)bm.bmHeight));
							m_iImageWidth = size.cx;
							m_iImageHeight = size.cy;
							pExtractImage->GetLocation(szImage,MAX_PATH,
								&dwPriority,&size,32,&dwFlags);
							hr = pExtractImage->Extract(&m_hbmThumbnail);

							if(SUCCEEDED(hr))
							{
								/* Check first if we've been cancelled. This might happen,
								for example, if another file is selected while the current
								thumbnail is been found. */
								EnterCriticalSection(&m_csDWThumbnails);

								if(!pte->bCancelled)
								{
									m_bThumbnailExtractionFailed = FALSE;
									InvalidateRect(m_hDisplayWindow,NULL,FALSE);
								}

								LeaveCriticalSection(&m_csDWThumbnails);
							}
							else
							{
								m_bThumbnailExtractionFailed = TRUE;
								m_hbmThumbnail = NULL;
							}
						}
					}

					pExtractImage->Release();
				}

				pShellFolder->Release();
			}

			pShellDesktop->Release();
		}

		CoTaskMemFree(pidlFull);
		CoTaskMemFree(pidlParent);
		CoTaskMemFree(pridl);
	}
}
Пример #14
0
//***************************************************************************************
void CBCGPShellList::DoDefault (int iItem)
{
	LVITEM lvItem;
	
	ZeroMemory(&lvItem, sizeof(lvItem));
	lvItem.mask = LVIF_PARAM;
	lvItem.iItem = iItem;
	
	if (!GetItem (&lvItem))
	{
		return;
	}

	LPBCGCBITEMINFO	pInfo = (LPBCGCBITEMINFO) lvItem.lParam;
	if (pInfo == NULL || pInfo->pParentFolder == NULL || pInfo->pidlRel == NULL)
	{
		ASSERT (FALSE);
		return;
	}

	IShellFolder *psfFolder = pInfo->pParentFolder;
	if (psfFolder == NULL)
	{
		SHGetDesktopFolder (&psfFolder);
	}
	else
	{
		psfFolder->AddRef ();
	}
	
	if (psfFolder == NULL)
	{
		return;
	}

	//-----------------------------------------------------
	// If specified element is a folder, try to display it:
	//-----------------------------------------------------
	ULONG ulAttrs = SFGAO_FOLDER;
	psfFolder->GetAttributesOf (1, 
		(const struct _ITEMIDLIST **) &pInfo->pidlRel, &ulAttrs);

	if (ulAttrs & SFGAO_FOLDER)
	{
		DisplayFolder (pInfo);
	}
	else
	{
		//-------------------------------
		// Invoke a default menu command:
		//-------------------------------
		IContextMenu *pcm;
		HRESULT hr = psfFolder->GetUIObjectOf (GetSafeHwnd (),
			1, 
			(LPCITEMIDLIST*)&pInfo->pidlRel, 
			IID_IContextMenu, 
			NULL, 
			(LPVOID*)&pcm);
		
		if (SUCCEEDED (hr))
		{
			HMENU hPopup = CreatePopupMenu ();

			if (hPopup != NULL)
			{
				hr = pcm->QueryContextMenu (hPopup, 0, 1, 0x7fff, 
											CMF_DEFAULTONLY | CMF_EXPLORE);
				
				if (SUCCEEDED (hr))
				{
					UINT idCmd = ::GetMenuDefaultItem (hPopup, FALSE, 0);
					if (idCmd != 0 && idCmd != (UINT)-1)
					{
						CMINVOKECOMMANDINFO cmi;
						cmi.cbSize = sizeof (CMINVOKECOMMANDINFO);
						cmi.fMask = 0;
						cmi.hwnd = GetParent()->GetSafeHwnd ();
						cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - 1);
						cmi.lpParameters = NULL;
						cmi.lpDirectory = NULL;
						cmi.nShow = SW_SHOWNORMAL;
						cmi.dwHotKey = 0;
						cmi.hIcon = NULL;

						hr = pcm->InvokeCommand (&cmi);

						if (SUCCEEDED (hr) && GetParent () != NULL)
						{
							GetParent ()->SendMessage (BCGPM_ON_AFTER_SHELL_COMMAND,
								(WPARAM) idCmd);
						}
					}
				}
			}
			
			pcm->Release ();
		}
	}
	
	psfFolder->Release ();
}