title: Is it possible in TWAIN to force a scanner to set the region to the entire width?
body: <p>I am writing an application that requires scanning in .net (<code>c#</code> version <code>4.0</code>, Visual Studio 2010).  I'm using the <code>TWAIN</code> API in order to do the scanning and I have a problem with the layout feature.  The following code works perfectly fine on a <code>Microtek i800</code>, a <code>CanoScan 9000F</code> and a <code>Microtek Artix Scan F2</code> but when I run it against an <a href="http://www.epson.com/cgi-bin/Store/jsp/Product.do?sku=B11B178011" rel="nofollow">Epson Perfection V700</a> something really strange occurs.</p>
  
  <p>Even though I am setting the left margin of the layout to <code>0</code> the left edge of the image is cut off.  I tried setting it to negative values but that made no difference.  It seems like there is some strangeness and it is forcing it to be a film size (perhaps because I am turning the light on).  If I use the tool that comes with the scanner it allows me to select a region that includes both edges (and have the light on) so it must be possible.  Also, the top and bottom coordinates work perfectly fine.</p>
  
  <p>So my question is...</p>
  
  <blockquote>
    <p>Does anyone know of any way I can make it scan the entire width?  Is there some other setting in TWAIN that I can set first to get it to forget its paper sizes perhaps?  (I tried setting PaperDetectable to false too but it made no difference).</p>
  </blockquote>
  
  <p>One other thing:  <em>If I do not set the layout, it still cuts off the picture on the edges (just not top and bottom) but if I also do not set the light on (or I do not set the light on but I do set the size) it does what I would expect: specifically scans the entire picture from the left most edge (but the problem is, I really need the light and the entire width of the scan - surely that isn't too much to ask...).</em></p>
  
  <hr>
  
  <p>Here is the code (it is the code behind for a 1 form windows form application with a single button on it):</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Drawing;
  using System.Drawing.Imaging;
  using System.Linq;
  using System.Windows.Forms;
  
  namespace TwainLayoutWindowsFormsApplication
  {
      public partial class Form1 : Form
      {
          public Form1()
          {
              InitializeComponent();
          }
  
          private void button1_Click(object sender, EventArgs e)
          {            
              TwainIdentity appid = null;
              TwainIdentity scanner = null;
              bool enabled = false;
  
              try
              {
                  appid = InitializeTwain(Handle);
  
                  scanner = GetSource(appid, "EPSON Perfection V700/V750");
  
                  Open(appid, scanner);
  
                  SetLightOn(appid, scanner);
  
                  SetLayout(appid, scanner);
  
                  Enable(appid, scanner, Handle);
                  enabled = true;
  
                  var bmps = Scan(appid, scanner);
  
                  Disable(appid, scanner);
                  enabled = false;
  
                  bmps.First().Save(@"c:\users\public\scan.bmp", ImageFormat.Bmp);
  
              }
              catch(Exception ex)
              {
                  MessageBox.Show(ex.Message);
              }
              finally
              {
                  if (appid != null &amp;&amp; scanner != null)
                  {
                      if (enabled)
                      {
                          try
                          {
                              Disable(appid, scanner);
                          }
                          catch(InvalidOperationException)
                          {
                          }
                      }
  
                      Close(appid, scanner);
                  }
              }
          }
  
          private static void SetLayout(TwainIdentity appid, 
                                        TwainIdentity scanner)
          {
              TwainImageLayout layout = new TwainImageLayout();
  
              var rc = NativeMethods.DSilayout(appid,
                                               scanner,
                                               TwainDataGroups.Image,
                                               TwainDataArgumentType.ImageLayout,
                                               TwainMessage.Get,
                                               layout);
  
              // 1 inch from the top and 0 from the left
              layout.Frame.Top = new TwainFix32();
              layout.Frame.Top.Whole = 1;
  
              layout.Frame.Left = new TwainFix32();
              layout.Frame.Left.Whole = 0;
  
              layout.Frame.Right = new TwainFix32();
              layout.Frame.Right.Whole = 6;
  
              layout.Frame.Bottom = new TwainFix32();
              layout.Frame.Bottom.Whole = 3;
  
              layout.FrameNumber = 1;
              layout.PageNumber = 1;
              layout.DocumentNumber = 1;
  
              rc = NativeMethods.DSilayout(appid,
                                           scanner,
                                           TwainDataGroups.Image,
                                           TwainDataArgumentType.ImageLayout,
                                           TwainMessage.Set,
                                           layout);
              if (rc != TwainReturnCode.Success)
                  throw new InvalidOperationException("Failed to set layout");
  
              var s = new TwainStatus();
  
              rc = NativeMethods.DSstatus(appid,
                                          scanner,
                                          TwainDataGroups.Control,
                                          TwainDataArgumentType.Status,
                                          TwainMessage.Get, s);
  
              if (rc != TwainReturnCode.Success)
                  throw new InvalidOperationException("Failed to get layout");
          }
  
          private IEnumerable&lt;Bitmap&gt; Scan(TwainIdentity appid, 
                                           TwainIdentity scanner)
          {
              var pictures = new List&lt;Bitmap&gt;();          
  
              TwainReturnCode rc;
              IntPtr hbitmap;
              var pxfr = new TwainPendingXfers();
  
              do
              {
                  pxfr.Count = 10;
                  hbitmap = IntPtr.Zero;
  
                  var iinf = new TwainImageInfo();
                  rc = NativeMethods.DSiinf(appid, 
                                            scanner, 
                                            TwainDataGroups.Image, 
                                            TwainDataArgumentType.ImageInfo, 
                                            TwainMessage.Get, 
                                            iinf);
                  if (rc != TwainReturnCode.Success)
                      throw new InvalidOperationException("Could not INF");
  
                  rc = NativeMethods.DSixfer(appid, 
                                             scanner, 
                                             TwainDataGroups.Image, 
                                             TwainDataArgumentType.ImageNativeXfer, 
                                             TwainMessage.Get, 
                                             ref hbitmap);
                  if (rc != TwainReturnCode.XferDone)
                      throw new InvalidOperationException("Could DSI XFER");
  
                  rc = NativeMethods.DSpxfer(appid, 
                                             scanner, 
                                             TwainDataGroups.Control, 
                                             TwainDataArgumentType.PendingXfers, 
                                             TwainMessage.EndXfer, 
                                             pxfr);
                  if (rc != TwainReturnCode.Success)
                      throw new InvalidOperationException("Could DSP XFER");
  
                  var bmp = TwainBitmapConvertor.ToBitmap(hbitmap);
                  pictures.Add(bmp);
              }
              while (pxfr.Count != 0);
  
              NativeMethods.DSpxfer(appid, 
                                    scanner, 
                                    TwainDataGroups.Control, 
                                    TwainDataArgumentType.PendingXfers, 
                                    TwainMessage.StopFeeder, 
                                    pxfr);
  
              return pictures;
          }
  
          private static void Enable(TwainIdentity appid, 
                                     TwainIdentity scanner, 
                                     IntPtr hwnd)
          {
              var guif = new TwainUserInterface();
              guif.ShowUI = 0;
              guif.ModalUI = 1;
              guif.ParentHand = hwnd;
  
              var rc = NativeMethods.DSuserif(appid, 
                                              scanner, 
                                              TwainDataGroups.Control, 
                                              TwainDataArgumentType.UserInterface, 
                                              TwainMessage.EnableDS, 
                                              guif);
              if (rc != TwainReturnCode.Success)
                  throw new InvalidOperationException("Could not enable");
          }
  
          private static void Disable(TwainIdentity appid, TwainIdentity scanner)
          {
              var guif = new TwainUserInterface();
  
              var rc = NativeMethods.DSuserif(appid,
                                              scanner, 
                                              TwainDataGroups.Control, 
                                              TwainDataArgumentType.UserInterface, 
                                              TwainMessage.DisableDS, 
                                              guif);
  
              if (rc != TwainReturnCode.Success)
                  throw new InvalidOperationException("Could not disable");
          }        
  
          private static void SetLightOn(TwainIdentity appid, TwainIdentity scanner)
          {
              using (var capability = new TwainCapability(TwainCapabilityType.Lightpath, 1))
              {
                  var rc = NativeMethods.DScap(appid,
                                               scanner,
                                               TwainDataGroups.Control,
                                               TwainDataArgumentType.Capability,
                                               TwainMessage.Set,
                                               capability);
  
                  if (rc != TwainReturnCode.Success)
                      throw new InvalidOperationException("Failed to set light");
              }
          }
  
          private static void Close(TwainIdentity appid, TwainIdentity scanner)
          {
              NativeMethods.DSMident(appid,
                                     IntPtr.Zero,
                                     TwainDataGroups.Control,
                                     TwainDataArgumentType.Identity,
                                     TwainMessage.CloseDS,
                                     scanner);
          }
  
          private static void Open(TwainIdentity appid, TwainIdentity scanner)
          {
              var rc = NativeMethods.DSMident(appid, 
                                              IntPtr.Zero, 
                                              TwainDataGroups.Control, 
                                              TwainDataArgumentType.Identity, 
                                              TwainMessage.OpenDS, 
                                              scanner);
  
              if (rc != TwainReturnCode.Success)
                  throw new InvalidOperationException("Failed to open");
          }
  
          private static TwainIdentity InitializeTwain(IntPtr hwndp)
          {
              var appid = new TwainIdentity();
  
              appid.Version.MajorNum = 1;
              appid.Version.MinorNum = 0;
              appid.Version.Language = 13;
              appid.Version.Country = 1;
              appid.Version.Info = "Test";
  
              appid.Id = IntPtr.Zero;
              appid.ProtocolMajor = 1;
              appid.ProtocolMinor = 9;
              appid.SupportedGroups = (int)(TwainDataGroups.Image | TwainDataGroups.Control);
              appid.Manufacturer = "Test Manufacturer";
              appid.ProductFamily = "Test Family";
              appid.ProductName = "Test Product";
  
              var rc = NativeMethods.DSMparent(appid,
                                               IntPtr.Zero,
                                               TwainDataGroups.Control,
                                               TwainDataArgumentType.Parent,
                                               TwainMessage.OpenDSM,
                                               ref hwndp);
  
              if (rc != TwainReturnCode.Success)
                  throw new InvalidOperationException("Could Not DSMParent");
  
              return appid;
          }
  
          private static TwainIdentity GetSource(TwainIdentity appid, string name)
          {
              var device = new TwainIdentity { Id = IntPtr.Zero };
  
              var rc = NativeMethods.DSMentry(appid, 
                                              IntPtr.Zero, 
                                              TwainDataGroups.Control, 
                                              TwainDataArgumentType.Identity, 
                                              TwainMessage.GetFirst, 
                                              device);
  
              if (rc != TwainReturnCode.EndOfList &amp;&amp; 
                  device.ProductName.Equals(name, 
                                            StringComparison.OrdinalIgnoreCase))
              {
                  return device;
              }
  
              while (rc != TwainReturnCode.EndOfList)
              {
                  device = new TwainIdentity { Id = IntPtr.Zero };
                  rc = NativeMethods.DSMentry(appid, 
                                              IntPtr.Zero, 
                                              TwainDataGroups.Control, 
                                              TwainDataArgumentType.Identity, 
                                              TwainMessage.GetNext, 
                                              device);
  
                  if (rc != TwainReturnCode.EndOfList &amp;&amp; 
                     device.ProductName.Equals(name, 
                                            StringComparison.OrdinalIgnoreCase))
                  {
                      return device;
                  }
              }
  
              throw new InvalidOperationException("Could not find device");
          }
      }
  }
  </code></pre>
  
  <p>For completeness here is the code I use to convert the HBITMAP to a <a href="http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx" rel="nofollow">System.Drawing.Bitmap</a>:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using System.Diagnostics;
  using System.Drawing;
  using System.Runtime.InteropServices;
  using System.Globalization;
  
  namespace TwainLayoutWindowsFormsApplication
  {
      internal static class TwainBitmapConvertor
      {
          [StructLayout(LayoutKind.Sequential, Pack = 2)]
          private class BitmapInfoHeader
          {
              public int Size;
              public int Width;
              public int Height;
              public short Planes;
              public short BitCount;
              public int Compression;
              public int SizeImage;
              public int XPelsPerMeter;
              public int YPelsPerMeter;
              public int ClrUsed;
              public int ClrImportant;
          }
  
          internal static Bitmap ToBitmap(IntPtr dibHandle)
          {
              var bitmapPointer = NativeMethods.GlobalLock(dibHandle);
  
              var bitmapInfo = new BitmapInfoHeader();
              Marshal.PtrToStructure(bitmapPointer, bitmapInfo);
  
              var rectangle = new Rectangle();
              rectangle.X = rectangle.Y = 0;
              rectangle.Width = bitmapInfo.Width;
              rectangle.Height = bitmapInfo.Height;
  
              if (bitmapInfo.SizeImage == 0)
              {
                  bitmapInfo.SizeImage =
                      ((((bitmapInfo.Width * bitmapInfo.BitCount) + 31) &amp; ~31) &gt;&gt; 3)
                      * bitmapInfo.Height;
              }
  
              // The following code only works on x86
              if (Marshal.SizeOf(typeof(IntPtr)) != 4)
                  throw new NotSupportedException("Only x86 is supported");
  
              int pixelInfoPointer = bitmapInfo.ClrUsed;
              if ((pixelInfoPointer == 0) &amp;&amp; (bitmapInfo.BitCount &lt;= 8))
              {
                  pixelInfoPointer = 1 &lt;&lt; bitmapInfo.BitCount;
              }
  
              pixelInfoPointer = (pixelInfoPointer * 4) + bitmapInfo.Size
                  + bitmapPointer.ToInt32();
  
              IntPtr pixelInfoIntPointer = new IntPtr(pixelInfoPointer);
  
              var bitmap = new Bitmap(rectangle.Width, rectangle.Height);
  
              using (Graphics graphics = Graphics.FromImage(bitmap))
              {
                  IntPtr hdc = graphics.GetHdc();
  
                  try
                  {
                      NativeMethods.SetDIBitsToDevice(hdc,
                          0, 0, rectangle.Width, rectangle.Height, 0, 0, 0,
                          rectangle.Height, pixelInfoIntPointer, bitmapPointer, 0);
                  }
                  finally
                  {
                      graphics.ReleaseHdc(hdc);
                  }
              }
  
              bitmap.SetResolution(PpmToDpi(bitmapInfo.XPelsPerMeter),
                  PpmToDpi(bitmapInfo.YPelsPerMeter));
  
              NativeMethods.GlobalUnlock(dibHandle);
              NativeMethods.GlobalFree(dibHandle);
  
              return bitmap;
          }
  
          private static float PpmToDpi(double pixelsPerMeter)
          {
              double pixelsPerMillimeter = (double)pixelsPerMeter / 1000.0;
              double dotsPerInch = pixelsPerMillimeter * 25.4;
              return (float)Math.Round(dotsPerInch, 2);
          }
      }
  }
  </code></pre>
  
  <p>and here are the p/invokes:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Runtime.InteropServices;
  using System.Text;
  using System.Threading.Tasks;
  
  namespace TwainLayoutWindowsFormsApplication
  {
      internal static class NativeMethods
      {
  
          [DllImport("kernel32.dll", ExactSpelling = true)]
          internal static extern IntPtr GlobalAlloc(int flags, int size);
  
          [DllImport("kernel32.dll", ExactSpelling = true)]
          internal static extern IntPtr GlobalLock(IntPtr handle);
  
          [DllImport("kernel32.dll", ExactSpelling = true)]
          internal static extern bool GlobalUnlock(IntPtr handle);
  
          [DllImport("kernel32.dll", ExactSpelling = true)]
          internal static extern IntPtr GlobalFree(IntPtr handle);
  
          [DllImport("gdi32.dll", ExactSpelling = true)]
          public static extern int SetDIBitsToDevice(IntPtr hdc, int xdst, int ydst, int width, int height,
              int xsrc, int ysrc, int start, int lines, IntPtr bitsptr, IntPtr bmiptr, int color);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSMparent([In, Out] TwainIdentity origin, IntPtr zeroptr, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, ref IntPtr refptr);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSMident([In, Out] TwainIdentity origin, IntPtr zeroptr, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, [In, Out] TwainIdentity idds);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSMentry([In, Out] TwainIdentity origin, IntPtr zeroptr, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, [In, Out] TwainIdentity idds);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSMstatus([In, Out] TwainIdentity origin, IntPtr zeroptr, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, [In, Out] TwainStatus dsmstat);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSuserif([In, Out] TwainIdentity origin, [In, Out] TwainIdentity dest, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, TwainUserInterface guif);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSevent([In, Out] TwainIdentity origin, [In, Out] TwainIdentity dest, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, ref TwainEvent evt);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSstatus([In, Out] TwainIdentity origin, [In] TwainIdentity dest, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, [In, Out] TwainStatus dsmstat);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DScap([In, Out] TwainIdentity origin, [In] TwainIdentity dest, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, [In, Out] TwainCapability capa);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSiinf([In, Out] TwainIdentity origin, [In] TwainIdentity dest, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, [In, Out] TwainImageInfo imginf);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSixfer([In, Out] TwainIdentity origin, [In] TwainIdentity dest, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, ref IntPtr hbitmap);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSMemixfer([In, Out] TwainIdentity origin, [In] TwainIdentity dest, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, [In, Out] TwainImageMemXfer memxfr);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSpxfer([In, Out] TwainIdentity origin, [In] TwainIdentity dest, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, [In, Out] TwainPendingXfers pxfr);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSilayout([In, Out] TwainIdentity origin, [In] TwainIdentity dest, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, [In, Out] TwainImageLayout layout);
  
          [DllImport("twain_32.dll", EntryPoint = "#1")]
          internal static extern TwainReturnCode DSMEntry([In, Out] TwainIdentity origin, [In] TwainIdentity dest, TwainDataGroups dg, TwainDataArgumentType dat, TwainMessage msg, [In, Out] TwainSetupFileXfer fileXf);
      }
  }
  </code></pre>
  
  <p>and finally, the rest of the stuff (structures and whatnot) that that needs to work:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Runtime.InteropServices;
  using System.Text;
  using System.Threading.Tasks;
  
  namespace TwainLayoutWindowsFormsApplication
  {
      [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Ansi)]
      internal class TwainIdentity
      {                                   
          public IntPtr Id;
          public TwainVersion Version;
          public short ProtocolMajor;
          public short ProtocolMinor;
          public int SupportedGroups;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)]
          public string Manufacturer;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)]
          public string ProductFamily;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)]
          public string ProductName;
      }
  
      internal enum TwainReturnCode : short
      {                                   
          Success = 0x0000,
          Failure = 0x0001,
          CheckStatus = 0x0002,
          Cancel = 0x0003,
          DSEvent = 0x0004,
          NotDSEvent = 0x0005,
          XferDone = 0x0006,
          EndOfList = 0x0007,
          InfoNotSupported = 0x0008,
          DataNotAvailable = 0x0009
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Ansi)]
      internal struct TwainVersion
      {                                   
          public short MajorNum;
          public short MinorNum;
          public short Language;
          public short Country;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)]
          public string Info;
      }
  
      [Flags]
      internal enum TwainDataGroups : short
      {
          Control = 0x0001,
          Image = 0x0002,
          Audio = 0x0004
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal struct TwainEvent
      {                                   
          public IntPtr EventPtr;
          public short Message;
      }
  
      internal enum TwainDataArgumentType : short
      {                                   
          Null = 0x0000,
          Capability = 0x0001,
          Event = 0x0002,
          Identity = 0x0003,
          Parent = 0x0004,
          PendingXfers = 0x0005,
          SetupMemXfer = 0x0006,
          SetupFileXfer = 0x0007,
          Status = 0x0008,
          UserInterface = 0x0009,
          XferGroup = 0x000a,
          TwunkIdentity = 0x000b,
          CustomDSData = 0x000c,
          DeviceEvent = 0x000d,
          FileSystem = 0x000e,
          PassThru = 0x000f,
  
          ImageInfo = 0x0101,
          ImageLayout = 0x0102,
          ImageMemXfer = 0x0103,
          ImageNativeXfer = 0x0104,
          ImageFileXfer = 0x0105,
          CieColor = 0x0106,
          GrayResponse = 0x0107,
          RGBResponse = 0x0108,
          JpegCompression = 0x0109,
          Palette8 = 0x010a,
          ExtImageInfo = 0x010b,
  
          SetupFileXfer2 = 0x0301
      }
  
      internal enum TwainMessage : short
      {                                   
          Null = 0x0000,
          Get = 0x0001,
          GetCurrent = 0x0002,
          GetDefault = 0x0003,
          GetFirst = 0x0004,
          GetNext = 0x0005,
          Set = 0x0006,
          Reset = 0x0007,
          QuerySupport = 0x0008,
  
          XFerReady = 0x0101,
          CloseDSReq = 0x0102,
          CloseDSOK = 0x0103,
          DeviceEvent = 0x0104,
  
          CheckStatus = 0x0201,
  
          OpenDSM = 0x0301,
          CloseDSM = 0x0302,
  
          OpenDS = 0x0401,
          CloseDS = 0x0402,
          UserSelect = 0x0403,
  
          DisableDS = 0x0501,
          EnableDS = 0x0502,
          EnableDSUIOnly = 0x0503,
  
          ProcessEvent = 0x0601,
  
          EndXfer = 0x0701,
          StopFeeder = 0x0702,
  
          ChangeDirectory = 0x0801,
          CreateDirectory = 0x0802,
          Delete = 0x0803,
          FormatMedia = 0x0804,
          GetClose = 0x0805,
          GetFirstFile = 0x0806,
          GetInfo = 0x0807,
          GetNextFile = 0x0808,
          Rename = 0x0809,
          Copy = 0x080A,
          AutoCaptureDir = 0x080B,
  
          PassThru = 0x0901
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 4)]
      internal struct TwainWindowMessage
      {
          public IntPtr hwnd;
          public int message;
          public IntPtr wParam;
          public IntPtr lParam;
          public int time;
          public int x;
          public int y;
      }
  
      internal enum TwainOn : short
      {                               
          Array = 0x0003,
          Enum = 0x0004,
          One = 0x0005,
          Range = 0x0006,
          DontCare = -1
      }
  
      internal enum TwainCapabilityType : short
      {
          XferCount = 0x0001,
  
          ICompression = 0x0100,
          IPixelType = 0x0101,
          IUnits = 0x0102,
          IXferMech = 0x0103,
  
          Author = 0x1000,
          Caption = 0x1001,
          FeederEnabled = 0x1002,
          FeederLoaded = 0x1003,
          Timedate = 0x1004,
          SupportedCapabilities = 0x1005,
          Extendedcaps = 0x1006,
          AutoFeed = 0x1007,
          ClearPage = 0x1008,
          FeedPage = 0x1009,
          RewindPage = 0x100a,
  
          Indicators = 0x100b,
          SupportedCapsExt = 0x100c,
          PaperDetectable = 0x100d,
          UIControllable = 0x100e,
          DeviceOnline = 0x100f,
          AutoScan = 0x1010,
          ThumbnailsEnabled = 0x1011,
          Duplex = 0x1012,
          DuplexEnabled = 0x1013,
          Enabledsuionly = 0x1014,
          CustomdsData = 0x1015,
          Endorser = 0x1016,
          JobControl = 0x1017,
          Alarms = 0x1018,
          AlarmVolume = 0x1019,
          AutomaticCapture = 0x101a,
          TimeBeforeFirstCapture = 0x101b,
          TimeBetweenCaptures = 0x101c,
          ClearBuffers = 0x101d,
          MaxBatchBuffers = 0x101e,
          DeviceTimeDate = 0x101f,
          PowerSupply = 0x1020,
          CameraPreviewUI = 0x1021,
          DeviceEvent = 0x1022,
          SerialNumber = 0x1024,
          Printer = 0x1026,
          PrinterEnabled = 0x1027,
          PrinterIndex = 0x1028,
          PrinterMode = 0x1029,
          PrinterString = 0x102a,
          PrinterSuffix = 0x102b,
          Language = 0x102c,
          FeederAlignment = 0x102d,
          FeederOrder = 0x102e,
          ReAcquireAllowed = 0x1030,
          BatteryMinutes = 0x1032,
          BatteryPercentage = 0x1033,
          CameraSide = 0x1034,
          Segmented = 0x1035,
          CameraEnabled = 0x1036,
          CameraOrder = 0x1037,
          MicrEnabled = 0x1038,
          FeederPrep = 0x1039,
          Feederpocket = 0x103a,
  
          Autobright = 0x1100,
          Brightness = 0x1101,
          Contrast = 0x1103,
          CustHalftone = 0x1104,
          ExposureTime = 0x1105,
          Filter = 0x1106,
          Flashused = 0x1107,
          Gamma = 0x1108,
          Halftones = 0x1109,
          Highlight = 0x110a,
          ImageFileFormat = 0x110c,
          LampState = 0x110d,
          LightSource = 0x110e,
          Orientation = 0x1110,
          PhysicalWidth = 0x1111,
          PhysicalHeight = 0x1112,
          Shadow = 0x1113,
          Frames = 0x1114,
          XNativeResolution = 0x1116,
          YNativeResolution = 0x1117,
          XResolution = 0x1118,
          YResolution = 0x1119,
          MaxFrames = 0x111a,
  
          Tiles = 0x111b,
          Bitorder = 0x111c,
          Ccittkfactor = 0x111d,
          Lightpath = 0x111e,
          Pixelflavor = 0x111f,
          Planarchunky = 0x1120,
          Rotation = 0x1121,
          Supportedsizes = 0x1122,
          Threshold = 0x1123,
          Xscaling = 0x1124,
          Yscaling = 0x1125,
          Bitordercodes = 0x1126,
          Pixelflavorcodes = 0x1127,
          Jpegpixeltype = 0x1128,
          Timefill = 0x112a,
          BitDepth = 0x112b,
          Bitdepthreduction = 0x112c,
          Undefinedimagesize = 0x112d,
          Imagedataset = 0x112e,
          Extimageinfo = 0x112f,
          Minimumheight = 0x1130,
          Minimumwidth = 0x1131,
          Fliprotation = 0x1136,
          Barcodedetectionenabled = 0x1137,
          Supportedbarcodetypes = 0x1138,
          Barcodemaxsearchpriorities = 0x1139,
          Barcodesearchpriorities = 0x113a,
          Barcodesearchmode = 0x113b,
          Barcodemaxretries = 0x113c,
          Barcodetimeout = 0x113d,
          Zoomfactor = 0x113e,
          Patchcodedetectionenabled = 0x113f,
          Supportedpatchcodetypes = 0x1140,
          Patchcodemaxsearchpriorities = 0x1141,
          Patchcodesearchpriorities = 0x1142,
          Patchcodesearchmode = 0x1143,
          Patchcodemaxretries = 0x1144,
          Patchcodetimeout = 0x1145,
          Flashused2 = 0x1146,
          Imagefilter = 0x1147,
          Noisefilter = 0x1148,
          Overscan = 0x1149,
          Automaticborderdetection = 0x1150,
          Automaticdeskew = 0x1151,
          Automaticrotate = 0x1152,
          Jpegquality = 0x1153,
          Feedertype = 0x1154,
          Iccprofile = 0x1155,
          Autosize = 0x1156,
          AutomaticCropUsesFrame = 0x1157,            
          AutomaticLengthDetection = 0x1158,          
          AutomaticColorEnabled = 0x1159,             
          AutomaticColorNonColorPixelType = 0x115a,   
          ColorManagementEnabled = 0x115b,            
          ImageMerge = 0x115c,                        
          ImageMergeHeightThreshold = 0x115d,       
          SupoortedExtImageInfo = 0x115e,             
          Audiofileformat = 0x1201,
          Xfermech = 0x1202
      }
  
      internal enum TwainType : short
      {                                   
          Int8 = 0x0000,
          Int16 = 0x0001,
          Int32 = 0x0002,
          UInt8 = 0x0003,
          UInt16 = 0x0004,
          UInt32 = 0x0005,
          Bool = 0x0006,
          Fix32 = 0x0007,
          Frame = 0x0008,
          Str32 = 0x0009,
          Str64 = 0x000a,
          Str128 = 0x000b,
          Str255 = 0x000c,
          Str1024 = 0x000d,
          Str512 = 0x000e
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal class TwainStatus
      {                                   
          public short ConditionCode;     
          public short Reserved;
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal class TwainUserInterface
      {                                   
          public short ShowUI;            
          public short ModalUI;
          public IntPtr ParentHand;
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal class TwainImageInfo
      {                                   
          public int XResolution;
          public int YResolution;
          public int ImageWidth;
          public int ImageLength;
          public short SamplesPerPixel;
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
          public short[] BitsPerSample;
          public short BitsPerPixel;
          public short Planar;
          public short PixelType;
          public short Compression;
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal class TwMemory
      {
          public uint Flags;
          public uint Length;
          IntPtr TheMem;
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal class TwainImageMemXfer
      {
          public ushort Compression;
          public uint BytesPerRow;
          public uint Columns;
          public uint Rows;
          public uint XOffset;
          public uint YOffset;
          public uint BytesWritten;
          [MarshalAs(UnmanagedType.Struct)]
          TwMemory Memory;
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal struct TwainFix32
      {                                               
          public short Whole;
          public ushort Frac;
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal class TwainFrame
      {
          public TwainFix32 Left;
          public TwainFix32 Top;
          public TwainFix32 Right;
          public TwainFix32 Bottom;
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal class TwainImageLayout
      {
          public TwainFrame Frame;
          public int DocumentNumber;
          public int PageNumber;
          public int FrameNumber;
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal class TwainPendingXfers
      {                                   
          public short Count;
          public int EOJ;
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal class TwainSetupFileXfer
      {
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
          public string FileName;
          public ushort Format;
          public short VRefNum;
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      internal class TwainCapability : IDisposable
      {                                   
  
          internal TwainCapability(TwainCapabilityType cap)
          {
              Cap = (short)cap;
              ConType = -1;
          }
  
          internal TwainCapability(TwainCapabilityType cap, short sval)
          {
              Cap = (short)cap;
              ConType = (short)TwainOn.One;
              Handle = NativeMethods.GlobalAlloc(0x42, 6);
              IntPtr pv = NativeMethods.GlobalLock(Handle);
              Marshal.WriteInt16(pv, 0, (short)TwainType.Int16);
              Marshal.WriteInt32(pv, 2, (int)sval);
              NativeMethods.GlobalUnlock(Handle);
          }
  
          ~TwainCapability()
          {
  
              Dispose(false);
          }
  
          public short Cap;
  
          public short ConType;
  
          public IntPtr Handle;
  
          public void Dispose()
          {
              Dispose(true);
              GC.SuppressFinalize(this);
          }
  
          protected virtual void Dispose(bool disposing)
          {
              if (Handle != IntPtr.Zero)
                  NativeMethods.GlobalFree(Handle);
          }
      }
  }
  </code></pre>