DTwainAcquirer::SetTwainLoopMode

Top  Previous  Next

Syntax

 

DTwainAcquirer& SetTwainLoopMode( DTwainLoopMode LoopMode = LOOP_MODAL );

 

 

Parameters

LoopMode

Sets the loop mode used when acquiring images.

 

Return Value

Returns reference to current DTwainAcquirer object (*this).

 

 

 

 

Comments

Sets the "TWAIN loop mode" when acquiring images.  The LoopMode must be either LOOP_MODAL or LOOP_MODELESS.  If the mode is LOOP_MODAL, then DTWAIN will employ an internal message loop when the acquisition process has started.  If the mode is LOOP_MODELESS, then the DTWAIN C++ wrapper class will be responsible for the message loop.

 

For TWAIN devices and image retrieval to work correctly during the acquisition process, a message loop must be executed that checks for TWAIN messages, as well as application specific messages.  When LOOP_MODAL is used, this loop is implemented and executed within the DTWAIN library.  When LOOP_MODELESS is used, then DTWAIN will not execute the internal loop, and the application (in this case, the C++ wrapper class) is responsible for the TWAIN loop.

 

 

LOOP_MODELESS processing

 

For most Source's, the LOOP_MODAL is adequate.  However, if you wish for your application to control the message loop during an acquisition, you should use LOOP_MODELESS.  The C++ wrapper has a function defined in CACQUIRE.CPP called TwainLoop.  The loop within this function is the TWAIN message loop that LOOP_MODELESS uses.

 

 

Please note:  the next section is meant for programmers who are familiar with the Windows API application loop processing:

 

For those familiar with Win32 API programming, note that TwainLoop incorporates a generic Window's message loop, with a few differences:

 

 MSG msg;

 int val;

 /* Perform a loop until acquisitions are done */

 while (((val = GetMessage (&msg, NULL, 0, 0)) != -1) // while there is a message

         && DTWAIN_IsUIEnabled(m_TS.GetSource()))         // and the Source is acquiring

 {

                 if ( val != 0 )

         {

         if ( !DTWAIN_IsTwainMsg(&msg) )  // send message to TWAIN if DTWAIN message

         {

 if ( !m_HookProc || (*m_HookProc)(this,&msg)) // User-defined message processing (i.e. IsDialogMessage)

 {

                 TranslateMessage (&msg);    // send message to app, not TWAIN

                 DispatchMessage (&msg);

         }

                         }

         }

 }

 

The while( ) loop effectively terminates if the TWAIN driver's user interface is disabled, or if no user interface, when all the pages are acquired.

 

The function DTWAIN_IsTwainMsg( ) is called to determine if the next message in the application loop is meant for the TWAIN manager and driver (in this case, the message is not sent to your application), or if it is a "normal" application message.

 

The m_HookProc is a special function pointer of type TWAINLOOPHOOKPROC.  This function pointer can point to any application specific processing that you may need to do before passing the message to TranslateMessage and DispatchMessage.  By default, this function pointer is NULL (meaning no hook procedure has been defined).

 

The m_HookProc has the following prototype:

 

typedef bool (*TWAINLOOPHOOKPROC) (DTwainAcquirer*, MSG*);

 

The application just needs to define a function that has the prototype above, and assign it to the hook procedure by calling DTwainAcquirer::SetTwainLoopHookProc:

 

For example, many user-defined message loops must employ modeless dialog or accelerator key processing.

           

              MSG msg;

              HWND someDlgWindow;

              // assume window is valid and denotes a modeless dialog box...

 

              // Check if the message is meant for our modeless dialog box              

               if ( !someDlgWindow || !IsDialogMessage( someDlgWindow, &msg) )

               {

                   TranslateMessage (&msg);    // send message to app, not TWAIN

                   DispatchMessage (&msg);

               }

           }

 

In the example above, the extra processing required is a test to see if the message is meant for the modeless dialog.  If it isn't, then it is passed onto the TranslateMessage / DispatchMessage functions (if you are not familiar with this, the IsDialogMessage( ) is a Windows API function, and must be called to process any keyboard keys to a modeless dialog.).

 

In this example, the hook procedure would be something like this:

 

bool MyHookProc( DTwainAcquirer* pAcq, MSG* pMsg )

{

  if (!someDlgWindow || !IsDialogMessage( someDlgWindow, pMsg) )

         return true;

   return false;

}

 

//...

DTwainAcquirer Acq;

Acq.SetTwainHookProc( MyHookProc );

//...

 

If the hook procedure wants the TWAIN loop to go ahead and call TranslateMessage and DispatchMessage, then true is returned, otherwise false is returned.  The parameters that are passed are pointers to the current DTwainAcquirer object, and a pointer to the MSG (message) structure that was retrieved in the GetMessage( ) loop.

 

The code above sets the hook procedure to MyHookProc.  So the end result is that when LOOP_MODELESS processing is used, the following application loop is essentially done:

 

 MSG msg;

 int val;

 /* Perform a loop until acquisitions are done */

 while (((val = GetMessage (&msg, NULL, 0, 0)) != -1) // while there is a message

         && DTWAIN_IsUIEnabled(m_TS.GetSource()))         // and the Source is acquiring

 {

                 if ( val != 0 )

         {

         if ( !DTWAIN_IsTwainMsg(&msg) )  // send message to TWAIN if DTWAIN message

         {

 // This is executed

                     if ( !m_HookProc || (*m_HookProc)(this,&msg))

 

                 // The following is actually done, given the hook procedure we created above

                 // if (!someDlgWindow || !IsDialogMessage( someDlgWindow, &msg) )

 

 if ( !m_HookProc || (*m_HookProc)(this,&msg)) // User-defined message processing (i.e. IsDialogMessage)

 {

                 TranslateMessage (&msg);    // send message to app, not TWAIN

                 DispatchMessage (&msg);

         }

                         }

         }

 }

 

Since many Windows C++ applications have customized loop processing (accelerator processing, modeless window processing, checking for a button press while a long operation is in session, etc.), usage of LOOP_MODELESS processing, plus the use of the hook procedure, allows the application to stil have the other processing to work simultaneously with the acquisition of the images.