More cap conversions.

This commit is contained in:
soukoku
2014-09-17 08:07:00 -04:00
parent 782f96827e
commit 8508bbb764
6 changed files with 255 additions and 296 deletions

View File

@@ -51,9 +51,6 @@
<Compile Include="..\NTwain\CapabilityReader.cs"> <Compile Include="..\NTwain\CapabilityReader.cs">
<Link>CapabilityReader.cs</Link> <Link>CapabilityReader.cs</Link>
</Compile> </Compile>
<Compile Include="..\NTwain\CapRoutines.cs">
<Link>CapRoutines.cs</Link>
</Compile>
<Compile Include="..\NTwain\DataSource.Caps.cs"> <Compile Include="..\NTwain\DataSource.Caps.cs">
<Link>DataSource.Caps.cs</Link> <Link>DataSource.Caps.cs</Link>
</Compile> </Compile>

View File

@@ -1,74 +0,0 @@
using NTwain.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NTwain
{
/// <summary>
/// Contains re-usable routines for cap use.
/// </summary>
public static class CapRoutines
{
#region handy conversions
/// <summary>
/// Routine that does nothing.
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static object NoConvertRoutine(object value)
{
return value;
}
/// <summary>
/// Predefined routine for <see cref="BoolType"/>
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static TEnum EnumRoutine<TEnum>(object value) where TEnum : struct, IConvertible
{
if (value != null)
{
return value.ConvertToEnum<TEnum>();
}
return default(TEnum);
}
/// <summary>
/// Predefined routine for <see cref="TWFix32"/>
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static TWFix32 TWFix32Routine(object value)
{
if (value != null)
{
if (value is TWFix32)
{
return (TWFix32)value;
}
return Convert.ToSingle(value);
}
return default(TWFix32);
}
/// <summary>
/// Predefined routine for <see cref="string"/>
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static string StringRoutine(object value)
{
if (value != null)
{
return value.ToString();
}
return default(string);
}
#endregion
}
}

View File

@@ -51,38 +51,42 @@ namespace NTwain.Data
/// <returns></returns> /// <returns></returns>
public static TEnum ConvertToEnum<TEnum>(this object value, bool tryUpperWord) where TEnum : struct,IConvertible public static TEnum ConvertToEnum<TEnum>(this object value, bool tryUpperWord) where TEnum : struct,IConvertible
{ {
var returnType = typeof(TEnum); if (value != null)
// standard int values
if (returnType.IsEnum)
{ {
if (tryUpperWord) var returnType = typeof(TEnum);
// standard int values
if (returnType.IsEnum)
{ {
// small routine to work with bad sources that may put if (tryUpperWord)
// 16bit value in the upper word instead of lower word (as per the twain spec).
var rawType = Enum.GetUnderlyingType(returnType);
if (typeof(ushort).IsAssignableFrom(rawType))
{ {
var intVal = Convert.ToUInt32(value, CultureInfo.InvariantCulture); // small routine to work with bad sources that may put
var enumVal = GetLowerWord(intVal); // 16bit value in the upper word instead of lower word (as per the twain spec).
if (!Enum.IsDefined(returnType, enumVal)) var rawType = Enum.GetUnderlyingType(returnType);
if (typeof(ushort).IsAssignableFrom(rawType))
{ {
return (TEnum)Enum.ToObject(returnType, GetUpperWord(intVal)); var intVal = Convert.ToUInt32(value, CultureInfo.InvariantCulture);
var enumVal = GetLowerWord(intVal);
if (!Enum.IsDefined(returnType, enumVal))
{
return (TEnum)Enum.ToObject(returnType, GetUpperWord(intVal));
}
} }
} }
// this may work better?
return (TEnum)Enum.ToObject(returnType, value);
//// cast to underlying type first then to the enum
//return (T)Convert.ChangeType(value, rawType);
} }
// this may work better? else if (typeof(IConvertible).IsAssignableFrom(returnType))
return (TEnum)Enum.ToObject(returnType, value); {
//// cast to underlying type first then to the enum // for regular integers and whatnot
//return (T)Convert.ChangeType(value, rawType); return (TEnum)Convert.ChangeType(value, returnType, CultureInfo.InvariantCulture);
}
// return as-is from cap. if caller made a mistake then there should be exceptions
return (TEnum)value;
} }
else if (typeof(IConvertible).IsAssignableFrom(returnType)) return default(TEnum);
{
// for regular integers and whatnot
return (TEnum)Convert.ChangeType(value, returnType, CultureInfo.InvariantCulture);
}
// return as-is from cap. if caller made a mistake then there should be exceptions
return (TEnum)value;
} }
static ushort GetLowerWord(uint value) static ushort GetLowerWord(uint value)
@@ -101,11 +105,40 @@ namespace NTwain.Data
/// <returns></returns> /// <returns></returns>
public static TWFix32 ConvertToFix32(this object value) public static TWFix32 ConvertToFix32(this object value)
{ {
if (value is TWFix32) if (value != null)
{ {
return (TWFix32)value; if (value is TWFix32)
{
return (TWFix32)value;
}
return (TWFix32)Convert.ToSingle(value, CultureInfo.InvariantCulture);
} }
return (TWFix32)Convert.ToSingle(value, CultureInfo.InvariantCulture); return default(TWFix32);
} }
///// <summary>
///// Routine that does nothing.
///// </summary>
///// <param name="value">The value.</param>
///// <returns></returns>
//public static object NoConvertRoutine(object value)
//{
// return value;
//}
///// <summary>
///// Predefined routine for <see cref="string"/>
///// </summary>
///// <param name="value">The value.</param>
///// <returns></returns>
//public static string ConvertToString(object value)
//{
// if (value != null)
// {
// return value.ToString();
// }
// return default(string);
//}
} }
} }

View File

@@ -172,31 +172,7 @@ namespace NTwain
#region high-level caps #region high-level caps
private CapabilityControl<XferMech> _imgXferMech; #region audio caps
/// <summary>
/// Gets the property to work with image <see cref="XferMech"/> for the current source.
/// </summary>
/// <value>
/// The image xfer mech.
/// </value>
public CapabilityControl<XferMech> CapImageXferMech
{
get
{
if (_imgXferMech == null)
{
_imgXferMech = new CapabilityControl<XferMech>(this, CapabilityId.ICapXferMech, CapRoutines.EnumRoutine<XferMech>,
value => new TWCapability(CapabilityId.ICapXferMech, new TWOneValue
{
Item = (uint)value,
ItemType = ItemType.UInt16
}));
}
return _imgXferMech;
}
}
private CapabilityControl<XferMech> _audXferMech; private CapabilityControl<XferMech> _audXferMech;
@@ -212,7 +188,7 @@ namespace NTwain
{ {
if (_audXferMech == null) if (_audXferMech == null)
{ {
_audXferMech = new CapabilityControl<XferMech>(this, CapabilityId.ACapXferMech, CapRoutines.EnumRoutine<XferMech>, _audXferMech = new CapabilityControl<XferMech>(this, CapabilityId.ACapXferMech, ValueExtensions.ConvertToEnum<XferMech>,
value => new TWCapability(CapabilityId.ACapXferMech, new TWOneValue value => new TWCapability(CapabilityId.ACapXferMech, new TWOneValue
{ {
Item = (uint)value, Item = (uint)value,
@@ -223,6 +199,35 @@ namespace NTwain
} }
} }
#endregion
#region img caps
private CapabilityControl<XferMech> _imgXferMech;
/// <summary>
/// Gets the property to work with image <see cref="XferMech"/> for the current source.
/// </summary>
/// <value>
/// The image xfer mech.
/// </value>
public CapabilityControl<XferMech> CapImageXferMech
{
get
{
if (_imgXferMech == null)
{
_imgXferMech = new CapabilityControl<XferMech>(this, CapabilityId.ICapXferMech, ValueExtensions.ConvertToEnum<XferMech>,
value => new TWCapability(CapabilityId.ICapXferMech, new TWOneValue
{
Item = (uint)value,
ItemType = ItemType.UInt16
}));
}
return _imgXferMech;
}
}
private CapabilityControl<CompressionType> _compression; private CapabilityControl<CompressionType> _compression;
@@ -238,7 +243,7 @@ namespace NTwain
{ {
if (_compression == null) if (_compression == null)
{ {
_compression = new CapabilityControl<CompressionType>(this, CapabilityId.ICapCompression, CapRoutines.EnumRoutine<CompressionType>, _compression = new CapabilityControl<CompressionType>(this, CapabilityId.ICapCompression, ValueExtensions.ConvertToEnum<CompressionType>,
value => new TWCapability(CapabilityId.ICapCompression, new TWOneValue value => new TWCapability(CapabilityId.ICapCompression, new TWOneValue
{ {
Item = (uint)value, Item = (uint)value,
@@ -264,7 +269,7 @@ namespace NTwain
{ {
if (_fileFormat == null) if (_fileFormat == null)
{ {
_fileFormat = new CapabilityControl<FileFormat>(this, CapabilityId.ICapImageFileFormat, CapRoutines.EnumRoutine<FileFormat>, _fileFormat = new CapabilityControl<FileFormat>(this, CapabilityId.ICapImageFileFormat, ValueExtensions.ConvertToEnum<FileFormat>,
value => new TWCapability(CapabilityId.ICapImageFileFormat, new TWOneValue value => new TWCapability(CapabilityId.ICapImageFileFormat, new TWOneValue
{ {
Item = (uint)value, Item = (uint)value,
@@ -290,7 +295,7 @@ namespace NTwain
{ {
if (_pixelType == null) if (_pixelType == null)
{ {
_pixelType = new CapabilityControl<PixelType>(this, CapabilityId.ICapPixelType, CapRoutines.EnumRoutine<PixelType>, _pixelType = new CapabilityControl<PixelType>(this, CapabilityId.ICapPixelType, ValueExtensions.ConvertToEnum<PixelType>,
value => new TWCapability(CapabilityId.ICapPixelType, new TWOneValue value => new TWCapability(CapabilityId.ICapPixelType, new TWOneValue
{ {
Item = (uint)value, Item = (uint)value,
@@ -316,7 +321,7 @@ namespace NTwain
{ {
if (_supportSize == null) if (_supportSize == null)
{ {
_supportSize = new CapabilityControl<SupportedSize>(this, CapabilityId.ICapSupportedSizes, CapRoutines.EnumRoutine<SupportedSize>, _supportSize = new CapabilityControl<SupportedSize>(this, CapabilityId.ICapSupportedSizes, ValueExtensions.ConvertToEnum<SupportedSize>,
value => new TWCapability(CapabilityId.ICapSupportedSizes, new TWOneValue value => new TWCapability(CapabilityId.ICapSupportedSizes, new TWOneValue
{ {
Item = (uint)value, Item = (uint)value,
@@ -334,7 +339,7 @@ namespace NTwain
/// Gets the property to work with image auto deskew flag for the current source. /// Gets the property to work with image auto deskew flag for the current source.
/// </summary> /// </summary>
/// <value> /// <value>
/// The image supported size. /// The image auto deskew flag.
/// </value> /// </value>
public CapabilityControl<BoolType> CapImageAutoDeskew public CapabilityControl<BoolType> CapImageAutoDeskew
{ {
@@ -342,143 +347,172 @@ namespace NTwain
{ {
if (_autoDeskew == null) if (_autoDeskew == null)
{ {
_autoDeskew = new CapabilityControl<BoolType>(this, CapabilityId.ICapAutomaticDeskew, CapRoutines.EnumRoutine<BoolType>, null); _autoDeskew = new CapabilityControl<BoolType>(this, CapabilityId.ICapAutomaticDeskew, ValueExtensions.ConvertToEnum<BoolType>, value =>
{
if (Identity.ProtocolMajor >= 2)
{
// if using twain 2.0 will need to use enum instead of onevalue (yuck)
TWEnumeration en = new TWEnumeration();
en.ItemList = new object[] { (uint)value };
en.ItemType = ItemType.Bool;
return new TWCapability(CapabilityId.ICapAutomaticDeskew, en);
}
else
{
TWOneValue one = new TWOneValue();
one.Item = (uint)value;
one.ItemType = ItemType.Bool;
return new TWCapability(CapabilityId.ICapAutomaticDeskew, one);
}
});
} }
return _autoDeskew; return _autoDeskew;
} }
} }
#endregion
#region dpi private CapabilityControl<BoolType> _autoRotate;
/// <summary> /// <summary>
/// Gets the supported DPI values for the current source. /// Gets the property to work with image auto rotate flag for the current source.
/// Only call this at state 4 or higher.
/// </summary> /// </summary>
/// <returns></returns> /// <value>
public IList<TWFix32> CapGetDPIs() /// The image auto rotate flag.
/// </value>
public CapabilityControl<BoolType> CapImageAutoRotate
{ {
var list = CapGet(CapabilityId.ICapXResolution); get
return list.Select(o => o.ConvertToFix32()).ToList();
}
/// <summary>
/// Change the DPI value for the current source.
/// </summary>
/// <param name="dpi">The DPI.</param>
/// <returns></returns>
public ReturnCode CapSetDPI(TWFix32 dpi)
{
return CapSetDPI(dpi, dpi);
}
/// <summary>
/// Change the DPI value for the current source.
/// </summary>
/// <param name="xDPI">The x DPI.</param>
/// <param name="yDPI">The y DPI.</param>
/// <returns></returns>
public ReturnCode CapSetDPI(TWFix32 xDPI, TWFix32 yDPI)
{
TWOneValue one = new TWOneValue();
one.Item = (uint)xDPI;// ((uint)dpi) << 16;
one.ItemType = ItemType.Fix32;
using (TWCapability xres = new TWCapability(CapabilityId.ICapXResolution, one))
{ {
var rc = _session.DGControl.Capability.Set(xres); if (_autoRotate == null)
if (rc == ReturnCode.Success)
{ {
one.Item = (uint)yDPI; _autoRotate = new CapabilityControl<BoolType>(this, CapabilityId.ICapAutomaticRotate, ValueExtensions.ConvertToEnum<BoolType>, value =>
using (TWCapability yres = new TWCapability(CapabilityId.ICapYResolution, one))
{ {
rc = _session.DGControl.Capability.Set(yres); if (Identity.ProtocolMajor >= 2)
} {
// if using twain 2.0 will need to use enum instead of onevalue (yuck)
TWEnumeration en = new TWEnumeration();
en.ItemList = new object[] { (uint)value };
en.ItemType = ItemType.Bool;
return new TWCapability(CapabilityId.ICapAutomaticRotate, en);
}
else
{
TWOneValue one = new TWOneValue();
one.Item = (uint)value;
one.ItemType = ItemType.Bool;
return new TWCapability(CapabilityId.ICapAutomaticRotate, one);
}
});
} }
return rc; return _autoRotate;
} }
} }
private CapabilityControl<TWFix32> _xResolution;
/// <summary>
/// Gets the property to work with image horizontal resolution for the current source.
/// </summary>
/// <value>
/// The image horizontal resolution.
/// </value>
public CapabilityControl<TWFix32> CapImageXResolution
{
get
{
if (_xResolution == null)
{
_xResolution = new CapabilityControl<TWFix32>(this, CapabilityId.ICapXResolution, ValueExtensions.ConvertToFix32,
value => new TWCapability(CapabilityId.ICapXResolution, new TWOneValue
{
Item = (uint)value,// ((uint)dpi) << 16;
ItemType = ItemType.Fix32
}));
}
return _xResolution;
}
}
private CapabilityControl<TWFix32> _yResolution;
/// <summary>
/// Gets the property to work with image vertical resolution for the current source.
/// </summary>
/// <value>
/// The image vertical resolution.
/// </value>
public CapabilityControl<TWFix32> CapImageYResolution
{
get
{
if (_yResolution == null)
{
_yResolution = new CapabilityControl<TWFix32>(this, CapabilityId.ICapYResolution, ValueExtensions.ConvertToFix32,
value => new TWCapability(CapabilityId.ICapYResolution, new TWOneValue
{
Item = (uint)value,// ((uint)dpi) << 16;
ItemType = ItemType.Fix32
}));
}
return _yResolution;
}
}
#endregion
#region other caps
private CapabilityControl<BoolType> _duplexEnabled;
/// <summary>
/// Gets the property to work with duplex enabled flag for the current source.
/// </summary>
/// <value>
/// The duplex enabled flag.
/// </value>
public CapabilityControl<BoolType> CapDuplexEnabled
{
get
{
if (_duplexEnabled == null)
{
_duplexEnabled = new CapabilityControl<BoolType>(this, CapabilityId.CapDuplexEnabled, ValueExtensions.ConvertToEnum<BoolType>, value =>
{
if (Identity.ProtocolMajor >= 2)
{
// if using twain 2.0 will need to use enum instead of onevalue (yuck)
TWEnumeration en = new TWEnumeration();
en.ItemList = new object[] { (uint)value };
en.ItemType = ItemType.Bool;
return new TWCapability(CapabilityId.CapDuplexEnabled, en);
}
else
{
TWOneValue one = new TWOneValue();
one.Item = (uint)value;
one.ItemType = ItemType.Bool;
return new TWCapability(CapabilityId.CapDuplexEnabled, one);
}
});
}
return _duplexEnabled;
}
}
#endregion
#endregion #endregion
#region onesie flags #region onesie flags
/// <summary>
/// Change the auto deskew flag for the current source.
/// </summary>
/// <param name="useIt">if set to <c>true</c> use it.</param>
/// <returns></returns>
public ReturnCode CapSetAutoDeskew(bool useIt)
{
var rc = ReturnCode.Failure;
if (SupportedCaps.Contains(CapabilityId.ICapAutomaticDeskew))
{
if (Identity.ProtocolMajor >= 2)
{
// if using twain 2.0 will need to use enum instead of onevalue (yuck)
TWEnumeration en = new TWEnumeration();
en.ItemList = new object[] { (uint)(useIt ? 1 : 0) };
en.ItemType = ItemType.Bool;
using (TWCapability dx = new TWCapability(CapabilityId.ICapAutomaticDeskew, en))
{
rc = _session.DGControl.Capability.Set(dx);
}
}
else
{
TWOneValue one = new TWOneValue();
one.Item = (uint)(useIt ? 1 : 0);
one.ItemType = ItemType.Bool;
using (TWCapability capValue = new TWCapability(CapabilityId.ICapAutomaticDeskew, one))
{
rc = _session.DGControl.Capability.Set(capValue);
}
}
}
return rc;
}
/// <summary>
/// Change the auto rotate flag for the current source.
/// </summary>
/// <param name="useIt">if set to <c>true</c> use it.</param>
/// <returns></returns>
public ReturnCode CapSetAutoRotate(bool useIt)
{
var rc = ReturnCode.Failure;
if (SupportedCaps.Contains(CapabilityId.ICapAutomaticRotate))
{
if (Identity.ProtocolMajor >= 2)
{
// if using twain 2.0 will need to use enum instead of onevalue (yuck)
TWEnumeration en = new TWEnumeration();
en.ItemList = new object[] { (uint)(useIt ? 1 : 0) };
en.ItemType = ItemType.Bool;
using (TWCapability dx = new TWCapability(CapabilityId.ICapAutomaticRotate, en))
{
rc = _session.DGControl.Capability.Set(dx);
}
}
else
{
TWOneValue one = new TWOneValue();
one.Item = (uint)(useIt ? 1 : 0);
one.ItemType = ItemType.Bool;
using (TWCapability capValue = new TWCapability(CapabilityId.ICapAutomaticRotate, one))
{
rc = _session.DGControl.Capability.Set(capValue);
}
}
}
return rc;
}
/// <summary> /// <summary>
/// Change the auto border detection flag for the current source. /// Change the auto border detection flag for the current source.
@@ -527,39 +561,6 @@ namespace NTwain
return rc; return rc;
} }
/// <summary>
/// Change the duplex flag for the current source.
/// </summary>
/// <param name="useIt">if set to <c>true</c> to use it.</param>
/// <returns></returns>
public ReturnCode CapSetDuplex(bool useIt)
{
if (Identity.ProtocolMajor >= 2)
{
// twain 2 likes to use enum :(
TWEnumeration en = new TWEnumeration();
en.ItemList = new object[] { (uint)(useIt ? 1 : 0) };
en.ItemType = ItemType.Bool;
using (TWCapability dx = new TWCapability(CapabilityId.CapDuplexEnabled, en))
{
return _session.DGControl.Capability.Set(dx);
}
}
else
{
TWOneValue one = new TWOneValue();
one.Item = (uint)(useIt ? 1 : 0);
one.ItemType = ItemType.Bool;
using (TWCapability dx = new TWCapability(CapabilityId.CapDuplexEnabled, one))
{
return _session.DGControl.Capability.Set(dx);
}
}
}
/// <summary> /// <summary>
/// Change the use feeder flag for the current source. /// Change the use feeder flag for the current source.
/// </summary> /// </summary>

View File

@@ -57,7 +57,6 @@
<ItemGroup> <ItemGroup>
<Compile Include="CapabilityControl.cs" /> <Compile Include="CapabilityControl.cs" />
<Compile Include="CapabilityReader.cs" /> <Compile Include="CapabilityReader.cs" />
<Compile Include="CapRoutines.cs" />
<Compile Include="Data\TypeReader.cs" /> <Compile Include="Data\TypeReader.cs" />
<Compile Include="Data\TwainTypesExtended.cs" /> <Compile Include="Data\TwainTypesExtended.cs" />
<Compile Include="DeviceEventArgs.cs" /> <Compile Include="DeviceEventArgs.cs" />

View File

@@ -280,14 +280,14 @@ namespace Tester.Winform
{ {
LoadDepth(src.CapImagePixelType); LoadDepth(src.CapImagePixelType);
} }
if (groupDPI.Enabled = caps.Contains(CapabilityId.ICapXResolution) && caps.Contains(CapabilityId.ICapYResolution)) if (groupDPI.Enabled = src.CapImageXResolution.IsSupported && src.CapImageYResolution.IsSupported)
{ {
LoadDPI(); LoadDPI(src.CapImageXResolution);
} }
// TODO: find out if this is how duplex works or also needs the other option // TODO: find out if this is how duplex works or also needs the other option
if (groupDuplex.Enabled = caps.Contains(CapabilityId.CapDuplexEnabled)) if (groupDuplex.Enabled = src.CapDuplexEnabled.IsSupported)
{ {
LoadDuplex(); LoadDuplex(src.CapDuplexEnabled);
} }
if (groupSize.Enabled = src.CapImageSupportedSize.IsSupported) if (groupSize.Enabled = src.CapImageSupportedSize.IsSupported)
{ {
@@ -312,18 +312,20 @@ namespace Tester.Winform
groupSize.Text = labelTest; groupSize.Text = labelTest;
} }
} }
private void LoadDuplex() private void LoadDuplex(CapabilityControl<BoolType> cap)
{ {
ckDuplex.Checked = _twain.CurrentSource.CapGetCurrent(CapabilityId.CapDuplexEnabled).ConvertToEnum<uint>() != 0; ckDuplex.Checked = cap.GetCurrent() == BoolType.True;
} }
private void LoadDPI()
private void LoadDPI(CapabilityControl<TWFix32> cap)
{ {
// only allow dpi of certain values for those source that lists everything // only allow dpi of certain values for those source that lists everything
var list = _twain.CurrentSource.CapGetDPIs().Where(dpi => (dpi % 50) == 0).ToList(); var list = cap.Get().Where(dpi => (dpi % 50) == 0).ToList();
comboDPI.DataSource = list; comboDPI.DataSource = list;
var cur = (TWFix32)_twain.CurrentSource.CapGetCurrent(CapabilityId.ICapXResolution); var cur = cap.GetCurrent();
if (list.Contains(cur)) if (list.Contains(cur))
{ {
comboDPI.SelectedItem = cur; comboDPI.SelectedItem = cur;
@@ -369,7 +371,8 @@ namespace Tester.Winform
if (!_loadingCaps && _twain.State == 4) if (!_loadingCaps && _twain.State == 4)
{ {
var sel = (TWFix32)comboDPI.SelectedItem; var sel = (TWFix32)comboDPI.SelectedItem;
_twain.CurrentSource.CapSetDPI(sel); _twain.CurrentSource.CapImageXResolution.Set(sel);
_twain.CurrentSource.CapImageYResolution.Set(sel);
} }
} }
@@ -377,7 +380,7 @@ namespace Tester.Winform
{ {
if (!_loadingCaps && _twain.State == 4) if (!_loadingCaps && _twain.State == 4)
{ {
_twain.CurrentSource.CapSetDuplex(ckDuplex.Checked); _twain.CurrentSource.CapDuplexEnabled.Set(ckDuplex.Checked ? BoolType.True : BoolType.False);
} }
} }