10

在我看来,MS Office Smooth Typing 是 Office 套件中一个非常创新的功能,我想知道 .NET Framework 中的程序员是否可以使用此功能,特别是 C# 语言。

如果是这样,您能否在答案中发布使用示例链接到文档

谢谢。

通过“流畅的打字”,我指的是打字动画,它使光标在打字过程中滑动。

4

2 回答 2

11

我没有 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();
}
于 2013-05-30T12:12:11.660 回答
3

将 SetCaretPos 与您自己的动画计时功能一起使用。创建一个新线程,根据先前的位置和新的所需位置插入插入符号的位置。

于 2013-03-11T20:34:09.357 回答