5ce2c8a982
为 Claude Code 提供原生 Windows toast 通知:点击跳回原窗口、切回 Windows Terminal 标签、跨虚拟桌面、调用方图标、非阻塞投递;NativeAOT 单文件分发。
93 lines
3.5 KiB
C#
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;
|
|
}
|