-1

I'm trying to integrate word spell checking into a WinForms application. So far, the interop lib has been a severe pain in the rear. After many hours of messing around with it, I finally got the actual spell checking to work. The CheckSpellingOnce as well as the underlying CheckSpelling methods perform as expected, but as soon as I call GetSpellingSuggestions, the application throws a...

Exception thrown: 'System.Runtime.InteropServices.COMException' in ClosedCaption.Spelling.dll Additional information: This command is not available because no document is open.

First idea was that the underlying COM object disconnects from its' respective wrapper because _wordApp is being called from a different thread than it was created. So I tried calling it from within CheckSpelling(), unfortunately with the same results. I've also tried opening and closing the document, adding a new document to the existing application instance, as well as getting the application from the _document object itself (_document.Application.GetSpellingSuggestions).

So what gives?

Additional info: the CheckSpellingOnce method gets called from the UI when a timer event gets fired (once the user stops typing in the RichTextField) - so multiple times - using the same _wordApp object, as I am trying to avoid launching multiple instances of winword.exe.

    /// <summary>
    /// Checks spelling with the text from the provided richtextbox in a new thread.
    /// </summary>
    public void CheckSpellingOnce()
    {
        _checkerThread = new Thread(new ThreadStart(CheckSpelling));
        _checkerThread.Start();
    }

    /// <summary>
    /// Checks the spelling of a richtextbox. Raises an event with the result when done.
    /// </summary>
    private void CheckSpelling()
    {
        if (_shouldBeChecking)
        {
            RaiseStatusChanged(SpellCheckStatus.Working);
            Word.ProofreadingErrors toReturn = null;
            UpdateStringFromTextBox();

            if (!string.IsNullOrEmpty(_fromTextBox))
            {
                _document.Content.Delete();
                _document.Words.First.InsertBefore(_fromTextBox);

                _document.Content.LanguageID = _language; //Must be set specifically here for some f***d reason.

                toReturn = _document.SpellingErrors;

                RaiseSpellingChecked(toReturn);
                RaiseStatusChanged(SpellCheckStatus.Idle);
            }
        }
    }

    public Word.SpellingSuggestions GetSpellingSuggestions(string word)
    {
        //throw new NotImplementedException();
        Word.SpellingSuggestions toReturn = _wordApp.GetSpellingSuggestions(word, _missing, _missing, _missing, _missing, _missing,  _missing);
        return toReturn;
    }

Even with this implementation of GetSpellingSuggestions, it complains at the "toReturn" line, and not at the ones above it...

        public void GetSpellingSuggestions(string word)
    {
        //throw new NotImplementedException();
        var _suggestionThread = new Thread(new ThreadStart(() =>
        {
            _document.Content.Delete();
            _document.Words.First.InsertBefore(word);

            _document.Content.LanguageID = _language;
            Word.SpellingSuggestions toReturn = _wordApp.GetSpellingSuggestions(word, _missing, _missing, _missing, _missing, _missing, _missing);
            Debug.Print(toReturn[0].ToString());
        }));
        _suggestionThread.Start();
    }
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • Did you have a look at [this](http://stackoverflow.com/questions/9718687/spell-checking-in-c-sharp-using-word-interop) SO question? – Jeroen Heier Jul 01 '16 at 06:08
  • @JeroenHeier I have - no joy. – Linas Martusevicius Jul 01 '16 at 06:13
  • The error says _"no document is open"_ so it's doubtful it's a threading issue. Also, COM threading models don't apply here because we're dealing with multiple processes. –  Jul 01 '16 at 06:14
  • Do you need to supply a value for `MainDictionary` as per Jeroen's link? –  Jul 01 '16 at 06:19
  • @MickyD But I've tried opening a new document, opening the same document as a second instance, adding another document and using that one, etc. – Linas Martusevicius Jul 01 '16 at 06:20
  • @MickyD I havent needed to supply a dictionary to get the spelling errors, I assumed the same goes for the spelling suggestions - will check it out. – Linas Martusevicius Jul 01 '16 at 06:21
  • @MickyD from the msdn docs... If you don't specify a main dictionary, Microsoft Word uses the main dictionary that corresponds to the language formatting of Word or of the first word in the range. – Linas Martusevicius Jul 01 '16 at 06:33
  • Ah goodo, wasn't sure. –  Jul 01 '16 at 06:35
  • @MickyD I even tried creating a document on the HDD, opening it via the _wordApp object and checking for spelling suggestions, with the same results. – Linas Martusevicius Jul 01 '16 at 06:39

1 Answers1

0
        /// <summary>
        /// Opens a Word interop lib document.
        /// </summary>
        /// <returns></returns>
        private Word._Document OpenDocument()
        {
            object visible = false;

            _document = _wordApp.Documents.Add(_missing, _missing, _missing, visible);
            return _document;
        }

This was how I opened my document (in-memory).

Setting the visible parameter to 'true' solves the problem - yet keeps the application process running in the background for some reason (as is intended in my case). My theory is that winword.exe stays invisible until a method like Document.CheckSpelling() is called - which actually invokes a Word GUI.

Can provide more code if anyone needs it.

Thanks for the suggestions, Cheers!