仅为屏幕上的范围获取范围坐标
Getting Range coordinates only for Ranges on the screen
我目前正在使用以下方法在文档中查找 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): Command
failed at Microsoft.Office.Interop.Word.Window.GetPoint(Int32&
ScreenPixelsLeft, Int32& ScreenPixelsTop, Int32& ScreenPixelsWidth,
Int32& ScreenPixelsHeight, Object obj) at
[ProjectName].[TaskpaneName].GetRangeCoordinates(Window w, Range r)
in
[...somePath...][TaskpaneName].cs:line
66
有没有办法确定 Range
是否在屏幕上,以便我只能在它出现时调用此方法?
我就是这样做的。
我为 Application
和 Range
创建了一些扩展方法:
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();
}
我目前正在使用以下方法在文档中查找 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): Command failed at Microsoft.Office.Interop.Word.Window.GetPoint(Int32& ScreenPixelsLeft, Int32& ScreenPixelsTop, Int32& ScreenPixelsWidth, Int32& ScreenPixelsHeight, Object obj) at [ProjectName].[TaskpaneName].GetRangeCoordinates(Window w, Range r) in [...somePath...][TaskpaneName].cs:line 66
有没有办法确定 Range
是否在屏幕上,以便我只能在它出现时调用此方法?
我就是这样做的。
我为 Application
和 Range
创建了一些扩展方法:
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();
}