Is there any way I can integrate the MS Office Smo

2019-02-08 23:53发布

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 Framework, specifically in the C# language.

If so, could you please post in your answer a link to the documentation and might also a usage example?

Thanks.

2条回答
趁早两清
2楼-- · 2019-02-09 00:12

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.

查看更多
小情绪 Triste *
3楼-- · 2019-02-09 00:22

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();
}
查看更多
登录 后发表回答