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

C#如何从PreFilterMessage(ref Message)方法获取坐标传给Draw方法

实现方案

核心问题是你现在的xPos、yPos是PreFilterMessage里的局部变量,作用域仅限当前判断分支内,Draw方法无法直接访问,按下面步骤修改即可,逻辑简单不容易出问题:

  • 首先在当前窗体类的方法外,定义类级别的字段存储坐标,整个类的所有方法都能访问这些值,你用的圆形宽高也可以放在这里统一管理:
// 存储鼠标点击的客户区坐标
private int clickX = 0;
private int clickY = 0;
// 圆形的宽高参数,可自行修改默认值
private float circleWidth = 10f;
private float circleHeight = 10f;
  • 精简修改PreFilterMessage方法,去掉原来冗余的重复给cursor_pos.Text赋值的代码,拿到坐标后直接给全局字段赋值,最后调用Draw方法即可:
public bool PreFilterMessage(ref Message msg)
{
    if (msg.Msg == 0x202) // 监听鼠标左键抬起消息
    {
        Point clickPos = Point.Empty;
        // 跨线程访问UI控件只需要一次Invoke即可,不用重复调用
        cursor_pos.Invoke(new MethodInvoker(delegate { 
            clickPos = this.PointToClient(Cursor.Position);
            clickX = (int)clickPos.X;
            clickY = (int)clickPos.Y;
            cursor_pos.Text = $"x = {clickX}, y = {clickY}";
        }));
        // 坐标存储完成后直接调用绘制方法
        Draw();
    }
    return false;
}
  • 修改Draw方法,直接调用全局存储的坐标参数即可:
public void Draw()
{
    RectangleF circle = new RectangleF(clickX, clickY, circleWidth, circleHeight);
    // 后续接你自己的绘制逻辑即可,示例GDI+绘制代码参考:
    using (Graphics g = this.CreateGraphics())
    using (Pen drawPen = new Pen(Color.Red, 2))
    {
        g.DrawEllipse(drawPen, circle);
    }
}

踩坑提示:如果需要绘制的图形在窗体拖动、最小化恢复后不消失,不要直接用CreateGraphics绘制,需要把圆形的参数存在集合里,在窗体的Paint事件触发时统一重绘所有图形。

内容的提问来源于stack exchange,提问作者J.COKS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:45:38