Is there any way I can integrate the MS Office Smooth Typing in a C# application?

后端 未结 2 431
一个人的身影
一个人的身影 2021-01-02 05:17

In my opinion the MS Office Smooth Typing is a very innovating feature in the Office Suite, and I\'d like to know if this feature is available for programmers in the .NET Fr

相关标签:
2条回答
  • 2021-01-02 05:54

    I don't own Office, so I can't look at the feature, but I needed to fiddle around with the caret in RichTextBoxes a while ago and decided that it wasn't worth the effort. Basically you are on your own. No helper functions from .NET, but everything is handled by the backing Win32 control. You will have a hard time defeating what already happens under the hood. And probably ending up intercepting window messages and lots of ugly code.

    So my basic advice is: Don't do it. At least for basic form controls like the TextBox or RichTextBox. You may have more luck trying to remote access an running office from within .NET, but that is a totally different can of worms.

    If you really insist on going the SetCaretPos - route, here is some code to get you up and running with a basic version where you can improve upon:

    // 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();
    }
    
    0 讨论(0)
  • 2021-01-02 06:15

    Use SetCaretPos with your own animation timing function. Create a new thread that interpolates the caret's position based on the previous location and the new desired location.

    0 讨论(0)
提交回复
热议问题