66 lines
1.9 KiB
C#
66 lines
1.9 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using System.Windows.Forms;
|
|
|
|
namespace JD.Threading
|
|
{
|
|
|
|
public static class Win32MessageLoop
|
|
{
|
|
#region Methods
|
|
|
|
public static void WaitAndPump(WaitHandle waitHandle)
|
|
{
|
|
var safeHandle = waitHandle.SafeWaitHandle;
|
|
IntPtr[] handles = new IntPtr[1];
|
|
|
|
const int QS_ALLINPUT = 0x04FF;
|
|
const int MWMO_INPUTAVAILABLE = 0x0004;
|
|
const int WAIT_OBJECT_0 = 0;
|
|
const int WAIT_FAILED = -1;
|
|
const int WAIT_MESSAGE = WAIT_OBJECT_0 + 1; // + handles.Length
|
|
|
|
while (true)
|
|
{
|
|
Application.DoEvents();
|
|
|
|
bool mustRelease = false;
|
|
safeHandle.DangerousAddRef(ref mustRelease);
|
|
handles[0] = safeHandle.DangerousGetHandle();
|
|
|
|
int result = MsgWaitForMultipleObjectsEx(1, handles, Timeout.Infinite, QS_ALLINPUT, MWMO_INPUTAVAILABLE);
|
|
|
|
if (mustRelease)
|
|
{
|
|
safeHandle.DangerousRelease();
|
|
}
|
|
|
|
switch (result)
|
|
{
|
|
case WAIT_FAILED:
|
|
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
|
|
break;
|
|
|
|
case WAIT_OBJECT_0:
|
|
return;
|
|
|
|
case WAIT_MESSAGE:
|
|
break;
|
|
|
|
default:
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Dll Interop
|
|
|
|
[DllImport("User32.dll", SetLastError = true)]
|
|
private static extern int MsgWaitForMultipleObjectsEx(int nCount, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] pHandles, int dwMilliseconds, int dwWakeMask, int dwFlags);
|
|
|
|
#endregion
|
|
}
|
|
}
|