From a779ee6b0e1425afa0d9b81347556e36a8fdced9 Mon Sep 17 00:00:00 2001 From: Eugene Wang <8755753+soukoku@users.noreply.github.com> Date: Sat, 1 Apr 2023 19:15:41 -0400 Subject: [PATCH] Added identity calls and other ds utilities. --- samples/Console32/Program.cs | 2 + samples/WinForm32/Form1.Designer.cs | 103 +++++++++++++++++- samples/WinForm32/Form1.cs | 27 ++++- samples/WinForm32/Form1.resx | 62 +---------- src/NTwain/TWAINWorkingGroup/TWAINH_EXTRAS.cs | 4 +- src/NTwain/Triplets/DATEntryPoint.cs | 4 +- src/NTwain/Triplets/DATIdentity.cs | 86 +++++++++++---- src/NTwain/Triplets/DATParent.cs | 16 ++- src/NTwain/TwainSession.PropEvents.cs | 72 ++++++++---- src/NTwain/TwainSession.Sources.cs | 25 +++++ src/NTwain/TwainSession.cs | 5 +- 11 files changed, 286 insertions(+), 120 deletions(-) create mode 100644 src/NTwain/TwainSession.Sources.cs diff --git a/samples/Console32/Program.cs b/samples/Console32/Program.cs index 05439c8..530bb93 100644 --- a/samples/Console32/Program.cs +++ b/samples/Console32/Program.cs @@ -8,6 +8,8 @@ namespace SampleConsole { internal class Program { + // CONSOLE won't work yet until I got a message loop going. + static void Main(string[] args) { TwainPlatform.PreferLegacyDSM = true; diff --git a/samples/WinForm32/Form1.Designer.cs b/samples/WinForm32/Form1.Designer.cs index 20ea62b..e2ee93a 100644 --- a/samples/WinForm32/Form1.Designer.cs +++ b/samples/WinForm32/Form1.Designer.cs @@ -28,12 +28,107 @@ /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 450); - this.Text = "Form1"; + btnSelect = new System.Windows.Forms.Button(); + label1 = new System.Windows.Forms.Label(); + lblDefault = new System.Windows.Forms.Label(); + label2 = new System.Windows.Forms.Label(); + lblCurrent = new System.Windows.Forms.Label(); + btnEnumSources = new System.Windows.Forms.Button(); + listSources = new System.Windows.Forms.ListBox(); + SuspendLayout(); + // + // btnSelect + // + btnSelect.Location = new System.Drawing.Point(12, 12); + btnSelect.Name = "btnSelect"; + btnSelect.Size = new System.Drawing.Size(151, 23); + btnSelect.TabIndex = 0; + btnSelect.Text = "Select default source"; + btnSelect.UseVisualStyleBackColor = true; + btnSelect.Click += btnSelect_Click; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(12, 51); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(98, 15); + label1.TabIndex = 1; + label1.Text = "Default Source = "; + // + // lblDefault + // + lblDefault.AutoSize = true; + lblDefault.Location = new System.Drawing.Point(115, 51); + lblDefault.Name = "lblDefault"; + lblDefault.Size = new System.Drawing.Size(24, 15); + lblDefault.TabIndex = 2; + lblDefault.Text = "NA"; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new System.Drawing.Point(12, 81); + label2.Name = "label2"; + label2.Size = new System.Drawing.Size(97, 15); + label2.TabIndex = 3; + label2.Text = "Current Source ="; + // + // lblCurrent + // + lblCurrent.AutoSize = true; + lblCurrent.Location = new System.Drawing.Point(115, 81); + lblCurrent.Name = "lblCurrent"; + lblCurrent.Size = new System.Drawing.Size(24, 15); + lblCurrent.TabIndex = 4; + lblCurrent.Text = "NA"; + // + // btnEnumSources + // + btnEnumSources.Location = new System.Drawing.Point(12, 114); + btnEnumSources.Name = "btnEnumSources"; + btnEnumSources.Size = new System.Drawing.Size(151, 23); + btnEnumSources.TabIndex = 5; + btnEnumSources.Text = "Enumerate sources"; + btnEnumSources.UseVisualStyleBackColor = true; + btnEnumSources.Click += btnEnumSources_Click; + // + // listSources + // + listSources.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left; + listSources.FormattingEnabled = true; + listSources.ItemHeight = 15; + listSources.Location = new System.Drawing.Point(12, 143); + listSources.Name = "listSources"; + listSources.Size = new System.Drawing.Size(279, 289); + listSources.TabIndex = 6; + // + // Form1 + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(800, 450); + Controls.Add(listSources); + Controls.Add(btnEnumSources); + Controls.Add(lblCurrent); + Controls.Add(label2); + Controls.Add(lblDefault); + Controls.Add(label1); + Controls.Add(btnSelect); + Name = "Form1"; + Text = "TWAIN Test"; + ResumeLayout(false); + PerformLayout(); } #endregion + + private System.Windows.Forms.Button btnSelect; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label lblDefault; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label lblCurrent; + private System.Windows.Forms.Button btnEnumSources; + private System.Windows.Forms.ListBox listSources; } } \ No newline at end of file diff --git a/samples/WinForm32/Form1.cs b/samples/WinForm32/Form1.cs index adf4713..4138104 100644 --- a/samples/WinForm32/Form1.cs +++ b/samples/WinForm32/Form1.cs @@ -20,6 +20,18 @@ namespace WinForm32 twain = new TwainSession(Assembly.GetExecutingAssembly().Location); twain.StateChanged += Twain_StateChanged; + twain.DefaultSourceChanged += Twain_DefaultSourceChanged; + twain.CurrentSourceChanged += Twain_CurrentSourceChanged; + } + + private void Twain_CurrentSourceChanged(TwainSession arg1, TW_IDENTITY_LEGACY ds) + { + lblCurrent.Text = ds.ProductName; + } + + private void Twain_DefaultSourceChanged(TwainSession arg1, TW_IDENTITY_LEGACY ds) + { + lblDefault.Text = ds.ProductName; } private static void Twain_StateChanged(TwainSession session, STATE state) @@ -35,7 +47,6 @@ namespace WinForm32 var hwnd = this.Handle; var rc = twain.DGControl.Parent.OpenDSM(ref hwnd); Debug.WriteLine($"OpenDSM={rc}"); - } protected override void OnClosing(CancelEventArgs e) @@ -45,5 +56,19 @@ namespace WinForm32 base.OnClosing(e); } + + private void btnSelect_Click(object sender, EventArgs e) + { + twain.DGControl.Identity.UserSelect(); + } + + private void btnEnumSources_Click(object sender, EventArgs e) + { + listSources.Items.Clear(); + foreach (var ds in twain.GetSources()) + { + listSources.Items.Add(ds); + } + } } } \ No newline at end of file diff --git a/samples/WinForm32/Form1.resx b/samples/WinForm32/Form1.resx index 1af7de1..f298a7b 100644 --- a/samples/WinForm32/Form1.resx +++ b/samples/WinForm32/Form1.resx @@ -1,64 +1,4 @@ - - - + diff --git a/src/NTwain/TWAINWorkingGroup/TWAINH_EXTRAS.cs b/src/NTwain/TWAINWorkingGroup/TWAINH_EXTRAS.cs index 52f7f86..9f1fca4 100644 --- a/src/NTwain/TWAINWorkingGroup/TWAINH_EXTRAS.cs +++ b/src/NTwain/TWAINWorkingGroup/TWAINH_EXTRAS.cs @@ -527,7 +527,7 @@ namespace TWAINWorkingGroup { public override string ToString() { - return $"{Manufacturer} - {ProductFamily} - {ProductName} {Version} (TWAIN {ProtocolMajor}.{ProtocolMinor})"; + return $"{Manufacturer} - {ProductName} v{Version.MajorNum}.{Version.MinorNum} (TWAIN {ProtocolMajor}.{ProtocolMinor})"; } public static implicit operator TW_IDENTITY_LEGACY(TW_IDENTITY_MACOSX value) => new() { @@ -552,7 +552,7 @@ namespace TWAINWorkingGroup { public override string ToString() { - return $"{Manufacturer} - {ProductFamily} - {ProductName} {Version} (TWAIN {ProtocolMajor}.{ProtocolMinor})"; + return $"{Manufacturer} - {ProductName} v{Version.MajorNum}.{Version.MinorNum} (TWAIN {ProtocolMajor}.{ProtocolMinor})"; } public static implicit operator TW_IDENTITY(TW_IDENTITY_LEGACY value) => new() { diff --git a/src/NTwain/Triplets/DATEntryPoint.cs b/src/NTwain/Triplets/DATEntryPoint.cs index 785076f..cee9687 100644 --- a/src/NTwain/Triplets/DATEntryPoint.cs +++ b/src/NTwain/Triplets/DATEntryPoint.cs @@ -51,7 +51,7 @@ namespace NTwain.Triplets var rc = STS.FAILURE; if (TwainPlatform.IsWindows) { - var app = Session._appIdentity; + var app = Session.AppIdentity; TW_IDENTITY_LEGACY dummy = default; if (TwainPlatform.Is32bit && TwainPlatform.PreferLegacyDSM) { @@ -68,7 +68,7 @@ namespace NTwain.Triplets //} else if (TwainPlatform.IsMacOSX) { - TW_IDENTITY_MACOSX app = Session._appIdentity; + TW_IDENTITY_MACOSX app = Session.AppIdentity; TW_IDENTITY_MACOSX dummy = default; if (TwainPlatform.PreferLegacyDSM) { diff --git a/src/NTwain/Triplets/DATIdentity.cs b/src/NTwain/Triplets/DATIdentity.cs index 1f4fde8..e3ff920 100644 --- a/src/NTwain/Triplets/DATIdentity.cs +++ b/src/NTwain/Triplets/DATIdentity.cs @@ -13,16 +13,16 @@ namespace NTwain.Triplets } /// - /// Loads and opens the specified DS. + /// Loads and opens the specified data source. /// /// /// public STS OpenDS(TW_IDENTITY_LEGACY ds) // not a ref on purpose { STS rc; - if ((rc = DoIt(MSG.OPENDS, ref ds, true)) == STS.SUCCESS) + if ((rc = DoIt(MSG.OPENDS, ref ds)) == STS.SUCCESS) { - Session._currentDS = ds; + Session.CurrentSource = ds; Session.State = STATE.S4; //// determine memory mgmt routines used //if ((((DG)Session._appIdentity.SupportedGroups) & DG.DSM2) == DG.DSM2) @@ -38,34 +38,82 @@ namespace NTwain.Triplets } /// - /// Closes the currently open DS. + /// Closes the currently open data source. /// /// public STS CloseDS() { - STS rc; - var ds = Session._currentDS; - if ((rc = DoIt(MSG.CLOSEDS, ref ds, true)) == STS.SUCCESS) - { - Session._currentDS = default; - Session.State = STATE.S3; - } - return rc; + STS rc; + var ds = Session.CurrentSource; + if ((rc = DoIt(MSG.CLOSEDS, ref ds)) == STS.SUCCESS) + { + Session.CurrentSource = default; + Session.State = STATE.S3; + } + return rc; } /// - /// Opens the TWAIN source selector dialog - /// to choose the default source. + /// Opens the TWAIN data source selector dialog + /// to choose the default data source. /// /// public STS UserSelect() { STS rc; - var ds = Session._defaultDS; - if ((rc = DoIt(MSG.USERSELECT, ref ds, true)) == STS.SUCCESS) + var ds = Session.DefaultSource; + if ((rc = DoIt(MSG.USERSELECT, ref ds)) == STS.SUCCESS) { - Session._defaultDS = ds; + Session.DefaultSource = ds; } + return rc; + } + + /// + /// Gets the default data source. + /// + /// + public STS GetDefault(out TW_IDENTITY_LEGACY ds) + { + ds = default; + return DoIt(MSG.GETDEFAULT, ref ds); + } + + /// + /// Sets the default data source. + /// + /// + /// + public STS Set(TW_IDENTITY_LEGACY ds) + { + STS rc; + if ((rc = DoIt(MSG.SET, ref ds)) == STS.SUCCESS) + { + Session.DefaultSource = ds; + } + return rc; + } + + /// + /// Gets the first available data source in an enumerating fashion + /// (use for subsequent ones). + /// + /// + public STS GetFirst(out TW_IDENTITY_LEGACY ds) + { + ds = default; + return DoIt(MSG.GETFIRST, ref ds); + } + + /// + /// Gets the next available data source in an enumerating fashion (after using ). + /// Ends when return values is . + /// + /// + public STS GetNext(out TW_IDENTITY_LEGACY ds) + { + ds = default; + return DoIt(MSG.GETNEXT, ref ds); } @@ -74,7 +122,7 @@ namespace NTwain.Triplets var rc = STS.FAILURE; if (TwainPlatform.IsWindows) { - var app = Session._appIdentity; + var app = Session.AppIdentity; if (TwainPlatform.Is32bit && TwainPlatform.PreferLegacyDSM) { rc = (STS)NativeMethods.WindowsTwain32DsmEntryIdentity(ref app, IntPtr.Zero, DG.CONTROL, DAT.IDENTITY, msg, ref ds); @@ -86,7 +134,7 @@ namespace NTwain.Triplets } else if (TwainPlatform.IsMacOSX) { - TW_IDENTITY_MACOSX app = Session._appIdentity; + TW_IDENTITY_MACOSX app = Session.AppIdentity; TW_IDENTITY_MACOSX osxds = ds; if (TwainPlatform.PreferLegacyDSM) { diff --git a/src/NTwain/Triplets/DATParent.cs b/src/NTwain/Triplets/DATParent.cs index d515e67..34bd540 100644 --- a/src/NTwain/Triplets/DATParent.cs +++ b/src/NTwain/Triplets/DATParent.cs @@ -25,10 +25,14 @@ namespace NTwain.Triplets Session._hwnd = hwnd; Session.State = STATE.S3; - // todo: get default source + // get default source + if (Session.DGControl.Identity.GetDefault(out TW_IDENTITY_LEGACY ds) == STS.SUCCESS) + { + Session.DefaultSource = ds; + } // determine memory mgmt routines used - if ((((DG)Session._appIdentity.SupportedGroups) & DG.DSM2) == DG.DSM2) + if ((((DG)Session.AppIdentity.SupportedGroups) & DG.DSM2) == DG.DSM2) { TW_ENTRYPOINT_DELEGATES entry = default; if (Session.DGControl.EntryPoint.Get(ref entry) == STS.SUCCESS) @@ -63,7 +67,7 @@ namespace NTwain.Triplets var rc = STS.FAILURE; if (TwainPlatform.IsWindows) { - var app = Session._appIdentity; + var app = Session.AppIdentity; if (TwainPlatform.Is32bit && TwainPlatform.PreferLegacyDSM) { rc = (STS)NativeMethods.WindowsTwain32DsmEntryParent(ref app, IntPtr.Zero, DG.CONTROL, DAT.PARENT, msg, ref hwnd); @@ -72,7 +76,7 @@ namespace NTwain.Triplets { rc = (STS)NativeMethods.WindowsTwaindsmDsmEntryParent(ref app, IntPtr.Zero, DG.CONTROL, DAT.PARENT, msg, ref hwnd); } - if (rc == STS.SUCCESS) Session._appIdentity = app; + if (rc == STS.SUCCESS) Session.AppIdentity = app; } //else if (TwainPlatform.IsLinux) //{ @@ -82,7 +86,7 @@ namespace NTwain.Triplets //} else if (TwainPlatform.IsMacOSX) { - TW_IDENTITY_MACOSX app = Session._appIdentity; + TW_IDENTITY_MACOSX app = Session.AppIdentity; if (TwainPlatform.PreferLegacyDSM) { rc = (STS)NativeMethods.MacosxTwainDsmEntryParent(ref app, IntPtr.Zero, DG.CONTROL, DAT.PARENT, msg, ref hwnd); @@ -93,7 +97,7 @@ namespace NTwain.Triplets } if (rc == STS.SUCCESS) { - Session._appIdentity = app; + Session.AppIdentity = app; } } return rc; diff --git a/src/NTwain/TwainSession.PropEvents.cs b/src/NTwain/TwainSession.PropEvents.cs index c4937d4..64c53da 100644 --- a/src/NTwain/TwainSession.PropEvents.cs +++ b/src/NTwain/TwainSession.PropEvents.cs @@ -1,11 +1,5 @@ using NTwain.Triplets; using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; using TWAINWorkingGroup; namespace NTwain @@ -14,29 +8,47 @@ namespace NTwain partial class TwainSession { - - // really legacy version is the one to be used (except on mac) or - // until it doesn't work (special linux) - /// /// Gets the app identity. /// - public TW_IDENTITY_LEGACY AppIdentity => _appIdentity; - internal TW_IDENTITY_LEGACY _appIdentity; + public TW_IDENTITY_LEGACY AppIdentity + { + get => _appIdentity; + internal set + { + _appIdentity = value; + } + } + TW_IDENTITY_LEGACY _appIdentity; /// - /// Gets the current data source. + /// Gets the current (opened) data source. /// - public TW_IDENTITY_LEGACY CurrentDS => _currentDS; - internal TW_IDENTITY_LEGACY _currentDS; + public TW_IDENTITY_LEGACY CurrentSource + { + get => _currentDS; + internal set + { + _currentDS = value; + CurrentSourceChanged?.Invoke(this, value); + } + } + TW_IDENTITY_LEGACY _currentDS; /// /// Gets the default data source. /// - public TW_IDENTITY_LEGACY DefaultDS => _defaultDS; - internal TW_IDENTITY_LEGACY _defaultDS; + public TW_IDENTITY_LEGACY DefaultSource + { + get => _defaultDS; + internal set + { + _defaultDS = value; + DefaultSourceChanged?.Invoke(this, value); + } + } + TW_IDENTITY_LEGACY _defaultDS; - private STATE _state = STATE.S1; /// /// Current TWAIN session state. @@ -53,11 +65,8 @@ namespace NTwain } } } + STATE _state = STATE.S1; - /// - /// Fired when changes. - /// - public event Action? StateChanged; /// /// TWAIN triplet API calls with . @@ -71,5 +80,24 @@ namespace NTwain /// TWAIN triplet API calls with . /// public DGAudio DGAudio { get; } + + + + + /// + /// Fires when changes. + /// + public event Action? StateChanged; + + /// + /// Fires when changes. + /// + public event Action? DefaultSourceChanged; + + /// + /// Fires when changes. + /// + public event Action? CurrentSourceChanged; + } } diff --git a/src/NTwain/TwainSession.Sources.cs b/src/NTwain/TwainSession.Sources.cs new file mode 100644 index 0000000..c54fbcb --- /dev/null +++ b/src/NTwain/TwainSession.Sources.cs @@ -0,0 +1,25 @@ +using NTwain.Triplets; +using System.Collections.Generic; +using TWAINWorkingGroup; + +namespace NTwain +{ + // this file contains data source utilities + + partial class TwainSession + { + /// + /// Gets all available sources. + /// + /// + public IEnumerable GetSources() + { + var rc = DGControl.Identity.GetFirst(out TW_IDENTITY_LEGACY ds); + while (rc == STS.SUCCESS) + { + yield return ds; + rc = DGControl.Identity.GetNext(out ds); + } + } + } +} diff --git a/src/NTwain/TwainSession.cs b/src/NTwain/TwainSession.cs index 73f2f5a..4eb3b1c 100644 --- a/src/NTwain/TwainSession.cs +++ b/src/NTwain/TwainSession.cs @@ -1,5 +1,6 @@ using NTwain.Triplets; using System; +using System.Collections; using System.Diagnostics; using System.Text; using TWAINWorkingGroup; @@ -59,7 +60,7 @@ namespace NTwain __encodingRegistered = true; } - _appIdentity; = new() + _appIdentity = new() { Manufacturer = companyName, ProductFamily = productFamily, @@ -76,8 +77,6 @@ namespace NTwain MinorNum = (ushort)productVersion.Minor, } }; - //if (TwainPlatform.IsLinux) _appIdentity = _appIdentity; - if (TwainPlatform.IsMacOSX) _appIdentityOSX = _appIdentity;; DGControl = new DGControl(this); DGImage = new DGImage(this);