/// <summary> /// Rollback the TWAIN state to whatever is requested... /// </summary> /// <param name="a_state"></param> public void Rollback(TWAIN.STATE a_state) { TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); TWAIN.TW_USERINTERFACE twuserinterface = default(TWAIN.TW_USERINTERFACE); TWAIN.TW_IDENTITY twidentity = default(TWAIN.TW_IDENTITY); // Make sure we have something to work with... if (m_twain == null) { return; } // Walk the states, we don't care about the status returns. Basically, // these need to work, or we're guaranteed to hang... // 7 --> 6 if ((m_twain.GetState() == TWAIN.STATE.S7) && (a_state < TWAIN.STATE.S7)) { m_twain.DatPendingxfers(TWAIN.DG.CONTROL, TWAIN.MSG.ENDXFER, ref twpendingxfers); } // 6 --> 5 if ((m_twain.GetState() == TWAIN.STATE.S6) && (a_state < TWAIN.STATE.S6)) { m_twain.DatPendingxfers(TWAIN.DG.CONTROL, TWAIN.MSG.RESET, ref twpendingxfers); } // 5 --> 4 if ((m_twain.GetState() == TWAIN.STATE.S5) && (a_state < TWAIN.STATE.S5)) { m_twain.DatUserinterface(TWAIN.DG.CONTROL, TWAIN.MSG.DISABLEDS, ref twuserinterface); } // 4 --> 3 if ((m_twain.GetState() == TWAIN.STATE.S4) && (a_state < TWAIN.STATE.S4)) { TWAIN.CsvToIdentity(ref twidentity, m_twain.GetDsIdentity()); m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.CLOSEDS, ref twidentity); } // 3 --> 2 if ((m_twain.GetState() == TWAIN.STATE.S3) && (a_state < TWAIN.STATE.S3)) { m_twain.DatParent(TWAIN.DG.CONTROL, TWAIN.MSG.CLOSEDSM, ref m_intptrHwnd); } }
/////////////////////////////////////////////////////////////////////////////// // Public Methods... /////////////////////////////////////////////////////////////////////////////// #region Public Methods... /// <summary> /// Our constructor... /// </summary> public FormScan() { // Build our form... InitializeComponent(); // Open the log in our working folder, and say hi... TWAINWorkingGroup.Log.Open("TWAINCSScan", ".", 1); TWAINWorkingGroup.Log.Info("TWAINCSScan v" + System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString()); // Init other stuff... m_blIndicators = true; m_blExit = false; m_iUseBitmap = 0; this.FormClosing += new FormClosingEventHandler(FormScan_FormClosing); // Create our image capture object... try { // Init stuff... TWAIN.DeviceEventCallback deviceeventcallback = DeviceEventCallback; TWAIN.ScanCallback scancallback = ScanCallbackTrigger; TWAIN.RunInUiThreadDelegate runinuithreaddelegate = RunInUiThread; // Instantiate TWAIN, and register ourselves... m_twain = new TWAIN ( "TWAIN Working Group", "TWAIN Open Source", "TWAIN CS Scan App", (ushort)TWAIN.TWON_PROTOCOL.MAJOR, (ushort)TWAIN.TWON_PROTOCOL.MINOR, ((uint)TWAIN.DG.APP2 | (uint)TWAIN.DG.CONTROL | (uint)TWAIN.DG.IMAGE), TWAIN.TWCY.USA, "TWAIN CS Scan App", TWAIN.TWLG.ENGLISH_USA, 2, 4, false, false, deviceeventcallback, scancallback, runinuithreaddelegate, this.Handle ); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); m_twain = null; m_blExit = true; MessageBox.Show ( "Unable to start, the most likely reason is that the TWAIN\n" + "Data Source Manager is not installed on your system.\n\n" + "An internet search for 'TWAIN DSM' will locate it and once\n" + "installed, you should be able to proceed.\n\n" + "You can also try the following link:\n" + "http://sourceforge.net/projects/twain-dsm/", "Error Starting TWAIN CS Scan" ); return; } // Init our picture box... InitImage(); // Prep for TWAIN events... SetMessageFilter(true); // Init our buttons... SetButtons(EBUTTONSTATE.CLOSED); }
/// <summary> /// Go through the sequence needed to capture images... /// </summary> private void CaptureImages() { TWAIN.STS sts; TWAIN.TW_IMAGEINFO twimageinfo = default(TWAIN.TW_IMAGEINFO); TWAIN.TW_IMAGEMEMXFER twimagememxfer = default(TWAIN.TW_IMAGEMEMXFER); TWAIN.TW_PENDINGXFERS twpendingxfers = default(TWAIN.TW_PENDINGXFERS); TWAIN.TW_USERINTERFACE twuserinterface = default(TWAIN.TW_USERINTERFACE); // Dispatch on the state... switch (m_twain.GetState()) { // Not a good state, just scoot... default: return; // We're on our way out... case TWAIN.STATE.S5: m_blDisableDsSent = true; m_twain.DatUserinterface(TWAIN.DG.CONTROL, TWAIN.MSG.DISABLEDS, ref twuserinterface); SetButtons(EBUTTONSTATE.OPEN); return; // Memory transfers... case TWAIN.STATE.S6: case TWAIN.STATE.S7: m_twain.CsvToImagememxfer(ref twimagememxfer, "0,0,0,0,0,0,0," + ((int)TWAIN.TWMF.APPOWNS | (int)TWAIN.TWMF.POINTER) + "," + m_twsetupmemxfer.Preferred + "," + m_intptrXfer); sts = m_twain.DatImagememxfer(TWAIN.DG.IMAGE, TWAIN.MSG.GET, ref twimagememxfer); break; } // Handle problems... if ((sts != TWAIN.STS.SUCCESS) && (sts != TWAIN.STS.XFERDONE)) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); SetButtons(EBUTTONSTATE.OPEN); return; } // Allocate or grow the image memory... if (m_intptrImage == IntPtr.Zero) { m_intptrImage = Marshal.AllocHGlobal((int)twimagememxfer.BytesWritten); } else { m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(m_iImageBytes + twimagememxfer.BytesWritten)); } // Ruh-roh... if (m_intptrImage == IntPtr.Zero) { m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); SetButtons(EBUTTONSTATE.OPEN); return; } // Copy into the buffer, and bump up our byte tally... TWAIN.MemCpy(m_intptrImage + m_iImageBytes, m_intptrXfer, (int)twimagememxfer.BytesWritten); m_iImageBytes += (int)twimagememxfer.BytesWritten; // If we saw XFERDONE we can save the image, display it, // end the transfer, and see if we have more images... if (sts == TWAIN.STS.XFERDONE) { // Bump up our image counter, this always grows for the // life of the entire session... m_iImageCount += 1; // Get the image info... sts = m_twain.DatImageinfo(TWAIN.DG.IMAGE, TWAIN.MSG.GET, ref twimageinfo); // Add the appropriate header... // Bitonal uncompressed... if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.BW) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffBitonalUncompressed tiffbitonaluncompressed; tiffbitonaluncompressed = new TWAIN.TiffBitonalUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffbitonaluncompressed) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffbitonaluncompressed)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffbitonaluncompressed, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffbitonaluncompressed); } // Bitonal GROUP4... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.BW) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.GROUP4)) { TWAIN.TiffBitonalG4 tiffbitonalg4; tiffbitonalg4 = new TWAIN.TiffBitonalG4((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffbitonalg4) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffbitonalg4)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffbitonalg4, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffbitonalg4); } // Gray uncompressed... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.GRAY) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffGrayscaleUncompressed tiffgrayscaleuncompressed; tiffgrayscaleuncompressed = new TWAIN.TiffGrayscaleUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffgrayscaleuncompressed) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffgrayscaleuncompressed)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffgrayscaleuncompressed, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffgrayscaleuncompressed); } // Gray JPEG... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.GRAY) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.JPEG)) { // No work to be done, we'll output JPEG... } // RGB uncompressed... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.RGB) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.NONE)) { TWAIN.TiffColorUncompressed tiffcoloruncompressed; tiffcoloruncompressed = new TWAIN.TiffColorUncompressed((uint)twimageinfo.ImageWidth, (uint)twimageinfo.ImageLength, (uint)twimageinfo.XResolution.Whole, (uint)m_iImageBytes); m_intptrImage = Marshal.ReAllocHGlobal(m_intptrImage, (IntPtr)(Marshal.SizeOf(tiffcoloruncompressed) + m_iImageBytes)); TWAIN.MemMove((IntPtr)((UInt64)m_intptrImage + (UInt64)Marshal.SizeOf(tiffcoloruncompressed)), m_intptrImage, m_iImageBytes); Marshal.StructureToPtr(tiffcoloruncompressed, m_intptrImage, true); m_iImageBytes += (int)Marshal.SizeOf(tiffcoloruncompressed); } // RGB JPEG... else if (((TWAIN.TWPT)twimageinfo.PixelType == TWAIN.TWPT.RGB) && ((TWAIN.TWCP)twimageinfo.Compression == TWAIN.TWCP.JPEG)) { // No work to be done, we'll output JPEG... } // Oh well... else { TWAINWorkingGroup.Log.Error("unsupported format <" + twimageinfo.PixelType + "," + twimageinfo.Compression + ">"); m_blDisableDsSent = true; Rollback(TWAIN.STATE.S4); SetButtons(EBUTTONSTATE.OPEN); return; } // Save the image to disk, if we're doing that... if (!string.IsNullOrEmpty(m_formsetup.GetImageFolder())) { // Create the directory, if needed... if (!Directory.Exists(m_formsetup.GetImageFolder())) { try { Directory.CreateDirectory(m_formsetup.GetImageFolder()); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("CreateDirectory failed - " + exception.Message); } } // Write it out... string szFilename = Path.Combine(m_formsetup.GetImageFolder(), "img" + string.Format("{0:D6}", m_iImageCount)); TWAIN.WriteImageFile(szFilename, m_intptrImage, m_iImageBytes, out szFilename); } // Turn the image into a byte array, and free the original memory... byte[] abImage = new byte[m_iImageBytes]; Marshal.Copy(m_intptrImage, abImage, 0, m_iImageBytes); Marshal.FreeHGlobal(m_intptrImage); m_intptrImage = IntPtr.Zero; m_iImageBytes = 0; // Turn the byte array into a stream... MemoryStream memorystream = new MemoryStream(abImage); Bitmap bitmap = (Bitmap)Image.FromStream(memorystream); // Display the image... if (m_iUseBitmap == 0) { m_iUseBitmap = 1; LoadImage(ref m_pictureboxImage1, ref m_graphics1, ref m_bitmapGraphic1, bitmap); } else { m_iUseBitmap = 0; LoadImage(ref m_pictureboxImage2, ref m_graphics2, ref m_bitmapGraphic2, bitmap); } // Cleanup... bitmap.Dispose(); memorystream = null; // disposed by the bitmap abImage = null; // End the transfer... m_twain.DatPendingxfers(TWAIN.DG.CONTROL, TWAIN.MSG.ENDXFER, ref twpendingxfers); // Looks like we're done! if (twpendingxfers.Count == 0) { m_blDisableDsSent = true; m_twain.DatUserinterface(TWAIN.DG.CONTROL, TWAIN.MSG.DISABLEDS, ref twuserinterface); SetButtons(EBUTTONSTATE.OPEN); return; } } }
/// <summary> /// Select the mode for this session, batch or interactive, /// based on the arguments. Don't be weirded out by this /// function calling TWAIN Local On Twain and then that function using /// Sword. This is a static function, it's just a convenience /// to use the Sword object to hold it, it could go anywhere /// and later on probably will (like as a function inside of /// the Program module). /// </summary> /// <returns>true for batch mode, false for interactive mode</returns> public static bool SelectMode() { int iPid = 0; string szIpc; string szTaskFile; string szImagesFolder; bool blTestPdfRaster; string szTestDnssd; // Check the arguments... string szWriteFolder = Config.Get("writeFolder", null); string szExecutableName = Config.Get("executableName", null); szTaskFile = Config.Get("task", null); blTestPdfRaster = (Config.Get("testpdfraster", null) != null); szTestDnssd = Config.Get("testdnssd", null); szIpc = Config.Get("ipc", null); szImagesFolder = Config.Get("images", null); if (string.IsNullOrEmpty(szImagesFolder)) { szImagesFolder = Path.Combine(szWriteFolder, "images"); } iPid = int.Parse(Config.Get("parentpid", "0")); // Run in IPC mode. The caller has set up a 'pipe' for us, so we'll use // that to send commands back and forth. This is the normal mode when // we're running with a scanner... if (szIpc != null) { // With Windows we need a window for the driver, but we can hide it... if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new FormTwain(szWriteFolder, szImagesFolder, szIpc, iPid)); return(true); } // Linux and Mac OS X are okay without a window... else { TwainLocalOnTwain twainlocalontwain; // Create our object... twainlocalontwain = new TwainLocalOnTwain(szWriteFolder, szImagesFolder, szIpc, iPid, null, null, IntPtr.Zero); // Run our object... twainlocalontwain.Run(); // All done... return(true); } } // Handle the TWAIN list, we use this during registration to find out // what drivers we can use, and collect some info about them... string szTwainList = Config.Get("twainlist", null); if (szTwainList != null) { string szTwainListAction = Config.Get("twainlistaction", null); string szTwainListData = Config.Get("twainlistdata", null); if (szTwainList == "") { szTwainList = Path.Combine(Config.Get("writeFolder", ""), "twainlist.txt"); } System.IO.File.WriteAllText(szTwainList, ProcessSwordTask.TwainListDrivers(szTwainListAction, szTwainListData)); return(true); } /// Test DNS-SD... if (!string.IsNullOrEmpty(szTestDnssd)) { if (szTestDnssd == "monitor") { int ii; int jj; Dnssd dnssd; bool blServiceIsAvailable; Interpreter.CreateConsole(); List <Dnssd.DnssdDeviceInfo> ldnssddeviceinfo = new List <Dnssd.DnssdDeviceInfo>(); dnssd = new Dnssd(Dnssd.Reason.Monitor, out blServiceIsAvailable); if (blServiceIsAvailable) { dnssd.MonitorStart(null, IntPtr.Zero); for (ii = 0; ii < 60; ii++) { bool blUpdated = false; bool blNoMonitor = false; Thread.Sleep(1000); ldnssddeviceinfo = dnssd.GetSnapshot(ldnssddeviceinfo, out blUpdated, out blNoMonitor); if (blUpdated) { Console.Out.WriteLine(""); if ((ldnssddeviceinfo == null) || (ldnssddeviceinfo.Count == 0)) { Console.Out.WriteLine("***empty***"); } else { for (jj = 0; jj < ldnssddeviceinfo.Count; jj++) { Console.Out.WriteLine(ldnssddeviceinfo[jj].GetInterface() + " " + ldnssddeviceinfo[jj].GetServiceName()); } } } } dnssd.MonitorStop(); } dnssd.Dispose(); dnssd = null; } else if (szTestDnssd == "register") { Dnssd dnssd; bool blServiceIsAvailable; Interpreter.CreateConsole(); dnssd = new Dnssd(Dnssd.Reason.Register, out blServiceIsAvailable); if (blServiceIsAvailable) { dnssd.RegisterStart("Instance", 55556, "Ty", "", "", "", "Note"); Thread.Sleep(60000); dnssd.RegisterStop(); } dnssd.Dispose(); dnssd = null; } // All done... return(true); } // Otherwise let the user interact with us... TWAINWorkingGroup.Log.Info("Interactive mode..."); return(false); }
static void Main(string[] a_aszArgs) { string szExecutableName; string szWriteFolder; // Load our configuration information and our arguments, // so that we can access them from anywhere in the code... if (!Config.Load(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), a_aszArgs, "appdata.txt")) { Console.Out.WriteLine("Error starting. Try uninstalling and reinstalling this software."); Environment.Exit(1); } // Set up our data folders... szWriteFolder = Config.Get("writeFolder", ""); szExecutableName = Config.Get("executableName", ""); // Turn on logging... Log.Open(szExecutableName, szWriteFolder, (int)Config.Get("logLevel", 0)); Log.Info(szExecutableName + " Log Started..."); // Windows needs a window, we need our console and window // in different threads for full control... if (TWAIN.GetPlatform() == TWAIN.Platform.WINDOWS) { // Init our form... Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); FormMain formmain = new FormMain(); // Launch the terminal window, we're doing this in // a thread so we can have a console and a form. When // the thread is done there's no reason to be subtle, // we can exit the application... Terminal terminal = new twaincscert.Terminal(formmain); Thread threadTerminal = new Thread( new ThreadStart( delegate() { terminal.Run(); Environment.Exit(0); } ) ); threadTerminal.Start(); // Run our form, the exit above will kill it off... formmain.SetTerminal(terminal); Application.Run(formmain); } // Linux and Mac come here, life is much simpler for them... else { Terminal terminal = new twaincscert.Terminal(null); terminal.Run(); } // All done... Log.Info(szExecutableName + " Log Ended..."); Log.Close(); Environment.Exit(0); }
/// <summary> /// Select and open a TWAIN driver... /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void m_buttonOpen_Click(object sender, EventArgs e) { string szIdentity; string szDefault = ""; string szStatus; List <string> lszIdentity = new List <string>(); FormSelect formselect; DialogResult dialogresult; TWAIN.STS sts; TWAIN.TW_CAPABILITY twcapability; TWAIN.TW_IDENTITY twidentity = default(TWAIN.TW_IDENTITY); // Get the default driver... m_intptrHwnd = this.Handle; sts = m_twain.DatParent(TWAIN.DG.CONTROL, TWAIN.MSG.OPENDSM, ref m_intptrHwnd); if (sts != TWAIN.STS.SUCCESS) { MessageBox.Show("OPENDSM failed..."); return; } // Get the default driver... sts = m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.GETDEFAULT, ref twidentity); if (sts == TWAIN.STS.SUCCESS) { szDefault = TWAIN.IdentityToCsv(twidentity); } // Enumerate the drivers... for (sts = m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.GETFIRST, ref twidentity); sts != TWAIN.STS.ENDOFLIST; sts = m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.GETNEXT, ref twidentity)) { lszIdentity.Add(TWAIN.IdentityToCsv(twidentity)); } // Ruh-roh... if (lszIdentity.Count == 0) { MessageBox.Show("There are no TWAIN drivers installed on this system..."); return; } // Instantiate our form... formselect = new FormSelect(lszIdentity, szDefault); formselect.StartPosition = FormStartPosition.CenterParent; dialogresult = formselect.ShowDialog(this); if (dialogresult != System.Windows.Forms.DialogResult.OK) { m_blExit = true; return; } // Get all the identities... szIdentity = formselect.GetSelectedDriver(); if (szIdentity == null) { m_blExit = true; return; } // Get the selected identity... m_blExit = true; foreach (string sz in lszIdentity) { if (sz.Contains(szIdentity)) { m_blExit = false; szIdentity = sz; break; } } if (m_blExit) { return; } // Make it the default, we don't care if this succeeds... twidentity = default(TWAIN.TW_IDENTITY); TWAIN.CsvToIdentity(ref twidentity, szIdentity); m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.SET, ref twidentity); // Open it... sts = m_twain.DatIdentity(TWAIN.DG.CONTROL, TWAIN.MSG.OPENDS, ref twidentity); if (sts != TWAIN.STS.SUCCESS) { MessageBox.Show("Unable to open scanner (it is turned on and plugged in?)"); m_blExit = true; return; } // Update the main form title... this.Text = "TWAIN C# Scan (" + twidentity.ProductName.Get() + ")"; // Strip off unsafe chars. Sadly, mono let's us down here... m_szProductDirectory = CSV.Parse(szIdentity)[11]; foreach (char c in new char [41] { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0A', '\x0B', '\x0C', '\x0D', '\x0E', '\x0F', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1A', '\x1B', '\x1C', '\x1D', '\x1E', '\x1F', '\x22', '\x3C', '\x3E', '\x7C', ':', '*', '?', '\\', '/' } ) { m_szProductDirectory = m_szProductDirectory.Replace(c, '_'); } // We're doing memory transfers... szStatus = ""; twcapability = default(TWAIN.TW_CAPABILITY); m_twain.CsvToCapability(ref twcapability, ref szStatus, "ICAP_XFERMECH,TWON_ONEVALUE,TWTY_UINT16,TWSX_MEMORY"); sts = m_twain.DatCapability(TWAIN.DG.CONTROL, TWAIN.MSG.SET, ref twcapability); if (sts != TWAIN.STS.SUCCESS) { m_blExit = true; return; } // Decide whether or not to show the driver's window messages... szStatus = ""; twcapability = default(TWAIN.TW_CAPABILITY); m_twain.CsvToCapability(ref twcapability, ref szStatus, "CAP_INDICATORS,TWON_ONEVALUE,TWTY_BOOL," + (m_blIndicators ? "TRUE" : "FALSE")); sts = m_twain.DatCapability(TWAIN.DG.CONTROL, TWAIN.MSG.SET, ref twcapability); if (sts != TWAIN.STS.SUCCESS) { m_blExit = true; return; } // New state... SetButtons(EBUTTONSTATE.OPEN); // Create the setup form... m_formsetup = new FormSetup(this, ref m_twain, m_szProductDirectory); }
public FormSetup(FormScan a_formscan, ref TWAIN a_twain, string a_szProductDirectory) { TWAIN.STS sts; string szStatus; string szCapability; string szUsrUiSettings; // Init stuff... InitializeComponent(); // More init stuff... this.FormClosing += new FormClosingEventHandler(FormSetup_FormClosing); // Init more stuff (the order matters). ApplicationData means the following: // Windows: C:\Users\USERNAME\AppData\Roaming (or C:\Documents and Settings\USERNAME\Application Data on XP) // Linux: /home/USERNAME/.config (or /root/.config for superuser) // Mac OS X: /Users/USERNAME/.config (or /var/root/.config for superuser) m_formscan = a_formscan; m_twain = a_twain; m_szTwainscanFolder = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "twain"), "twaincsscan"); m_szSettingsFolder = Path.Combine(m_szTwainscanFolder, "settings"); m_szSettingsFolder = Path.Combine(m_szSettingsFolder, a_szProductDirectory); if (!Directory.Exists(m_szTwainscanFolder)) { try { Directory.CreateDirectory(m_szTwainscanFolder); } catch (Exception exception) { TWAINWorkingGroup.Log.Error("exception - " + exception.Message); m_szTwainscanFolder = Directory.GetCurrentDirectory(); } } // Restore values... m_textboxFolder.Text = RestoreFolder(); m_textboxUseUiSettings.Text = ""; // Check for support of Custom DS Data... szStatus = ""; TWAIN.TW_CAPABILITY twcapability = default(TWAIN.TW_CAPABILITY); m_twain.CsvToCapability(ref twcapability, ref szStatus, "CAP_CUSTOMDSDATA,0,0,0"); sts = m_twain.DatCapability(TWAIN.DG.CONTROL, TWAIN.MSG.GETCURRENT, ref twcapability); szCapability = m_twain.CapabilityToCsv(twcapability, true); if ((sts != TWAIN.STS.SUCCESS) || (!szCapability.EndsWith(",1") && !szCapability.EndsWith(",TRUE"))) { m_labelUseUiSettings.Enabled = false; m_textboxUseUiSettings.Enabled = false; m_buttonSaveUiSettings.Enabled = false; m_buttonUseUiSettings.Enabled = false; } // Restore the last saved snapshot... else { m_textboxUseUiSettings.Text = RestoreSetting(); if (m_textboxUseUiSettings.Text != "") { szUsrUiSettings = Path.Combine(m_szSettingsFolder, m_textboxUseUiSettings.Text); if (File.Exists(szUsrUiSettings)) { m_formscan.RestoreSnapshot(szUsrUiSettings); } else { m_textboxUseUiSettings.Text = ""; } } } }