Rich KeyDown

RichTextBox で Function キーを使います。

前田稔(Maeda Minoru)の超初心者のプログラム入門

キー操作

  1. Text Editor は当然のことながらキーを使ってタイプします。
    そのとき「コピー/削除/貼り付け」の度にマウスに持ち変えて操作するのは面倒です。
    そこで行の「コピー/削除/貼り付け」を Function キーで操作する機能をプログラムします。
    このページは Rich Contex の続きで、自動生成で作成したプロジェクトです。
  2. デザイン画面から RichTextBox の稲妻アイコンを選択して、KeyDown イベントを設定して下さい。
    richTextBox1_KeyDown() メソッドをプログラムします。
    まず最初に Esc キーが押されたらプログラムを終了するコードを書いてみました。
    ただし、日本語の入力では Esc キーを使うことがあるので、適切では無いかも知れません。
        private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
        {
            int st_idx, nxline, nx_idx;
            switch (e.KeyCode)
            {
                case Keys.Escape:
                    this.Dispose();
                    break;
    
  3. Function キーの F6 で現在行を取得してクリップボードにコピーします。
    GetFirstCharIndexOfCurrentLine() で現在行の先頭 Index を取得します。
    GetLineFromCharIndex(st_idx)+1 で次の行の行番号を取得します。
    GetFirstCharIndexFromLine(nxline) で次の行の先頭 Index を取得します。
    nx_idx-st_idx がコピーする文字列の長さです。
                case Keys.F6:       //Line Copy
                    st_idx = richTextBox1.GetFirstCharIndexOfCurrentLine();
                    nxline = richTextBox1.GetLineFromCharIndex(st_idx)+1;
                    nx_idx = richTextBox1.GetFirstCharIndexFromLine(nxline);
                    Clipboard.SetDataObject(richTextBox1.Text.Substring(st_idx, nx_idx-st_idx), true);
                    break;
    
  4. Function キーの F7 で現在行をクリップボードにコピーしてから削除します。
    richTextBox1.SelectionStart = st_idx; で、削除後にカーソル位置を元に戻します。
                case Keys.F7:       //Line Cut
                    st_idx = richTextBox1.GetFirstCharIndexOfCurrentLine();
                    nxline = richTextBox1.GetLineFromCharIndex(st_idx)+1;
                    nx_idx = richTextBox1.GetFirstCharIndexFromLine(nxline);
                    Clipboard.SetDataObject(richTextBox1.Text.Substring(st_idx, nx_idx-st_idx), true);
                    richTextBox1.Text = richTextBox1.Text.Remove(st_idx,nx_idx-st_idx);
                    richTextBox1.SelectionStart = st_idx;
                    break;
    
  5. Function キーの F8 でクリップボードから貼り付けます。
                case Keys.F8:       //Paste
                    IDataObject data = Clipboard.GetDataObject();
                    if (data != null && data.GetDataPresent(DataFormats.Text) == true)
                    {
                        richTextBox1.Paste();
                    }
                    break;
    
  6. コンパイル&実行して、行の「コピー/削除/貼り付け」を確かめて下さい。
    この要領で編集に便利な機能キーをプログラムして下さい。
  7. 文字列や行を削除する場合は Text.Remove() に代えて、選択文字列の置き換え機能を使うことも出来ます。
    例えば st_idx から nx_idx-st_idx の文字列を削除するときは、次のようにします。
    この方法の利点は、RichTextBox の表示位置が乱れないことです。
    richTextBox1.Select(st_idx, nx_idx-st_idx);
    richTextBox1.SelectedText = "";
    

Keyword の選択と検索

  1. 私が Text Editor を使っていて便利だと思う機能が、RichTextBox上から検索キーワードを取得して検索する機能です。
    それもキーを使って、簡単に操作出来ることが条件です。
    Keyword の選択と検索のために、次のキーを割り当てます。
    キー 説明
    Shift+F5 検索キーで後方に検索
    Shift+F6 検索キーで前方に検索
    F5 検索キーの選択
  2. キーワードの選択が少し面倒なので、説明しておきましょう。
    F5(Function 5) キーを押すと、現在のカーソル位置からキーワードを抽出します。
    キーワードは[空白, カンマ, セミコロン, 行末]などで区切られます。
    続けて F5 キーを押すと、最初の位置からその次の区切り文字までをキーワードとします。
    キーワードが抽出できたら、Shift+F5, Shift+F6 で検索します。
    上下左右の矢印キーが押されると、新しいキーワードを選択できるようになります。
  3. 検索の作業領域です。
    kline はキーワードを抽出するために、F5 が押されたときに現在行をコピーします。
    この値が空のときに、新しいキーワードを選択することが出来ます。
    kword は確定したキーワードで、この文字列を検索します。
    k_lt は kline の左(開始位置)で、k_rt が右(終了位置)です。
        public partial class Form1 : Form
        {
            string  kline= string.Empty;  //Select Line
            string  kword;          //Keyword
            int     k_lt;           //Keyword Left
            int     k_rt;           //Keyword Right
    
  4. richTextBox1_KeyDown() メソッドでは、最初に Shiftキーを調べて F5, F6 の検索からプログラムしています。
    Shift+F5 で後方に検索します。
    kword が空の時は、検索キーワードが設定されていません。
    wp に現在のカーソルの位置を格納します。
    wp = richTextBox1.Find(kword, wp, -1, RichTextBoxFinds.None); で後方に検索します。
    wp が開始位置で、-1 が終了位置(TEXT の最後)です。
    キーワードが見つからなかったときは -1 が返されます。
    richTextBox1.Select(wp, kword.Length); でキーワードを選択状態にして、強調表示します。
            private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
            {
                int st_idx, nxline, nx_idx, wp;
                if (e.Shift == true)
                {
                    switch (e.KeyCode)
                    {
                        case Keys.F5:
                            if (kword == string.Empty) break;
                            wp = richTextBox1.SelectionStart + kword.Length;
                            wp = richTextBox1.Find(kword, wp, -1, RichTextBoxFinds.None);
                            if (wp < 0) break;
                            richTextBox1.Select(wp, kword.Length);
                            break;
    
  5. Shift+F6 で前方に検索します。
    wp = richTextBox1.Find(kword, 0, wp, RichTextBoxFinds.Reverse); で前方に検索します。
    wp が開始位置で、0(先頭)が終了位置です。
    後方検索とは、開始位置と終了位置が入れ替わっていることに注意して下さい。
                        case Keys.F6:
                            if (kword == string.Empty) break;
                            wp = richTextBox1.SelectionStart;
                            wp = richTextBox1.Find(kword, 0, wp, RichTextBoxFinds.Reverse);
                            if (wp < 0)    break;
                            richTextBox1.Select(wp, kword.Length);
                            break;
                    }
                    return;
                }
    
  6. Shift が押されなかったときの処理です。
    Escape キーでプログラムを終了します。
                switch (e.KeyCode)
                {
                    case Keys.Escape:
                        this.Dispose();
                        break;
    
  7. F5 キーでキーワードを選択します。
    kline が空のときに、新しいキーワードの設定を開始します。
    現在行を kline にコピーして、k_lt, k_rt にカラム位置を設定します。
    k_rt+1 の位置から区切り符号を検索します。
    k_lt がキーワードの左で、k_rt がキーワードの右です。
    選択したキーワードを確認できるように Forn のキャプションに表示します。
                    case Keys.F5:       //Key Word
                        if (kline==string.Empty)
                        {   // 現在行をklineに保存
                            st_idx = richTextBox1.GetFirstCharIndexOfCurrentLine();
                            nxline = richTextBox1.GetLineFromCharIndex(st_idx)+1;
                            nx_idx = richTextBox1.GetFirstCharIndexFromLine(nxline);
                            kline = richTextBox1.Text.Substring(st_idx, nx_idx-st_idx);
                            // kline からの Offset
                            k_lt = richTextBox1.SelectionStart - st_idx;
                            k_rt = k_lt;
                        }
                        for(k_rt+=1; k_rt<kline.Length; k_rt++)
                        {   if (kline[k_rt] == '\n')    break;
                            if (kline[k_rt] == ' ')     break;
                            if (kline[k_rt] == ',')     break;
                            if (kline[k_rt] == ';')     break;
                            if (kline[k_rt] == '\\')    break;
                        }
                        if (k_rt > kline.Length)  k_rt= kline.Length;
                        kword = kline.Substring(k_lt, k_rt-k_lt);
                        Text = "[" + kword + "]";
                        break;
    
  8. 矢印キーが押されると kline を空にして、新しいキーワードの選択が出来るようにします。
    この段階では、kword が残っているので、引き続き現在のキーワードで検索することが出来ます。
                    case Keys.Down: case Keys.Up: case Keys.Right: case Keys.Left:
                        kline = string.Empty;
                        break;
                }
            }
    

超初心者のプログラム入門(C# Frame Work)