Search code examples
c#ms-wordadd-in

Why Application.Selection.Range.Start returns incorrect value sometimes?


Situation context - MS Word addin.
Langiage - C#
Problem:

I'm trying to get current cursor position. I'm using Application.Selection.Range as it returns InsertionPoint. After each Space,Tab or Enter keys pressing I do the following: MessageBox.Show(Application.Selection.Range.Start.ToString()); Sometimes I see MessageBox with the correct value sometimes actual_value_of_insertion_point_position+128. Why insertion point index sometimes increased to 128? I'm doing nothing specific I'm just typing some text, press Space and see sometimes correct value as expected someimes not.

UPDATE Actually, my problem is deeper - here my other SO question with detailed description. My plan:

1) When user types Space remember insertion point - it returns next future letter's position.
2)If user typed some letter and previous key was Space, it means user typing first letter of some new word. Create range as the following Application.ActiveDocument.Range(remembered_pos,rem_pos+1) and style it as you want.

My code

 private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int pointerCode = Marshal.ReadInt32(lParam);
                string pressedKey = ((Keys)pointerCode).ToString();

                IntPtr curHandle = GetForegroundWindow();

                if(curHandle==wordHandle)
                {

                    //MessageBox.Show(app.ActiveDocument.Content.LanguageID +" "+ WdLanguageID.wdKazakh);
                    if(pressedKey.Equals("Space")||pressedKey.Equals("Return")||pressedKey.Equals("Tab"))
                    {

                        Word.Range r = app.Application.Selection.Range; 
                        MessageBox.Show(app.Application.Selection.Type.ToString());
                        MessageBox.Show("-"+r.Start.ToString()+"-"+r.End.ToString()); // sometimes +128!


                    }
                    else if(firstAfterSpace!=-1)
                    { // right now doesn't make sense 
                        MessageBox.Show(firstAfterSpace.ToString());
                        //Word.Range rng = app.Application.ActiveDocument.Range(firstAfterSpace,firstAfterSpace+1);
                        //MessageBox.Show("-"+rng.Text+"-");
                        //rng.Underline = Word.WdUnderline.wdUnderlineNone;
                        firstAfterSpace = -1;
                    }



                }

            }
            return CallNextHookEx(hookId, nCode, wParam, lParam);
        }

Solution

  • You could try different way of setting range after someone pressed Space, Return or Tab assuming that you search for the word before any of these'characters'.

    Here is the code which you could place into your If statement:

        Word.Range r = appWRD.Application.Selection.Range;
        Word.Range tmpR = r.Previous(Word.WdUnits.wdWord,2);
        MessageBox.Show("-" + tmpR.Start.ToString() + "-" + (r.Start-1).ToString());
    
        //set temporarily for checking word text
        tmpR = appWRD.ActiveDocument.Range(tmpR.Start, r.Start -1 );
        MessageBox.Show(string.Format("Word found: {0}!", tmpR.Text));
        //this shows it doesn't include any tab or space
    

    Tip. There are a lot of Range modification methods in Word but some of them don't work correctly. Previous works fine in this situation according to my test.