windows-nt/Source/XPSP1/NT/printscan/ui/uicommon/uiexthlp.cpp
2020-09-26 16:20:57 +08:00

292 lines
10 KiB
C++

/*******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORPORATION, 1998
*
* TITLE: UIEXTHLP.CPP
*
* VERSION: 1.0
*
* AUTHOR: ShaunIv
*
* DATE: 7/8/1999
*
* DESCRIPTION: Helper functions for loading UI extensions for WIA devices
*
*******************************************************************************/
#include "precomp.h"
#pragma hdrstop
#include <initguid.h>
#include "uiexthlp.h"
#include "wiadevd.h"
#include "wiadevdp.h"
#include "itranhlp.h"
#include "isuppfmt.h"
#include "wiaffmt.h"
namespace WiaUiExtensionHelper
{
/*
* Get the clsid of the DLL that implements the interface in the given category
* Example: GetDeviceExtensionClassID( L"{5d8ef5a3-ac13-11d2-a093-00c04f72dc3c}", TEXT("WiaDialogExtensionHandlers"), iid );
* where:
* L"{5d8ef5a3-ac13-11d2-a093-00c04f72dc3c}" is the GUID stored in the WIA property WIA_DIP_UI_CLSID
* TEXT("WiaDialogExtensionHandlers") is the category of extension
* iid is a reference to the CLSID of the in process COM object
*/
HRESULT GetDeviceExtensionClassID( LPCWSTR pwszUiClassId, LPCTSTR pszCategory, IID &iidClassID )
{
TCHAR szRootKeyName[1024];
HRESULT hr = E_FAIL;
// Make sure all of the parameters are valid
if (pwszUiClassId && pszCategory && lstrlenW(pwszUiClassId) && lstrlen(pszCategory))
{
// construct the key name
wsprintf( szRootKeyName, TEXT("CLSID\\%ws\\shellex\\%s"), pwszUiClassId, pszCategory );
HKEY hKeyRoot;
// open the reg key
DWORD dwResult = RegOpenKeyEx( HKEY_CLASSES_ROOT, szRootKeyName, 0, KEY_READ, &hKeyRoot );
if (ERROR_SUCCESS == dwResult)
{
TCHAR szClassID[MAX_PATH];
DWORD dwLength = ARRAYSIZE(szClassID);
// Note that we only take the first one
dwResult = RegEnumKeyEx( hKeyRoot, 0, szClassID, &dwLength, NULL, NULL, NULL, NULL );
if (ERROR_SUCCESS == dwResult)
{
#if defined(UNICODE)
hr = CLSIDFromString(szClassID, &iidClassID);
#else
WCHAR wszClassID[MAX_PATH];
MultiByteToWideChar (CP_ACP, 0, szClassID, -1, wszClassID, MAX_PATH );
hr = CLSIDFromString (wszClassID, &iidClassID);
#endif
}
else hr = HRESULT_FROM_WIN32(dwResult);
RegCloseKey(hKeyRoot);
}
else hr = HRESULT_FROM_WIN32(dwResult);
}
else hr = E_INVALIDARG;
return hr;
}
HRESULT CreateDeviceExtension( LPCWSTR pwszUiClassId, LPCTSTR pszCategory, const IID &iid, void **ppvObject )
{
IID iidClassID;
HRESULT hr = GetDeviceExtensionClassID( pwszUiClassId, pszCategory, iidClassID );
if (SUCCEEDED(hr))
{
WIA_PRINTGUID((iidClassID,TEXT("Calling CoCreateInstance on")));
WIA_PRINTGUID((iid,TEXT("Attempting to get an interface pointer for")));
hr = CoCreateInstance( iidClassID, NULL, CLSCTX_INPROC_SERVER, iid, ppvObject );
}
return hr;
}
HRESULT GetUiGuidFromWiaItem( IWiaItem *pWiaItem, LPWSTR pwszGuid )
{
IWiaPropertyStorage *pPropertyStorage = NULL;
HRESULT hr;
if (pWiaItem && pwszGuid)
{
hr = pWiaItem->QueryInterface( IID_IWiaPropertyStorage, (void**)&pPropertyStorage );
if (SUCCEEDED(hr))
{
PROPSPEC ps[1];
PROPVARIANT pv[1];
ps[0].ulKind = PRSPEC_PROPID;
ps[0].propid = WIA_DIP_UI_CLSID;
hr = pPropertyStorage->ReadMultiple(sizeof(ps)/sizeof(ps[0]), ps, pv);
if (SUCCEEDED(hr))
{
if (VT_LPWSTR == pv[0].vt || VT_BSTR == pv[0].vt)
{
lstrcpyW( pwszGuid, pv[0].bstrVal );
hr = S_OK;
}
FreePropVariantArray( sizeof(pv)/sizeof(pv[0]), pv );
}
pPropertyStorage->Release();
}
}
else hr = E_INVALIDARG;
return hr;
}
HRESULT GetDeviceExtensionClassID( IWiaItem *pWiaItem, LPCTSTR pszCategory, IID &iidClassID )
{
WCHAR wszGuid[MAX_PATH];
HRESULT hr = GetUiGuidFromWiaItem(pWiaItem,wszGuid);
if (SUCCEEDED(hr))
{
hr = GetDeviceExtensionClassID( wszGuid, pszCategory, iidClassID );
}
return hr;
}
HRESULT CreateDeviceExtension( IWiaItem *pWiaItem, LPCTSTR pszCategory, const IID &iid, void **ppvObject )
{
WCHAR wszGuid[MAX_PATH];
HRESULT hr = GetUiGuidFromWiaItem(pWiaItem,wszGuid);
if (SUCCEEDED(hr))
{
hr = CreateDeviceExtension( wszGuid, pszCategory, iid, ppvObject );
}
return hr;
}
HRESULT GetDeviceIcons( IWiaUIExtension *pWiaUIExtension, BSTR bstrDeviceId, HICON *phIconSmall, HICON *phIconLarge, UINT nIconSize )
{
if (!pWiaUIExtension || !bstrDeviceId || !lstrlenW(bstrDeviceId))
return E_INVALIDARG;
// Assume success
HRESULT hr = S_OK;
// Get the small icon, if requested. Return on failure
if (phIconSmall)
{
hr = pWiaUIExtension->GetDeviceIcon(bstrDeviceId,phIconSmall,HIWORD(nIconSize));
if (FAILED(hr))
{
return hr;
}
}
// Get the large icon, if requested. Return on failure
if (phIconLarge)
{
hr = pWiaUIExtension->GetDeviceIcon(bstrDeviceId,phIconLarge,LOWORD(nIconSize));
if (FAILED(hr))
{
return hr;
}
}
return hr;
}
HRESULT GetDeviceIcons( BSTR bstrDeviceId, LONG nDeviceType, HICON *phIconSmall, HICON *phIconLarge, UINT nIconSize )
{
WIA_PUSH_FUNCTION((TEXT("GetDeviceIcons( %ws, %08X, %p, %p, %d )"), bstrDeviceId, nDeviceType, phIconSmall, phIconLarge, nIconSize ));
// Check args
if (!bstrDeviceId || !lstrlenW(bstrDeviceId))
{
return E_INVALIDARG;
}
// Initialize the icons, if necessary
if (phIconSmall)
{
*phIconSmall = NULL;
}
if (phIconLarge)
{
*phIconLarge = NULL;
}
if (!nIconSize)
{
int iLarge = GetSystemMetrics(SM_CXICON);
int iSmall = GetSystemMetrics(SM_CXSMICON);
nIconSize = (UINT)MAKELONG(iLarge, iSmall);
}
// Assume we'll use our own icons
bool bUseDefaultUI = true;
// Try to load device ui extension
CComPtr<IWiaUIExtension> pWiaUIExtension;
HRESULT hr = WiaUiExtensionHelper::CreateDeviceExtension( bstrDeviceId, SHELLEX_WIAUIEXTENSION_NAME, IID_IWiaUIExtension, (void **)&pWiaUIExtension );
if (SUCCEEDED(hr))
{
hr = GetDeviceIcons( pWiaUIExtension, bstrDeviceId, phIconSmall, phIconLarge, nIconSize );
if (SUCCEEDED(hr) || hr != E_NOTIMPL)
{
bUseDefaultUI = false;
}
WIA_PRINTHRESULT((hr,TEXT("GetDeviceIcons returned")));
}
else
{
WIA_PRINTHRESULT((hr,TEXT("WiaUiExtensionHelper::CreateDeviceExtension failed")));
}
WIA_TRACE((TEXT("bUseDefaultUI: %d"), bUseDefaultUI ));
// Use our own extensions (the default UI). We use IWiaMiscellaneousHelpers::GetDeviceIcon, because
// finding the device type given only a device id is horribly slow, since we have to create a device
// manager AND enumerate devices until we find a match. Ugh.
if (bUseDefaultUI)
{
CComPtr<IWiaMiscellaneousHelpers> pWiaMiscellaneousHelpers;
hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaMiscellaneousHelpers, (void**)(&pWiaMiscellaneousHelpers) );
if (SUCCEEDED(hr) && phIconSmall)
{
hr = pWiaMiscellaneousHelpers->GetDeviceIcon( nDeviceType, phIconSmall, HIWORD(nIconSize));
}
if (SUCCEEDED(hr) && phIconLarge)
{
hr = pWiaMiscellaneousHelpers->GetDeviceIcon( nDeviceType, phIconLarge, LOWORD(nIconSize) );
}
if (FAILED(hr))
{
if (phIconSmall && *phIconSmall)
{
DestroyIcon(*phIconSmall);
}
if (phIconLarge && *phIconLarge)
{
DestroyIcon(*phIconLarge);
}
}
}
return hr;
}
CSimpleString GetExtensionFromGuid( IWiaItem *pWiaItem, const GUID &guidFormat )
{
//
// Use the supplied format to get the extension
//
GUID guidFormatToUse = guidFormat;
//
// If we don't have a supplied format, get the default format and use that
//
if (IID_NULL == guidFormatToUse)
{
//
// Get the IWiaSupportedFormats interface
//
CComPtr<IWiaSupportedFormats> pWiaSupportedFormats;
HRESULT hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaSupportedFormats, (void**)&pWiaSupportedFormats );
if (SUCCEEDED(hr))
{
//
// Tell it we want file information for pWiaItem
//
hr = pWiaSupportedFormats->Initialize( pWiaItem, TYMED_FILE );
if (SUCCEEDED(hr))
{
//
// Get the default format
//
GUID guidDefFormat;
hr = pWiaSupportedFormats->GetDefaultClipboardFileFormat( &guidDefFormat );
if (SUCCEEDED(hr))
{
//
// Save this format and use it.
//
guidFormatToUse = guidDefFormat;
}
}
}
}
return CWiaFileFormat::GetExtension( guidFormatToUse, TYMED_FILE, pWiaItem );
}
}