Ejemplo n.º 1
0
// On Vista or 7 we could use SHIL_JUMBO to get a 256x256 icon,
// but we'll use SHCreateItemFromParsingName as it'll give an identical
// icon to the one shown in explorer and it scales automatically.
bool WinIconProvider::addIconFromShellFactory(QString filePath, QIcon& icon) const
{
	HRESULT hr = S_FALSE;

	if (fnSHCreateItemFromParsingName)
	{
		IShellItem* psi = NULL;
        hr = fnSHCreateItemFromParsingName((PCWSTR)filePath.utf16(), 0, IID_IShellItem, (void**)&psi);
		if (hr == S_OK)
		{
			IShellItemImageFactory* psiif = NULL;
			hr = psi->QueryInterface(IID_IShellItemImageFactory, (void**)&psiif);
			if (hr == S_OK)
			{
				HBITMAP iconBitmap = NULL;
				SIZE iconSize = {preferredSize, preferredSize};
				hr = psiif->GetImage(iconSize, SIIGBF_RESIZETOFIT | SIIGBF_ICONONLY, &iconBitmap);
				if (hr == S_OK)
				{
                    QPixmap iconPixmap = QtWin::fromHBITMAP(iconBitmap);
					icon.addPixmap(iconPixmap);
					DeleteObject(iconBitmap);
				}

				psiif->Release();
			}
			psi->Release();
		}
	}

	return hr == S_OK;
}
//------------------------------------------------------------------------------
// CDeviceContextMenu::Invoke
//
//      Invoke the context menu item.
//------------------------------------------------------------------------------
IFACEMETHODIMP CDeviceContextMenu::Invoke(
    __in IShellItemArray* psiItemArray,
    __in IBindCtx* pbc
    )
{
    UNREFERENCED_PARAMETER( pbc );

    HRESULT         hr              = S_OK;
    IShellItem*     pShellItem      = NULL;
    IShellItem2*    pShellItem2     = NULL;
    LPWSTR          pszHardwareID   = NULL;
    PROPVARIANT     pv              = {0};
    PWSTR           pszName         = NULL;

    if( NULL == psiItemArray )
    {
        return E_INVALIDARG;
    }

    PropVariantInit( &pv );

    // 
    // The selected device is the only shell item in the shell item array.
    // Use GetItemAt with index 0 to get the shell item corresponding to the
    // selected device.
    //
    if( S_OK == hr )
    {
        hr = psiItemArray->GetItemAt( 0, &pShellItem );
    }

    //
    // Get the IShellItem2 interface of the shell item, so we can
    // access its properties from the shell item directly or from
    // the devnode(s) of the device. 
    //
    if( S_OK == hr )
    {
        hr = pShellItem->QueryInterface( 
            __uuidof(pShellItem2), 
            reinterpret_cast<void**>(&pShellItem2)
            );
    }

    //
    // Here you might take a look at the saved m_pszCommandName to
    // decide what actions to take and what application to end up
    // launching.
    //

    //
    // Get device's properties directly from the shell item object. In
    // this case we'll get the name. 
    //
    if( S_OK == hr )
    {
        hr = pShellItem2->GetProperty( PKEY_ItemNameDisplay, &pv );
    }
    if( S_OK == hr &&
        VT_LPWSTR == pv.vt )
    {
        hr = SHStrDup( pv.pwszVal, &pszName );
    }

    //
    // Get device's properties from the devnode(s) of the device.
    // We get one of the device's hardware ids in this sample.
    //
    if( S_OK == hr )
    {
        // ignore the failure because we don't use this information
        // in this sample.
        GetDeviceHardwareID( pShellItem2, &pszHardwareID );
    }

    //
    // Launch a thread to show a message box with one of the properties
    // we grabbed. This section of code would be replaced with code to
    // launch an relevant device related application based on
    // contextual information from the properties (if needed).
    //
    // A separate thread is used here to avoid blocking the main UI 
    // thread while the message box exists.
    //
    if( S_OK == hr )
    {
        CreateThread( NULL, 0, _ExecuteThreadProc, pszName, 0, NULL );
    }

    //
    // Clean up
    //
    if( NULL != pShellItem )
    {
        pShellItem->Release();
    }

    if( NULL != pShellItem2 )
    {
        pShellItem2->Release();
    }

    if( NULL != pszHardwareID )
    {
        CoTaskMemFree( pszHardwareID );
    }
        
    PropVariantClear( &pv );
   
    return hr;
} // CDeviceContextMenu::Invoke