2025-11-28 00:35:46 +09:00

475 lines
16 KiB
C++

//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//--------------------------------------------------------------------------
//------------------------------------------------------------
//Please read the ReadME.txt which explains the purpose of the
//sample.
//-------------------------------------------------------------
#include "ScanProfile.h"
// This function creates a Scan Profile Dialog
HRESULT CreateScanProfileUI(HWND hwndParent)
{
IScanProfileUI* pScanProfileUI = NULL;
//Create ScanProfileUI instance
HRESULT hr = CoCreateInstance(CLSID_ScanProfileUI, NULL, CLSCTX_INPROC_SERVER, IID_IScanProfileUI, reinterpret_cast<LPVOID *>(&pScanProfileUI));
if(SUCCEEDED(hr))
{
//Create ScanProfileDialog from IScanProfileUI interface
hr = pScanProfileUI->ScanProfileDialog(hwndParent);
if(FAILED(hr))
{
ReportError( TEXT("An error occurred while creating ScanProfileDialog"), hr );
}
//Release IScanProfileUI interface
pScanProfileUI->Release();
pScanProfileUI = NULL;
}
else
{
ReportError( TEXT("CoCreateInstance failed on CLSID_ScanProfileUI"), hr );
}
return hr;
}
// This function reads the Device ID (needed for creating scan profiles) and Device name.
HRESULT ReadDevIDandDevName( IWiaPropertyStorage *pWiaPropertyStorage , BSTR* pbstrDevID , BSTR* pbstrDevName)
{
// Validate arguments
if ( (NULL == pWiaPropertyStorage) || (NULL == pbstrDevID) || (NULL == pbstrDevName) )
{
HRESULT hr = E_INVALIDARG;
ReportError(TEXT("Invalid args passed to ReadDevIDandDevName()"),hr);
return hr;
}
//Read the Device ID from the IWiaPropertyStorage interface
HRESULT hr = ReadPropertyBSTR(pWiaPropertyStorage,WIA_DIP_DEV_ID, pbstrDevID);
if(FAILED(hr))
{
ReportError(TEXT("ReadPropertyBSTR() failed for WIA_DIP_DEV_ID"),hr);
*pbstrDevID = NULL;
return hr;
}
//Read the Device Name from the IWiaPropertyStorage interface
hr = ReadPropertyBSTR(pWiaPropertyStorage,WIA_DIP_DEV_NAME, pbstrDevName);
if(FAILED(hr))
{
ReportError(TEXT("ReadPropertyBSTR() failed for WIA_DIP_DEV_NAME"),hr);
*pbstrDevName = NULL;
}
return hr;
}
// This function gets the Device ID from the profile and prints it
HRESULT ProfileDisplayDeviceID(IScanProfile* pScanProfile)
{
// Validate arguments
if( (!pScanProfile) )
{
HRESULT hr = E_INVALIDARG;
ReportError(TEXT("Invalid args passed to ProfileDisplayDeviceID()"),hr);
return hr;
}
BSTR bstrDevID = NULL;
HRESULT hr = pScanProfile->GetDeviceID(&bstrDevID);
if(SUCCEEDED(hr))
{
_tprintf(TEXT("\nDeviceID retreived from the profile => %ws"),bstrDevID);
}
else
{
ReportError(TEXT("Error calling pScanProfile->GetDeviceID()"),hr);
}
return hr;
}
// This function sets the name of the profile and then prints it
HRESULT ProfileSetAndDisplayName(IScanProfile* pScanProfile)
{
// Validate arguments
if( (!pScanProfile) )
{
HRESULT hr = E_INVALIDARG;
ReportError(TEXT("Invalid args passed to ProfileSetAndDisplayName()"),hr);
return hr;
}
BSTR bstrProfileName = SysAllocString(PROFILE_NAME);
HRESULT hr = pScanProfile->SetName(bstrProfileName);
if(SUCCEEDED(hr))
{
//Get the name of the profile
BSTR bstrProfileGetName;
hr = pScanProfile->GetName(&bstrProfileGetName);
if(SUCCEEDED(hr))
{
_tprintf(TEXT("\nProfile name just created for the device => %ws"),bstrProfileGetName);
}
else
{
ReportError(TEXT("Error calling pScanProfile->GetName()"),hr);
}
}
else
{
ReportError(TEXT("Error calling pScanProfile->SetName()"),hr);
}
return hr;
}
// This function prints the no of profiles associated with the device
HRESULT GetNumberOfProfiles(IScanProfileMgr* pScanProfileMgr, BSTR bstrDevID, ULONG* lNumProfiles)
{
// Validate arguments
if( (!bstrDevID) || (!lNumProfiles) || (!pScanProfileMgr) )
{
HRESULT hr = E_INVALIDARG;
ReportError(TEXT("Invalid args passed to GetNumberOfProfiles()"),hr);
return hr;
}
//Initialize out variables
*lNumProfiles = 0;
HRESULT hr = pScanProfileMgr->GetNumProfilesforDeviceID(bstrDevID,lNumProfiles);
if(SUCCEEDED(hr))
{
_tprintf(TEXT("\nNo of Profiles for this device => %ld"),*lNumProfiles);
}
else
{
ReportError(TEXT("Error calling pScanProfileMgr->GetNumProfilesforDeviceID()"),hr);
}
return hr;
}
// This function prints all the names of the profiles associated with the device
HRESULT DisplayAllProfilesForDevice(IScanProfileMgr* pScanProfileMgr,BSTR bstrDevID, ULONG lNumProfiles)
{
// Validate arguments
if( (!bstrDevID) || (!pScanProfileMgr) )
{
HRESULT hr = E_INVALIDARG;
ReportError(TEXT("Invalid args passed to DisplayAllProfilesForDevice()"),hr);
return hr;
}
HRESULT hr = S_OK;
IScanProfile** arr_pScanProfileDevice = NULL;
arr_pScanProfileDevice = new IScanProfile*[lNumProfiles * sizeof(IScanProfile*)];
if(arr_pScanProfileDevice)
{
hr = pScanProfileMgr->GetProfilesforDeviceID(bstrDevID,&lNumProfiles,arr_pScanProfileDevice);
if(SUCCEEDED(hr))
{
for( ULONG count=0 ; count < lNumProfiles ; count ++)
{
BSTR bstrProfDeviceName = NULL;
//Print the names of all the profiles
hr = arr_pScanProfileDevice[count]->GetName(&bstrProfDeviceName);
if(SUCCEEDED(hr))
{
_tprintf(TEXT("\nName of Profile No.%d for the device => %ws"),count+1,bstrProfDeviceName);
//release all the IScanProfile pointers
arr_pScanProfileDevice[count]->Release();
arr_pScanProfileDevice[count] = NULL;
}
else
{
ReportError(TEXT("Error calling IScanProfile::GetName()"),hr);
}
}
}
else
{
ReportError(TEXT("Error calling pScanProfileMgr->GetProfilesforDeviceID()"),hr);
}
}
else
{
hr = E_OUTOFMEMORY;
ReportError(TEXT("Could not allocate memory for arr_pScanProfileDevice"),hr);
}
return hr;
}
//This function creates the scan profiles for the device and also performs various operations on them
HRESULT CreateScanProfiles(BSTR bstrDeviceID , BSTR bstrDeviceName)
{
// Validate arguments
if( (!bstrDeviceName) || (!bstrDeviceID) )
{
HRESULT hr = E_INVALIDARG;
ReportError(TEXT("Invalid args passed to CreateScanProfiles()"),hr);
return hr;
}
//Create scan profile manager
IScanProfileMgr* pScanProfileMgr = NULL;
HRESULT hr = CoCreateInstance(CLSID_ScanProfileMgr, NULL, CLSCTX_INPROC_SERVER, IID_IScanProfileMgr, reinterpret_cast<LPVOID *>(&pScanProfileMgr));
_tprintf(TEXT("\n\n\nDevice Name => %ws \nDeviceID => %ws"), bstrDeviceName, bstrDeviceID);
if(SUCCEEDED(hr)){
//create scan profile
IScanProfile* pScanProfile = NULL;
hr = pScanProfileMgr->CreateProfile(bstrDeviceID,bstrDeviceName,WIA_CATEGORY_FLATBED, &pScanProfile);
if(SUCCEEDED(hr)){
_tprintf(TEXT("\nSuccessfully created profile for the device"));
// Display the deviceID back from the profile
ProfileDisplayDeviceID(pScanProfile);
// Set the name of the profile and display it.
ProfileSetAndDisplayName(pScanProfile);
//Set various properties in the profile
PROPID propID[3] = {WIA_IPS_BRIGHTNESS,WIA_IPS_CONTRAST,WIA_IPA_FORMAT};
PROPVARIANT propVar[3];
propVar[0].vt = VT_I4;
propVar[0].lVal = 75;
propVar[1].vt = VT_I4;
propVar[1].lVal = 60;
propVar[2].vt = VT_CLSID;
GUID guidFormat = WiaImgFmt_BMP;
propVar[2].puuid = &guidFormat;
hr = pScanProfile->SetProperty(3, propID, propVar);
if(SUCCEEDED(hr))
{
//Get Various properties in the profile
PROPID propid[] = {WIA_IPS_BRIGHTNESS,WIA_IPS_CONTRAST};
PROPVARIANT propVariant[2];
PropVariantInit(propVariant);
hr = pScanProfile->GetProperty(2, propid, propVariant);
if(SUCCEEDED(hr))
{
//Print the Brightness and XRES
_tprintf(TEXT("\nFor the profile just created, Brightness = %ld , WIA_IPS_CONTRAST = %ld") , propVariant[0].lVal , propVariant[1].lVal);
}
else
{
ReportError(TEXT("Error calling pScanProfile->GetProperty()"),hr);
}
}
else
{
ReportError(TEXT("Error calling pScanProfile->SetProperty()"),hr);
}
//Save the Scanprofile
hr = pScanProfile->Save();
if(SUCCEEDED(hr))
{
//Set the profile as default . Hence in push scanning this profile will be used.
hr = pScanProfileMgr->SetDefault(pScanProfile);
if(FAILED(hr))
{
ReportError(TEXT("Error calling pScanProfileMgr->SetDefault()"),hr);
}
}
else
{
ReportError(TEXT("Error calling pScanProfile->Save()"),hr);
}
//Release pScanProfile
pScanProfile->Release();
pScanProfile = NULL;
}
else
{
ReportError(TEXT("pScanProfileMgr->CreateProfile() failed."),hr);
}
// get the no of profiles for the device
ULONG lNumProfiles = 0;
hr = GetNumberOfProfiles(pScanProfileMgr,bstrDeviceID,&lNumProfiles);
if(SUCCEEDED(hr))
{
//Display all the profiles for the device
DisplayAllProfilesForDevice(pScanProfileMgr,bstrDeviceID,lNumProfiles);
}
else
{
ReportError(TEXT("Error calling GetNumberOfProfiles()"),hr);
}
//Release pScanProfileMgr
pScanProfileMgr->Release();
pScanProfileMgr = NULL;
}
else
{
ReportError(TEXT("CoCreateInstance failed for ScanProfileMgr"),hr);
}
return hr;
}
//This function enumerates the WIA devices and then creates scan profiles for each.
HRESULT EnumWiaDevicesandCreateScanProfiles( IWiaDevMgr2 *pWiaDevMgr2 )
{
// Validate arguments
if (NULL == pWiaDevMgr2)
{
return E_INVALIDARG;
}
// Get a device enumerator interface
IEnumWIA_DEV_INFO *pWiaEnumDevInfo = NULL;
HRESULT hr = pWiaDevMgr2->EnumDeviceInfo( WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo );
if (SUCCEEDED(hr))
{
// Reset the device enumerator to the beginning of the list
hr = pWiaEnumDevInfo->Reset();
if (SUCCEEDED(hr))
{
// We will loop until we get an error or pWiaEnumDevInfo->Next returns
// S_FALSE to signal the end of the list.
while (S_OK == hr)
{
// Get the next device's property storage interface pointer
IWiaPropertyStorage *pWiaPropertyStorage = NULL;
hr = pWiaEnumDevInfo->Next( 1, &pWiaPropertyStorage, NULL );
// pWiaEnumDevInfo->Next will return S_FALSE when the list is
// exhausted, so check for S_OK before using the returned
// value.
if (hr == S_OK)
{
//Read Device name and Device ID
//We will use Device name to create profile names
BSTR bstrDevID = NULL;
BSTR bstrDevName = NULL;
HRESULT hr1 = ReadDevIDandDevName(pWiaPropertyStorage , &bstrDevID ,&bstrDevName);
if(SUCCEEDED(hr1))
{
//Create and perform operations on profiles by calling various IScanProfile API's
hr1 = CreateScanProfiles(bstrDevID,bstrDevName);
if(FAILED(hr1))
{
ReportError(TEXT("Error calling CreateScanProfiles()"),hr1);
}
}
// Release the device's IWiaPropertyStorage*
pWiaPropertyStorage->Release();
pWiaPropertyStorage = NULL;
}
else if (FAILED(hr))
{
// Report that an error occurred during enumeration
ReportError( TEXT("Error calling IEnumWIA_DEV_INFO::Next()"), hr );
}
}
// If the result of the enumeration is S_FALSE, since this
// is normal, we will change it to S_OK.
if (S_FALSE == hr)
{
hr = S_OK;
}
}
else
{
// Report that an error occurred calling Reset()
ReportError( TEXT("Error calling IEnumWIA_DEV_INFO::Reset()"), hr );
}
// Release the enumerator
pWiaEnumDevInfo->Release();
pWiaEnumDevInfo = NULL;
}
else
{
// Report that an error occurred trying to create the enumerator
ReportError( TEXT("Error calling IWiaDevMgr2::EnumDeviceInfo"), hr );
}
// Return the result of the enumeration
return hr;
}
//Entry point of the application
extern "C"
int __cdecl _tmain( int, TCHAR *[] )
{
// Initialize COM
HRESULT hr = CoInitialize(NULL);
if (SUCCEEDED(hr))
{
//Now Demonstrating how to create scan profiles and do operations on them by calling various IScanProfile API's, ie. without GUI.
hr = CreateScanProfilesWithoutUI();
if(FAILED(hr))
{
ReportError(TEXT("Error calling CreateScanProfilesWithoutUI()"),hr);
}
//Demonstrating how to create, edit and delete scan profiles through a ScanProfile dialog, ie. using a GUI interface IScanProfileUI.
hr = CreateScanProfileUI((HWND)0);
if(FAILED(hr))
{
ReportError(TEXT("Error calling CreateScanProfileUI()"),hr);
}
// Uninitialize COM
CoUninitialize();
}
else
{
ReportError(TEXT("CoInitialize() failed"),hr);
}
return 0;
}
// This function is the top level function for creating scan profiles .
HRESULT CreateScanProfilesWithoutUI()
{
// Create the device manager
IWiaDevMgr2 *pWiaDevMgr2 = NULL;
HRESULT hr = CoCreateInstance( CLSID_WiaDevMgr2, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr2, (void**)&pWiaDevMgr2 );
if (SUCCEEDED(hr))
{
//To create scan profiles without a ScanProfile dialog , deviceID is needed
//Hence we will get the device ID's of all WIA devices and then create scan profiles for each device
//Enumerate all of the WIA devices, get deviceID's and create scan profiles for each device
hr = EnumWiaDevicesandCreateScanProfiles( pWiaDevMgr2 );
if (FAILED(hr))
{
ReportError( TEXT("Error calling EnumWiaDevicesandCreateScanProfiles()"), hr );
}
// Release the device manager
pWiaDevMgr2->Release();
pWiaDevMgr2 = NULL;
}
else
{
ReportError( TEXT("CoCreateInstance() failed on CLSID_WiaDevMgr"), hr );
}
return hr;
}