saraff-9EB1047A4BEB4cef8506B29BA325BD5A / Saraff.Twain.NET

Saraff.Twain.NET is the skillful scanning component which allows you to control work of flatbed scanner, web and digital camera and any other TWAIN device from .NET environment. You can use this library in your programs written in any programming languages compatible with .NET technology.
GNU General Public License v3.0
102 stars 35 forks source link

Question: Blocking mode vs non-blocking mode #49

Closed bkraul closed 5 years ago

bkraul commented 5 years ago

I am experiencing an issue that probably has a very easy answer. I have written a small class library to simplify the calling of the scanning operation and source selection. It sits on top of Saraff.Twain.NET and Saraff.Twain.Extensions.

I understand, from the examples how xDS provides very nice .FileTransfer method, but I am trying to understand how it works.

I am using the class in a Console application, and calling the method works great, scanner is called, and scans however many pages, and the thread does not continue until .FileTransfer is completed.

However, when calling the same class from a Windows Forms application, the .FileTransfer method is called, but it does not wait, which causes my function to work incorrectly.

image

What am I missing here? I have tried to pass a parameter in order to make the twain object modal to the form while scanning, hoping that will block the window/application until the .FileTransfer call is complete, because my function has to return a completed result, but I have not had much luck.

The question. How do I cause the twain component to be called modally and block the calling form until completed?

bkraul commented 5 years ago

I figured out the situation with the waiting. I had to use a callback in my encapsulated method (just like .FileTransfer uses a completeCallback method. However, I still want to find out how to show the scanning UI modally to the calling form.

saraff-9EB1047A4BEB4cef8506B29BA325BD5A commented 5 years ago

Hello, @bkraul If the application has its own the message loop that the Twain32.Acquire method can't block invoking thread, because the UI will be disabled (since the windows messages can't be processed).

The console application does not have any the message loop, so the Twain32.Acquire method create own the message loop and block invoking thread.

So, the winform application can use only the callback, like as the Saraff.Twain.Sample1 or the Saraff.Twain.Sample2 in the Saraff.Twain.NET CS Samples.

Also you can see TWAIN 2.4 Specification 3-19

DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDS

Points to the application’s TW_IDENTITY structure.

Points to the Source’s TW_IDENTITY structure.

Points to a structure of type TW_USERINTERFACE. The definition of TW_USERINTERFACE is:

typedef struct {
TW_BOOL ShowUI;
TW_BOOL ModalUI;
TW_HANDLE hParent;
} TW_USERINTERFACE, FAR *pTW_USERINTERFACE;

Set the ShowUI field to TRUE if you want the Source to display its user interface. Otherwise, set to FALSE. The Application will set the ModalUI field to TRUE if it wants the Source to run modal, and FALSE if it wants the Source to run modeless. Please note that to successfully run modal, it may be necessary for the application to disable inputs to its windows while the Source’s GUI is running.

The application sets the hParent field differently depending on the platform on which the application runs.