我正在尝试在我的 winform 中获取鼠标的坐标。
myMousePosition = myForm.PointToClient(Control.MousePosition)
这有效,但它会生成垃圾(堆分配)。由于我经常调用此方法,因此这是一个问题。
myMousePosition.X = Control.MousePosition.X - myForm.Location.X;
myMousePosition.Y = Control.MousePosition.Y - myForm.Location.Y;
这是行不通的,因为还需要考虑标题栏。有什么建议吗?
编辑:更多信息。VS2010性能分析向导显示,当我使用PointToClient方法时,会生成数千个类型为draw.point的实例。问题是,我没有在我的 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);
}
}
这是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()
,但这可能是可取的,也可能是不可取的。
它不会产生垃圾,因为您使用的是值类型的struct
。没有收集压力,即使会是一个问题吗?看起来不像是游戏的瓶颈。