Solved

Acquiring with TWAIN

Posted on 1998-10-11
1
3,096 Views
Last Modified: 2013-11-20
I have downloaded the TWAIN SDK from the twain org website, but am having a heck of a time understanding it all.  I want scan a small image from my scanner and use the newly acquired bitmap in my program.  Does anyone know how to implement the acquire funtion? (or ANY function for that matter)  How do i get the scanner to scan, and How do i retreive the image that is scanned?  I am using visualc++ 5.  I am reading the literature included in the devel. kit but it is confusing. a more simplified approach would be helpful. thanks.
0
Comment
Question by:progstudent
1 Comment
 
LVL 7

Accepted Solution

by:
psdavis earned 70 total points
Comment Utility
Here's my own implementation of the TWAIN code for you...  Ignore the imgdes stuff.  That is a separate library that I used for implementing the images...

// TWAINDRV.CPP

#include "stdafx.h"

#include "twaindrv.h"

#ifdef _WIN32
  #define DSM_FILENAME "TWAIN_32.DLL"
  #define DSM_ENTRYPOINT "DSM_Entry"
#else
  #define DSM_FILENAME "TWAIN.DLL"
  #define DSM_ENTRYPOINT "DSM_ENTRY"
#endif

CTwain::CTwain( imgdes* vImage )
{
   m_vTwainImage   = vImage;
   m_hWnd          = NULL;

   m_hDSMDLL       = NULL;                   // handle to Source Manager for explicit load
   m_lpDSM_Entry   = NULL;                   // function pointer to Source Mang. entry
   m_eCurrentState = TWAIN_MANAGER_PRE;      // State 1
   m_bShowUI       = TRUE;

   TRACE0( "TWAIN: Initialized\n" );
   }

CTwain::~CTwain( )
{
   CloseSourceManager();
   UnloadSourceManager();
   }

// User callable functions

void CTwain::SetWindow( CWnd* pWnd )
{
   m_hWnd = pWnd->GetSafeHwnd( );
   }

// Underlying private functions                          

BOOL CTwain::LoadSourceManager( )
{
   if( m_eCurrentState >= TWAIN_MANAGER_LOADED )
      return TRUE;

// Get the windows path

   char szWinDir[ MAX_PATH ];
   GetWindowsDirectory( szWinDir, MAX_PATH );

   if( szWinDir[ strlen( szWinDir ) - 1 ] != '\\' )
      lstrcat( szWinDir, "\\" );

// Add the name of the DLL to the path

   lstrcat( szWinDir, DSM_FILENAME );

// Make sure that the twain DLL exists!

   CFileStatus pStatus;
   if( CFile::GetStatus( szWinDir, pStatus ) == 0 )
      return FALSE;

// Load the library!

   m_hDSMDLL = LoadLibrary( DSM_FILENAME );
           
   #if _WIN32
      if( m_hDSMDLL == NULL || m_hDSMDLL < (HANDLE) VALID_HANDLE )
         return FALSE;
   #else
      if( (UINT) m_hDSMDLL <= 32 )
         return FALSE;        
   #endif

// Find the pointer to the function DSM_Entry!

   m_lpDSM_Entry = (DSMENTRYPROC) GetProcAddress( (HINSTANCE) m_hDSMDLL, DSM_ENTRYPOINT );

   if( m_lpDSM_Entry == NULL )
      return FALSE;

   m_eCurrentState = TWAIN_MANAGER_LOADED;

   return TRUE;
   }

BOOL CTwain::UnloadSourceManager( )
{
   if( m_eCurrentState == TWAIN_MANAGER_PRE )
      return TRUE;

   FreeLibrary( (HINSTANCE) m_hDSMDLL );
   m_hDSMDLL      = NULL;     // handle to Source Manager for explicit load
   m_lpDSM_Entry  = NULL;     // function pointer to Source Mang. entry

   m_eCurrentState = TWAIN_MANAGER_PRE;

   return TRUE;
   }

BOOL CTwain::OpenSourceManager( )
{
   TRACE0( "TWAIN: OpenSourceManager Attempted\n" );

   if( m_eCurrentState >= TWAIN_MANAGER_OPEN )
      return TRUE;

   if( ! LoadSourceManager( ))
      return FALSE;

   RegisterApp( 1, 0, TWLG_USA, TWCY_USA, "Visa.exe 1.0 10/10/97", "The Phoenix Group", "Scanning", "Visa" );

// Now initialize it!

   TW_UINT16 iStatus = (*m_lpDSM_Entry )( &m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, (TW_MEMREF) &m_hWnd );

   if( iStatus != TWRC_SUCCESS )
   {
      AfxMessageBox( "Error in Open Source Manager!" );
      return FALSE;
      }

   m_eCurrentState = TWAIN_MANAGER_OPEN;

   TRACE0( "TWAIN: OpenSourceManager Succeeded\n" );

   return TRUE;
   }

void CTwain::RegisterApp(           // record application information
   int   sMajorNum, int sMinorNum,  // major and incremental revision e.g. version 2.1, nMajorNum == 2, nMinorNum == 1
   int   sLanguage,                 // language of this version (use TWLG_xxx from TWAIN.H)
   int   sCountry,                  // country of this version (use TWCY_xxx from TWAIN.H)
   LPSTR lpszVersion,               // version info string e.g. "1.0b3 Beta release"
   LPSTR lpszMfg,                   // name of manufacturer/developer e.g. "Crazbat Software"
   LPSTR lpszFamily,                // product family e.g. "BitStomper"
   LPSTR lpszProduct)               // specific product e.g. "BitStomper Deluxe Pro"
{
   memset( &m_AppId, 0, sizeof( TW_IDENTITY ));

   m_AppId.Id = 0;                       // init to 0, but Source Manager will assign real value
   m_AppId.Version.MajorNum = (TW_INT16) sMajorNum;
   m_AppId.Version.MinorNum = (TW_INT16) sMinorNum;
   m_AppId.Version.Language = (TW_INT16) sLanguage;
   m_AppId.Version.Country  = (TW_INT16) sCountry;
   m_AppId.ProtocolMajor    = TWON_PROTOCOLMAJOR;
   m_AppId.ProtocolMinor    = TWON_PROTOCOLMINOR;
   m_AppId.SupportedGroups  = DG_IMAGE | DG_CONTROL;

   lstrcpy( m_AppId.Version.Info,  lpszVersion  );
   lstrcpy( m_AppId.Manufacturer,  lpszMfg      );
   lstrcpy( m_AppId.ProductFamily, lpszFamily   );
   lstrcpy( m_AppId.ProductName,   lpszProduct  );
   }

BOOL CTwain::CloseSourceManager( )
{
   TRACE0( "TWAIN: CloseSourceManager Attempted\n" );

   if( m_eCurrentState <= TWAIN_MANAGER_LOADED )
      return TRUE;

   CloseSource( );

   int iStatus = (*m_lpDSM_Entry)( &m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, (TW_MEMREF) &m_hWnd );

   if( iStatus != TWRC_SUCCESS )
   {
      AfxMessageBox( "Error in Close DSM!" );
      return FALSE;
      }

   m_eCurrentState = TWAIN_MANAGER_LOADED;

   TRACE0( "TWAIN: CloseSourceManager Succeeded\n" );

   return TRUE;
   }

BOOL CTwain::OpenSource( )
{
   TRACE0( "TWAIN: OpenSource Attempted\n" );

   if( m_eCurrentState >= TWAIN_SOURCE_OPEN )
      return TRUE;
                                         
   #if _WIN32                                        
      memset( &m_SourceId, 0, sizeof( TW_IDENTITY ));
   #else
      _fmemset( &m_SourceId, 0, sizeof( TW_IDENTITY ));
   #endif

   TW_UINT16 twRC = (*m_lpDSM_Entry )( &m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, (TW_MEMREF) &m_SourceId );

   if( twRC != TWRC_SUCCESS )
   {
      AfxMessageBox( "Get Default DS failed with an error!" );
      return FALSE;
      }

   twRC = (*m_lpDSM_Entry )( &m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, &m_SourceId );

   if( twRC != TWRC_SUCCESS )
   {
      AfxMessageBox( "Open Source Failed with an error!" );
      return FALSE;
      }

   m_eCurrentState = TWAIN_SOURCE_OPEN;

   TRACE0( "TWAIN: OpenSource Succeeded\n" );

   return TRUE;
   }

BOOL CTwain::OpenSourceList( )
{
   TRACE0( "TWAIN: Select Source Attempted\n" );

   if( m_eCurrentState >= TWAIN_SOURCE_OPEN )
   {
      AfxMessageBox( "A Data Source is already open!" );
      return FALSE;
      }

   TW_IDENTITY NewIdentity;
   
   #if _WIN32
      memset( &NewIdentity, 0, sizeof( NewIdentity ));
   #else
      _fmemset( &NewIdentity, 0, sizeof( NewIdentity ));
   #endif
   
   TW_UINT16 twRC = (*m_lpDSM_Entry )( &m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, (TW_MEMREF) &NewIdentity );
     
// This call performs one important function:
// - should cause SM to put up dialog box of available Source's
// - tells the SM which application, m_AppId.id, is requesting, REQUIRED
// - returns the SM assigned NewDSIdentity.id field, you check if changed
//  (needed to talk to a particular Data Source)
// - be sure to test return code, failure indicates SM did not close !!

   twRC = (*m_lpDSM_Entry )( &m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, (TW_MEMREF) &NewIdentity );

   if( twRC != TWRC_SUCCESS )
   {
      AfxMessageBox( "Select DS Failed with an error!" );
      return FALSE;
      }

   m_SourceId = NewIdentity;

   TRACE0( "TWAIN: Select Source Succeeded\n" );
   
   return TRUE;
   }

BOOL CTwain::EnableSource( )
{
   TRACE0( "TWAIN: Enable Source Attempted\n" );

   if( m_eCurrentState != TWAIN_SOURCE_OPEN )
      return TRUE;

   memset( &m_UserInterface, 0, sizeof( TW_USERINTERFACE ));

   m_UserInterface.hParent = m_hWnd;
   m_UserInterface.ShowUI  = (TW_BOOL) m_bShowUI;

   TW_UINT16 twRC = (*m_lpDSM_Entry )( &m_AppId, &m_SourceId, DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS, (TW_MEMREF) &m_UserInterface );

   if( twRC != TWRC_SUCCESS )
   {
      AfxMessageBox( "Enable Source Failed with an error!" );
      return FALSE;
      }

   m_eCurrentState = TWAIN_SOURCE_ENABLED;

   TRACE0( "TWAIN: Enable Source Succeeded\n" );

   return TRUE;
   }

BOOL CTwain::DisableSource( )
{
   TRACE0( "TWAIN: Disable Source Attempted\n" );

   if( m_eCurrentState != TWAIN_SOURCE_ENABLED )
      return TRUE;

   TW_USERINTERFACE tempUserInterface;
   
   tempUserInterface.hParent = m_hWnd;
   tempUserInterface.ShowUI  = TWON_DONTCARE8;

   TW_UINT16 twRC = (*m_lpDSM_Entry )( &m_AppId, &m_SourceId, DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, (TW_MEMREF) &tempUserInterface );

   if( twRC != TWRC_SUCCESS )
   {
      AfxMessageBox( "Disable Source Failed with an error!" );
      return FALSE;
      }

   m_eCurrentState = TWAIN_SOURCE_OPEN;

   TRACE0( "TWAIN: Disable Source Succeeded\n" );

   return TRUE;
   }

BOOL CTwain::CloseSource( )
{
   TRACE0( "TWAIN: Close Source Attempted\n" );

   if( m_eCurrentState != TWAIN_SOURCE_OPEN && m_eCurrentState != TWAIN_SOURCE_ENABLED )
      return TRUE;

   if( m_eCurrentState == TWAIN_SOURCE_ENABLED )
      DisableSource( );

   TW_UINT16 twRC = (*m_lpDSM_Entry )( &m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, &m_SourceId );

   if( twRC != TWRC_SUCCESS )
   {
      AfxMessageBox( "Close Source Failed with an error!" );
      return FALSE;
      }

   m_SourceId.Id = 0;
   m_SourceId.ProductName[ 0 ] = 0x00;

   m_eCurrentState = TWAIN_MANAGER_OPEN;

   TRACE0( "TWAIN: Close Source Succeeded\n" );

   return TRUE;
   }
                       
BOOL CTwain::SelectSource( )
{
   TRACE0( "TWAIN: Select Source\n" );

   if( ! OpenSourceManager( ))
      return FALSE;

   OpenSourceList( );
   CloseSourceManager( );

   return TRUE;
   }
                       
void CTwain::SetShowGUI( BOOL bShowUI )
{
   m_bShowUI = bShowUI;

   return;
   }

BOOL CTwain::PreAcquire( )
{
   TRACE0( "TWAIN: Acquire Attempted\n" );

// CWaitCursor wait;

   if( ! OpenSourceManager( ))
      return FALSE;

   if( ! OpenSource( ))
   {
      CloseSourceManager( );
      return FALSE;
      }

   TRACE0( "TWAIN: PreAcquire Succeeded\n" );

   return TRUE;
   }

BOOL CTwain::Acquire( )
{
   EnableWindow( m_hWnd, FALSE );

   if( ! EnableSource( ))
   {
      CloseSourceManager( );
      return FALSE;
      }

// Source is enabled, wait for transfer or source closed

   MSG msg;

   while( GetMessage( &msg, NULL, 0, 0 ) && m_eCurrentState >= TWAIN_SOURCE_ENABLED )
   {
      if( ! PreTranslateMessage( &msg ))
      {
         TranslateMessage( &msg );
         DispatchMessage ( &msg );
         }
      }

   StopAcquire( );

   EnableWindow( m_hWnd, TRUE );

   return TRUE;
   }

BOOL CTwain::StopAcquire( )
{
   TRACE0( "TWAIN: Acquire Stop\n" );

   CloseSourceManager( );

   return TRUE;
   }


BOOL CTwain::PreTranslateMessage( MSG* pMsg )
{
   if( m_eCurrentState < TWAIN_SOURCE_ENABLED )
      return FALSE;

   TW_EVENT twEvent;

   twEvent.pEvent    = (TW_MEMREF) pMsg;
   twEvent.TWMessage = MSG_NULL;

   TW_UINT16 twRC = (*m_lpDSM_Entry)( &m_AppId, &m_SourceId, DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, (TW_MEMREF) &twEvent );

   if( twRC == TWRC_NOTDSEVENT )
      return FALSE;

   switch( twEvent.TWMessage )
   {
// Retrieve the image!

   case MSG_XFERREADY:
      TRACE0( "TWAIN: Pre-Translate XFerReady\n" );
      TransferNativeImage( );     // XferReady( lpmsg );
      break;

// Default callback closes the source

   case MSG_CLOSEDSREQ:
      TRACE0( "TWAIN: Pre-Translate CloseDSReq\n" );
      StopAcquire( );                  // CloseDSReq
      break;

// No message returned

   case MSG_NULL:
      break;
      } // switch

   return TRUE;
   }

BOOL CTwain::TransferNativeImage( )
{
// Do until there are no more pending transfers
// explicitly initialize the our flags

   BOOL  bReturn = FALSE;
   int   iStatus;

   TW_IMAGEINFO    twImageInfo;
   TW_PENDINGXFERS twPendingXfer;

   memset( &twPendingXfer, 0, sizeof( TW_PENDINGXFERS ));
   twPendingXfer.Count = 0;

   TRACE0( "TWAIN: TransferNative\n" );

   do
   {
      TRACE1( "TWAIN: TransferNative IMAGENATIVEXFER begin: %d\n", twPendingXfer.Count );

      TW_UINT16 twRC2;
      TW_UINT16 twRC = (*m_lpDSM_Entry )( &m_AppId, &m_SourceId, DG_IMAGE, DAT_IMAGEINFO, MSG_GET, (TW_MEMREF) &twImageInfo );

      if( twRC != TWRC_SUCCESS )
      {
         continue;
         }

  //  TW_UINT32 hBitmap = NULL;
      HBITMAP hBitmap = NULL;

      twRC = (*m_lpDSM_Entry )( &m_AppId, &m_SourceId, DG_IMAGE, DAT_IMAGENATIVEXFER, MSG_GET, (TW_MEMREF) &hBitmap );

      switch( twRC )
      {
         case TWRC_XFERDONE:  // Session is in State 7
               
            TRACE0( "TWAIN: TransferNative XFERDONE\n" );

         // Acknowledge the end of the transfer and transition to state 6/5

            twRC2 = ( *m_lpDSM_Entry)(&m_AppId, &m_SourceId, DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, (TW_MEMREF) &twPendingXfer );
               
         // close the DSM and DS

            if( twPendingXfer.Count == 0 )
            {  
               LPBITMAPINFOHEADER pBitmap = (LPBITMAPINFOHEADER) GlobalLock( hBitmap );
//             BYTE* pBitmap = (BYTE*) GlobalLock( (void*) hBitmap );

               freeimage( m_vTwainImage );
               iStatus = dibtoimage( (BYTE*) pBitmap, m_vTwainImage );

            // Free the bitmap now.  The dibtoimage function copied it for us!

               GlobalUnlock( hBitmap );
               GlobalFree  ( hBitmap );

               TRACE0( "TWAIN: TransferNative CopyImage\n" );

            // Send a message to the main app that we're done!!

               SendMessage( m_hWnd, PM_XFERDONE, 0, 0);

               StopAcquire( );
               }

            PostMessage( m_hWnd, WM_COMMAND, PM_XFERDONE, 0 );
            TRACE0( "TWAIN: TransferNative PM_XFERDONE\n" );
            break;

         // the user canceled or wants to rescan the image
         // something wrong, abort the transfer and delete the image
         // pass a null ptr back to App

         case TWRC_CANCEL:   // Session is in State 7
         case TWRC_FAILURE:  
         default:
               
         // Source (or User) Canceled Transfer transistion to state 6/5

            twRC2 = (*m_lpDSM_Entry)(&m_AppId, &m_SourceId, DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, (TW_MEMREF) &twPendingXfer );
               
        // Close the DSM and DS

            if( twPendingXfer.Count == 0)
               StopAcquire( );

            PostMessage( m_hWnd, WM_COMMAND, PM_XFERDONE, 0 );
            TRACE0( "TWAIN: TransferNative TWRC_FAILURE\n" );

            break;
         }

      } while( twPendingXfer.Count != 0 );

   TRACE0( "TWAIN: TransferNative exiting\n" );

   return bReturn;
   }


TW_UINT32 CTwain::FloatToUInt32( float fConvert )
{
   TW_FIX32 Fix32_value;
   TW_INT32 value = (TW_INT32) ( fConvert * 65536.0 + 0.5);
   Fix32_value.Whole = LOWORD(value >> 16);
   Fix32_value.Frac = LOWORD(value & 0x0000ffffL);

   return *(TW_UINT32*)&Fix32_value;
   }

TW_FIX32 CTwain::FloatToFixed32( float fConvert )
{
   TW_FIX32 Fix32_value;
   TW_INT32 value = (TW_INT32) ( fConvert * 65536.0 + 0.5);
   Fix32_value.Whole = LOWORD(value >> 16);
   Fix32_value.Frac = LOWORD(value & 0x0000ffffL);
   return Fix32_value;
   }

TW_FIX32 CTwain::FloatToFixed32( short sConvert )
{
   TW_FIX32 Fix32_value;
   TW_INT32 value = (TW_INT32) ( (float) sConvert * 65536.0 + 0.5);
   Fix32_value.Whole = LOWORD(value >> 16);
   Fix32_value.Frac = LOWORD(value & 0x0000ffffL);
   return Fix32_value;
   }


BOOL CTwain::SetImageCount( short sImageCount )
{
   return SetCapability( "Image Count",     CAP_XFERCOUNT, TWON_ONEVALUE, TWTY_UINT16, sImageCount );
   }

BOOL CTwain::SetLightPath( BOOL bLightPath )
{
   BOOL bReturn = FALSE;

   if( bLightPath )
      bReturn = SetCapability( "Light Path Reflect",  ICAP_LIGHTPATH, TWON_ONEVALUE, TWTY_UINT16, TWLP_REFLECTIVE );
   else
      bReturn = SetCapability( "Light Path Transmit", ICAP_LIGHTPATH, TWON_ONEVALUE, TWTY_UINT16, TWLP_TRANSMISSIVE );

   return bReturn;
   }


BOOL CTwain::SetUnits( short sUnits )
{
   return SetCapability( "Units",           ICAP_UNITS,    TWON_ONEVALUE, TWTY_UINT16, sUnits );
   }

short CTwain::GetUnits( )
{
   return (short) GetCapability( "Units",           ICAP_UNITS,    TWON_ONEVALUE, TWTY_UINT16 );
   }

BOOL CTwain::SetBitDepth( short sBitDepth )
{
   if( sBitDepth != 1 && sBitDepth != 4 && sBitDepth != 8 && sBitDepth != 24 )
      return FALSE;

   return SetCapability( "Bit Depth",       ICAP_BITDEPTH, TWON_ONEVALUE, TWTY_UINT16, sBitDepth );
   }

float CTwain::GetXResolution( )
{
   return (float) GetCapability( "X Resolution", ICAP_XRESOLUTION, TWON_ONEVALUE, TWTY_FIX32 );
   }

BOOL CTwain::SetXResolution( float fResolution )
{
   return SetCapability( "X Resolution", ICAP_XRESOLUTION, TWON_ONEVALUE, TWTY_FIX32, FloatToUInt32( fResolution ));
   }

BOOL CTwain::SetYResolution( float fResolution )
{
   return SetCapability( "Y Resolution", ICAP_YRESOLUTION, TWON_ONEVALUE, TWTY_FIX32, FloatToUInt32( fResolution ));
   }

BOOL CTwain::SetXScaling( float fScaling )
{
   return SetCapability( "X Scaling", ICAP_XSCALING, TWON_ONEVALUE, TWTY_FIX32, FloatToUInt32( fScaling ));
   }

BOOL CTwain::SetYScaling( float fScaling )
{
   return SetCapability( "Y Scaling", ICAP_YSCALING, TWON_ONEVALUE, TWTY_FIX32, FloatToUInt32( fScaling ));
   }

BOOL CTwain::SetContrast( float fContrast )
{
   if( fContrast < -1000.0 || fContrast > 1000.0 )
      return FALSE;

   return SetCapability( "Contrast", ICAP_CONTRAST, TWON_ONEVALUE, TWTY_FIX32, FloatToUInt32( fContrast ));
   }

BOOL CTwain::SetBrightness( float fBrightness )
{
   if( fBrightness < -1000.0 || fBrightness > 1000.0 )
      return FALSE;

   return SetCapability( "Brightness", ICAP_BRIGHTNESS, TWON_ONEVALUE, TWTY_FIX32, FloatToUInt32( fBrightness ));
   }
/*
BOOL CTwain::SetSaturation( float fSaturation )
{
   if( fSaturation < -1000.0 || fSaturation > 1000.0 )
      return FALSE;

   return SetCapability( "Saturation", ICAP_SATURATION, TWON_ONEVALUE, TWTY_FIX32, FloatToUInt32( fSaturation ));
   }

BOOL CTwain::SetHue( float fHue )
{
   if( fHue < -1000.0 || fHue > 1000.0 )
      return FALSE;

   return SetCapability( "Hue", ICAP_HUE, TWON_ONEVALUE, TWTY_FIX32, FloatToUInt32( fHue ));
   }
*/
BOOL CTwain::SetHighlight( float fHighlight )
{
   if( fHighlight < 0.0 || fHighlight > 255.0 )
      return FALSE;

   return SetCapability( "Highlight", ICAP_HIGHLIGHT, TWON_ONEVALUE, TWTY_FIX32, FloatToUInt32( fHighlight ));
   }

BOOL CTwain::SetShadow( float fShadow )
{
   if( fShadow < 0.0 || fShadow > 255.0 )
      return FALSE;

   return SetCapability( "Shadow", ICAP_SHADOW, TWON_ONEVALUE, TWTY_FIX32, FloatToUInt32( fShadow ));
   }

BOOL CTwain::SetGamma( float fGamma )
{
   return SetCapability( "Gamma", ICAP_GAMMA, TWON_ONEVALUE, TWTY_FIX32, FloatToUInt32( fGamma ));
   }

BOOL CTwain::SetTransferNative( )
{
   return SetCapability( "Transfer Native", ICAP_XFERMECH, TWON_ONEVALUE, TWTY_UINT16, TWSX_NATIVE );
   }

BOOL CTwain::SetGrayScale( )
{
   return SetCapability( "Gray-Scale Image", ICAP_PIXELTYPE, TWON_ONEVALUE, TWTY_UINT16, TWPT_GRAY );
   }

BOOL CTwain::SetImagePixels( short sLeft, short sRight, short sTop, short sBottom )
{
   if( ! SetCapability( "Image Pixels", ICAP_UNITS, TWON_ONEVALUE, TWTY_INT16, TWUN_PIXELS ))
      return FALSE;

   // Set the scan area!

   TW_IMAGELAYOUT  Image;

   memset( &Image, 0, sizeof( TW_IMAGELAYOUT ));

   Image.Frame.Left     = FloatToFixed32( sLeft    );
   Image.Frame.Right    = FloatToFixed32( sRight   );
   Image.Frame.Top      = FloatToFixed32( sTop     );
   Image.Frame.Bottom   = FloatToFixed32( sBottom  );

   TW_UINT32 twRC = (*m_lpDSM_Entry)( &m_AppId, &m_SourceId, DG_IMAGE, DAT_IMAGELAYOUT, MSG_SET, (TW_MEMREF) &Image );

   if( twRC != TWRC_SUCCESS )
   {
      AfxMessageBox( "SetImage Capability Failed" );
      return FALSE;
      }

   return TRUE;
   }

BOOL CTwain::SetImageInches( float fLeft, float fRight, float fTop, float fBottom )
{
// if( ! SetCapability( "Image Inches", ICAP_UNITS, TWON_ONEVALUE, TWTY_INT16, TWUN_INCHES ))
//    return FALSE;

   // Set the scan area!

   TW_IMAGELAYOUT  Image;

   memset( &Image, 0, sizeof( TW_IMAGELAYOUT ));

   Image.Frame.Left     = FloatToFixed32( fLeft    );
   Image.Frame.Right    = FloatToFixed32( fRight   );
   Image.Frame.Top      = FloatToFixed32( fTop     );
   Image.Frame.Bottom   = FloatToFixed32( fBottom  );

   TW_UINT32 twRC = (*m_lpDSM_Entry)( &m_AppId, &m_SourceId, DG_IMAGE, DAT_IMAGELAYOUT, MSG_SET, (TW_MEMREF) &Image );

   if( twRC != TWRC_SUCCESS )
   {
      AfxMessageBox( "SetImage Capability Failed" );
      return FALSE;
      }

   return TRUE;
   }



BOOL CTwain::SetCapability( const char* szCapability, TW_UINT16 iCapability, TW_UINT16 iContainer, TW_UINT16 iItemType, TW_UINT32 iValue )
{
   TW_CAPABILITY   Capability;

   Capability.Cap     = iCapability;
   Capability.ConType = iContainer;

   Capability.hContainer = GlobalAlloc( GHND, sizeof( TW_ONEVALUE ));

   if( ! Capability.hContainer )
      return FALSE;

   TW_ONEVALUE far * pOneValue = (TW_ONEVALUE*) GlobalLock( Capability.hContainer );
/* TW_ONEVALUE     * pOneValue = (TW_ONEVALUE*) GlobalLock( Capability.hContainer ); */

   if( pOneValue == NULL )
      return FALSE;

   pOneValue -> ItemType = iItemType;
   pOneValue -> Item     = iValue;

   GlobalUnlock( Capability.hContainer );

   TW_UINT32 twRC = (*m_lpDSM_Entry)( &m_AppId, &m_SourceId, DG_CONTROL, DAT_CAPABILITY, MSG_SET, (TW_MEMREF) &Capability );

   GlobalFree( (HANDLE) Capability.hContainer );

   if( twRC != TWRC_SUCCESS )
   {
      TW_STATUS twStatus;

      twRC = (*m_lpDSM_Entry)(&m_AppId, &m_SourceId, DG_CONTROL, DAT_STATUS, MSG_GET, (TW_MEMREF) &twStatus );

      switch( twStatus.ConditionCode )
      {
         case TWCC_BADCAP:
            TRACE1( "Twain - %s - Source does not support setting this capability\n", szCapability );
            break;

         case TWCC_BADDEST:
            TRACE1( "Twain - %s - The source specified by pSourceID is not open\n", szCapability );
            break;

         case TWCC_BADVALUE:
            TRACE1( "Twain - %s - The value set was out of range for this source\n", szCapability );
            break;

         case TWCC_OPERATIONERROR:
            TRACE1( "Twain - %s - DS or DSM reported error, app shouldn't\n", szCapability );
            break;

         case TWCC_SEQERROR:
            TRACE1( "Twain - %s - Operation invoked in an invalid state\n", szCapability );
            break;
         }

      return FALSE;
      }

   return TRUE;
   }

/*

int FAR PASCAL EXPORT TWAIN_GetCapCurrent(unsigned Cap, unsigned ItemType, void FAR *pVal)
{
   void far *     pv = NULL;
   BOOL        bSuccess = FALSE;

   if (TWAIN_DS(DG_CONTROL, DAT_CAPABILITY, MSG_GETCURRENT, (TW_MEMREF)&cap) &&
       cap.hContainer &&
       (pv = GlobalLock(cap.hContainer))) {

      if (cap.ConType == TWON_ENUMERATION) {
         TW_ENUMERATION far *pcon = (TW_ENUMERATION far *)pv;
         TW_UINT32 index = pcon->CurrentIndex;
         if (index < pcon->NumItems && TypeMatch(pcon->ItemType, ItemType)) {
            LPSTR pitem = (LPSTR)pcon->ItemList + index*nTypeSize[ItemType];
            FMEMCPY(pVal, pitem, nTypeSize[ItemType]);
            bSuccess = TRUE;
         }
      } else if (cap.ConType == TWON_ONEVALUE) {
         TW_ONEVALUE far *pcon = (TW_ONEVALUE far *)pv;
         if (TypeMatch(pcon->ItemType, ItemType)) {
            FMEMCPY(pVal, &pcon->Item, nTypeSize[ItemType]);
            bSuccess = TRUE;
         }
      }
   }
   
   if (pv) GlobalUnlock(cap.hContainer);
   if (cap.hContainer) GlobalFree(cap.hContainer);

   return bSuccess;
}

  */

TW_UINT32 CTwain::GetCapability( const char* szCapability, TW_UINT16 iCapability, TW_UINT16 iContainer, TW_UINT16 /* iItemType */ )
{
   if( m_eCurrentState != TWAIN_SOURCE_OPEN )
   {
      TRACE1( "Twain - %s - The value 'Get' was performed in the wrong state \n", szCapability );
      return 0;
      }

   BOOL            bSuccess = FALSE;
   TW_UINT32       iValue   = 0;
   TW_CAPABILITY   Capability;

   Capability.Cap        = iCapability;
   Capability.ConType    = iContainer;
   Capability.hContainer = NULL;

   TW_UINT32 twRC = (*m_lpDSM_Entry)( &m_AppId, &m_SourceId, DG_CONTROL, DAT_CAPABILITY, MSG_GETCURRENT, (TW_MEMREF) &Capability );

   if( twRC == TWRC_SUCCESS )
   {
      TW_ONEVALUE* pUnknownValue = (TW_ONEVALUE*) GlobalLock( Capability.hContainer );

      if( Capability.ConType == TWON_ONEVALUE )
      {
         TW_ONEVALUE *pOneValue = (TW_ONEVALUE*) pUnknownValue;
         iValue = pOneValue->Item;
         }
      /*
      else if( Capability.ConType == TWON_ENUMERATION )
      {
         TW_ENUMERATION* pEnumValue = (TW_ENUMERATION*) pUnknownValue;
         TW_UINT32 index = pcon->CurrentIndex;
         if (index < pcon->NumItems && TypeMatch(pcon->ItemType, ItemType))
         {
            LPSTR pitem = (LPSTR)pcon->ItemList + index*nTypeSize[ItemType];
            FMEMCPY(pVal, pitem, nTypeSize[ItemType]);
            bSuccess = TRUE;
            }
         }
      */

      GlobalUnlock( Capability.hContainer );
      }

   if( Capability.hContainer )
      GlobalFree( Capability.hContainer );

   return iValue;
   }

// TwainDrv.h

#ifndef CTWAIN
#define CTWAIN

#include "twain.h"
#include "vicdefs.h"

#define VALID_HANDLE       32      // valid windows handle SB >= 32

#define PM_XFERDONE        WM_USER + 108

class CTwain
{
public:

   CTwain( imgdes* vImage );
  ~CTwain( );

public:

   BOOL PreAcquire( );
   BOOL Acquire( );
   BOOL StopAcquire( );

   BOOL SelectSource( );

   void SetWindow( CWnd* );
   void SetImage( imgdes* );

private:

   enum eState { TWAIN_MANAGER_PRE = 1, TWAIN_MANAGER_LOADED, TWAIN_MANAGER_OPEN,
                 TWAIN_SOURCE_OPEN, TWAIN_SOURCE_ENABLED, TWAIN_SOURCE_READY, TWAIN_SOURCE_TRANSFERRING };

   eState            m_eCurrentState;
   DSMENTRYPROC      m_lpDSM_Entry;    // function pointer to Source Mang. entry
   HINSTANCE         m_hDSMDLL;        // handle to Source Manager for explicit load
   HWND              m_hWnd;
   imgdes*           m_vTwainImage;

   TW_IDENTITY       m_SourceId;
   TW_IDENTITY       m_AppId;
   TW_USERINTERFACE  m_UserInterface;

private:

   BOOL              m_bShowUI;

protected:

   BOOL LoadSourceManager( );
   BOOL OpenSourceManager( );
   BOOL CloseSourceManager( );
   BOOL UnloadSourceManager( );

   BOOL OpenSource( );
   BOOL OpenSourceList( );
   BOOL EnableSource( );
   BOOL DisableSource( );
   BOOL CloseSource( );

   void RegisterApp( int sMajorNum, int sMinorNum, int sLanguage, int sCountry,
                     LPSTR lpszVersion, LPSTR lpszMfg, LPSTR lpszFamily, LPSTR lpszProduct );

public:

// Determine capabilities

   BOOL  SetTransferNative  ( );
   BOOL  SetLightPath       ( BOOL bLightPath );
   short GetUnits           ( );
   BOOL  SetUnits           ( short iUnits );
   BOOL  SetBitDepth        ( short iBitDepth );
   float GetXResolution     ( );
   BOOL  SetXResolution     ( float fResolution );
   BOOL  SetYResolution     ( float fResolution );
   BOOL  SetXScaling        ( float fScaling    );
   BOOL  SetYScaling        ( float fScaling    );
   BOOL  SetGamma           ( float fGamma      );
   BOOL  SetContrast        ( float fContrast );
   BOOL  SetBrightness      ( float fBrightness );
   BOOL  SetHighlight       ( float fHighlight );
   BOOL  SetShadow          ( float fShadow );
   BOOL  SetGrayScale       ( );
   BOOL  SetImagePixels     ( short sLeft, short sRight, short sTop, short sBottom );
   BOOL  SetImageInches     ( float fLeft, float fRight, float fTop, float fBottom );
   void  SetShowGUI         ( BOOL bShowUI = TRUE );
   BOOL  SetImageCount      ( short iImageCount );

private:

   BOOL      SetCapability( const char* szCapability, TW_UINT16 iCapability, TW_UINT16 iContainer, TW_UINT16 iItemType, TW_UINT32 iValue );
   TW_UINT32 GetCapability( const char* szCapability, TW_UINT16 iCapability, TW_UINT16 iContainer, TW_UINT16 iItemType );

   TW_UINT32 FloatToUInt32 ( float );
   TW_FIX32  FloatToFixed32( float );
   TW_FIX32  FloatToFixed32( short );

   BOOL PreTranslateMessage( MSG* );
   BOOL XferReady( );
   BOOL TransferNativeImage( );
   };

#endif

// And here's how I used it in one app...

CCalibrate::CCalibrate(CWnd* pParent /*=NULL*/)
   : CDialog(CCalibrate::IDD, pParent)
{
   //{{AFX_DATA_INIT(CCalibrate)
      // NOTE: the ClassWizard will add member initialization here
   //}}AFX_DATA_INIT
   
   m_pTwain = NULL;
   m_pEntireImage = NULL;
   m_pShrunkImage = NULL;
   }
   
void CCalibrate::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(CCalibrate)
      // NOTE: the ClassWizard will add DDX and DDV calls here
   //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CCalibrate, CDialog)
   //{{AFX_MSG_MAP(CCalibrate)
   ON_WM_PAINT()
   ON_WM_DESTROY()
   ON_WM_LBUTTONDOWN()
   ON_WM_SETCURSOR()
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CCalibrate message handlers

BOOL CCalibrate::OnInitDialog()
{
   CDialog::OnInitDialog();

   CMyApp* pApp = CMyApp::GetApp( );
   
   m_pEntireImage = new CImage( );
   m_pEntireImage->Initialize( 16, 16, 8 );

   m_pTwain        = new CTwain( m_pEntireImage->ImageDescriptor( ));

   m_pTwain->SetWindow   ( this );
           
   if( ! m_pTwain->PreAcquire( ))
   {  
      OnCancel( );
      return TRUE;
      }

   m_pTwain->SetShowGUI    ( TRUE );
   m_pTwain->SetImageCount ( 1 );
   m_pTwain->SetTransferNative( );

   if( ! m_pTwain->Acquire( ))
   {  
      OnCancel( );
      return TRUE;
      }
             
   
   return TRUE;
   }

void CCalibrate::OnPaint()
{
   CPaintDC dc(this);
   
   if( m_pShrunkImage != NULL )
   {                
      SetDIBitsToDevice( dc.GetSafeHdc( ),
                         m_rectImageArea.left,
                         m_rectImageArea.top,
                         m_rectImageArea.Width ( ),
                         m_rectImageArea.Height( ),
//                       m_pScrollImage.GetScrollPos( ) * 10,
                         0,
                         0,
                         0,
                         m_pShrunkImage->Height( ),
                         m_pShrunkImage->ImageBuffer( ),
                         m_pShrunkImage->ImageBitmapInfo( ),
                         DIB_RGB_COLORS );
      }
   
     
   for( short sCurrTracker = 0; sCurrTracker < 4; sCurrTracker ++ )
      m_rectWindow[ sCurrTracker ].Draw( &dc );
   }



void CCalibrate::OnDestroy()
{
   CDialog::OnDestroy();
   
   if( m_pTwain )
   {
      delete m_pTwain;
      m_pTwain = NULL;
      }

   if( m_pEntireImage )
   {
      delete m_pEntireImage;
      m_pEntireImage = NULL;
      }
     
   if( m_pShrunkImage )
   {
      delete m_pShrunkImage;
      m_pShrunkImage = NULL;
      }
   }

// There's a lot of custom code in that one, but you should be able to get the idea from that...

Good Luck

Phillip

0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
GIF file bit manipulation for color change 5 104
Error on moodle after upgrade 3 105
has22 challenge 11 71
post4 challenge 28 81
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now