Реализовать проверку орфографии Word в приложении Windows Form

У меня есть собственное приложение Windows Form, которое я хотел бы использовать для проверки орфографии. У всех установлен Office 2007, поэтому у меня не должно возникнуть проблем, но у меня проблемы с его полноценной работой.

Вот что у меня есть:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Word = Microsoft.Office.Interop.Word;
using System.Reflection;

namespace Refraction.Spelling
{
    public static class SpellCheckers
    {
        public static string CheckSpelling(string text)
        {
            Word.Application app = new Word.Application();
 object nullobj = Missing.Value;
                object template = Missing.Value;
                object newTemplate = Missing.Value;
                object documentType = Missing.Value;
                object visible = true;
                object optional = Missing.Value;
            object savechanges = false;
            Word._Document doc = app.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);

        doc.Words.First.InsertBefore(text);
        Word.ProofreadingErrors errors = doc.SpellingErrors;

        var ecount = errors.Count;
        doc.CheckSpelling(ref optional, ref optional, ref optional, ref optional, 
            ref optional, ref optional, ref optional, ref optional, ref optional, 
            ref optional, ref optional, ref optional);
        object first = 0;
        object last = doc.Characters.Count - 1;
        var results = doc.Range(ref first, ref last).Text;
        doc.Close(ref savechanges, ref nullobj, ref nullobj);
        app.Quit(ref savechanges, ref nullobj, ref nullobj);

        return results;
    }
}

}

Я использую это так:

memDirectionsToAddress.Text = SpellCheckers.CheckSpelling(memDirectionsToAddress.Text);

Теперь это успешно открывает диалоговое окно проверки орфографии из Word и обнаруживает любые слова с ошибками , но я не могу заставить его внести исправления в приложение WinForm.

Кроме того, эта «оболочка» документа Word остается открытой с исправленным текстом. Как мне этого не показать или хотя бы заставить его уйти?

Две вещи:

  • Во-первых, хоть "оболочка" закрывает, то каждый раз мигает. Какие-нибудь решения для этого?
  • Во-вторых, диалоговое окно проверки орфографии не отображается в ТОПе, что я могу настроить, чтобы исправить это?

Спасибо


person Refracted Paladin    schedule 31.08.2009    source источник
comment
Дополнительный вопрос: есть ли причина НЕ делать это СТАТИЧЕСКИМ?   -  person Refracted Paladin    schedule 31.08.2009
comment
Если вы не сделаете его статичным, вы можете сохранить ссылки на конкретный документ и / или слово application. Это поможет вам избежать затрат на запуск нового приложения или документа. (Вы можете сохранить документ открытым, но невидимым, играя со свойством Visible или приложением и всегда запуская новое приложение.)   -  person John Fisher    schedule 31.08.2009
comment
проблема в том, что если я не сделаю app.Close() в конце, оболочка Word останется открытой ...   -  person Refracted Paladin    schedule 31.08.2009
comment
Мне пришлось изменить object visible = true; и добавить app.ShowMe();. Ответ ниже помог мне сориентироваться, поэтому я принял его.   -  person Refracted Paladin    schedule 10.09.2009


Ответы (2)


Следующие шаги будут такими:

  1. Вытяните исправленный текст обратно из документа.
  2. Закройте документ. (Если в Word открыт только один документ, вы можете закрыть или скрыть приложение Word.)
  3. Вернуть исправленный текст вызывающей функции.

Больше информации:

person John Fisher    schedule 31.08.2009
comment
Спасибо, так что он действительно исправляет текст в скрытом слове doc, и тогда мне нужно это схватить. Есть какие-нибудь намеки на то, как я забираю текст обратно? - person Refracted Paladin; 31.08.2009
comment
Используйте объект выбора. Сделайте выделение все, затем зачитайте текст из выделенного. - person John Fisher; 31.08.2009
comment
см. мой комментарий к вопросу для ПОЛНОГО ответа - person Refracted Paladin; 10.09.2009

У меня есть старый скрипт для этого, в котором вызываются все необходимые функции, поэтому для самого слова не требуется ссылка на DLL:

internal class SpellChecker
{
    public SpellChecker()
    {
    }

    public static string Check(string text)
    {
        bool flag;
        string str = text;
        flag = (text == null ? true : !(text != ""));
        bool flag1 = flag;
        if (!flag1)
        {
            Type typeFromProgID = Type.GetTypeFromProgID("Word.Application");
            object obj = Activator.CreateInstance(typeFromProgID);
            object[] objArray = new object[1];
            object obj1 = typeFromProgID.InvokeMember("Documents", BindingFlags.GetProperty, null, obj, null);
            object obj2 = obj1.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, obj1, null);
            object obj3 = obj2.GetType().InvokeMember("ActiveWindow", BindingFlags.GetProperty, null, obj2, null);
            objArray[0] = 0;
            obj3.GetType().InvokeMember("WindowState", BindingFlags.SetProperty, null, obj3, objArray);
            object[] objArray1 = new object[] { -2000, -2000 };
            obj.GetType().InvokeMember("Move", BindingFlags.InvokeMethod, null, obj, objArray1);
            objArray[0] = "Spell Check";
            obj3.GetType().InvokeMember("Caption", BindingFlags.SetProperty, null, obj3, objArray);
            object obj4 = typeFromProgID.InvokeMember("Selection", BindingFlags.GetProperty, null, obj, null);
            objArray[0] = text;
            obj4.GetType().InvokeMember("TypeText", BindingFlags.InvokeMethod, null, obj4, objArray);
            objArray[0] = 6;
            obj4.GetType().InvokeMember("HomeKey", BindingFlags.InvokeMethod, null, obj4, objArray);
            object obj5 = obj2.GetType().InvokeMember("SpellingErrors", BindingFlags.GetProperty, null, obj2, null);
            int num = (int)obj5.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, obj5, null);
            flag1 = num <= 0;
            if (flag1)
            {
                System.Windows.Forms.MessageBox.Show("Spellcheck is correct");
            }
            else
            {
                obj3.GetType().InvokeMember("Activate", BindingFlags.InvokeMethod, null, obj3, null);
                objArray1 = new object[] { -5000, -5000 };
                obj.GetType().InvokeMember("Move", BindingFlags.InvokeMethod, null, obj, objArray1);
                objArray[0] = true;
                obj.GetType().InvokeMember("Visible", BindingFlags.SetProperty, null, obj, objArray);
                obj2.GetType().InvokeMember("CheckSpelling", BindingFlags.InvokeMethod, null, obj2, null);
                objArray[0] = true;
                obj2.GetType().InvokeMember("Saved", BindingFlags.SetProperty, null, obj2, objArray);
                object obj6 = obj2.GetType().InvokeMember("Content", BindingFlags.GetProperty, null, obj2, null);
                str = obj6.GetType().InvokeMember("Text", BindingFlags.GetProperty, null, obj6, null).ToString();
                str = str.Trim();
            }
            flag1 = obj == null;
            if (!flag1)
            {
                objArray[0] = true;
                obj2.GetType().InvokeMember("Saved", BindingFlags.SetProperty, null, obj2, objArray);
                obj.GetType().InvokeMember("Quit", BindingFlags.InvokeMethod, null, obj, null);
            }
        }
        string str1 = str;
        return str1;
    }
}

Просто подайте ему текст, и он вернется с любыми исправлениями, которые вы одобрите.

person Monolithcode    schedule 02.12.2015