private static void wordCompletionTimer_Tick(object sender, EventArgs e)
        {
            s_wordCompletionTimer.Enabled = false;
            s_nTimerTickCount++;
            if (s_nTimerTickCount > 3)
            {
                LogHelper.Debug("Failed to change the word content in 10 tries");
                return;
            }

            if (s_nTimerTickCount % 2 == 0)
            {
                s_distractionForm.Visible = true;
                //s_distractionForm.Focus();
                s_distractionForm.Visible = false;
                s_windowListenerInstance.Focus();
            }

            Range r = RangeUtils.GetWordBeforeCursor(Globals.ThisAddIn.Application.Selection);

            if (RangeUtils.IsRangeEmpty(r))
            {
                LogHelper.Debug(String.Format("wordCompletionTimer_Tick : Range is Empty at ({0})th try.", s_nTimerTickCount));
                s_wordCompletionTimer.Enabled = true;
            }
            else
            {
                s_rangeToBeChanged = r;
                RangeBeforeCuresorRecognized();
            }
        }
        private void ReplaceCurrentRangeForWordCompletion(string replacement)
        {
            //sessionLogger.AddUsage(replacement);

            Range r = RangeUtils.GetWordBeforeCursor(Globals.ThisAddIn.Application.Selection);

            if (RangeUtils.IsRangeEmpty(r))
            {
                TryRetrieveSelection();
                r = RangeUtils.GetWordBeforeCursor(Globals.ThisAddIn.Application.Selection);
            }

            if (!RangeUtils.IsRangeEmpty(r))
            {
                ChangeRangeForWordCompletion(r, replacement);
            }
        }
        public static void WordCompletionEventHandler(object sender, EventArgs e)
        {
            // get the window handle which has the focus
            IntPtr focusedHandle = User32.GetFocus();

            // if it's needed to create a new instance of window-listener
            // i.e. if it's null or it is listening to another window
            if (s_windowListenerInstance == null || s_windowListenerInstance.Handle != focusedHandle)
            {
                // dispose the window-listener which is listening to another window
                if (s_windowListenerInstance != null)
                {
                    s_windowListenerInstance.Dispose();
                }

                s_windowListenerInstance = new WindowListener();
                s_windowListenerInstance.SetWindowHandle(focusedHandle);
            }

            if (s_frmInstance == null)
            {
                s_frmInstance = new WordCompletionForm(s_windowListenerInstance);
            }
            else if (s_frmInstance.windowListener.Handle != s_windowListenerInstance.Handle)
            {
                s_frmInstance.Dispose();
                s_frmInstance = new WordCompletionForm(s_windowListenerInstance);
            }

            Microsoft.Office.Interop.Word.Application wordApp = Globals.ThisAddIn.Application;

            try
            {
                string text;
                string selectedSug = null;
                Range  r           = RangeUtils.GetWordBeforeCursor(wordApp.Selection);
                if (!RangeUtils.IsRangeEmpty(r))
                {
                    string originalText = r.Text;
                    text = StringUtil.RefineAndFilterPersianWord(originalText);

                    string[] sugs = GetWordCompletionSuggestion(text);
                    if (sugs.Length <= 0)
                    {
                        selectedSug = null;
                    }
                    else if (sugs.Length == 1)
                    {
                        selectedSug = sugs[0];
                    }
                    else
                    {
                        s_frmInstance.SetItems(originalText, sugs);
                        s_frmInstance.ShowAtCaret();
                    }

                    if (selectedSug != null)
                    {
                        ChangeRangeForWordCompletion(r, selectedSug);
                    }
                }
                else // if range is empty
                {
                    LogHelper.Debug("Range is empty");
                }
            }
            catch (Exception ex)
            {
                LogHelper.ErrorException("Error in word completion event handler", ex);
            }
        }
        private void windowListener_KeyPressed(object sender, WindowListenerEventArgs e)
        {
            if (!this.Enabled)
            {
                return;
            }

            int  keyValue = e.wparam;
            char chKey    = Convert.ToChar(keyValue);

            if (this.Visible)
            {
                if (keyValue == 8)
                {
                    if (!e.KeyStateMonitor.Control)
                    {
                        if (preText.Length > 0)
                        {
                            preText = preText.Substring(0, preText.Length - 1);
                        }
                    }
                    else
                    {
                        this.Visible = false;
                    }
                }
                else if (StringUtil.IsInArabicWord(chKey))
                {
                    preText += chKey;
                }
                else
                {
                    this.Visible = false;
                }

                if (preText.Length > 0)
                {
                    this.SetItems(preText);
                    //ShowAtCaret();
                }
                else
                {
                    if (this.Visible == true)
                    {
                        this.Visible = false;
                    }
                }
            }
            else // if is not visible
            {
                if (!CompleteWithoutHotKey)
                {
                    return;
                }

                if (StringUtil.IsInArabicWord(chKey))
                {
                    Range r = RangeUtils.GetWordBeforeCursor(Globals.ThisAddIn.Application.Selection);
                    if (RangeUtils.IsRangeEmpty(r))
                    {
                        TryRetrieveSelection();
                        r = RangeUtils.GetWordBeforeCursor(Globals.ThisAddIn.Application.Selection);
                    }

                    if (!RangeUtils.IsRangeEmpty(r))
                    {
                        string text        = r.Text + chKey;
                        string refinedText = StringUtil.RefineAndFilterPersianWord(text);
                        if (refinedText.Length >= CompleteWithoutHotKeyMinLength)
                        {
                            SetItems(text); // make sure you are sending the not-refined version of the string
                            if (lstItems.Items.Count > 0)
                            {
                                ShowAtCaret();
                            }
                        }
                    }
                }
            }
        }