【问题标题】:Getting Range coordinates only for Ranges on the screen仅为屏幕上的范围获取范围坐标
【发布时间】:2019-03-19 00:05:59
【问题描述】:

我目前正在使用以下方法在文档中查找Range 的坐标:

private Rectangle GetRangeCoordinates(Window w, Range r)
{
    int left = 0;
    int top = 0;
    int width = 0;
    int height = 0;

    w.GetPoint(out left, out top, out width, out height, r);

    return new Rectangle(left, top, width, height);
}

这非常有效,除非Range 以相当大的距离(相当多的页面)离开屏幕,在这种情况下我得到以下异常:

System.Runtime.InteropServices.COMException (0x800A1066):命令 在 Microsoft.Office.Interop.Word.Window.GetPoint 失败(Int32& ScreenPixelsLeft, Int32& ScreenPixelsTop, Int32& ScreenPixelsWidth, Int32& ScreenPixelsHeight, 对象 obj) 在 [ProjectName].[TaskpaneName].GetRangeCoordinates(Window w, Range r) 在 [...somePath...][TaskpaneName].cs:line 66

有没有办法确定Range 是否在屏幕上,以便我只能在它出现时调用此方法?

【问题讨论】:

  • 要计算所选范围是否在文档上,您需要知道文档的尺寸。紧随其后的是矩形的单击起点。通过屏幕的尺寸和矩形的起点,您可以创建所选范围的阈值。
  • @Innominatum 问题是我不能在(相当大)屏幕外的范围上调用GetPoint,因为我得到一个COMException - 我不能catch
  • 不能在调用方法周围添加catch try块并捕获COMException?
  • 能否提供更详细的 COMException 版本?
  • @Innominatum - 我可以捕捉到异常,我只是想知道是否有更好的方法......

标签: c# ms-word vsto netoffice


【解决方案1】:

我就是这样做的。

我为ApplicationRange 创建了一些扩展方法:

public static class ApplicationExensions
{
    // more (rather than less)
    // does not do headers and footers
    public static Range GetCurrentlyVisibleRange(this Application application)
    {
        try
        {
            Window activeWindow = application.ActiveWindow;
            var left = application.PointsToPixels(activeWindow.Left);
            var top = application.PointsToPixels(activeWindow.Top);
            var width = application.PointsToPixels(activeWindow.Width);
            var height = application.PointsToPixels(activeWindow.Height);
            var usableWidth = application.PointsToPixels(activeWindow.UsableWidth);
            var usableHeight = application.PointsToPixels(activeWindow.UsableHeight);

            var startRangeX = left;// + (width - usableWidth);
            var startRangeY = top;// + (height - usableHeight);

            var endRangeX = startRangeX + width;//usableWidth;
            var endRangeY = startRangeY + height;//usableHeight;

            Range start = (Range) activeWindow.RangeFromPoint((int) startRangeX, (int) startRangeY);
            Range end = (Range) activeWindow.RangeFromPoint((int) endRangeX, (int) endRangeY);

            Range r = application.ActiveDocument.Range(start.Start, end.Start);

            return r;
        }
        catch (COMException)
        {
            return null;
        }
    }
}

public static class RangeExtensions
{
    public static bool Intersects(this Range a, Range b)
    {
        return a.Start <= b.End && b.Start <= a.End;
    }

    public static Rectangle? GetCoordinates(this Range range)
    {
        try
        {
            Application application = range.Application;
            Window window = application.ActiveWindow;

            int left = 0;
            int top = 0;
            int width = 0;
            int height = 0;

            window.GetPoint(out left, out top, out width, out height, range);

            return new Rectangle(left, top, width, height);
        }
        catch (COMException e)
        {
            return null;
        }
    }
}

然后我像这样使用它们:

Range currentlyVisibleRange = application.GetCurrentlyVisibleRange();

if (currentlyVisibleRange.Intersects(rng)){
    var coords = rng.GetCoordinates();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多