如何在桌面窗口外显示文本?WPF/WinForms实现屏幕提醒标签
嘿,这个需求用WPF完全能搞定!我给你整理了一套完整的实现方案,刚好能用上你提到的透明鼠标穿透窗口技术,直接就能上手~
WPF实现无窗口式屏幕中央提醒
核心思路拆解
- 搞一个无边框、全透明、鼠标完全穿透的独立小窗口,里面只放居中的文本标签——这样看起来就像文本直接浮在屏幕上,没有窗口边框的干扰
- 监听主窗口的最小化状态,一旦主窗口最小化,就启动定时器,到你指定的时间后弹出这个提醒窗口,显示完还能自动关闭
- 用Windows API实现窗口的透明和鼠标穿透,完全不影响用户操作其他程序
第一步:创建透明提醒窗口的XAML
先写一个极简的窗口,去掉所有边框,设置全透明,然后把文本块居中放好:
<Window x:Class="ReminderApp.TransparentReminderWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" WindowStyle="None" AllowsTransparency="True" Background="Transparent" Topmost="True" ShowInTaskbar="False"> <Grid> <!-- 这里可以自定义提醒文本的样式,比如颜色、字号、加粗 --> <TextBlock x:Name="ReminderTextBlock" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="28" Foreground="#FF457B9D" FontWeight="Bold"> 你的提醒内容! </TextBlock> </Grid> </Window>
第二步:实现窗口的鼠标穿透逻辑
在窗口的后台代码里,调用Windows API来设置窗口的穿透属性,这样鼠标就能直接穿过窗口点击下面的内容:
using System; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; namespace ReminderApp { public partial class TransparentReminderWindow : Window { // 用到的Windows API常量和函数 private const int GWL_EXSTYLE = -20; private const int WS_EX_TRANSPARENT = 0x00000020; private const int WS_EX_LAYERED = 0x00080000; [DllImport("user32.dll")] private static extern int GetWindowLong(IntPtr hwnd, int index); [DllImport("user32.dll")] private static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle); public TransparentReminderWindow(string reminderText) { InitializeComponent(); ReminderTextBlock.Text = reminderText; Loaded += OnWindowLoaded; } private void OnWindowLoaded(object sender, RoutedEventArgs e) { // 获取窗口句柄,设置穿透样式 var hwnd = new WindowInteropHelper(this).Handle; int currentStyle = GetWindowLong(hwnd, GWL_EXSTYLE); SetWindowLong(hwnd, GWL_EXSTYLE, currentStyle | WS_EX_TRANSPARENT | WS_EX_LAYERED); } // 封装一个自动关闭的方法,比如显示3秒后自动消失 public void ShowAndAutoClose(int displaySeconds = 3) { Show(); var closeTimer = new System.Windows.Threading.DispatcherTimer(); closeTimer.Interval = TimeSpan.FromSeconds(displaySeconds); closeTimer.Tick += (s, args) => { closeTimer.Stop(); Close(); }; closeTimer.Start(); } } }
第三步:主窗口的触发逻辑
在主窗口里监听状态变化,当窗口最小化时启动定时器,到时间就弹出提醒:
using System; using System.Windows; namespace ReminderApp { public partial class MainWindow : Window { private System.Windows.Threading.DispatcherTimer _reminderTimer; // 这里可以改成你需要的延迟时间(单位:秒) private const int ReminderDelay = 5; public MainWindow() { InitializeComponent(); StateChanged += OnMainWindowStateChanged; } private void OnMainWindowStateChanged(object sender, EventArgs e) { if (WindowState == WindowState.Minimized) { // 启动定时器,到点触发提醒 _reminderTimer?.Stop(); _reminderTimer = new System.Windows.Threading.DispatcherTimer(); _reminderTimer.Interval = TimeSpan.FromSeconds(ReminderDelay); _reminderTimer.Tick += OnReminderTimerTick; _reminderTimer.Start(); } else { // 主窗口恢复时取消定时器 _reminderTimer?.Stop(); } } private void OnReminderTimerTick(object sender, EventArgs e) { _reminderTimer.Stop(); // 创建提醒窗口,设置居中显示,然后自动关闭 var reminderWindow = new TransparentReminderWindow("该休息一下啦!"); reminderWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen; reminderWindow.ShowAndAutoClose(3); } } }
补充说明(WinForms备选方案)
如果WPF在你的场景里没法用,WinForms的思路差不多:
- 创建一个无边框的Form,设置
Opacity = 0,ShowInTaskbar = false - 用同样的Windows API设置鼠标穿透
- 在Form里放一个Label,设置居中,调整样式
- 主窗口最小化时启动定时器,到时间显示这个Form,之后自动关闭
内容的提问来源于stack exchange,提问作者n0e
相关产品推荐
相关产品推荐

