mirror of
https://github.com/soukoku/ntwain.git
synced 2025-04-05 20:59:23 +08:00
Add callback reg after opening source.
This commit is contained in:
parent
94fc3f623c
commit
3fc0b97096
@ -93,5 +93,26 @@ namespace NTwain.DSM
|
||||
MSG msg,
|
||||
ref TW_CUSTOMDSDATA twcustomedsdata
|
||||
);
|
||||
|
||||
[DllImport(DsmName, CharSet = CharSet.Ansi)]
|
||||
internal static extern UInt16 DSM_Entry
|
||||
(
|
||||
ref TW_IDENTITY_MACOSX origin,
|
||||
ref TW_IDENTITY_MACOSX dest,
|
||||
DG dg,
|
||||
DAT dat,
|
||||
MSG msg,
|
||||
ref TW_CALLBACK twcallback
|
||||
);
|
||||
[DllImport(DsmName, CharSet = CharSet.Ansi)]
|
||||
internal static extern UInt16 DSM_Entry
|
||||
(
|
||||
ref TW_IDENTITY_MACOSX origin,
|
||||
ref TW_IDENTITY_MACOSX dest,
|
||||
DG dg,
|
||||
DAT dat,
|
||||
MSG msg,
|
||||
ref TW_CALLBACK2 twcallback
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -93,5 +93,26 @@ namespace NTwain.DSM
|
||||
MSG msg,
|
||||
ref TW_CUSTOMDSDATA twcustomedsdata
|
||||
);
|
||||
|
||||
[DllImport(DsmName, CharSet = CharSet.Ansi)]
|
||||
internal static extern UInt16 DSM_Entry
|
||||
(
|
||||
ref TW_IDENTITY_MACOSX origin,
|
||||
ref TW_IDENTITY_MACOSX dest,
|
||||
DG dg,
|
||||
DAT dat,
|
||||
MSG msg,
|
||||
ref TW_CALLBACK twcallback
|
||||
);
|
||||
[DllImport(DsmName, CharSet = CharSet.Ansi)]
|
||||
internal static extern UInt16 DSM_Entry
|
||||
(
|
||||
ref TW_IDENTITY_MACOSX origin,
|
||||
ref TW_IDENTITY_MACOSX dest,
|
||||
DG dg,
|
||||
DAT dat,
|
||||
MSG msg,
|
||||
ref TW_CALLBACK2 twcallback
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -93,5 +93,26 @@ namespace NTwain.DSM
|
||||
MSG msg,
|
||||
ref TW_CUSTOMDSDATA twcustomedsdata
|
||||
);
|
||||
|
||||
[DllImport(DsmName, CharSet = CharSet.Ansi)]
|
||||
internal static extern UInt16 DSM_Entry
|
||||
(
|
||||
ref TW_IDENTITY_LEGACY origin,
|
||||
ref TW_IDENTITY_LEGACY dest,
|
||||
DG dg,
|
||||
DAT dat,
|
||||
MSG msg,
|
||||
ref TW_CALLBACK twcallback
|
||||
);
|
||||
[DllImport(DsmName, CharSet = CharSet.Ansi)]
|
||||
internal static extern UInt16 DSM_Entry
|
||||
(
|
||||
ref TW_IDENTITY_LEGACY origin,
|
||||
ref TW_IDENTITY_LEGACY dest,
|
||||
DG dg,
|
||||
DAT dat,
|
||||
MSG msg,
|
||||
ref TW_CALLBACK2 twcallback
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -93,5 +93,26 @@ namespace NTwain.DSM
|
||||
MSG msg,
|
||||
ref TW_CUSTOMDSDATA twcustomedsdata
|
||||
);
|
||||
|
||||
[DllImport(DsmName, CharSet = CharSet.Ansi)]
|
||||
internal static extern UInt16 DSM_Entry
|
||||
(
|
||||
ref TW_IDENTITY_LEGACY origin,
|
||||
ref TW_IDENTITY_LEGACY dest,
|
||||
DG dg,
|
||||
DAT dat,
|
||||
MSG msg,
|
||||
ref TW_CALLBACK twcallback
|
||||
);
|
||||
[DllImport(DsmName, CharSet = CharSet.Ansi)]
|
||||
internal static extern UInt16 DSM_Entry
|
||||
(
|
||||
ref TW_IDENTITY_LEGACY origin,
|
||||
ref TW_IDENTITY_LEGACY dest,
|
||||
DG dg,
|
||||
DAT dat,
|
||||
MSG msg,
|
||||
ref TW_CALLBACK2 twcallback
|
||||
);
|
||||
}
|
||||
}
|
||||
|
57
src/NTwain/Triplets/DATCallback.cs
Normal file
57
src/NTwain/Triplets/DATCallback.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using NTwain.DSM;
|
||||
using TWAINWorkingGroup;
|
||||
|
||||
namespace NTwain.Triplets
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains calls used with <see cref="DG.CONTROL"/> and <see cref="DAT.CALLBACK"/>.
|
||||
/// </summary>
|
||||
public class DATCallback : TripletBase
|
||||
{
|
||||
public DATCallback(TwainSession session) : base(session)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the callback function.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public STS RegisterCallback(ref TW_CALLBACK data)
|
||||
{
|
||||
return DoIt(MSG.REGISTER_CALLBACK, ref data);
|
||||
}
|
||||
|
||||
STS DoIt(MSG msg, ref TW_CALLBACK data)
|
||||
{
|
||||
var rc = STS.FAILURE;
|
||||
if (TwainPlatform.IsWindows)
|
||||
{
|
||||
var app = Session.AppIdentity;
|
||||
var ds = Session.CurrentSource;
|
||||
if (TwainPlatform.Is32bit && TwainPlatform.PreferLegacyDSM)
|
||||
{
|
||||
rc = (STS)WinLegacyDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = (STS)WinNewDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
|
||||
}
|
||||
}
|
||||
else if (TwainPlatform.IsMacOSX)
|
||||
{
|
||||
TW_IDENTITY_MACOSX app = Session.AppIdentity;
|
||||
TW_IDENTITY_MACOSX ds = Session.CurrentSource;
|
||||
if (TwainPlatform.PreferLegacyDSM)
|
||||
{
|
||||
rc = (STS)OSXLegacyDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = (STS)OSXNewDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
57
src/NTwain/Triplets/DATCallback2.cs
Normal file
57
src/NTwain/Triplets/DATCallback2.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using NTwain.DSM;
|
||||
using TWAINWorkingGroup;
|
||||
|
||||
namespace NTwain.Triplets
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains calls used with <see cref="DG.CONTROL"/> and <see cref="DAT.CALLBACK2"/>.
|
||||
/// </summary>
|
||||
public class DATCallback2 : TripletBase
|
||||
{
|
||||
public DATCallback2(TwainSession session) : base(session)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the callback function.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public STS RegisterCallback(ref TW_CALLBACK2 data)
|
||||
{
|
||||
return DoIt(MSG.REGISTER_CALLBACK, ref data);
|
||||
}
|
||||
|
||||
STS DoIt(MSG msg, ref TW_CALLBACK2 data)
|
||||
{
|
||||
var rc = STS.FAILURE;
|
||||
if (TwainPlatform.IsWindows)
|
||||
{
|
||||
var app = Session.AppIdentity;
|
||||
var ds = Session.CurrentSource;
|
||||
if (TwainPlatform.Is32bit && TwainPlatform.PreferLegacyDSM)
|
||||
{
|
||||
rc = (STS)WinLegacyDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = (STS)WinNewDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
|
||||
}
|
||||
}
|
||||
else if (TwainPlatform.IsMacOSX)
|
||||
{
|
||||
TW_IDENTITY_MACOSX app = Session.AppIdentity;
|
||||
TW_IDENTITY_MACOSX ds = Session.CurrentSource;
|
||||
if (TwainPlatform.PreferLegacyDSM)
|
||||
{
|
||||
rc = (STS)OSXLegacyDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = (STS)OSXNewDSM.DSM_Entry(ref app, ref ds, DG.CONTROL, DAT.DEVICEEVENT, msg, ref data);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
@ -24,16 +24,8 @@ namespace NTwain.Triplets
|
||||
if ((rc = DoIt(MSG.OPENDS, ref ds)) == STS.SUCCESS)
|
||||
{
|
||||
Session.CurrentSource = ds;
|
||||
Session.RegisterCallback();
|
||||
Session.State = STATE.S4;
|
||||
//// determine memory mgmt routines used
|
||||
//if ((((DG)Session._appIdentity.SupportedGroups) & DG.DSM2) == DG.DSM2)
|
||||
//{
|
||||
// TW_ENTRYPOINT_DELEGATES entry = default;
|
||||
// if (Session.DGControl.EntryPoint.Get(ref entry) == STS.SUCCESS)
|
||||
// {
|
||||
// Session._entryPoint = entry;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@ -48,8 +40,8 @@ namespace NTwain.Triplets
|
||||
var ds = Session.CurrentSource;
|
||||
if ((rc = DoIt(MSG.CLOSEDS, ref ds)) == STS.SUCCESS)
|
||||
{
|
||||
Session.CurrentSource = default;
|
||||
Session.State = STATE.S3;
|
||||
Session.CurrentSource = default;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ namespace NTwain.Triplets
|
||||
if ((rc = DoIt(MSG.OPENDSM, ref hwnd)) == STS.SUCCESS)
|
||||
{
|
||||
Session._hwnd = hwnd;
|
||||
Session.State = STATE.S3;
|
||||
|
||||
// get default source
|
||||
if (Session.DGControl.Identity.GetDefault(out TW_IDENTITY_LEGACY ds) == STS.SUCCESS)
|
||||
@ -40,6 +39,7 @@ namespace NTwain.Triplets
|
||||
Session._entryPoint = entry;
|
||||
}
|
||||
}
|
||||
Session.State = STATE.S3;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@ -54,9 +54,10 @@ namespace NTwain.Triplets
|
||||
STS rc;
|
||||
if ((rc = DoIt(MSG.CLOSEDSM, ref hwnd)) == STS.SUCCESS)
|
||||
{
|
||||
Session._hwnd = IntPtr.Zero;
|
||||
Session._entryPoint = default;
|
||||
Session.State = STATE.S2;
|
||||
Session._entryPoint = default;
|
||||
Session.DefaultSource = default;
|
||||
Session._hwnd = IntPtr.Zero;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -30,5 +30,11 @@
|
||||
private DATDeviceEvent? _deviceEvent;
|
||||
public DATDeviceEvent DeviceEvent => _deviceEvent ??= new DATDeviceEvent(Session);
|
||||
|
||||
private DATCallback? _callback;
|
||||
public DATCallback Callback => _callback ??= new DATCallback(Session);
|
||||
|
||||
private DATCallback2? _callback2;
|
||||
public DATCallback2 Callback2 => _callback2 ??= new DATCallback2(Session);
|
||||
|
||||
}
|
||||
}
|
91
src/NTwain/TwainSession.Callbacks.cs
Normal file
91
src/NTwain/TwainSession.Callbacks.cs
Normal file
@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using TWAINWorkingGroup;
|
||||
|
||||
namespace NTwain
|
||||
{
|
||||
// this file contains callback methods
|
||||
|
||||
partial class TwainSession
|
||||
{
|
||||
// these are kept around while a callback ptr is registered so they
|
||||
// don't get gc'd
|
||||
readonly NativeMethods.WindowsDsmEntryCallbackDelegate _legacyCallbackDelegate;
|
||||
readonly NativeMethods.MacosxDsmEntryCallbackDelegate _osxCallbackDelegate;
|
||||
|
||||
/// <summary>
|
||||
/// Try to registers callbacks for after opening the source.
|
||||
/// </summary>
|
||||
internal void RegisterCallback()
|
||||
{
|
||||
IntPtr cbPtr = IntPtr.Zero;
|
||||
|
||||
if (TwainPlatform.IsMacOSX)
|
||||
{
|
||||
cbPtr = Marshal.GetFunctionPointerForDelegate(_osxCallbackDelegate);
|
||||
}
|
||||
else
|
||||
{
|
||||
cbPtr = Marshal.GetFunctionPointerForDelegate(_legacyCallbackDelegate);
|
||||
}
|
||||
|
||||
var rc = STS.FAILURE;
|
||||
|
||||
// per the spec (pg 8-10), apps for 2.2 or higher uses callback2 so try this first
|
||||
if (_appIdentity.ProtocolMajor > 2 || (_appIdentity.ProtocolMajor >= 2 && _appIdentity.ProtocolMinor >= 2))
|
||||
{
|
||||
var cb2 = new TW_CALLBACK2 { CallBackProc = cbPtr };
|
||||
rc = DGControl.Callback2.RegisterCallback(ref cb2);
|
||||
}
|
||||
if (rc != STS.SUCCESS)
|
||||
{
|
||||
// always try old callback
|
||||
var cb = new TW_CALLBACK { CallBackProc = cbPtr };
|
||||
DGControl.Callback.RegisterCallback(ref cb);
|
||||
}
|
||||
}
|
||||
|
||||
private ushort LegacyCallbackHandler
|
||||
(
|
||||
ref TW_IDENTITY_LEGACY origin,
|
||||
ref TW_IDENTITY_LEGACY dest,
|
||||
DG dg,
|
||||
DAT dat,
|
||||
MSG msg,
|
||||
IntPtr twnull
|
||||
)
|
||||
{
|
||||
HandleSourceMsg(msg);
|
||||
return (ushort)STS.SUCCESS;
|
||||
}
|
||||
|
||||
private ushort OSXCallbackHandler
|
||||
(
|
||||
ref TW_IDENTITY_MACOSX origin,
|
||||
ref TW_IDENTITY_MACOSX dest,
|
||||
DG dg,
|
||||
DAT dat,
|
||||
MSG msg,
|
||||
IntPtr twnull
|
||||
)
|
||||
{
|
||||
HandleSourceMsg(msg);
|
||||
return (ushort)STS.SUCCESS;
|
||||
}
|
||||
|
||||
private void HandleSourceMsg(MSG msg)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case MSG.XFERREADY:
|
||||
break;
|
||||
case MSG.DEVICEEVENT:
|
||||
break;
|
||||
case MSG.CLOSEDSOK:
|
||||
break;
|
||||
case MSG.CLOSEDSREQ:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using TWAINWorkingGroup;
|
||||
using static System.Collections.Specialized.BitVector32;
|
||||
|
||||
namespace NTwain
|
||||
{
|
||||
@ -151,6 +152,5 @@ namespace NTwain
|
||||
/// Fires when <see cref="CurrentSource"/> changes.
|
||||
/// </summary>
|
||||
public event Action<TwainSession, TW_IDENTITY_LEGACY>? CurrentSourceChanged;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +81,9 @@ namespace NTwain
|
||||
DGControl = new DGControl(this);
|
||||
DGImage = new DGImage(this);
|
||||
DGAudio = new DGAudio(this);
|
||||
|
||||
_legacyCallbackDelegate = LegacyCallbackHandler;
|
||||
_osxCallbackDelegate = OSXCallbackHandler;
|
||||
}
|
||||
|
||||
internal IntPtr _hwnd;
|
||||
|
Loading…
Reference in New Issue
Block a user