私の意見では、MS Office SmoothTypingはOfficeSuiteの非常に革新的な機能であり、この機能が.NET Framework、特にC#言語のプログラマーに利用できるかどうかを知りたいと思います。
もしそうなら、あなたの答えに使用例とドキュメントへのリンクを投稿していただけますか?
ありがとう。
「スムーズなタイピング」とは、タイピング中にカーソルをスライドさせるタイピングアニメーションのことです。
私の意見では、MS Office SmoothTypingはOfficeSuiteの非常に革新的な機能であり、この機能が.NET Framework、特にC#言語のプログラマーに利用できるかどうかを知りたいと思います。
もしそうなら、あなたの答えに使用例とドキュメントへのリンクを投稿していただけますか?
ありがとう。
「スムーズなタイピング」とは、タイピング中にカーソルをスライドさせるタイピングアニメーションのことです。
私はOfficeを所有していないので、この機能を見ることができませんが、しばらく前にRichTextBoxesのキャレットをいじくり回す必要があり、努力する価値がないと判断しました。基本的にあなたはあなた自身です。.NETのヘルパー関数はありませんが、すべてがバッキングWin32コントロールによって処理されます。あなたはすでにボンネットの下で起こっていることを打ち負かすのに苦労するでしょう。そして、おそらくウィンドウメッセージと多くの醜いコードを傍受することになります。
だから私の基本的なアドバイスは:それをしないでください。少なくとも、TextBoxやRichTextBoxなどの基本的なフォームコントロールの場合。.NET内から実行中のオフィスにリモートアクセスしようとすると、運が良くなる可能性がありますが、それはまったく異なるワームの可能性です。
SetCaretPos --routeを実行することを本当に主張している場合は、以下を改善できる基本バージョンを使用して実行するためのコードを次に示します。
// 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();
}
独自のアニメーションタイミング関数でSetCaretPosを使用します。以前の場所と新しい目的の場所に基づいて、キャレットの位置を補間する新しいスレッドを作成します。