You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#实现跟随鼠标移动的稳定屏幕绘制字符串?

解决C#绘制跟随鼠标移动的字符串时的重复绘制与消失问题

我尝试用C#在屏幕上绘制跟随鼠标光标移动的字符串,字符串内容和位置随鼠标移动变化。现在遇到的问题是:鼠标移动时,字符串会在多个位置重复绘制,而且会在不到1秒内明显消失。想知道有没有方法实现稳定的绘制效果?目标效果是类似跟随鼠标的悬浮提示,字符串稳定显示且仅在当前鼠标位置更新。

用户提供的部分代码:

System.Drawing.Point drawPoint = new System.Drawing.Point(mouse_click_x, mouse_click_y);
Graphics g = Graphics.FromHdc(desktopPtr);
g.DrawString(oState1.SmartTagText(oPath), drawFont, drawBrush, drawPoint);

问题根源

直接通过桌面HDC绘制的内容属于临时绘制,系统刷新桌面(比如窗口移动、屏幕重绘)时就会被清除;而且鼠标移动时每次绘制都不清理之前的内容,导致重复残留。

稳定实现的两种方案

方案1:使用无边框透明窗体承载文本(推荐)

这是最可靠的方式,用一个始终在最顶层的透明窗体显示文本,跟随鼠标移动:

  1. 创建透明提示窗体:
    public class TextTooltipForm : Form
    {
        public TextTooltipForm()
        {
            FormBorderStyle = FormBorderStyle.None;
            ShowInTaskbar = false;
            TopMost = true;
            BackColor = Color.Magenta; // 用特殊颜色作为透明键
            TransparencyKey = Color.Magenta;
            DoubleBuffered = true; // 消除闪烁
        }
    
        public void UpdateTextAndPosition(string text, Point mousePos)
        {
            Text = text;
            // 适配文本大小调整窗体尺寸
            using (var g = CreateGraphics())
            {
                SizeF textSize = g.MeasureString(text, Font);
                Size = new Size((int)textSize.Width + 8, (int)textSize.Height + 4);
            }
            // 让文本在鼠标右下方显示,避免遮挡光标
            Location = new Point(mousePos.X + 10, mousePos.Y + 10);
            if (!Visible) Show();
        }
    }
    
  2. 在鼠标移动事件中更新窗体:
    private TextTooltipForm _tooltipForm;
    
    private void OnMouseMove(object sender, MouseEventArgs e)
    {
        _tooltipForm ??= new TextTooltipForm();
        
        string displayText = oState1.SmartTagText(oPath);
        _tooltipForm.UpdateTextAndPosition(displayText, e.Location);
    }
    

方案2:Hook桌面重绘,持续刷新绘制内容

如果不想用窗体,可通过定时刷新或监听桌面重绘事件,每次重新绘制文本(但易闪烁):

  1. 定时刷新实现:
    private Timer _drawTimer;
    private Rectangle _lastDrawRect = Rectangle.Empty;
    
    private void InitializeDrawing()
    {
        _drawTimer = new Timer { Interval = 16 }; // 60帧/秒
        _drawTimer.Tick += (s, e) => RedrawText();
        _drawTimer.Start();
    }
    
    private void RedrawText()
    {
        Point mousePos = Cursor.Position;
        IntPtr desktopDC = GetDC(IntPtr.Zero);
        using (Graphics g = Graphics.FromHdc(desktopDC))
        {
            // 清除上一次绘制的区域
            if (_lastDrawRect != Rectangle.Empty)
            {
                g.FillRectangle(new SolidBrush(SystemColors.Desktop), _lastDrawRect);
            }
            // 绘制新文本
            string text = oState1.SmartTagText(oPath);
            SizeF textSize = g.MeasureString(text, drawFont);
            _lastDrawRect = new Rectangle(mousePos.X, mousePos.Y, (int)textSize.Width, (int)textSize.Height);
            g.DrawString(text, drawFont, drawBrush, mousePos);
        }
        ReleaseDC(IntPtr.Zero, desktopDC);
    }
    
    // 引入Win32 API
    [DllImport("user32.dll")]
    private static extern IntPtr GetDC(IntPtr hWnd);
    [DllImport("user32.dll")]
    private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
    

内容的提问来源于stack exchange,提问作者Sameh_Saady

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:23:13