// 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