2

我正在尝试在我的 winform 中获取鼠标的坐标。

  myMousePosition = myForm.PointToClient(Control.MousePosition)

这可行,但会产生垃圾(堆分配)。因为我经常调用这个方法,所以这是一个问题。

  myMousePosition.X = Control.MousePosition.X - myForm.Location.X;
  myMousePosition.Y = Control.MousePosition.Y - myForm.Location.Y;

这不起作用,因为还需要考虑标题栏。有什么建议么?

编辑:更多信息。VS2010 分析向导说,当我使用 PointToClient 方法时,会生成数千个绘图类型的实例。问题是,我没有在我的 Update 方法中创建一个新变量,那么这些实例来自哪里?

public sealed class InputManager
{
  private System.Drawing.Point  mPos;

  public InputManager() 
  {
    mPos = new System.Drawing.Point(0, 0);
  }
  //////////////////////////////////////////////////////////////////////////

  public void Update()
  {
    mPos = myForm.PointToClient(Control.MousePosition);
  }
}
4

2 回答 2

1

它不会产生垃圾,因为您使用struct的是值类型。没有收集压力,即使这是一个问题?看起来不像是游戏的瓶颈。

于 2012-12-06T18:52:48.627 回答
1

这是代码PointToClient()

public Point PointToClient(Point p) { 
    return PointToClientInternal(p);
} 

internal Point PointToClientInternal(Point p) { 
    NativeMethods.POINT point = new NativeMethods.POINT(p.X, p.Y); 
    UnsafeNativeMethods.MapWindowPoints(NativeMethods.NullHandleRef, new HandleRef(this, Handle), point, 1);
    return new Point(point.x, point.y); 
}

PointToClient()调用PointToClientInternal(),它创建一个新的NativeMethods.POINT.

这是NativeMethods.POINT

[StructLayout(LayoutKind.Sequential)] 
public class POINT {
    public int x; 
    public int y; 

    public POINT() { 
    }

    public POINT(int x, int y) {
        this.x = x; 
        this.y = y;
    } 
}

所以我认为这就是你的堆分配的来源。调用PointToClient()会导致实例化一个新NativeMethods.POINT对象(注意这是一个类,而不是一个结构)。

如果这是您的应用程序中的问题,我建议仅PointToClient()在您实际需要该值时调用。您也可能会考虑MapWindowPoints()直接使用,但这可能是可取的,也可能不是可取的。

于 2012-12-07T14:22:50.450 回答