我正在尝试使用Microsoft.Office.Interop.Word获取C#中MS Word窗口中显示的文本。 请注意,这不是整个文件甚至是页面;只是用户看到的相同内容。
以下代码似乎适用于简单文档:
Application word = new Application();
word.Visible = true;
object fileName = @"example.docx";
word.Documents.Add(ref fileName, Type.Missing, Type.Missing, true);
Rect rect = AutomationElement.FocusedElement.Current.BoundingRectangle;
Range r1 = word.ActiveWindow.RangeFromPoint((int)rect.Left, (int)rect.Top);
Range r2 = word.ActiveWindow.RangeFromPoint((int)rect.Left + (int)rect.Width, (int)rect.Top + (int)rect.Height);
r1.End = r2.Start;
Console.WriteLine(r1.Text.Replace("\r", "\r\n"));
但是,当文档包含其他结构(如标题)时,只返回部分文本。
那么,实现这一目标的正确方法是什么?
非常感谢!
更新代码
Rect rect = AutomationElement.FocusedElement.Current.BoundingRectangle;
foreach (Range r in word.ActiveDocument.StoryRanges) {
int left = 0, top = 0, width = 0, height = 0;
try {
try {
word.ActiveWindow.GetPoint(out left, out top, out width, out height, r);
} catch {
left = (int)rect.Left;
top = (int)rect.Top;
width = (int)rect.Width;
height = (int)rect.Height;
}
Rect newRect = new Rect(left, top, width, height);
Rect inter;
if ((inter = Rect.Intersect(rect, newRect)) != Rect.Empty) {
Range r1 = word.ActiveWindow.RangeFromPoint((int)inter.Left, (int)inter.Top);
Range r2 = word.ActiveWindow.RangeFromPoint((int)inter.Right, (int)inter.Bottom);
r.SetRange(r1.Start, r2.Start);
Console.WriteLine(r.Text.Replace("\r", "\r\n"));
}
} catch { }
}
答案 0 :(得分:3)
可能存在一些问题:
enumerator = r1.StoryRanges.GetEnumerator();
{
while (enumerator.MoveNext()
{
Range current = (Range) enumerator.Current;
}
}
答案 1 :(得分:1)
您可能会看到跨页面元素选择范围的副作用 在大多数情况下,如果将光标移动到屏幕的左上角,直到屏幕的右下角,它将只选择主体文本(没有页眉或页脚)。此外,如果文档有列,并且这些列从屏幕开始或结束,那么当您从第一列中选择时,即使文本不在屏幕上,也会选择文本到最后一列。
据我所知,除非您愿意忽略不一致性,或者想要专门处理所有用例(图像,列,表格等),否则没有简单的方法来实现您的目标。
如果您可以告诉我们您要做什么,那么我们可以提供替代方案,否则请将答案标记为正确。
答案 2 :(得分:1)
上述讨论非常具体针对Office版本。
我认为我的代码适用于所有情况。
IntPtr h = (IntPtr)Globals.ThisAddIn.Application.ActiveWindow.Hwnd;
String strText = NativeInvoker.GetWindowText(h);
if (strText != null && strText.StartsWith(Globals.ThisAddIn.Application.ActiveWindow.Caption))
{
h = NativeInvoker.FindWindowEx(h, IntPtr.Zero, "_WwF", "");
h = NativeInvoker.FindWindowEx(h, IntPtr.Zero, "_WwB", null);
h = NativeInvoker.FindWindowEx(h, IntPtr.Zero, "_WwG", null);
Rect t;
if (NativeInvoker.GetWindowRect(h, out t))
{
Range r1 = (Range)Globals.ThisAddIn.Application.ActiveWindow.RangeFromPoint((int)t.Left, (int)t.Top);
Range r2 = (Range)Globals.ThisAddIn.Application.ActiveWindow.RangeFromPoint((int)t.Right, (int)t.Bottom);
Range r = Globals.ThisAddIn.Application.ActiveDocument.Range(r1.Start, r2.Start);
....
您可以从任何软件中引用NativeInvoker类内容。
我希望我的代码可以帮助您完成工作。
响度单位。
答案 3 :(得分:0)
我在Word加载项中有类似的要求。
尝试下面的代码,它对我有用。
IntPtr h = Process.GetCurrentProcess().MainWindowHandle;
h = NativeMethodsActiveScreen.FindWindowExW(h, new IntPtr(0), "_WwF", "");
h = NativeMethodsActiveScreen.FindWindowExW(h, new IntPtr(0), "_WwB", null);
h = NativeMethodsActiveScreen.FindWindowExW(h, new IntPtr(0), "_WwG", null);
NativeMethodsActiveScreen.tagRECT t = new NativeMethodsActiveScreen.tagRECT();
NativeMethodsActiveScreen.GetWindowRect(h, out t);
var Aw = RibbonHelper.SharedApplicationInstance.ActiveWindow;
Range fullDocRange = RibbonHelper.SharedApplicationInstance.ActiveDocument.Range();
Range r1 = RibbonHelper.SharedApplicationInstance.ActiveWindow.RangeFromPoint(t.left, t.top);
Range r2 = RibbonHelper.SharedApplicationInstance.ActiveWindow.RangeFromPoint(t.right, t.bottom);
Range r = RibbonHelper.SharedApplicationInstance.ActiveDocument.Range(r1.Start, r2.Start);
如果有帮助,请将答案标记为有帮助。
谢谢