Ist es in TWAIN möglich, einen Scanner zu zwingen, den Bereich auf die gesamte Breite einzustellen?

Ich schreibe eine Anwendung, die das Scannen in .net erfordert (c# Ausführung4.0, Visual Studio 2010). Ich benutze dieTWAIN API, um das Scannen durchzuführen, und ich habe ein Problem mit der Layoutfunktion. Der folgende Code funktioniert einwandfrei auf einemMicrotek i800, einCanoScan 9000F und einMicrotek Artix Scan F2 aber wenn ich es gegen einen laufen lasseEpson Perfection V700 etwas wirklich seltsames passiert.

Auch wenn ich den linken Rand des Layouts auf setze0 Der linke Bildrand wird abgeschnitten. Ich habe versucht, negative Werte einzustellen, aber das machte keinen Unterschied. Es sieht so aus, als ob es etwas Seltsames gibt und es zwingt es zu einer Filmgröße (vielleicht, weil ich das Licht anmache). Wenn ich das mit dem Scanner gelieferte Werkzeug verwende, kann ich einen Bereich auswählen, der beide Kanten enthält (und das Licht an hat), sodass dies möglich sein muss. Auch die oberen und unteren Koordinaten funktionieren einwandfrei.

Also meine Frage ist ...

Kennt jemand eine Möglichkeit, mit der ich die gesamte Breite scannen kann? Gibt es eine andere Einstellung in TWAIN, die ich zuerst festlegen kann, damit die Papierformate möglicherweise vergessen werden? (Ich habe versucht, PaperDetectable ebenfalls auf false zu setzen, aber es machte keinen Unterschied).

Eine andere Sache:Wenn ich das Layout nicht einstelle, schneidet es immer noch das Bild an den Rändern ab (nur nicht oben und unten), aber wenn ich das Licht auch nicht einstelle (oder ich stelle das Licht nicht ein, aber ich stelle die Größe ein) Es macht das, was ich erwarten würde: Es scannt das gesamte Bild vom linken Rand aus (aber das Problem ist, dass ich das Licht und die gesamte Breite des Scans wirklich brauche - das ist sicher nicht zu viel verlangt ...).

Hier ist der Code (es ist der Code hinter einer 1-Formular-Windows-Formularanwendung mit einer einzigen Schaltfläche):

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 && 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<Bitmap> Scan(TwainIdentity appid, 
                                         TwainIdentity scanner)
        {
            var pictures = new List<Bitmap>();          

            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 && 
                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 && 
                   device.ProductName.Equals(name, 
                                          StringComparison.OrdinalIgnoreCase))
                {
                    return device;
                }
            }

            throw new InvalidOperationException("Could not find device");
        }
    }
}

Der Vollständigkeit halber hier der Code, mit dem ich die HBITMAP in eine konvertiereSystem.Drawing.Bitmap:

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) & ~31) >> 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) && (bitmapInfo.BitCount <= 8))
            {
                pixelInfoPointer = 1 << 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);
        }
    }
}

und hier sind die p / invokes:

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);
    }
}

und schließlich der Rest der Dinge (Strukturen und so weiter), die funktionieren müssen:

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);
        }
    }
}

Antworten auf die Frage(1)

Ihre Antwort auf die Frage