diff --git a/Tests/Tester.WPF/MainWindow.xaml b/Tests/Tester.WPF/MainWindow.xaml
index 943e98d..08677b6 100644
--- a/Tests/Tester.WPF/MainWindow.xaml
+++ b/Tests/Tester.WPF/MainWindow.xaml
@@ -2,8 +2,17 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:modern="http://modernwpf"
- Title="TWAIN Data Source Tester" Height="600" Width="900" ResizeMode="CanResizeWithGrip"
+ xmlns:proj="clr-namespace:Tester.WPF"
+ Title="{Binding AppTitle}"
+ Height="600" Width="900" ResizeMode="CanResizeWithGrip"
+ x:Name="theWindow"
Style="{StaticResource AppWindow}">
+
+
+
+
+
+
@@ -19,7 +28,8 @@
@@ -35,11 +45,11 @@
-
@@ -51,7 +61,8 @@
FontStyle="Italic"/>
-
+
+
-
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/Tester.WPF/MainWindow.xaml.cs b/Tests/Tester.WPF/MainWindow.xaml.cs
index a9a9c04..96eb449 100644
--- a/Tests/Tester.WPF/MainWindow.xaml.cs
+++ b/Tests/Tester.WPF/MainWindow.xaml.cs
@@ -1,5 +1,6 @@
using GalaSoft.MvvmLight.Messaging;
using ModernWPF.Controls;
+using ModernWPF.Messages;
using NTwain;
using NTwain.Data;
using System;
@@ -26,29 +27,20 @@ namespace Tester.WPF
InitializeComponent();
if (!DesignerProperties.GetIsInDesignMode(this))
{
- if (PlatformInfo.Current.IsApp64Bit)
- {
- Title = Title + " (64bit)";
- }
- else
- {
- Title = Title + " (32bit)";
- }
-
- _twainVM = new TwainVM();
- this.DataContext = _twainVM;
+ _twainVM = this.DataContext as TwainVM;
+ Messenger.Default.Register(this, m => m.HandleRefreshCommands());
Messenger.Default.Register(this, msg =>
{
if (Dispatcher.CheckAccess())
{
- ModernMessageBox.Show(this, msg.Content, msg.Caption, msg.Button, msg.Icon, msg.DefaultResult);
+ this.HandleDialogMessageModern(msg);
}
else
{
Dispatcher.BeginInvoke(new Action(() =>
{
- ModernMessageBox.Show(this, msg.Content, msg.Caption, msg.Button, msg.Icon, msg.DefaultResult);
+ this.HandleDialogMessageModern(msg);
}));
}
});
@@ -61,48 +53,16 @@ namespace Tester.WPF
}
protected override void OnClosed(EventArgs e)
{
- if (_twainVM.State == 4)
- {
- _twainVM.CurrentSource.Close();
- }
- _twainVM.Close();
+ _twainVM.CloseDown();
base.OnClosed(e);
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
+ _twainVM.WindowHandle = new WindowInteropHelper(this).Handle;
- // use this for internal msg loop
- //var rc = _twainVM.Open();
-
- // use this to hook into current app loop
- var rc = _twainVM.Open(new WpfMessageLoopHook(new WindowInteropHelper(this).Handle));
-
- if (rc == ReturnCode.Success)
- {
- SrcList.ItemsSource = _twainVM.Select(s => new DSVM { DS = s });
- }
}
- private void Button_Click_1(object sender, RoutedEventArgs e)
- {
- _twainVM.TestCapture(new WindowInteropHelper(this).Handle);
- }
-
- private void SrcList_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (_twainVM.State == 4)
- {
- _twainVM.CurrentSource.Close();
- }
-
- var dsId = SrcList.SelectedItem as DSVM;
- if (dsId != null)
- {
- dsId.Open();
- }
- }
-
private void CapList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
diff --git a/Tests/Tester.WPF/Tester.WPF.csproj b/Tests/Tester.WPF/Tester.WPF.csproj
index a45d667..f745f83 100644
--- a/Tests/Tester.WPF/Tester.WPF.csproj
+++ b/Tests/Tester.WPF/Tester.WPF.csproj
@@ -59,10 +59,22 @@
False
..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll
+
+ ..\..\packages\Microsoft.WindowsAPICodePack-Core.1.1.0.0\lib\Microsoft.WindowsAPICodePack.dll
+
+
+ ..\..\packages\Microsoft.WindowsAPICodePack-Shell.1.1.0.0\lib\Microsoft.WindowsAPICodePack.Shell.dll
+
+
+ ..\..\packages\Microsoft.WindowsAPICodePack-Shell.1.1.0.0\lib\Microsoft.WindowsAPICodePack.ShellExtensions.dll
+
False
..\..\packages\ModernWPF.1.2.9.1\lib\net40-Client\ModernWPF.dll
+
+ ..\..\packages\ModernWPF.Mvvm.0.7.0\lib\net40-Client\ModernWPF.Mvvm.dll
+
@@ -103,7 +115,7 @@
Code
-
+
MainWindow.xaml
Code
diff --git a/Tests/Tester.WPF/ViewModels/DSVM.cs b/Tests/Tester.WPF/ViewModels/DataSourceVM.cs
similarity index 96%
rename from Tests/Tester.WPF/ViewModels/DSVM.cs
rename to Tests/Tester.WPF/ViewModels/DataSourceVM.cs
index 3ad0b26..0f75562 100644
--- a/Tests/Tester.WPF/ViewModels/DSVM.cs
+++ b/Tests/Tester.WPF/ViewModels/DataSourceVM.cs
@@ -12,7 +12,7 @@ namespace Tester.WPF
///
/// Wraps a data source as view model.
///
- class DSVM : ViewModelBase
+ class DataSourceVM : ViewModelBase
{
public DataSource DS { get; set; }
@@ -21,7 +21,7 @@ namespace Tester.WPF
public string Protocol { get { return DS.ProtocolVersion.ToString(); } }
ICollectionView _capView;
- public DSVM()
+ public DataSourceVM()
{
Caps = new ObservableCollection();
_capView = CollectionViewSource.GetDefaultView(Caps);
diff --git a/Tests/Tester.WPF/ViewModels/TwainVM.cs b/Tests/Tester.WPF/ViewModels/TwainVM.cs
index 6148965..ee90526 100644
--- a/Tests/Tester.WPF/ViewModels/TwainVM.cs
+++ b/Tests/Tester.WPF/ViewModels/TwainVM.cs
@@ -9,39 +9,216 @@ using System.Reflection;
using System.Threading;
using System.Windows.Media;
using System.Windows.Media.Imaging;
+using System.Collections.ObjectModel;
+using GalaSoft.MvvmLight;
+using System.Windows.Input;
+using GalaSoft.MvvmLight.Command;
+using ModernWPF;
+using ModernWPF.Messages;
namespace Tester.WPF
{
///
/// Wraps the twain session as a view model for databinding.
///
- class TwainVM : TwainSession
+ class TwainVM : ViewModelBase
{
public TwainVM()
- : base(TWIdentity.CreateFromAssembly(DataGroups.Image | DataGroups.Audio, Assembly.GetEntryAssembly()))
{
+ DataSources = new ObservableCollection();
+ CapturedImages = new ObservableCollection();
+
//this.SynchronizationContext = SynchronizationContext.Current;
+ var appId = TWIdentity.CreateFromAssembly(DataGroups.Image | DataGroups.Audio, Assembly.GetEntryAssembly());
+ _session = new TwainSession(appId);
+ _session.TransferError += _session_TransferError;
+ _session.TransferReady += _session_TransferReady;
+ _session.DataTransferred += _session_DataTransferred;
+ _session.SourceDisabled += _session_SourceDisabled;
}
- private ImageSource _image;
+ TwainSession _session;
- ///
- /// Gets or sets the captured image.
- ///
- ///
- /// The image.
- ///
- public ImageSource Image
+ #region properties
+
+ public string AppTitle
{
- get { return _image; }
+ get
+ {
+ if (NTwain.PlatformInfo.Current.IsApp64Bit)
+ {
+ return "TWAIN Data Source Tester (64bit)";
+ }
+ else
+ {
+ return "TWAIN Data Source Tester (32bit)";
+ }
+ }
+ }
+ public ObservableCollection DataSources { get; private set; }
+ private DataSourceVM _selectedSource;
+
+ public DataSourceVM SelectedSource
+ {
+ get { return _selectedSource; }
set
{
- _image = value;
- OnPropertyChanged("Image");
+ if (_session.State == 4)
+ {
+ _session.CurrentSource.Close();
+ }
+ _selectedSource = value;
+ RaisePropertyChanged(() => SelectedSource);
+ if (_selectedSource != null)
+ {
+ _selectedSource.Open();
+ }
}
}
- protected override void OnTransferError(TransferErrorEventArgs e)
+ public int State { get { return _session.State; } }
+
+ private IntPtr _winHandle;
+ public IntPtr WindowHandle
+ {
+ get { return _winHandle; }
+ set
+ {
+ _winHandle = value;
+ if (value == IntPtr.Zero)
+ {
+
+ }
+ else
+ {
+ // use this for internal msg loop
+ var rc = _session.Open();
+
+ // use this to hook into current app loop
+ //var rc = _session.Open(new WpfMessageLoopHook(value));
+
+ if (rc == ReturnCode.Success)
+ {
+ ReloadSourcesCommand.Execute(null);
+ }
+ }
+ }
+ }
+
+
+ private ICommand _showDriverCommand;
+ public ICommand ShowDriverCommand
+ {
+ get
+ {
+ return _showDriverCommand ?? (_showDriverCommand = new RelayCommand(() =>
+ {
+ if (_session.State == 4)
+ {
+ var rc = _session.CurrentSource.Enable(SourceEnableMode.ShowUIOnly, false, WindowHandle);
+ }
+ }, () =>
+ {
+ return _session.State == 4 && _session.CurrentSource.CapEnableDSUIOnly.GetCurrent() == BoolType.True;
+ }));
+ }
+ }
+
+ private ICommand _captureCommand;
+ public ICommand CaptureCommand
+ {
+ get
+ {
+ return _captureCommand ?? (_captureCommand = new RelayCommand(() =>
+ {
+ if (_session.State == 4)
+ {
+ //if (this.CurrentSource.ICapPixelType.Get().Contains(PixelType.BlackWhite))
+ //{
+ // this.CurrentSource.ICapPixelType.Set(PixelType.BlackWhite);
+ //}
+
+ //if (this.CurrentSource.ICapXferMech.Get().Contains(XferMech.File))
+ //{
+ // this.CurrentSource.ICapXferMech.Set(XferMech.File);
+ //}
+
+ var rc = _session.CurrentSource.Enable(SourceEnableMode.NoUI, false, WindowHandle);
+ }
+ }, () =>
+ {
+ return _session.State == 4;
+ }));
+ }
+ }
+
+
+ private ICommand _clearCommand;
+ public ICommand ClearCommand
+ {
+ get
+ {
+ return _clearCommand ?? (_clearCommand = new RelayCommand(() =>
+ {
+ CapturedImages.Clear();
+ }, () =>
+ {
+ return CapturedImages.Count > 0;
+ }));
+ }
+ }
+ private ICommand _reloadSrc;
+ public ICommand ReloadSourcesCommand
+ {
+ get
+ {
+ return _reloadSrc ?? (_reloadSrc = new RelayCommand(() =>
+ {
+ DataSources.Clear();
+ foreach (var s in _session.Select(s => new DataSourceVM { DS = s }))
+ {
+ DataSources.Add(s);
+ }
+ }, () =>
+ {
+ return _session.State > 2;
+ }));
+ }
+ }
+
+ ///
+ /// Gets the captured images.
+ ///
+ ///
+ /// The captured images.
+ ///
+ public ObservableCollection CapturedImages { get; private set; }
+
+ public double MinThumbnailSize { get { return 50; } }
+ public double MaxThumbnailSize { get { return 300; } }
+
+ private double _thumbSize = 150;
+ public double ThumbnailSize
+ {
+ get { return _thumbSize; }
+ set
+ {
+ if (value > MaxThumbnailSize) { value = MaxThumbnailSize; }
+ else if (value < MinThumbnailSize) { value = MinThumbnailSize; }
+ _thumbSize = value;
+ RaisePropertyChanged(() => ThumbnailSize);
+ }
+ }
+
+
+ #endregion
+
+ void _session_SourceDisabled(object sender, EventArgs e)
+ {
+ Messenger.Default.Send(new RefreshCommandsMessage());
+ }
+
+ void _session_TransferError(object sender, TransferErrorEventArgs e)
{
App.Current.Dispatcher.BeginInvoke(new Action(() =>
{
@@ -66,25 +243,23 @@ namespace Tester.WPF
}));
}
- protected override void OnTransferReady(TransferReadyEventArgs e)
+ void _session_TransferReady(object sender, TransferReadyEventArgs e)
{
- // set it up to use file xfer
-
- if (this.CurrentSource.CapGetCurrent(CapabilityId.ICapXferMech).ConvertToEnum() == XferMech.File)
+ if (_session.CurrentSource.ICapXferMech.GetCurrent() == XferMech.File)
{
- var formats = this.CurrentSource.ICapImageFileFormat.Get();
+ var formats = _session.CurrentSource.ICapImageFileFormat.Get();
var wantFormat = formats.Contains(FileFormat.Tiff) ? FileFormat.Tiff : FileFormat.Bmp;
var fileSetup = new TWSetupFileXfer
{
Format = wantFormat,
- FileName = GetUniqueName(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test", ".tif")
+ FileName = GetUniqueName(Path.GetTempPath(), "twain-test", "." + wantFormat)
};
- var rc = this.CurrentSource.DGControl.SetupFileXfer.Set(fileSetup);
+ var rc = _session.CurrentSource.DGControl.SetupFileXfer.Set(fileSetup);
}
}
- private string GetUniqueName(string dir, string name, string ext)
+ string GetUniqueName(string dir, string name, string ext)
{
var filePath = Path.Combine(dir, name + ext);
int next = 1;
@@ -95,9 +270,22 @@ namespace Tester.WPF
return filePath;
}
- protected override void OnDataTransferred(DataTransferredEventArgs e)
+ void _session_DataTransferred(object sender, DataTransferredEventArgs e)
{
- ImageSource img = null;
+ ImageSource img = GenerateThumbnail(e);
+ if (img != null)
+ {
+ App.Current.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ CapturedImages.Add(img);
+ }));
+ }
+ }
+
+
+ ImageSource GenerateThumbnail(DataTransferredEventArgs e)
+ {
+ BitmapSource img = null;
if (e.NativeData != IntPtr.Zero)
{
img = e.NativeData.GetWPFBitmap();
@@ -106,35 +294,26 @@ namespace Tester.WPF
{
img = new BitmapImage(new Uri(e.FileDataPath));
}
+
if (img != null)
{
- if (img.CanFreeze)
- {
- img.Freeze();
- }
- App.Current.Dispatcher.BeginInvoke(new Action(() =>
- {
- Image = img;
- }));
+ // from http://stackoverflow.com/questions/18189501/create-thumbnail-image-directly-from-header-less-image-byte-array
+ var scale = MaxThumbnailSize / img.PixelWidth;
+ var transform = new ScaleTransform(scale, scale);
+ var thumbnail = new TransformedBitmap(img, transform);
+ img = new WriteableBitmap(new TransformedBitmap(img, transform));
+ img.Freeze();
}
+ return img;
}
- public void TestCapture(IntPtr hwnd)
+ internal void CloseDown()
{
- if (State == 4)
+ if (_session.State == 4)
{
- //if (this.CurrentSource.ICapPixelType.Get().Contains(PixelType.BlackWhite))
- //{
- // this.CurrentSource.ICapPixelType.Set(PixelType.BlackWhite);
- //}
-
- //if (this.CurrentSource.ICapXferMech.Get().Contains(XferMech.File))
- //{
- // this.CurrentSource.ICapXferMech.Set(XferMech.File);
- //}
-
- var rc = this.CurrentSource.Enable(SourceEnableMode.NoUI, false, hwnd);
+ _session.CurrentSource.Close();
}
+ _session.Close();
}
}
}
diff --git a/Tests/Tester.WPF/packages.config b/Tests/Tester.WPF/packages.config
index f9a86fc..b52fe3a 100644
--- a/Tests/Tester.WPF/packages.config
+++ b/Tests/Tester.WPF/packages.config
@@ -2,6 +2,9 @@
+
+
+
\ No newline at end of file