Visual Basic and Modal / Modeless Processing
The best way to implement image retrieval in a Visual Basic program is to use Modal acquisitions. The reason for this is that it is difficult for Visual Basic to intercept the application messages so that they can be sent to the TWAIN Source Manager during image acquisition. With modal acquisitions, DTWAIN is responsible for sending the messages to the Twain Source Manager -- however, some Sources cannot work with Modal acquisitions (most do, but a few still have problems).
Modeless acquisitions rely on the application to intercept the application message loop. The tell-tale sign that a TWAIN Source relies on modeless processing is that if modal processing is used, the Source user interface may display, but the user interface does not respond to any user interaction, or the acquisitions show erratic behavior.
The best option is to not use Visual Basic for these types of Sources, and use C or C++ to control the device using modeless acquisitions. The other option which may work is to attempt modeless acquisitions in Visual Basic in the following manner:
a) Call DTWAIN_SetTwainMode with the DTWAIN_MODELESS argument after the call to DTWAIN_SysInitialize
b) When an acquisition function is called, i.e. DTWAIN_AcquireNative, DTWAIN_AcquireFile, etc. write a "wait" loop to process and send messages to either your application or to the TWAIN Source Manager: Here is an example
Dim message As WinMsg Dim Source As Long ' DTWAIN_SetTwainMode DTWAIN_MODELESS ' Source = DTWAIN_SelectSource
' Call the acquisition function DTWAIN_AcquireFile params
' Wait for the acquisitions to finish While GetMessage(message, 0, 0, 0) And DTWAIN_IsUIEnabled(source) If DTWAIN_IsTwainMsg(message) = 0 Then TranslateMessage message DispatchMessage message End If Wend
The GetMessage, TranslateMessage, and DispatchMessage functions are Windows API functions. Their prototypes for Visual Basic is as follows:
Declare Function GetMessage Lib "user32" Alias "GetMessageA" \ (lpMsg As WinMsg, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long) As Long
Declare Function TranslateMessage Lib "user32" (lpMsg As WinMsg) As Long
Declare Function DispatchMessage Lib "user32" Alias "DispatchMessageA" (lpMsg As WinMsg) As Long
For VB .NET/2005/2008/2010, the following declarations are as follows:
Declare Ansi Function GetMessage Lib "user32" Alias "GetMessageA" \ (lpMsg As WinMsg, ByVal hwnd As IntPtr, ByVal wMsgFilterMin As Integer, ByVal wMsgFilterMax As Integer) As Integer
Declare Ansi Function TranslateMessage Lib "user32" (lpMsg As WinMsg) As Integer
Declare Ansi Function DispatchMessage Lib "user32" Alias "DispatchMessageA" (lpMsg As WinMsg) As Integer
The loop basically calls DTWAIN_IsTwainMsg and checks if the next message is meant for the TWAIN manager. If it isn't, then it is sent to your application. This loop terminates when the acquisition terminates (the DTWAIN_IsUIEnabled determines if the interface is still shown -- even if you don't use a user interface when acquiring images, DTWAIN_IsUIEnabled will still reflect whether the device is still acquiring an image).
One caveat is that this may still not work for some Sources due to the fact that Visual Basic is still enclosed in a wrapper that may not allow all the messages to be sent or come through to the application. However, give this method a try if you need to accomplish modeless processing in Visual Basic.
|