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
相关产品推荐
相关产品推荐

