Hi,
I finally found a solution in this blog post.
I'm pasting my code here for those who might be interested:
public static class AutoCadCoordinateHelper
{
// https://adndevblog.typepad.com/autocad/2013/02/how-to-get-the-mouse-cursor-coordinates-in-ucs.html
public static Point2d GetMousePositionInUcs(int screenX, int screenY)
{
var doc = Application.DocumentManager.MdiActiveDocument;
var ed = doc.Editor;
var pointInScreen = new Point(screenX, screenY);
// Get point in DCS
var pointInDcs = ed.PointToWorld(pointInScreen);
// Convert to UCS
var pointInUcs = AutoCadCoordinateTransformer.Transform(
pointInDcs,
AutoCadCoordinateTransformer.CoordinateSystem.Display,
AutoCadCoordinateTransformer.CoordinateSystem.User);
// Project to UCS XY plane
var view = ed.GetCurrentView();
var projectedPoint = view.ProjectToUcsXYPlane(pointInUcs);
return new Point2d(projectedPoint.X, projectedPoint.Y);
}
}
public static class AutoCadCoordinateTransformer
{
private const int RTSHORT = 5003;
private const int RTNORM = 5100;
public enum CoordinateSystem
{
World = 0,
User = 1,
Display = 2,
PaperSpace = 3
}
[DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int acedTrans(
double[] point,
IntPtr fromRb,
IntPtr toRb,
int disp,
double[] result
);
public static Point3d Transform(Point3d point, CoordinateSystem from, CoordinateSystem to)
{
var result = new double[3];
using var rbFrom = new ResultBuffer(new TypedValue(RTSHORT, (int)from));
using var rbTo = new ResultBuffer(new TypedValue(RTSHORT, (int)to));
var status = acedTrans(point.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, result);
if (status != RTNORM)
throw new InvalidOperationException("Coordinate transformation failed.");
return new Point3d(result);
}
}
public static class ViewExtensions
{
public static Point3d ProjectToUcsXYPlane(this ViewTableRecord view, Point3d pointInUcs)
{
if (view == null)
throw new ArgumentNullException(nameof(view));
var ucsPlane = new Plane(Point3d.Origin, Vector3d.ZAxis);
var direction = view.ViewDirection.GetNormal();
return pointInUcs.Project(ucsPlane, direction);
}
}
Note that PointToWorld adds a step to take into account the screen scale before calling acedCoordFromPixelToWorld.
Rather than calling acedtrans I saw this post but didn't test it.
Finally, I don't know if I could come up with anything simpler.