tags:

views:

1799

answers:

2

I have a C# (WinForm) program that supports scanning using WIA. I am trying to set device properties before scanning one or more documents. Primarily I want to set the paper size for the scanner. Following is a snippet of the code:

foreach (Property property in selectedDevice.Properties)
{
   //WiaProperties.WiaDpsHorizontalBedSize is my constant
   if (property.PropertyID == WiaProperties.WiaDpsHorizontalBedSize)
   {
       //Set property value here...    
   }
}

I am finding the Horizontal Bed Size property, but the question is how do I set it to a value? There is a set_Value property off of property but that seems to take a ref to a result object. So I am at a loss as to how can I set properties on a device?

+1  A: 

I am working on a scanning project as well, and there are very few WIA examples. This code is what you are looking for to set the bed size, DPI, etc. Check out the SetProperty method with an example on how to deal with set_Value.

class Scan
{
 // Scanner only device properties (DPS)
 public const int WIA_RESERVED_FOR_NEW_PROPS = 1024;
 public const int WIA_DIP_FIRST = 2;
 public const int WIA_DPA_FIRST = WIA_DIP_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
 public const int WIA_DPC_FIRST = WIA_DPA_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
 public const int WIA_DPS_FIRST = WIA_DPC_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
 public const int WIA_DPS_DOCUMENT_HANDLING_STATUS = WIA_DPS_FIRST + 13;
 public const int WIA_DPS_DOCUMENT_HANDLING_SELECT = WIA_DPS_FIRST + 14;
 public const int FEEDER = 1;
 public const int FLATBED = 2;
 public const int DUPLEX = 4;
 public const int FEED_READY = 1;

 WIA.CommonDialog _dialog = new WIA.CommonDialog();
 WIA.Device _scanner;

 public void ADFScan()
 {

  _dialog = new CommonDialogClass();
  _scanner = _dialog.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType, false, false);


  foreach (Property item in _scanner.Items[1].Properties)
  {
   switch (item.PropertyID)
   {
    case 6146: //4 is Black-white,gray is 2, color 1
     SetProperty(item, 2);
     break;
    case 6147: //dots per inch/horizontal 
     SetProperty(item, 100);
     break;
    case 6148: //dots per inch/vertical 
     SetProperty(item, 100);
     break;
    case 6149: //x point where to start scan 
     SetProperty(item, 0);
     break;
    case 6150: //y-point where to start scan 
     SetProperty(item, 0);
     break;
    case 6151: //horizontal exent 
     SetProperty(item, (int)(8.5 * 100));
     break;
    case 6152: //vertical extent 
     SetProperty(item, 11 * 100);
     break;
   }
  }
  ImageFile image = (ImageFile)_scanner.Items[1].Transfer(FormatID.wiaFormatPNG);
  System.IO.File.Delete("tmp.png");
  image.SaveFile("tmp.png");
 }

 private void SetProperty(Property property, int value)
 {
  IProperty x = (IProperty)property;
  Object val = value;
  x.set_Value(ref val);
 }


 public void test()
 {
  bool WantsToScan = true;
  while (WantsToScan) ScanAndSaveOnePage();

 }


 static void Main(string[] args)
 {
  new Scan().test();
 }
}
Nice. Could you explain me why this cast is necessary? IProperty x = (IProperty)property;
driAn
A: 

Hi all,

Does this sample code works in multithreaded app? I've implemented a very similar class (in C++) with witch I want to do several scans (from the machine's feeder) in a worker thread. Unfortunatelly the WIA::Item::Transfer() is blocking my GUI.

Here's a code snippet:

...
String^ scanDocumentHandlingStatus = "3087";
int scanFeederReady = 1;

if (_scanner->Properties->Exists(scanDocumentHandlingStatus) &&
    ((int)_scanner->Properties[scanDocumentHandlingStatus]->default & scanFeederReady))
{
    do
    {
     Drawing::Image^ img = ImageFile2Image((WIA::ImageFile^)_scanner->Items[1]->Transfer(WIA::FormatID::wiaFormatPNG));
     // use img...
    }
    while ((int)_scanner->Properties[scanDocumentHandlingStatus]->default & scanFeederReady);
}
...

Note that the _scanner member object is created outside the thread. If I create a new WIA::Device inside the thread all works, but I loose any property previously set in the _scanner object.

Any idea why this happens and how can I use the _scanner object to perform scan asynchronously?

Thanks in advance!