Home › Forums › TWAIN Classic › Simple TWAIN app question – reverse the process
- This topic has 11 replies, 3 voices, and was last updated 14 years, 4 months ago by spike.
- AuthorPosts
I found this code on codeproject.com. It works fine. I run the app, i have the scacnner connected to my laptop. App has menu options and I click “Acquire” and it scans. All is fine…
I’m communicating from this code to the scanner. I click a button and code has an order number on the screen and when I save the scanned doc, i can use that order number and save the scanned doc with that order number….
Now, my manager wants to reverse this. He doesnt want the app to have a button to communicate with the scanner. He wants to put the paper on the scanner, click the scanner button (not the button on the app)… and somehow now read the order number from the screen and when saving the doc…save the doc with the order number…
I dont think this is doable. I have control over the code…but i dont have control over what the scanner is doing…is this correct?
@eramgarden wrote:
I found this code on codeproject.com. It works fine. I run the app, i have the scacnner connected to my laptop. App has menu options and I click “Acquire” and it scans. All is fine…
I’m communicating from this code to the scanner. I click a button and code has an order number on the screen and when I save the scanned doc, i can use that order number and save the scanned doc with that order number….
Now, my manager wants to reverse this. He doesnt want the app to have a button to communicate with the scanner. He wants to put the paper on the scanner, click the scanner button (not the button on the app)… and somehow now read the order number from the screen and when saving the doc…save the doc with the order number…
I dont think this is doable. I have control over the code…but i dont have control over what the scanner is doing…is this correct?
I have same problem. And also doubt it’s doable…. kinda ran out of ideas.. 🙁
This is called ‘push model’ – where the scan is initiated from the scanner instead of from the application.
I’m sure others know more about this than I do, but I have two suggestions:
In your code, open the scanner and poll the scanner for feeder loaded (ICAP_FEEDERLOADED) and when it shows true, wait a moment (in case user is straightening the paper) and then start a scan. User doesn’t even have to push a button. But only works if the scanner can (silently) poll and report feeder loaded.
Check out ‘STI’ – this is an older Microsoft scanner API, the ancestor of WIA. It allows scanners to generate events like button-presses, and applications (like yours) can register to receive notice of those events.
Or at least, an app can be launched… so you might have to have a little mini-app that gets launched on the button-press, and it sends a message to your main app…
Try google for STI scanner button pressWhoo! Found a guy who does his own STI registration by filling in the registry entries – muy macho:
http://icopy.sourceforge.net/?p=98let me look into this. thanks.
Do you have an example of this:
>>open the scanner and poll the scanner for feeder loaded (ICAP_FEEDERLOADED) and when it shows true
how do i open the scanner via code? with “Acquire” command?
Hi eramgarden – I’d like to help, but the library you are using from CodeProject is kind of a hack – minimal comments, and almost everything done in-line. So for example there is no ‘Open the scanner’ function, nor are there the basic functions you need for reading capabilities. So I hope I’m getting this right…
The code that opens the scanner appears inside the Acquire method, here is one version I found, this is just the actual ‘open the scanner’ call:
rc = DSMident( appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.OpenDS, srcds );
if( rc != TwRC.Success )
return;
If successful, that call will open the default TWAIN device.
Note that it depends on previous code that initializes the various variables like srcds and appid.You’ll need to add this definition to the enum TwCap:
CAP_FEEDERLOADED = 0x1003
Once the scanner is in the open state, you could call
// create a capability structure with the capability code:
TwCapability cap = new TwCapability(TwCap.CAP_FEEDERLOADED);
// query the scanner for the current value of the capability:
rc = DScap( appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Get, cap);
if( rc != TWRC.Success ) {
// something's wrong
CloseSrc();
return;
}
// Dig out the returned value of the capability.
// I'm going to ASSUME the returned container has
// ConType==TwOn.One.
// and contains a TWTY_BOOL value.
// Lock the container handle to get a pointer to its contents:
IntPtr pv = Twain.GlobalLock( cap.Handle );
// Read the 32-bit value of the container, it
// follows a 2-byte ItemType field in the container:
bool bFeederLoaded = ( 0 != (short)Marshal.ReadInt32( pv, 2 ) );
Twain.GlobalUnlock( cap.Handle );
Twain.GlobalFree( cap.Handle );Thanks, let me try. Hope this works. I’ll post back.
>>CodeProject is kind of a hack – minimal comments, and almost everything done in-line
do u have another code that you use?
uhm, well, yes – I use the commercial library that I wrote, EZTwain Pro 😉
There’s a freeware version called EZTwain Classic.
I don’t want to push my own product here, here are some alternatives I would not hesitate to recommend:
Atalasoft specialize in imaging & scanning components for .NET
VintaSoft has always had very affordable TWAIN components
And there is Loïc of GdPicture, who apparently lives on another Earth that has much longer days…Those are just some of the outstanding .NET scanning components I have some familiarity with – there are many others which I omit only for lack of familiarity or lack of time.
Thanks, let me try your code snippet and see what happens. Will look at your recommendations as well. thanks.
This fails;
TwCapability cap1 = new TwCapability(TwCap.CAP_FEEDERLOADED,1);
// query the scanner for the current value of the capability:
rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Get, cap1);
if (rc != TwRC.Success)
{
// something's wrong
CloseSrc();
return;
}Their orig code works tho, but it doesnt use teh CAP_FeederLoaded
TwCapability cap = new TwCapability(TwCap.XferCount, 1);
rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Set, cap);
if (rc != TwRC.Success)
{
CloseSrc();
return;
}
Might just leave it as the orig code and have the users just click a button…
What exactly do you mean?
- AuthorPosts