Msg loop filter tweaks.

This commit is contained in:
Eugene Wang 2023-04-03 06:35:03 -04:00
parent eee811df14
commit 0f0f613ced
4 changed files with 42 additions and 38 deletions

View File

@ -31,8 +31,4 @@
<LastGenOutput>DSMGenerator.dummy</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
</Project>

View File

@ -88,20 +88,24 @@ namespace NTwain
/// <returns></returns>
public STS EnableSource(bool showUI, bool uiOnly)
{
var ui = new TW_USERINTERFACE
if (State != STATE.S4) return STS.SEQERROR; // shouldn't check it ourselves but whatev
_userInterface = new TW_USERINTERFACE
{
ShowUI = (ushort)((showUI || uiOnly) ? 1 : 0),
hParent = _hwnd,
};
var rc = uiOnly ?
DGControl.UserInterface.EnableDSUIOnly(ref _appIdentity, ref _currentDS, ref ui) :
DGControl.UserInterface.EnableDS(ref _appIdentity, ref _currentDS, ref ui);
DGControl.UserInterface.EnableDSUIOnly(ref _appIdentity, ref _currentDS, ref _userInterface) :
DGControl.UserInterface.EnableDS(ref _appIdentity, ref _currentDS, ref _userInterface);
if (rc == STS.SUCCESS || (!uiOnly && !showUI && rc == STS.CHECKSTATUS))
{
// keep it around for disable use
_userInterface = ui;
State = STATE.S5;
};
}
else
{
_userInterface = default;
}
return rc;
}

View File

@ -17,7 +17,7 @@ namespace NTwain
partial class TwainSession : IMessageFilter
{
private HwndSource? _wpfhook;
HwndSource? _wpfhook;
/// <summary>
/// Registers this session for use in a Winform UI thread.
@ -75,32 +75,24 @@ namespace NTwain
bool handled = false;
if (_state >= STATE.S5)
{
TW_EVENT evt = default;
try
var winMsg = new WIN_MESSAGE
{
var winMsg = new WIN_MESSAGE
{
hwnd = hWnd,
message = (uint)msg,
wParam = wParam,
lParam = lParam
};
// no need to do another lock call when using marshal alloc
evt.pEvent = Marshal.AllocHGlobal(Marshal.SizeOf(winMsg));
Marshal.StructureToPtr(winMsg, evt.pEvent, false);
hwnd = hWnd,
message = (uint)msg,
wParam = wParam,
lParam = lParam
};
// no need to do another lock call when using marshal alloc
if (_procEvent.pEvent == IntPtr.Zero)
_procEvent.pEvent = Marshal.AllocHGlobal(Marshal.SizeOf(winMsg));
Marshal.StructureToPtr(winMsg, _procEvent.pEvent, true);
var rc = DGControl.Event.ProcessEvent(ref _appIdentity, ref _currentDS, ref evt);
handled = rc == STS.DSEVENT;
if (evt.TWMessage != 0 && (handled || rc == STS.NOTDSEVENT))
{
Debug.WriteLine("Thread {0}: CheckIfTwainMessage at state {1} with MSG={2}.", Thread.CurrentThread.ManagedThreadId, State, (MSG)evt.TWMessage);
HandleSourceMsg((MSG)evt.TWMessage);
}
}
finally
var rc = DGControl.Event.ProcessEvent(ref _appIdentity, ref _currentDS, ref _procEvent);
handled = rc == STS.DSEVENT;
if (_procEvent.TWMessage != 0 && (handled || rc == STS.NOTDSEVENT))
{
// do we need to free it
if (evt.pEvent != IntPtr.Zero) Marshal.FreeHGlobal(evt.pEvent);
Debug.WriteLine("Thread {0}: CheckIfTwainMessage at state {1} with MSG={2}.", Thread.CurrentThread.ManagedThreadId, State, (MSG)_procEvent.TWMessage);
HandleSourceMsg((MSG)_procEvent.TWMessage);
}
}
return handled;

View File

@ -3,6 +3,7 @@ using NTwain.Triplets;
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
@ -96,8 +97,9 @@ namespace NTwain
}
internal IntPtr _hwnd;
internal TW_USERINTERFACE _userInterface;
// test this a bit
internal TW_USERINTERFACE _userInterface; // kept around for disable use
TW_EVENT _procEvent = default; // kept here so the alloc/free only happens once
// test threads a bit
readonly BlockingCollection<MSG> _bgPendingMsgs = new();
private readonly IThreadMarshaller _uiThreadMarshaller;
private bool disposedValue;
@ -152,6 +154,7 @@ namespace NTwain
// this will end the bg thread
_bgPendingMsgs.CompleteAdding();
}
if (_procEvent.pEvent != IntPtr.Zero) Marshal.FreeHGlobal(_procEvent.pEvent);
disposedValue = true;
}
}
@ -263,10 +266,14 @@ namespace NTwain
int tries = 0;
while (State > targetState)
{
if (tries++ > 5) break;
var oldState = State;
switch (State)
switch (oldState)
{
// todo: finish
case STATE.S7:
case STATE.S6:
break;
case STATE.S5:
DisableSource();
break;
@ -277,6 +284,11 @@ namespace NTwain
CloseDSM();
break;
}
if (oldState == State)
{
// didn't work
if (tries++ > 5) break;
}
}
return State;
}