Есть ли способ интегрировать MS Office Smooth Typing в приложение С#?

По-моему, MS Office Smooth Typing - очень инновационная функция в Office Suite, и я хотел бы знать, доступна ли эта функция для программистов в .NET Framework, в частности на языке С#.

Если да, не могли бы вы разместить в своем ответе ссылку на документацию, а также пример использования?

Спасибо.

Ответ 1

Я не владею Office, поэтому я не могу смотреть на эту функцию, но мне нужно было немного поработать с кареткой в ​​RichTextBoxes некоторое время назад и решил, что это не стоит усилий. В основном вы сами по себе. Никаких вспомогательных функций от .NET, но все обрабатывается под управлением Win32. Вам будет трудно победить то, что уже происходит под капотом. И, вероятно, в итоге перехватывают оконные сообщения и много уродливого кода.

Итак, мой основной совет: не делай этого. По крайней мере, для элемента управления основной формы, например TextBox или RichTextBox. У вас может быть больше удачи при удачном доступе к работающему офису из .NET, но это совершенно другая возможность червей.

Если вы действительно настаиваете на том, чтобы идти по маршруту SetCaretPos, вот какой код вы получите и используете с базовой версией, где вы можете улучшить:

// import the functions (which are part of Win32 API - not .NET)
[DllImport("user32.dll")] static extern bool SetCaretPos(int x, int y);
[DllImport("user32.dll")] static extern Point GetCaretPos(out Point point);

public Form1()
{
    InitializeComponent();

    // target position to animate towards
    Point targetCaretPos; GetCaretPos(out targetCaretPos);

    // richTextBox1 is some RichTextBox that I dragged on the form in the Designer
    richTextBox1.TextChanged += (s, e) =>
        {
            // we need to capture the new position and restore to the old one
            Point temp;
            GetCaretPos(out temp);
            SetCaretPos(targetCaretPos.X, targetCaretPos.Y);
            targetCaretPos = temp;
        };

    // Spawn a new thread that animates toward the new target position.
    Thread t = new Thread(() => 
    {
        Point current = targetCaretPos; // current is the actual position within the current animation
        while (true)
        {
            if (current != targetCaretPos)
            {
                // The "30" is just some number to have a boundary when not animating
                // (e.g. when pressing enter). You can experiment with your own distances..
                if (Math.Abs(current.X - targetCaretPos.X) + Math.Abs(current.Y - targetCaretPos.Y) > 30)
                    current = targetCaretPos; // target too far. Just move there immediately
                else
                {
                    current.X += Math.Sign(targetCaretPos.X - current.X);
                    current.Y += Math.Sign(targetCaretPos.Y - current.Y);
                }

                // you need to invoke SetCaretPos on the thread which created the control!
                richTextBox1.Invoke((Action)(() => SetCaretPos(current.X, current.Y)));
            }
            // 7 is just some number I liked. The more, the slower.
            Thread.Sleep(7);
        }
    });
    t.IsBackground = true; // The animation thread won't prevent the application from exiting.
    t.Start();
}

Ответ 2

Используйте SetCaretPos с собственной функцией синхронизации анимации. Создайте новый поток, который будет интерполировать позицию каретки на основе предыдущего местоположения и нового желаемого местоположения.