//========================================================================== // // 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(&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(&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; }