67 lines
2.2 KiB
C#
67 lines
2.2 KiB
C#
using System.Runtime.InteropServices;
|
|
|
|
namespace CursorLang.Core.Threading;
|
|
|
|
/// <summary>
|
|
/// The Win32 message loop — what the application has instead of a dispatcher.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// It lives in Core rather than in the agent because the things that need a pumping
|
|
/// thread do: <see cref="MessageTimer"/> is used by the layout polling and by saving
|
|
/// the settings, and both are Core's. The settings window has a loop of its own, run
|
|
/// by WPF, and everything here works inside it just the same.
|
|
/// </remarks>
|
|
public static class MessageLoop
|
|
{
|
|
/// <summary>
|
|
/// Pumps messages until <c>WM_QUIT</c> and returns its exit code.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// A -1 from GetMessage means the window handle has already gone; going round
|
|
/// again would spin forever, so the loop gives up instead.
|
|
/// </remarks>
|
|
public static int Run()
|
|
{
|
|
while (true)
|
|
{
|
|
int result = GetMessage(out Message message, IntPtr.Zero, 0, 0);
|
|
if (result is 0 or -1)
|
|
{
|
|
return result == 0 ? (int)message.wParam : 1;
|
|
}
|
|
|
|
TranslateMessage(ref message);
|
|
DispatchMessage(ref message);
|
|
}
|
|
}
|
|
|
|
/// <summary>Asks the loop on this thread to finish.</summary>
|
|
public static void Quit(int exitCode = 0) => PostQuitMessage(exitCode);
|
|
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "GetMessageW")]
|
|
private static extern int GetMessage(out Message lpMsg, IntPtr hWnd, uint filterMin, uint filterMax);
|
|
|
|
[DllImport("user32.dll")]
|
|
private static extern bool TranslateMessage(ref Message lpMsg);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "DispatchMessageW")]
|
|
private static extern IntPtr DispatchMessage(ref Message lpMsg);
|
|
|
|
[DllImport("user32.dll")]
|
|
private static extern void PostQuitMessage(int exitCode);
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct Message
|
|
{
|
|
public IntPtr hwnd;
|
|
public uint message;
|
|
public IntPtr wParam;
|
|
public IntPtr lParam;
|
|
public uint time;
|
|
public int x;
|
|
public int y;
|
|
public uint lPrivate;
|
|
}
|
|
}
|