「
.NETプラグイン開発 イベント編
」を編集中
ナビゲーションに移動
検索に移動
警告:
ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。
ログイン
または
アカウントを作成
すれば、あなたの編集はその利用者名とともに表示されるほか、さまざまなメリットもあります。
スパム攻撃防止用のチェックです。 決して、ここには、値の入力は
しない
でください!
== 概要 == イベント(テキスト変更、キー操作)対応の説明。 == テキスト変更イベント == プラグインの基本は、発生するイベントに応じて処理していくことです。まずは使うことの多いであろう、テキスト変更イベントを処理してみます。 ソースの中で「#region OnEvents のディスパッチ」が閉じられていると思いますので、これを開きます。基本的に対応しているイベントは全て書かれていますので、コメントを外すことで各イベント発生時に呼ばれるようになります。なおコメントアウトしておけば無駄に呼ばれることがないため、遅くしないためにも無駄にコメントアウトは外さないようにしましょう。 イベントの OnChanged のコメントアウトを外しましょう。これがテキストが変更されたときに呼ばれるイベントです。ここに、時折要望として挙がる「テキスト全体の文字数をステータスバーに表示する」処理を書いてみましょう。 <syntaxhighlight lang="csharp"> /// <summary> /// テキストが変更された時。 /// </summary> /// <param name="hWnd">対象のエディタハンドル</param> public void OnChanged(IntPtr hWnd) { // (1)Mery 操作用のオブジェクト生成 var editor = new Editor(hWnd); // (2)文字数を取得(改行含む) int length = editor.GetLength(true); // (3)ステータスバーに結果を表示 editor.SetStatus(length.ToString()); } </syntaxhighlight> どうですか、簡単でしょう! 続いて、文字数ではなく Shift-JIS の byte 数にしてみましょう。 <syntaxhighlight lang="csharp"> /// <summary> /// テキストが変更された時。 /// </summary> /// <param name="hWnd">対象のエディタハンドル</param> public void OnChanged(IntPtr hWnd) { // (1)Mery 操作用のオブジェクト生成 var editor = new Editor(hWnd); // (2)文字列を取得 string text = editor.GetText(); // (3) Shift-JIS のバイト数に変換 int length = Encoding.GetEncoding(932).GetByteCount(text); // (4)改行コードが CR+LF だった場合は、その分追加 if (editor.GetNewLineType() == Editor.NewLineType.CrLf) { length += editor.GetLines(true) - 1; } // (5)ステータスバーに結果を表示 editor.SetStatus(length.ToString()); } </syntaxhighlight> GetLength() は Unicode 文字数を返すので、Shift-JIS のバイト数を取得するためにはまずテキスト全体を取得します((2))。次に(3)でテキストを Shift-JIS でのバイト数に換算します。正確には Shift-JIS では表現できない文字などの対応が必要になりますが、ここでは省略しています。これで取得できた、としたいのですが、プラグインから取得する文字列の改行コードは全て LF という仕様があります。CR+LF だと改行分だけバイト数がずれてしまいますので、(4)の改行コード判定およびその分の調整をしています。ちょっと面倒ですが、ここまで来ればマクロより楽なはずです。 === 遅延処理 === 先ほどのコードで GetText() を使っていますが、覚えているでしょうか……この処理が重いということを。単純に OnChanged の中で使用してしまうと、文字列が変更される度にこの処理が呼ばれます。実際に実行し、a を押しっぱなしにすると、入力される度にステータスバーが更新されます。文字数が少ないうちは良いですが、多くなったときはとてもではないですが実用的な速度で動くことはないでしょう。 これを解決するのに、「入力後一定時間変更がなければ更新する」という遅延処理をします。.NET プラグインには独自のタイマー処理が実装されていますので、対応は極めて簡単です。 <syntaxhighlight lang="csharp"> /// <summary> /// テキストが変更された時。 /// </summary> /// <param name="hWnd">対象のエディタハンドル</param> public void OnChanged(IntPtr hWnd) { // (1)固有のタイマーID ushort TimerID = 1; // (2)1000ms 後に処理を開始する // 1000ms の間に再度呼ばれた場合は後の方が有効になる SetTimer(hWnd, TimerID, 1000, () => { var editor = new Editor(hWnd); string text = editor.GetText(); int length = Encoding.GetEncoding(932).GetByteCount(text); if (editor.GetNewLineType() == Editor.NewLineType.CrLf) { length += editor.GetLines(true) - 1; } editor.SetStatus(length.ToString()); }); } </syntaxhighlight> 基本的には、SetTimer() で遅延させているだけです。これだけで、最後の編集から 1 秒後に反映されるようになり、頻繁な更新を抑制できます。ここでは簡単にするためラムダ式で記述していますが、別のメソッドに仕立てて登録しても良いですし、OnTimer() イベントも用意しているのでそちらで処理しても良いです。 このように、いくつかのイベントは呼ばれる度に実行するより遅延させた方が良い場合があります。 == キー操作イベント == 矩形選択は先に Alt を押した状態で選択を開始する必要があります。が、プラグインを使うとこの順番を逆にしても使えるようになります。 今度は「#region PreTranslateMessage のディスパッチ」を開きます。その中の OnSysKeyDown() のコメントアウトを外して、以下のコードを入力します。 <syntaxhighlight lang="csharp"> /// <summary> /// システムキーを押したときに呼ばれます。 /// </summary> /// <param name="hWnd">対象のエディタハンドル</param> /// <param name="keycode">仮想キーコード。<see cref="VIRTUAL_KEY"/> に定義されています。</param> /// <param name="repeat">リピートカウント</param> /// <param name="alt">ALT キーが押されているか</param> /// <param name="previous">直前のキー状態が指定されます。true の場合、メッセージが送られる前からキーが押されています。</param> /// <returns>メッセージ処理を継続する場合は false。</returns> public bool OnSysKeyDown(IntPtr hWnd, int keycode, int repeat, bool alt, bool previous) { // (1)Alt キーが押されたことによるイベントかを判定 if (keycode == (int)VIRTUAL_KEY.VK_MENU) { // (2)選択されていて、まだ矩形選択になっていないか // これを確認しないと何度も矩形選択処理をしてしまう var editor = new Editor(hWnd); if (editor.GetSelType() == Editor.SEL_TYPE.CHAR) { // (3)選択範囲を取得 var start = editor.GetSelStart(true); var end = editor.GetSelEnd(true); // (4)矩形選択し直す editor.Select(start, end, true, true); // (5)通常の Alt 処理をキャンセル return true; } } // (6)処理しなかった場合は本体のキー操作処理にゆだねる return false; } </syntaxhighlight> OnSysKeyDown() は Alt や Ctrl などの特別なキーを処理するためのイベントです。通常の a などのキーは OnKeyDown() になるので、使い分けに注意してください。コードとしては、矩形選択にし直す、という便利なメソッドは用意されていないので、(3)選択範囲の取得→(4)矩形選択し直し、という流れになります。(5)で true を返さないと、本体のキー処理が走るためメニューが表示されてしまいます。無闇にキャンセルしても本体や他のプラグインの邪魔をしてしまうのでよくありませんが、今回ぐらいであれば true で以降の処理をキャンセルした方が良いでしょう。
編集内容の要約:
MeryWikiへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は
MeryWiki:著作権
を参照)。
著作権保護されている作品は、許諾なしに投稿しないでください!
このページを編集するには、下記の数式を計算してその答えを欄に入力してください (
ヘルプ
):
いちたすには =
キャンセル
編集ヘルプ
(新しいウィンドウで開きます)
スポンサーリンク
ナビゲーション メニュー
個人用ツール
ログインしていません
トーク
投稿記録
アカウント作成
ログイン
名前空間
ページ
議論
日本語
表示
閲覧
編集
履歴表示
その他
検索
スポンサーリンク
スポンサーリンク
案内
メインページ
ヘルプ
よくある質問
マクロリファレンス
マクロライブラリ
プラグインライブラリ
構文ファイル
テーマ
寄付・開発支援
練習用ページ
開発室
開発者のブログ
ツール
スポンサーリンク