none
Hovering mouse over table of contents in Word stops timer in add-in RRS feed

  • Question

  • I developing shimmed COM add-in for Word and encoutered very strange problem.

    I use a WinFoms timer to be able to do some background work in Word (using same message queue).

    But when I move mouse over table of contents (it become highlighted), timer events don't raised anymore. When I remove mouse from it, events raised again.

    If I move mouse over one of the items in table of contents - even animated gif on WinForm's control stops. In table of contents area outside items - only timer stops, but animation continue to work.

    It seems that hovering cursor over table of contents stops word message queue somehow...

    Is there anything I can do with it?

    I am thinking about moving all code in separate thread, but in this case I will need to handle cross-thread COM-calls issues. And I still have to create Taskpane in the same thread as Word...

    • Edited by Nightblade Monday, January 23, 2012 1:38 PM
    Monday, January 23, 2012 1:37 PM

All replies

  • Hello,

    In an Office add-in, moving code to a thread makes sense only if the code doesn't access the object model of the host application.

    If System.Windows.Form.Timer stops producing events, this means the main thread is busy and Word doesn't (cannot) handle the message queue at this moment. But I cannot reproduce this with a test Add-in Express add-in in Word 2010.


    Regards from Belarus (GMT + 3),

    Andrei Smolin
    Add-in Express Team Leader

    Please mark answers and useful posts to help other developers use the forums efficiently.
    Monday, January 23, 2012 2:56 PM
  • Thanks for the answer!

    I thought about using Add-in express, but trying to work without additional components (even VSTO) to simplify deployment and get more control. But maybe I will try it.

    There is a way to acces object model even from another thread. 

    http://blogs.msdn.com/b/andreww/archive/2008/11/19/implementing-imessagefilter-in-an-office-add-in.aspx

    But I can't use it due to architecture of my add-in. I need to be sure that text didn't change when I work with it. That's why I use timer which Tick event works in the same thread with word. BTW, some of the Word object model calls make something like Application.DoEvents (welcome to hell of race errors without threads). But I solved this with separate methods for such calls in their own timer ticks.

    I understand that Word don't handle message queue, but I want to know why and what can I do with it.

    Here is example that reproduce this problem. You need to put TableOfContentsTest.docx on drive C: or change path in Word project properties.

    https://skydrive.live.com/redir.aspx?cid=1022c9e215bae9cf&resid=1022C9E215BAE9CF!123&parid=root

     



    • Edited by Nightblade Tuesday, January 24, 2012 8:41 AM
    Tuesday, January 24, 2012 8:32 AM
    • Edited by Nightblade Tuesday, January 24, 2012 8:41 AM
    Tuesday, January 24, 2012 8:40 AM
  • I posted same problem in Word developer forum, but it also reproduced in VSTO2010.

     

    I use a WinFoms timer to be able to do some background work in Word (using same message queue).

    But when I move mouse over table of contents (it become highlighted), timer events don't raised anymore. When I remove mouse from it, events raised again.

    If I move mouse over one of the items in table of contents - even animated gif on WinForm's control stops. In table of contents area outside items - only timer stops, but animation continue to work.

    It seems that hovering cursor over table of contents stops word message queue somehow...

    Is there anything I can do with it?

    I am thinking about moving all code in separate thread, but in this case I will need to handle cross-thread COM-calls issues. And I still have to create Taskpane in the same thread as Word...

    Here is example that allow to reproduce this bug:

    https://skydrive.live.com/redir.aspx?cid=1022c9e215bae9cf&resid=1022C9E215BAE9CF!123&parid=root

    File: TableOfContentsBugVSTO.zip

    It contains TableOfContentsTest.docx


    Tuesday, January 24, 2012 8:45 AM
  • Tuesday, January 24, 2012 12:26 PM
    Moderator
  • Hi Nightblade,

    I am afraid you have to start a new thread to resolve the problem:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;
    using Word = Microsoft.Office.Interop.Word;
    using Office = Microsoft.Office.Core;
    using Microsoft.Office.Tools.Word;
    using System.Threading;
    using System.Windows.Forms;
     
    namespace TableOfContentsBugVSTO
    {
        public partial class ThisAddIn
        {
     
            Form1 _form;
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                Thread t = new Thread(ShowFromAndOutput);
                t.Start();
            }
            void ShowFromAndOutput()
            {
                _form = new Form1();
                _form.ShowDialog();
            }
            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
            {
                _form.Close();
            }
     
            #region VSTO generated code
     
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InternalStartup()
            {
                this.Startup += new System.EventHandler(ThisAddIn_Startup);
                this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
            }
            
            #endregion
        }
    }
    

    This can work well on my side. Hope this can help you and just feel free to follow up after you have tried.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Thursday, January 26, 2012 7:34 AM
  • I thought about using threads, but there is one problem. I am using ActiveX to put controls on Word Taskpane. I can't create it from thread other than main Word thread (or there is some way to do this?). So even if I can access Word object model from separate thread (I doubt it will respond if message queue processing is suspended), I still can't report progress to my UI created in main thread and working with same message queue.

    The only way I see by now - is to create monitoring thread which detect when message queue get suspended and try to select something in document to remove focus from table of contents. If this won't work - show window to user indicating that work of add-in suspended due another "feature" of Word...

    Thursday, January 26, 2012 8:41 AM
  • Nightblade, I will help you involve other experts to help you. Please wait to see whether they can give you some suggestions or hints. There might be some delay about the response. Appreciate your patience.
    Best Regards,
    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Friday, January 27, 2012 3:20 AM
  • Hello Nightblade,

    Thank you for sharing the VSTO version of your problem. I downloaded it, built the project without a problem, added an setup to the project, rebuilt and ran the add-in. The Form loaded and the timer shwing in the text box showed the time. I opened the specific test file and the timer continued to run. When I mouseover’ed the TOC the timer continued to run.

    I’m using Visual Studio 2010, Word 2010 on Windows 7

    In that environment I did not experience the problem.

    Content that might help you to relate your experience to Windows design and behavior is in the following article.

    31747    INFO: Changing the Mouse Cursor for a Window
    http://support.microsoft.com/default.aspx?scid=kb;EN-US;31747

    Windows sends the WM_SETCURSOR message any time the mouse cursor moves on the screen. Normally, Windows sends the message to the window "under" the mouse cursor. However, if a window sets the mouse capture, using the SetCapture function, that window receives all mouse messages, without regard to the position of the mouse cursor.

    When an application calls SetCursor, the mouse cursor changes to reflect the cursor specified in the call. The cursor retains that shape until SetCursor is called again, either explicitly by the application, by the DefWindowProc function, or by another application.

    Because Windows is a nonpreemptive multitasking environment, no other application will gain control of the processor until the application that has the processor releases it. If the application calls one of a number of Windows functions, it can potentially lose control of the processor. For a list of Windows functions that can cause control of the processor to pass between applications, search on the following words in the Microsoft Knowledge Base:

    prod(winsdk) and nonpreemptive and multitasking

     

    Regards,
    Chris Jensen
    Senior Technical Support Lead

     


    Chris Jensen
    Tuesday, January 31, 2012 6:25 PM
    Moderator
  • Thanks for answer! But I can reproduce this problem on my machine (Windows 7, Word 2010 sp1 rus, VS2010) and on test machine with Word 2010 (eng).

    I forgot to mention, that text in table of contents should not be selected. It should show blue outline around table of contents when you hover it.

    Here is the video:

    https://skydrive.live.com/redir.aspx?cid=1022c9e215bae9cf&resid=1022C9E215BAE9CF!124&parid=1022C9E215BAE9CF!111

    I tried to use separate thread which monitors suspend of timer events. It works and even allow to access Word object model, and if I select some range there, it helps, but not always. And I don't want to users see some text selected suddenly only to avoid this problem...

     

    Wednesday, February 1, 2012 3:00 PM
  • Hello Nightblade,

    I am able to reproduce the problem on my system; the events from the system time are blocked while the mouse hovers over the TOC table region.  The Timer event handler for your form doesn’t sink events at that time.

    Interestingly enough, if you click just above the TOC the entire table is shown as a table, and hovering over it does not select the contents. You can jump using Ctrl+click to a topic without making the outline of the table disappear, and hovering does not select the TOC regions.

    By inserting the highlighted code into the event handler

    private void timer1_Tick(object sender, EventArgs e)

            {

                System.Diagnostics.Debug.WriteLine("Tick");

                _sb.Insert(0, DateTime.Now.ToString("HH:mm:ss") + Environment.NewLine);          

                textBox1.Text = _sb.ToString();

            }

    You can see several events happening when the timer events are blocked. Different events show in the VS IDE output window. Here is an example of the output

     

    Tick

    Tick

    Tick

    Tick

    The thread '<No Name>' (0x2444) has exited with code 0 (0x0).

    The thread '<No Name>' (0x2690) has exited with code 0 (0x0).

    The thread 'Win32 Thread' (0x2444) has exited with code 0 (0x0).

    The thread 'Win32 Thread' (0x2690) has exited with code 0 (0x0).

    Tick

    Tick

    Tick

     

    The ID of the exiting thread changes from one debug session to the next.

     

    You have implemented the workaround with your separate thread. Calls from there into the WinWord objects need to be marshaled.

     

    Regards,
    Chris Jensen
    Senior Technical Support Lead

     


    Chris Jensen
    Thursday, February 2, 2012 5:47 PM
    Moderator