Files
chuan 5ce2c8a982 feat: Claude Code 原生 Windows 通知(C# / .NET 10 + Avalonia 12)
为 Claude Code 提供原生 Windows toast 通知:点击跳回原窗口、切回 Windows
Terminal 标签、跨虚拟桌面、调用方图标、非阻塞投递;NativeAOT 单文件分发。
2026-06-22 18:05:15 +08:00

93 lines
3.5 KiB
C#

using System;
using System.Runtime.InteropServices;
namespace Notify.Interop;
internal static partial class Win32
{
[LibraryImport("user32.dll")]
internal static partial IntPtr GetForegroundWindow();
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool SetForegroundWindow(IntPtr hWnd);
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool AllowSetForegroundWindow(uint dwProcessId);
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool AttachThreadInput(uint idAttach, uint idAttachTo, [MarshalAs(UnmanagedType.Bool)] bool fAttach);
[LibraryImport("user32.dll")]
internal static partial uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool BringWindowToTop(IntPtr hWnd);
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool ShowWindow(IntPtr hWnd, int nCmdShow);
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool IsIconic(IntPtr hWnd);
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool IsWindow(IntPtr hWnd);
[LibraryImport("user32.dll")]
internal static partial void SwitchToThisWindow(IntPtr hWnd, [MarshalAs(UnmanagedType.Bool)] bool fAltTab);
[LibraryImport("user32.dll")]
internal static partial void keybd_event(byte bVk, byte bScan, uint dwFlags, IntPtr dwExtraInfo);
[LibraryImport("kernel32.dll")]
internal static partial uint GetCurrentThreadId();
[LibraryImport("user32.dll", EntryPoint = "GetClassNameW", StringMarshalling = StringMarshalling.Utf16)]
internal static partial int GetClassName(IntPtr hWnd, ref char lpClassName, int nMaxCount);
[LibraryImport("user32.dll", EntryPoint = "GetWindowLongPtrW")]
internal static partial IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
[LibraryImport("user32.dll", EntryPoint = "SetWindowLongPtrW")]
internal static partial IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
// 把窗口设为工具窗口:从任务栏与 Alt+Tab 中隐藏
internal static void MakeToolWindow(IntPtr hWnd)
{
var ex = GetWindowLongPtr(hWnd, GWL_EXSTYLE).ToInt64();
ex = (ex | WS_EX_TOOLWINDOW) & ~WS_EX_APPWINDOW;
SetWindowLongPtr(hWnd, GWL_EXSTYLE, new IntPtr(ex));
}
// 取窗口类名
internal static string GetClassNameOf(IntPtr hWnd)
{
var buf = new char[256];
var n = GetClassName(hWnd, ref buf[0], buf.Length);
return n > 0 ? new string(buf, 0, n) : "";
}
// --- 常量 ---
internal const uint ASFW_ANY = 0xFFFFFFFF;
internal const int SW_RESTORE = 9;
internal const int SW_SHOW = 5;
internal const uint SWP_NOSIZE = 0x0001;
internal const uint SWP_NOMOVE = 0x0002;
internal const uint SWP_SHOWWINDOW = 0x0040;
internal const byte VK_MENU = 0x12;
internal const uint KEYEVENTF_KEYUP = 0x0002;
internal const int GWL_EXSTYLE = -20;
internal const long WS_EX_TOOLWINDOW = 0x00000080;
internal const long WS_EX_APPWINDOW = 0x00040000;
}