none
CheckSpelling dialog box hidden for windows forms RRS feed

  • Question

  • We are using the following code to use Microsoft Word's spellchecking functionality, but the dialog box for the spell checker does not appear as the top most window. If the calling form is maximized the user does not see the dialog box at all. I have tried all the suggestion I could find on the internet, calling Activate() before calling CheckSpellling, hide all open forms (which I didn't really like as a solution). Nothing seems to work. Someone else suggested to run code in user32.dll to bring the dialog box window to the topmost getting a window handle, but I'm not sure how that would be implemented. Does anyone have this issue or any suggestions? I tried my solutions on the following configs: Vista / Office 2007, Windows 7 / Office 2010.

     

        private void button1_Click(object sender, EventArgs e)
        {
          
          Microsoft.Office.Interop.Word._Application app = new Microsoft.Office.Interop.Word.Application();
    
          int errors = 0;
          if (textBox1.Text.Length > 0)
          {
            app.Visible = false;
    
            object template = Missing.Value;
            object newTemplate = Missing.Value;
            object documentType = Missing.Value;
            object visible = false;
            object optional = null;
    
            Microsoft.Office.Interop.Word._Document doc1 = app.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);
            
            doc1.Words.First.InsertBefore(textBox1.Text);
            Microsoft.Office.Interop.Word.ProofreadingErrors spellErrorsColl = doc1.SpellingErrors;
            errors = spellErrorsColl.Count;
    
            
    
            this.Opacity = 0;
    
            doc1.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);
    
            this.Opacity = 1;
    
            object first = 0;
            object last = doc1.Characters.Count - 1;
            textBox1.Text = doc1.Range(ref first, ref last).Text;
          }
    
          object saveChanges = false;
          object originalFormat = Missing.Value;
          object routeDocument = Missing.Value;
    
          app.Quit(ref saveChanges, ref originalFormat, ref routeDocument);
    
          MessageBox.Show("Check completed!");
    
          this.Activate();
        }  

    Thank you,

    Brad

    Friday, June 24, 2011 5:04 PM

All replies

  • Dear Brade

     

    All what you need concerning the spell checking  or Proofing you can get through these steps

     

    open Microsoft office document

    <upright button of the office>

    <word options>

    <Proofing>

    choose or leave what you want concerning spell checking

     

    Please tell me if it works with you

    Regards

    Mona

    Saturday, June 25, 2011 6:57 PM
  • Hi Mona,

    I don't understand what you are suggesting as the solution to my coding issue?

    Thank you

    BRAD

    Monday, June 27, 2011 4:33 PM
  • Dear Brade

     

    All what you need concerning the spell checking  or Proofing you can get through these steps

     

    open Microsoft office document

    <upright button of the office>

    <word options>

    <Proofing>

    choose or leave what you want concerning spell checking

     

    Please tell me if it works with you

    Regards

    Mona


    Seriously?!? Not only does this not make sense, it has nothing to do with the question.

    --

    Brad, are you saying that in your Windows Forms application, when a user clicks the spell check button, the dialog box is in the background - hidden by the forms - to the user it looks like the application is frozen but it's not, the hidden spell checker dialog is waiting for your input?

    I'm also looking for a solution. It's very inconsistent.

     

    Monday, June 27, 2011 6:22 PM
  • Yes d_e_k,

    That is exactly what is going on. Very annoying for the users.

    Brad

    Monday, June 27, 2011 6:40 PM
  • Hi Brad,

    I tested your code but it works well, the spell check dialog is on the top of the other windows. I also set the WindowState of the form to be Maximized. When checking, the form will disappear and the spelling check dialog pop up at the top of other windows, after finishing the checking, the from show again.

    Then, did I miss something when reproducing your scenario? Below is the code snippet which I tested:

     private void button2_Click(object sender, EventArgs e)
            {
                Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
     
                int errors = 0;
                if (textBox1.Text.Length > 0)
                {
                    app.Visible = false;
     
                    object template = Missing.Value;
                    object newTemplate = Missing.Value;
                    object documentType = Missing.Value;
                    object visible = false;
                    object optional = null;
     
                    Microsoft.Office.Interop.Word.Document doc1 = app.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);
     
                    doc1.Words.First.InsertBefore(textBox1.Text);
                    Microsoft.Office.Interop.Word.ProofreadingErrors spellErrorsColl = doc1.SpellingErrors;
                    errors = spellErrorsColl.Count;
     
     
     
                    this.Opacity = 0;
     
                    doc1.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);
     
                    this.Opacity = 1;
     
                    object first = 0;
                    object last = doc1.Characters.Count - 1;
                    textBox1.Text = doc1.Range(ref first, ref last).Text;
                }
     
                object saveChanges = false;
                object originalFormat = Missing.Value;
                object routeDocument = Missing.Value;
     
                app.Quit(ref saveChanges, ref originalFormat, ref routeDocument);
     
                MessageBox.Show("Check completed!");
     
                this.Activate();
     
            }

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.



    Wednesday, June 29, 2011 9:57 AM
  • Hi Bruce,

    Thank you for your response. If you want I can setup a remote control session so that you can see this in action.

    These are the steps are use to reproduce the problem:

    1. start my test application, my initial form is a switchboard like form (let's call it main form) with a single button on it to open my test form with the spellchecking textbox and spellcheck button

    2. I then click the button on my main form to load the test form

    3. I then click the spell check button

    4. my spell check form disappears and the dialog box is behind the main form.

    OR

    2. I maximize the main form

    3. I then click the button on my main form to load the test form

    4. I then click the spell check button

    5. my test form disappears and the main form is shown, but I cannot see the spellchecker dialog box.

    Try these steps and see if you can reproduce the issue.

    P.S. I also have MS Word and Excel running in a maximized state also.

    Wednesday, June 29, 2011 12:18 PM
  • Hi Brad,

    I have reproduced your problem on a high cofiguration machine but on a low configuration the scenarion can't be reproduced.

    Finally, I found the root cause about the problem, if we want to make the spelling check form in the front, we should firstly wait for the test form show in the front , only in this way the the spelling check form can base on the test form and then show in the top.

    In lower configuration machine, after clicking button, it has enough time to let the test form show as in the foreground window, while in higher configuration machine the code runs faster than showing the test form which directly cause the spelling check form unable to show in the foreground. Hope this can explain the scenario and you can figure out the reason.

    As for this problem, I figured out a workaround through waiting for the test form to be the foreground window. The method is to use while statement to detect whether the current foreground window's handler is equal to test form's handler. After the test form become the foreground window, then execute the next code. Below is the code snippet for you to reference:

    [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();
     
        private void button2_Click(object sender, EventArgs e)
        {
          Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
     
          int errors = 0;
          if (textBox1.Text.Length > 0)
          {
            app.Visible = false;
     
            object template = Missing.Value;
            object newTemplate = Missing.Value;
            object documentType = Missing.Value;
            object visible = false;
            object optional = null;
     
            Microsoft.Office.Interop.Word.Document doc1 = app.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);
     
            doc1.Words.First.InsertBefore(textBox1.Text);
            Microsoft.Office.Interop.Word.ProofreadingErrors spellErrorsColl = doc1.SpellingErrors;
            errors = spellErrorsColl.Count;
            this.Opacity = 0;
     
            // get test form's handler
            IntPtr hwnd = this.Handle;
            // wait until the test form is the foreground window
            while(true)
            {
              if (GetForegroundWindow() == hwnd)
                break;
            }
     
            doc1.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);        
              
            this.Opacity = 1;
            object first = 0;
            object last = doc1.Characters.Count - 1;
            textBox1.Text = doc1.Range(ref first, ref last).Text;
          }
     
          object saveChanges = false;
          object originalFormat = Missing.Value;
          object routeDocument = Missing.Value;
     
          app.Quit(ref saveChanges, ref originalFormat, ref routeDocument);
     
          MessageBox.Show("Check completed!");
     
          this.Activate();
     
        }

    You can try to add the while statment and P-Invoke method in your code. Hope this can resovle you problem, if anything is unclear, feel free to let me know.
    Wish you a nice day.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, June 30, 2011 11:41 AM
  • Hi Bruce,

    the code you supplied works sometimes and then does work if I have the following state:

    - initial application form maximized

    - second form opened and maximized

    - click spell check button

    - second form disappears

    - intial form displays, dialog box hidden

     

    If forgot to mention that the this.Opacity = 0; and this.Opacity = 1; where only there to try as a workaround to the initial problem. So please remove this from your tests.

    Thanks again for the help!

    P.S. is there anyway to get the handle of the spellchecker dialog box so that I can hide or display it before calling the doc1.CheckSpelling ??

     

    Thank you,

    Brad

    Thursday, June 30, 2011 12:07 PM
  • Hi Bard,

    >>is there anyway to get the handle of the spellchecker dialog box so that I can hide or display it before calling the doc1.CheckSpelling ??

    We can't get the handle of the spellchecker from the UI thread. We shoud create a new thread and detect to get the handle of hte spelling check dialog, I use the following code:

     [DllImport("User32.dll")]
            public static extern Int32 SetForegroundWindow(int hWnd);
     
            [DllImport("user32.dll")]
            public static extern int FindWindow(string lpClassName, int nptWindowName);
     
            private void BringToFront(string className, int nptCaptionName)
            {
                SetForegroundWindow(FindWindow(className, nptCaptionName));
            }
     
            [DllImport("user32.dll")]
            private static extern IntPtr GetForegroundWindow();
     
            private void button2_Click(object sender, EventArgs e)
            {
                Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
     
                int errors = 0;
                if (textBox1.Text.Length > 0)
                {
                    app.Visible = false;
     
                    object template = Missing.Value;
                    object newTemplate = Missing.Value;
                    object documentType = Missing.Value;
                    object visible = false;
                    object optional = null;
     
                    Microsoft.Office.Interop.Word.Document doc1 = 
                        app.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);
     
                    doc1.Words.First.InsertBefore(textBox1.Text);
                    Microsoft.Office.Interop.Word.ProofreadingErrors spellErrorsColl = doc1.SpellingErrors;
                    errors = spellErrorsColl.Count;
                    this.Opacity = 0;
     
                   // // get test form's handler
                   // IntPtr hwnd = this.Handle;
                   // // wait until the test form is the foreground window
                   // while (true)
                   // {
                   //     if (GetForegroundWindow() == hwnd)
                   //         break;
                   // }
                   //// Thread.Sleep(2000);
     
                    // create a new thread to get the spelling check dialog
                    Thread t = new Thread(new ThreadStart(GetSpellcheckingHandle));
                    t.Start();
     
                    doc1.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);                
                       
                    this.Opacity = 1;
                    object first = 0;
                    object last = doc1.Characters.Count - 1;
                    textBox1.Text = doc1.Range(ref first, ref last).Text;
                }
     
                object saveChanges = false;
                object originalFormat = Missing.Value;
                object routeDocument = Missing.Value;
     
                app.Quit(ref saveChanges, ref originalFormat, ref routeDocument);
     
                MessageBox.Show("Check completed!");
     
                this.Activate();
     
            }
     
            /// <summary>
            /// get the spelling check handle
            /// </summary>
            public void GetSpellcheckingHandle()
            {
               int i =  FindWindow("bosa_sdm_msword",(int)IntPtr.Zero);
               while (i != 0)
               {
                   // bring the spelling check dialog to the front.
                   BringToFront("bosa_sdm_msword", (int)IntPtr.Zero);
               }
     
            }

    Hope your problem can be resolve by this approach.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, July 1, 2011 8:35 AM
  • Hi Bruce,

    I tried your code and it didn't work. The spellchecker dialog box was appearing sometimes in the foreground and sometimes it was in the background. So I tried an xcopy of the test app on one of our user's computers (Vista Business) and it didn't work at all. It was always behind the calling form.

    Do you need a demonstration of how it's working on my computer?

    What else can we try?

    Thank you,

    Brad

    Monday, July 4, 2011 11:33 AM
  • Hi Brad,

    I am not very sure why it does not work on your side. I run the program as the following process:

    1. initial application form maximized

    2.second form opened and maximized

    3.click spell check button

    4.second form disappears

    5.then the spelling check dialog was bing to the front.

    I can get the handle of the spelling check dialog, and then make it show in the front. Can you get the handle of the spelling check dialog? You can try to debug it to see whether you can get the spelling check dialog.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Tuesday, July 5, 2011 8:54 AM
  • Hi Bruce,

    Good suggestion. I put a break point on the BringToFront("bosa... code line and it was inconsistent on finding the window.

    Sometimes it didn't find it and others it did.

    Ahhhhhh.....

    I'm thinking a 3rd party spellchecking product might be the way to go. It's a shame when all users have Microsoft Word available on their computers. Is there any other way to use the spellchecking features of Word?

    Brad

     

     

    Thursday, July 7, 2011 6:35 PM
  • Hi Brad,

    As far as I know, it can only be used in this way via C# or VB.Net. I will do further research about this problem.

    Thank you for your understanding and wish you a nice day.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, July 8, 2011 8:46 AM
  •   

    /// <summary>/// get the spelling check handle/// </summary>

    public void GetSpellcheckingHandle()         {            int i =  FindWindow("bosa_sdm_msword",(int)IntPtr.Zero);            while (i != 0)            {                // bring the spelling check dialog to the front.                BringToFront("bosa_sdm_msword", (int)IntPtr.Zero);            }         }

    is problematic if the Window doesn't appear quickly enough. One way to mitigate this is to change the code to:

    private static void GetSpellcheckingHandle(){
              int checkerWindow = 0;
              do{
                  checkerWindow =FindWindow("bosa_sdm_msword", (int)IntPtr.Zero);
                  System.Threading.Thread.Sleep(50);
              }while ((checkerWindow == 0) && keepCheckerAlive);
              if ((checkerWindow != 0) && keepCheckerAlive){
                  // bring the spelling check dialog to the front.              
                  BringToFront("bosa_sdm_msword", (int)IntPtr.Zero);          
              }
    }          
    and you would need to declare both keepCheckerAlive and initialize it to true before you do your spell-checking and to false after you kill the app (to prevent the thread from running endlessly)
                        
    Friday, July 18, 2014 5:53 PM