Working wia device selection and property setting (minus subtypes)

This commit is contained in:
Ben Olden-Cooligan 2018-11-08 15:20:34 -05:00
parent 48943e3868
commit 5b950ba056
11 changed files with 91 additions and 40 deletions

View File

@ -213,6 +213,7 @@
<Compile Include="Scan\Wia\Native\WiaPropertyCollection.cs" />
<Compile Include="Scan\Wia\Native\WiaProperty.cs" />
<Compile Include="Scan\Wia\Native\WiaPropertyId.cs" />
<Compile Include="Scan\Wia\Native\WiaPropertyType.cs" />
<Compile Include="Scan\Wia\Native\WiaPropertyValue.cs" />
<Compile Include="Scan\Wia\Native\WiaTransfer.cs" />
<Compile Include="Scan\Wia\Native\WiaItem.cs" />

View File

@ -25,8 +25,19 @@ namespace NAPS2.Scan.Wia.Native
[DllImport("NAPS2.WIA.dll")]
public static extern uint GetItemPropertyStorage(IntPtr item, out IntPtr propStorage);
public delegate void EnumPropertyCallback(int propId, [MarshalAs(UnmanagedType.LPWStr)] string propName, ushort propType);
[DllImport("NAPS2.WIA.dll")]
public static extern uint SetItemProperty(IntPtr item, int propId, int value);
public static extern uint EnumerateProperties(IntPtr propStorage, [MarshalAs(UnmanagedType.FunctionPtr)] EnumPropertyCallback func);
[DllImport("NAPS2.WIA.dll")]
public static extern uint GetPropertyBstr(IntPtr propStorage, int propId, [MarshalAs(UnmanagedType.BStr), Out] out string value);
[DllImport("NAPS2.WIA.dll")]
public static extern uint GetPropertyInt(IntPtr propStorage, int propId, [Out] out int value);
[DllImport("NAPS2.WIA.dll")]
public static extern uint SetPropertyInt(IntPtr propStorage, int propId, int value);
[DllImport("NAPS2.WIA.dll")]
public static extern uint StartTransfer(IntPtr item, [Out] out IntPtr transfer);

View File

@ -41,7 +41,10 @@ namespace NAPS2.Scan.Wia.Native
{
if (!disposed)
{
Marshal.Release(Handle);
if (Handle != IntPtr.Zero)
{
Marshal.Release(Handle);
}
disposed = true;
}
}

View File

@ -35,5 +35,14 @@ namespace NAPS2.Scan.Wia.Native
WiaException.Check(NativeWiaMethods.GetItem(Handle, name, out var itemHandle));
return new WiaItem(itemHandle);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
properties?.Dispose();
}
}
}
}

View File

@ -16,25 +16,25 @@ namespace NAPS2.Scan.Wia.Native
return device.Properties[WiaPropertyId.DIP_DEV_NAME].Value.ToString();
}
public static bool SupportsFeeder(this IWiaDeviceProps device)
public static bool SupportsFeeder(this WiaDevice device)
{
int capabilities = (int)device.Properties[WiaPropertyId.DPS_DOCUMENT_HANDLING_CAPABILITIES].Value;
return (capabilities & WiaPropertyValue.FEEDER) != 0;
}
public static bool SupportsDuplex(this IWiaDeviceProps device)
public static bool SupportsDuplex(this WiaDevice device)
{
int capabilities = (int)device.Properties[WiaPropertyId.DPS_DOCUMENT_HANDLING_CAPABILITIES].Value;
return (capabilities & WiaPropertyValue.DUPLEX) != 0;
}
public static bool FeederReady(this IWiaDeviceProps device)
public static bool FeederReady(this WiaDevice device)
{
int status = (int)device.Properties[WiaPropertyId.DPS_DOCUMENT_HANDLING_STATUS].Value;
return (status & WiaPropertyValue.FEED_READY) != 0;
}
public static void SetProperty(this WiaItem item, int propId, int value)
public static void SetProperty(this WiaItemBase item, int propId, int value)
{
var prop = item.Properties[propId];
if (prop != null)
@ -43,7 +43,7 @@ namespace NAPS2.Scan.Wia.Native
}
}
public static void SetPropertyRange(this WiaItem item, int propId, int value, int expectedMin, int expectedMax)
public static void SetPropertyRange(this WiaItemBase item, int propId, int value, int expectedMin, int expectedMax)
{
var prop = item.Properties[propId];
if (prop != null)

View File

@ -6,29 +6,44 @@ namespace NAPS2.Scan.Wia.Native
{
public class WiaProperty
{
private object value;
protected internal WiaProperty(WiaItem owner, int id)
protected internal WiaProperty(IntPtr storage, int id, string name, ushort type)
{
Owner = owner;
Storage = storage;
Id = id;
Name = name;
Type = type;
}
private WiaItem Owner { get; }
private IntPtr Storage { get; }
public int Id { get; set; }
public string Name { get; }
public ushort Type { get; }
// TODO: Full R/W impl
public object Value
{
get => value;
get
{
if (Type == WiaPropertyType.I4)
{
WiaException.Check(NativeWiaMethods.GetPropertyInt(Storage, Id, out int value));
return value;
}
if (Type == WiaPropertyType.BSTR)
{
WiaException.Check(NativeWiaMethods.GetPropertyBstr(Storage, Id, out string value));
return value;
}
throw new NotImplementedException("Not implemented property type");
}
set
{
if (value is int valueInt)
if (Type == WiaPropertyType.I4)
{
WiaException.Check(NativeWiaMethods.SetItemProperty(Owner.Handle, Id, valueInt));
// TODO: Get the value from the backing in case it changes
this.value = value;
WiaException.Check(NativeWiaMethods.SetPropertyInt(Storage, Id, (int)value));
}
else
{
@ -47,6 +62,8 @@ namespace NAPS2.Scan.Wia.Native
public object[] SubTypeValues { get; set; }
public override string ToString() => Name;
public enum SubTypes
{
None,

View File

@ -1,28 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using NAPS2.Util;
namespace NAPS2.Scan.Wia.Native
{
public class WiaPropertyCollection
public class WiaPropertyCollection : NativeWiaObject
{
private readonly Dictionary<int, WiaProperty> propertyDict;
public WiaPropertyCollection(IntPtr propertyStorageHandle)
public WiaPropertyCollection(IntPtr propertyStorageHandle) : base(propertyStorageHandle)
{
propertyDict = new Dictionary<int, WiaProperty>();
// TODO
try
{
}
finally
{
Marshal.Release(propertyStorageHandle);
}
WiaException.Check(NativeWiaMethods.EnumerateProperties(Handle,
(id, name, type) => propertyDict.Add(id, new WiaProperty(Handle, id, name, type))));
}
public WiaProperty this[int propId] => propertyDict.Get(propId);
}
}

View File

@ -43,6 +43,8 @@ namespace NAPS2.Scan.Wia.Native
public const int IPS_BRIGHTNESS = 6154;
public const int IPS_CONTRAST = 6155;
public const int IPS_ORIENTATION = 6156;
public const int IPS_MAX_HORIZONTAL_SIZE = 6165;
public const int IPS_MAX_VERTICAL_SIZE = 6166;
public const int IPS_PAGES = 3096;
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NAPS2.Scan.Wia.Native
{
/// <summary>
/// Property type constants.
/// </summary>
public static class WiaPropertyType
{
public const int I4 = 3;
public const int BSTR = 8;
}
}

View File

@ -44,7 +44,13 @@ namespace NAPS2.Scan.Wia
{
using (var deviceManager = new WiaDeviceManager())
{
return deviceManager.GetDeviceInfos().Select(x => new ScanDevice(x.Id(), x.Name())).ToList();
return deviceManager.GetDeviceInfos().Select(x =>
{
using (x)
{
return new ScanDevice(x.Id(), x.Name());
}
}).ToList();
}
}
@ -73,7 +79,7 @@ namespace NAPS2.Scan.Wia
// TODO: Props
ConfigureDeviceProps(device);
ConfigureItemProps(device, item);
ConfigureItemProps(item);
// TODO: Format BMP "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}"
// TODO: Arrrggg... WIA native UI is an option I'm supposed to support.
@ -115,7 +121,7 @@ namespace NAPS2.Scan.Wia
}
}
private void ConfigureItemProps(WiaDevice device, WiaItem item)
private void ConfigureItemProps(WiaItem item)
{
switch (ScanProfile.BitDepth)
{
@ -143,14 +149,8 @@ namespace NAPS2.Scan.Wia
int pageWidth = pageDimensions.WidthInThousandthsOfAnInch() * resolution / 1000;
int pageHeight = pageDimensions.HeightInThousandthsOfAnInch() * resolution / 1000;
int horizontalSize =
(int)device.Properties[ScanProfile.PaperSource == ScanSource.Glass
? WiaPropertyId.DPS_HORIZONTAL_BED_SIZE
: WiaPropertyId.DPS_HORIZONTAL_SHEET_FEED_SIZE].Value;
int verticalSize =
(int)device.Properties[ScanProfile.PaperSource == ScanSource.Glass
? WiaPropertyId.DPS_VERTICAL_BED_SIZE
: WiaPropertyId.DPS_VERTICAL_SHEET_FEED_SIZE].Value;
int horizontalSize = (int)item.Properties[WiaPropertyId.IPS_MAX_HORIZONTAL_SIZE].Value;
int verticalSize = (int)item.Properties[WiaPropertyId.IPS_MAX_VERTICAL_SIZE].Value;
int pagemaxwidth = horizontalSize * resolution / 1000;
int pagemaxheight = verticalSize * resolution / 1000;

Binary file not shown.