Jump to content

dN!3L

Newbies
  • Posts

    8
  • Joined

  • Last visited

Everything posted by dN!3L

  1. But for 3.0 the menu item click logic sure is an other than this, so there will be nedessity for an update.
  2. I never said you have to do... (maybe the wrong forum...?) I rather aimed the users that want to have a TWAIN support. My personal version works and I'm happy with this solution.
  3. Hope the code is complete... I tested this code with a pc and a notebook, and a not TWAIN supporting scanner and WIA supporting webcam. Regards, dN!3L
  4. 4. implement menu item click logic And finally you have to add the menu click logic for TWAIN acquirering. Add this code to "MainForm.cs": private void menuFileAcquireFromScannerOrCameraTwain_Click(object sender,System.EventArgs e) { using (new WaitCursorChanger(this)) { // initialize TwainSource if (twainSource==null) { twainSource = new TwainSource(this.Handle); twainSource.TransferFinished += new EventHandler(twainSource_TransferFinished); } // select source and show Twain-UI twainSource.SelectTwainSource(); twainSource.ShowTwainUi(); } } // the TWAIN supporting class TwainSource twainSource = null; /// /// when TWAIN finished the transfer, put results into workspace /// void twainSource_TransferFinished(object sender,EventArgs e) { using (new WaitCursorChanger(this)) { string errorText = null; try { foreach (Bitmap bitmap in twainSource.ScannedImages) { // first ask for save if needed if (workspace.Document.Dirty) { switch (AskForSave()) { case DialogResult.Yes: if (!DoSave()) { return; } break; case DialogResult.No: break; case DialogResult.Cancel: return; } } // create new document from scanned image... Document document; try { document = Document.FromImage(bitmap); } catch (OutOfMemoryException) { errorText = PdnResources.GetString("MainForm.LoadDocument.Error.OutOfMemoryException"); throw; } // ... and replace current document with it try { workspace.SetDocument(document); } catch (OutOfMemoryException) { errorText = PdnResources.GetString("MainForm.LoadDocument.Error.OutOfMemoryException"); throw; } document = null; workspace.SetDocumentSaveOptions(null,null,null); workspace.History.ClearAll(); HistoryAction newHA = new NullHistoryAction(PdnResources.GetString("AcquireImageAction.Name"),this.AddNewLayerIcon); workspace.History.PushNewAction(newHA); } } catch (Exception) { if (errorText != null) { Utility.ErrorBox(this,errorText); } else { throw; } } } }
  5. 3. add new menu item Now you have to add a new menu item to the main menu. Open "MainForm.cs" (project "paintdotnet"). Search the code between the following -Tags and replace it with the code between the -Tags. // // private System.Windows.Forms.ToolStripMenuItem menuFileAcquireFromScannerOrCamera; // // private System.Windows.Forms.ToolStripMenuItem menuFileAcquireFromScannerOrCameraWia; private System.Windows.Forms.ToolStripMenuItem menuFileAcquireFromScannerOrCameraTwain; // // //this.menuFileAcquireFromScannerOrCamera = new System.Windows.Forms.ToolStripMenuItem(); // // this.menuFileAcquireFromScannerOrCameraWia = new System.Windows.Forms.ToolStripMenuItem(); this.menuFileAcquireFromScannerOrCameraTwain = new System.Windows.Forms.ToolStripMenuItem(); // // // menuFileAcquire // this.menuFileAcquire.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.menuFileAcquireFromClipboard, // // this.menuFileAcquireFromScannerOrCamera // // this.menuFileAcquireFromScannerOrCameraWia, this.menuFileAcquireFromScannerOrCameraTwain // }); // // // menuFileAcquireFromScannerOrCamera // //this.menuFileAcquireFromScannerOrCamera.Click += new System.EventHandler(this.menuFileAcquireFromScannerOrCamera_Click); // // // // menuFileAcquireFromScannerOrCameraWia // this.menuFileAcquireFromScannerOrCameraWia.Click += new System.EventHandler(this.menuFileAcquireFromScannerOrCameraWia_Click); // // menuFileAcquireFromScannerOrCameraTwain // this.menuFileAcquireFromScannerOrCameraTwain.Click += new System.EventHandler(this.menuFileAcquireFromScannerOrCameraTwain_Click); // // // this.menuFileAcquireFromScannerOrCamera.Text = PdnResources.GetString("MainForm.Menu.File.Acquire.FromScannerOrCamera.Text"); // // this.menuFileAcquireFromScannerOrCameraWia.Text = PdnResources.GetString("MainForm.Menu.File.Acquire.FromScannerOrCamera.Text").Replace("..."," (WIA)..."); this.menuFileAcquireFromScannerOrCameraTwain.Text = PdnResources.GetString("MainForm.Menu.File.Acquire.FromScannerOrCamera.Text").Replace("..."," (TWAIN)..."); // // // private void menuFileAcquireFromScannerOrCamera_Click(object sender,System.EventArgs e) // // private void menuFileAcquireFromScannerOrCameraWia_Click(object sender,System.EventArgs e) // // // menuFileAcquireFromScannerOrCamera.Enabled = scannerEnabled; // // menuFileAcquireFromScannerOrCameraWia.Enabled = scannerEnabled; //
  6. 2. create TwainSource class The same procedure as in 1., but name it "TwainSource.cs" and take the following code: ///////////////////////////////////////////////////////////////////////////////// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. ///////////////////////////////////////////////////////////////////////////////// using System; using System.Windows.Forms; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; using System.Reflection; using System.Threading; using TwainLib; namespace PaintDotNet.SystemLayer { /// /// a simple API for TWAIN device /// public class TwainSource : IMessageFilter,IDisposable { /// /// constructor /// /// parent window handle public TwainSource(IntPtr hwndp) { twain = new Twain(); twain.Init(hwndp); } /// /// clear ressources /// public void Dispose() { twain.Finish(); } private bool messageFilterIsActive; private TwainLib.Twain twain; /// /// all aquired pictures from TWAIN device /// public IList ScannedImages = new List(); /// /// TWAIN device begins to acquire images /// public event EventHandler TransferStarted; /// /// TWAIN device finished acquire images /// public event EventHandler TransferFinished; /// /// displays a form for selecting the TWAIN device /// public void SelectTwainSource() { twain.Select(); } /// /// displays the UI of the TWAIN device /// public void ShowTwainUi() { if (!messageFilterIsActive) { messageFilterIsActive = true; ScannedImages.Clear(); Application.AddMessageFilter(this); } twain.Acquire(); } /// /// stop listening for TWAIN device results /// public void EndingScan() { if (messageFilterIsActive) { Application.RemoveMessageFilter(this); messageFilterIsActive = false; if (TransferFinished!=null) TransferFinished(this,null); } } /// /// receives messages and handles TWAIN device messages /// /// the message /// message is handled public bool PreFilterMessage(ref System.Windows.Forms.Message m) { TwainCommand twainCommand = twain.PassMessage(ref m); if (twainCommand==TwainCommand.Not) return false; switch (twainCommand) { case TwainCommand.CloseRequest: { EndingScan(); twain.CloseSrc(); break; } case TwainCommand.CloseOk: { EndingScan(); twain.CloseSrc(); break; } case TwainCommand.DeviceEvent: { break; } case TwainCommand.TransferReady: { if (TransferStarted!=null) TransferStarted(this,null); ArrayList pics = twain.TransferPictures(); foreach (IntPtr img in pics) ScannedImages.Add(bitmapFromDIB(img)); EndingScan(); twain.CloseSrc(); } break; case TwainCommand.Null: { twainCommandNullCount++; if (twainCommandNullCount>25) { twainCommandNullCount = 0; EndingScan(); twain.CloseSrc(); } break; } } return true; } // hack: TwainCommand.Null is sended continuously after TWAIN device is not available or when once preview is done private int twainCommandNullCount = 0; /// /// converts the TWAIN device result to .NET Bitmap /// /// pointer to aquired image /// TWAIN device as .NET Bitmap private Bitmap bitmapFromDIB(IntPtr dibhand) { IntPtr bmpptr = GlobalLock(dibhand); IntPtr pixptr = GetPixelInfo(bmpptr); IntPtr pBmp = IntPtr.Zero; int status = GdipCreateBitmapFromGdiDib(bmpptr,pixptr,ref pBmp); if ((status == 0) && (pBmp != IntPtr.Zero)) { MethodInfo mi = typeof(Bitmap).GetMethod("FromGDIplus",BindingFlags.Static | BindingFlags.NonPublic); if (mi == null) return null; Bitmap result = new Bitmap(mi.Invoke(null,new object[] { pBmp }) as Bitmap); GlobalFree(dibhand); dibhand = IntPtr.Zero; return result; } else return null; } private IntPtr GetPixelInfo(IntPtr bmpptr) { BITMAPINFOHEADER bmi = new BITMAPINFOHEADER(); Marshal.PtrToStructure(bmpptr,bmi); Rectangle bmprect = new Rectangle(0,0,bmi.biWidth,bmi.biHeight); if (bmi.biSizeImage == 0) bmi.biSizeImage = ((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * bmi.biHeight; int p = bmi.biClrUsed; if ((p == 0) && (bmi.biBitCount <= 8)) p = 1 << bmi.biBitCount; p = (p * 4) + bmi.biSize + (int)bmpptr; return (IntPtr)p; } [DllImport("gdiplus.dll",ExactSpelling=true)] private static extern int GdipCreateBitmapFromGdiDib(IntPtr bminfo,IntPtr pixdat,ref IntPtr image); [DllImport("kernel32.dll",ExactSpelling=true)] private static extern IntPtr GlobalLock(IntPtr handle); [DllImport("kernel32.dll",ExactSpelling=true)] private static extern IntPtr GlobalFree(IntPtr handle); [structLayout(LayoutKind.Sequential,Pack=2)] private class BITMAPINFOHEADER { public int biSize=0; public int biWidth=0; public int biHeight=0; public short biPlanes=0; public short biBitCount=0; public int biCompression=0; public int biSizeImage=0; public int biXPelsPerMeter=0; public int biYPelsPerMeter=0; public int biClrUsed=0; public int biClrImportant=0; } } }
  7. 1. create TwainLib class First you have to add an new *.cs-file to your solution. The project "SystemLayer" contains the base scanning features, so I add it to this project. So add there a new *.cs-File, name it "TwainLib.cs" and copy the following code into it: ///////////////////////////////////////////////////////////////////////////////// // // Source: http://www.codeproject.com/dotnet/twaindotnet.asp // by Thomas Scheidegger // (public domain) // // ///////////////////////////////////////////////////////////////////////////////// using System; using System.Collections; using System.Runtime.InteropServices; using System.Windows.Forms; namespace TwainLib { public enum TwainCommand { Not=-1, Null=0, TransferReady=1, CloseRequest=2, CloseOk=3, DeviceEvent=4 } public class Twain { private const short CountryUSA = 1; private const short LanguageUSA = 13; public Twain() { appid = new TwIdentity(); appid.Id = IntPtr.Zero; appid.Version.MajorNum = 1; appid.Version.MinorNum = 1; appid.Version.Language = LanguageUSA; appid.Version.Country = CountryUSA; appid.Version.Info = "Hack 1"; appid.ProtocolMajor = TwProtocol.Major; appid.ProtocolMinor = TwProtocol.Minor; appid.SupportedGroups = (int)(TwDG.Image | TwDG.Control); appid.Manufacturer = "NETMaster"; appid.ProductFamily = "Freeware"; appid.ProductName = "Hack"; srcds = new TwIdentity(); srcds.Id = IntPtr.Zero; evtmsg.EventPtr = Marshal.AllocHGlobal(Marshal.SizeOf(winmsg)); } ~Twain() { Marshal.FreeHGlobal(evtmsg.EventPtr); } public void Init(IntPtr hwndp) { Finish(); TwRC rc = DSMparent(appid,IntPtr.Zero,TwDG.Control,TwDAT.Parent,TwMSG.OpenDSM,ref hwndp); if (rc == TwRC.Success) { rc = DSMident(appid,IntPtr.Zero,TwDG.Control,TwDAT.Identity,TwMSG.GetDefault,srcds); if (rc == TwRC.Success) hwnd = hwndp; else rc = DSMparent(appid,IntPtr.Zero,TwDG.Control,TwDAT.Parent,TwMSG.CloseDSM,ref hwndp); } } public void Select() { TwRC rc; CloseSrc(); if (appid.Id == IntPtr.Zero) { Init(hwnd); if (appid.Id == IntPtr.Zero) return; } rc = DSMident(appid,IntPtr.Zero,TwDG.Control,TwDAT.Identity,TwMSG.UserSelect,srcds); } public void Acquire() { TwRC rc; CloseSrc(); if (appid.Id == IntPtr.Zero) { Init(hwnd); if (appid.Id == IntPtr.Zero) return; } rc = DSMident(appid,IntPtr.Zero,TwDG.Control,TwDAT.Identity,TwMSG.OpenDS,srcds); if (rc != TwRC.Success) return; TwCapability cap = new TwCapability(TwCap.XferCount,1); rc = DScap(appid,srcds,TwDG.Control,TwDAT.Capability,TwMSG.Set,cap); if (rc != TwRC.Success) { CloseSrc(); return; } TwUserInterface guif = new TwUserInterface(); guif.ShowUI = 1; guif.ModalUI = 1; guif.ParentHand = hwnd; rc = DSuserif(appid,srcds,TwDG.Control,TwDAT.UserInterface,TwMSG.EnableDS,guif); if (rc != TwRC.Success) { CloseSrc(); return; } } public ArrayList TransferPictures() { ArrayList pics = new ArrayList(); if (srcds.Id == IntPtr.Zero) return pics; TwRC rc; IntPtr hbitmap = IntPtr.Zero; TwPendingXfers pxfr = new TwPendingXfers(); do { pxfr.Count = 0; hbitmap = IntPtr.Zero; TwImageInfo iinf = new TwImageInfo(); rc = DSiinf(appid,srcds,TwDG.Image,TwDAT.ImageInfo,TwMSG.Get,iinf); if (rc != TwRC.Success) { CloseSrc(); return pics; } rc = DSixfer(appid,srcds,TwDG.Image,TwDAT.ImageNativeXfer,TwMSG.Get,ref hbitmap); if (rc != TwRC.XferDone) { CloseSrc(); return pics; } rc = DSpxfer(appid,srcds,TwDG.Control,TwDAT.PendingXfers,TwMSG.EndXfer,pxfr); if (rc != TwRC.Success) { CloseSrc(); return pics; } pics.Add(hbitmap); } while (pxfr.Count != 0); rc = DSpxfer(appid,srcds,TwDG.Control,TwDAT.PendingXfers,TwMSG.Reset,pxfr); return pics; } public TwainCommand PassMessage(ref Message m) { if (srcds.Id == IntPtr.Zero) return TwainCommand.Not; int pos = GetMessagePos(); winmsg.hwnd = m.HWnd; winmsg.message = m.Msg; winmsg.wParam = m.WParam; winmsg.lParam = m.LParam; winmsg.time = GetMessageTime(); unchecked { winmsg.x = (short)pos; winmsg.y = (short)(pos >> 16); } Marshal.StructureToPtr(winmsg,evtmsg.EventPtr,false); evtmsg.Message = 0; TwRC rc = DSevent(appid,srcds,TwDG.Control,TwDAT.Event,TwMSG.ProcessEvent,ref evtmsg); if (rc == TwRC.NotDSEvent) return TwainCommand.Not; if (evtmsg.Message == (short)TwMSG.XFerReady) return TwainCommand.TransferReady; if (evtmsg.Message == (short)TwMSG.CloseDSReq) return TwainCommand.CloseRequest; if (evtmsg.Message == (short)TwMSG.CloseDSOK) return TwainCommand.CloseOk; if (evtmsg.Message == (short)TwMSG.DeviceEvent) return TwainCommand.DeviceEvent; return TwainCommand.Null; } public void CloseSrc() { TwRC rc; if (srcds.Id != IntPtr.Zero) { TwUserInterface guif = new TwUserInterface(); rc = DSuserif(appid,srcds,TwDG.Control,TwDAT.UserInterface,TwMSG.DisableDS,guif); rc = DSMident(appid,IntPtr.Zero,TwDG.Control,TwDAT.Identity,TwMSG.CloseDS,srcds); } } public void Finish() { TwRC rc; CloseSrc(); if (appid.Id != IntPtr.Zero) rc = DSMparent(appid,IntPtr.Zero,TwDG.Control,TwDAT.Parent,TwMSG.CloseDSM,ref hwnd); appid.Id = IntPtr.Zero; } internal IntPtr hwnd; private TwIdentity appid; private TwIdentity srcds; private TwEvent evtmsg; private WINMSG winmsg; // ------ DSM entry point DAT_ variants: [DllImport("twain_32.dll",EntryPoint="#1")] private static extern TwRC DSMparent([in,Out] TwIdentity origin,IntPtr zeroptr,TwDG dg,TwDAT dat,TwMSG msg,ref IntPtr refptr); [DllImport("twain_32.dll",EntryPoint="#1")] private static extern TwRC DSMident([in,Out] TwIdentity origin,IntPtr zeroptr,TwDG dg,TwDAT dat,TwMSG msg,[in,Out] TwIdentity idds); [DllImport("twain_32.dll",EntryPoint="#1")] private static extern TwRC DSMstatus([in,Out] TwIdentity origin,IntPtr zeroptr,TwDG dg,TwDAT dat,TwMSG msg,[in,Out] TwStatus dsmstat); // ------ DSM entry point DAT_ variants to DS: [DllImport("twain_32.dll",EntryPoint="#1")] private static extern TwRC DSuserif([in,Out] TwIdentity origin,[in,Out] TwIdentity dest,TwDG dg,TwDAT dat,TwMSG msg,TwUserInterface guif); [DllImport("twain_32.dll",EntryPoint="#1")] private static extern TwRC DSevent([in,Out] TwIdentity origin,[in,Out] TwIdentity dest,TwDG dg,TwDAT dat,TwMSG msg,ref TwEvent evt); [DllImport("twain_32.dll",EntryPoint="#1")] private static extern TwRC DSstatus([in,Out] TwIdentity origin,[in] TwIdentity dest,TwDG dg,TwDAT dat,TwMSG msg,[in,Out] TwStatus dsmstat); [DllImport("twain_32.dll",EntryPoint="#1")] private static extern TwRC DScap([in,Out] TwIdentity origin,[in] TwIdentity dest,TwDG dg,TwDAT dat,TwMSG msg,[in,Out] TwCapability capa); [DllImport("twain_32.dll",EntryPoint="#1")] private static extern TwRC DSiinf([in,Out] TwIdentity origin,[in] TwIdentity dest,TwDG dg,TwDAT dat,TwMSG msg,[in,Out] TwImageInfo imginf); [DllImport("twain_32.dll",EntryPoint="#1")] private static extern TwRC DSixfer([in,Out] TwIdentity origin,[in] TwIdentity dest,TwDG dg,TwDAT dat,TwMSG msg,ref IntPtr hbitmap); [DllImport("twain_32.dll",EntryPoint="#1")] private static extern TwRC DSpxfer([in,Out] TwIdentity origin,[in] TwIdentity dest,TwDG dg,TwDAT dat,TwMSG msg,[in,Out] TwPendingXfers pxfr); [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("user32.dll",ExactSpelling=true)] private static extern int GetMessagePos(); [DllImport("user32.dll",ExactSpelling=true)] private static extern int GetMessageTime(); [DllImport("gdi32.dll",ExactSpelling=true)] private static extern int GetDeviceCaps(IntPtr hDC,int nIndex); [DllImport("gdi32.dll",CharSet=CharSet.Auto)] private static extern IntPtr CreateDC(string szdriver,string szdevice,string szoutput,IntPtr devmode); [DllImport("gdi32.dll",ExactSpelling=true)] private static extern bool DeleteDC(IntPtr hdc); public static int ScreenBitDepth { get { IntPtr screenDC = CreateDC("DISPLAY",null,null,IntPtr.Zero); int bitDepth = GetDeviceCaps(screenDC,12); bitDepth *= GetDeviceCaps(screenDC,14); DeleteDC(screenDC); return bitDepth; } } [structLayout(LayoutKind.Sequential,Pack=4)] internal struct WINMSG { public IntPtr hwnd; public int message; public IntPtr wParam; public IntPtr lParam; public int time; public int x; public int y; } } // class Twain public class TwProtocol { // TWON_PROTOCOL... public const short Major = 1; public const short Minor = 9; } [Flags] internal enum TwDG : short { // DG_..... Control=0x0001, Image=0x0002, Audio=0x0004 } internal enum TwDAT : short { // DAT_.... 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 TwMSG : short { // MSG_..... 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 } internal enum TwRC : short { // TWRC_.... Success=0x0000, Failure=0x0001, CheckStatus=0x0002, Cancel=0x0003, DSEvent=0x0004, NotDSEvent=0x0005, XferDone=0x0006, EndOfList=0x0007, InfoNotSupported=0x0008, DataNotAvailable=0x0009 } internal enum TwCC : short { // TWCC_.... Success=0x0000, Bummer=0x0001, LowMemory=0x0002, NoDS=0x0003, MaxConnections=0x0004, OperationError=0x0005, BadCap=0x0006, BadProtocol=0x0009, BadValue=0x000a, SeqError=0x000b, BadDest=0x000c, CapUnsupported=0x000d, CapBadOperation=0x000e, CapSeqError=0x000f, Denied=0x0010, FileExists=0x0011, FileNotFound=0x0012, NotEmpty=0x0013, PaperJam=0x0014, PaperDoubleFeed=0x0015, FileWriteError=0x0016, CheckDeviceOnline=0x0017 } internal enum TwOn : short { // TWON_.... Array=0x0003, Enum=0x0004, One=0x0005, Range=0x0006, DontCare=-1 } internal enum TwType : short { // TWTY_.... 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 } internal enum TwCap : short { XferCount=0x0001, // CAP_XFERCOUNT ICompression=0x0100, // ICAP_... IPixelType=0x0101, IUnits=0x0102, IXferMech=0x0103 } // ------------------- STRUCTS -------------------------------------------- [structLayout(LayoutKind.Sequential,Pack=2,CharSet=CharSet.Ansi)] internal class TwIdentity { // TW_IDENTITY public IntPtr Id; public TwVersion 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; } [structLayout(LayoutKind.Sequential,Pack=2,CharSet=CharSet.Ansi)] internal struct TwVersion { // TW_VERSION public short MajorNum; public short MinorNum; public short Language; public short Country; [MarshalAs(UnmanagedType.ByValTStr,SizeConst=34)] public string Info; } [structLayout(LayoutKind.Sequential,Pack=2)] internal class TwUserInterface { // TW_USERINTERFACE public short ShowUI; // bool is strictly 32 bit, so use short public short ModalUI; public IntPtr ParentHand; } [structLayout(LayoutKind.Sequential,Pack=2)] internal class TwStatus { // TW_STATUS public short ConditionCode; // TwCC public short Reserved; } [structLayout(LayoutKind.Sequential,Pack=2)] internal struct TwEvent { // TW_EVENT public IntPtr EventPtr; public short Message; } [structLayout(LayoutKind.Sequential,Pack=2)] internal class TwImageInfo { // TW_IMAGEINFO 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 TwPendingXfers { // TW_PENDINGXFERS public short Count; public int EOJ; } [structLayout(LayoutKind.Sequential,Pack=2)] internal struct TwFix32 { // TW_FIX32 public short Whole; public ushort Frac; public float ToFloat() { return (float)Whole + ((float)Frac /65536.0f); } public void FromFloat(float f) { int i = (int)((f * 65536.0f) + 0.5f); Whole = (short)(i >> 16); Frac = (ushort)(i & 0x0000ffff); } } [structLayout(LayoutKind.Sequential,Pack=2)] internal class TwCapability { // TW_CAPABILITY public TwCapability(TwCap cap) { Cap = (short)cap; ConType = -1; } public TwCapability(TwCap cap,short sval) { Cap = (short)cap; ConType = (short)TwOn.One; Handle = Twain.GlobalAlloc(0x42,6); IntPtr pv = Twain.GlobalLock(Handle); Marshal.WriteInt16(pv,0,(short)TwType.Int16); Marshal.WriteInt32(pv,2,(int)sval); Twain.GlobalUnlock(Handle); } ~TwCapability() { if (Handle != IntPtr.Zero) Twain.GlobalFree(Handle); } public short Cap; public short ConType; public IntPtr Handle; } } // namespace TwainLib
  8. Hi, my scanner doesn't support WIA, so I made PDN support TWAIN devices. Some of the PDN users miss this function, so here is my code (the PDN source code has to be changed and recompiled): overview: 1. create TwainLib class 2. create TwainSource class 3. add new menu item 4. implement menu item click logic
×
×
  • Create New...