リッチテキスト試作 VB6 |
キーワードの文字色を変える
特定の単語(キーワード)に対して、文字色の属性を設定する。ここでは、HTMLデータを入力することを想定して、HTMLのタグを赤色にする。
タグ(tag)は、ブラウザにデータを表示するときの書式などを指定する命令で、"<"と">"ではさまれている。サンプルのHTMLデータとして次のファイルを用意しておくこと。ファイル名はHTMLTest.htmとする。(←ファイル名を右クリックして「対象をファイルに保存(A)...」を選択し、プログラムと同じフォルダに保存する。)
<HTML> <HEAD> <TITLE>課題研究テストデータ</TITLE> <BODY> <CENTER> <H1>課題研究テストページ</H1> <HR ALIGN="center" WIDTH="80%"> 課題研究 Visual Basic<BR> Webページ作成用エディタを作成する。<BR> </BODY> </HTML> |
ボタンの追加
図のようにタグ(キーワード)に色を付けるボタン(Command6)をひとつ用意する。
Tagボタン(Command6)
Height … 375、 Left … 5520、 Top … 5880、 Width …
495
Caption … Tag
文字属性のプログラムでの設定
通常、文字属性を設定するには、@文字属性を設定したい文字列を範囲選択(反転表示)し、A文字属性のボタン(太字や斜体のボタン)をクリックする。
例えば、abcdefghijklmnのghijkを赤色にする。プログラムでは、最初の文字のけた数(6けた目、0からカウントする)をSelStartプロパティに設定し、文字属性を設定したいghijkの文字数(5けた)をSelLengthプロパティに設定する。これで文字列を範囲選択したのと同じことになる。この状態で色を設定するのでSelColorプロパティに色データを設定する。
@ RichTExtBox1.SelStart = 6 カーソルがfとgの間に移動する。 A RichTextBox1.SelLength=5 B RichTextBox1.SelColor = RGB(&hFF, 0, 0) |
文字列の検索方法
ここでは、"<"から">"までのタグを赤色にしたいので、"<"の位置と">"までの文字数が必要になる。文字列を検索するには、InStr関数を使う。
InStr(検索開始位置,被検索文字列,検索文字列)
例えば、abcdefgabcdefgからgを探すには、InStr(1, "abcdefgabcdefg", "g")とする。最初のgの位置である7が返却される。次のgを探すには、今見つかったgの次の位置(8)から検索する。InStr(8, "abcdefgabcdefg", "g")とすると14が返却される。文字数は、1からカウントされる(SelStartは0からカウントする)。検索したい文字列がなかったときは0が返却される。
・プログラムリスト
Private Sub Command6_Click() Dim savept As Integer, endpt As Integer savept = RichTextBox1.SelStart '現在のカーソル位置を保存. RichTextBox1.SelStart = 1 'テキストの先頭から. Do '"<"の位置を検索. RichTextBox1.SelStart = InStr(RichTextBox1.SelStart, RichTextBox1.Text, "<") If RichTextBox1.SelStart = 0 Then '"<"がない. Exit Do End If '">"の位置を検索. endpt = InStr(RichTextBox1.SelStart, RichTextBox1.Text, ">") 'RichTextBox1のけた数は0からカウントするので-1する. RichTextBox1.SelStart = RichTextBox1.SelStart - 1 '"<"から">"までの文字数カウント ※1 RichTextBox1.SelLength = endpt - RichTextBox1.SelStart '選択範囲を赤色にする ↓正しくは255です。2004.05.20 RichTextBox1.SelColor = RGB(256, 0, 0) '(KAIさんにご指摘いただきました。) RichTextBox1.SelStart = endpt Loop RichTextBox1.SelStart = savept 'カーソルを元の位置に移動. RichTextBox1.SetFocus 'フォーカス設定. End Sub
※1 文字数のカウントは、例えば5けた目から8けた目までの文字数は、5678の4文字である。計算式で表すと8 - 5 + 1 のように1を加算するが、その直前で開始位置(SelStart)から1を減じているので、プログラムでは1を加算していない。
実行して、ファイル名にHTMLTest.htmと入力し、開くボタンをクリックしてデータを読み込む。次にTabボタンをクリックするとデータのタグが赤色になる。
入力したタグに色を付ける
入力作業中もタグを入力すると色が変わるようにする。具体的には、"<"を入力すると次に">"が入力されるまでが赤色になるようにする。
リッチテキストへのデータ入力時、カーソルの左側の文字属性を引き継ぐようになっている。例えば、ABCと赤色で入力されており、カーソルがCの右側にあるとき、次にDEFと入力するとCの文字属性を引き継ぐのでABCDEFと赤色で入力される。
ABCI → DEFを入力 → ABCDEFI
Iはカーソルの位置を表している。 |
したがって、"<"が入力されたとき、"<"を赤色に設定するだけで、"<"に続く文字は同じ赤色になる。逆に、">"の入力された次の文字を黒色に設定するとそれに続く文字は黒になる。
この処理をするプログラムは、キーを押したときに"<"か">"であるかを判定するので、KeyPressやKeyDownプロシージャなどに書くことが思いつくが、キーを判定したときにはカーソル位置を表すSelStartプロパティの値が入力文字の左側にあるので、">"の処理で正しく処理ができない。
↓このプログラムでは期待通りに動作しない。 Private Sub RichTextBox1_KeyPress(KeyAscii As Integer) If KeyAscii = Asc("<") Then RichTextBox1.SelColor = RGB(&HFF, 0, 0) '赤色設定 ElseIf KeyAscii = Asc(">") Then RichTextBox1.SelStart = RichTextBox1.SelStart + 1 ←※1 RichTextBox1.SelColor = RGB(0, 0, 0) '黒色設定 End If End Sub
上のプログラムで"<"が押されたときカーソル位置が"<"の右側にあり、カーソル位置が赤色に設定されてから"<"がリッチテキストに入力されるので赤色の"<"が表示されカーソルは"<"の左側に移動する。同じように、">"が押されたとき、カーソルは">"の左側にあるので、カーソル位置を1加算してから黒色に設定しているが、正しく処理されない。
例えば、ABCDのBとCの間に<HTML>を入力すると AB<HTMLCD とここまでは正しく処理されるが、次の">"を入力するとカーソル位置が1加算されるのでCとDの間に移動し黒色に設定されて">"がリッチテキストに入力されるので黒色の">"がCとDの間に表示される。すなわち、AB<HTMLC>Dとなる。
※1のカーソルに1を加算しなければ(※1の行を削除)AB<HTML>CDとなりカーソルは>とCの間にある。続けて、123と入力するとAB<HTML>123CDとなってしまう。
上のプログラム通りのとき ABICD → <HTML を入力 → AB<HTMLICD → > を入力 → AB<HTMLC>ID ※1の行を削除したとき Iはカーソルの位置を表している。 |
解決編 (不具合(エラーが出たり、処理が遅くなる)があるようです。こちらへどうぞ(2003.3.11))
リッチテキストにデータが表示されカーソル位置も入力データの右側に移動した後、色設定の処理をする。入力データの処理が完了した後にはChangeプロシージャが呼び出されるので、ここへプログラムを書くことを考える。
Changeプロシージャが呼び出されたとき、"<"を入力したときは
sss<Iss、 ">"を入力したときは sss<HTML>Iss という状態になっている。したがって、カーソル位置の1文字後ろ(左側)を調べて、"<"であれば赤色に、">"であれば次の文字から黒色に設定すればよい。
・プログラムリスト
Private Sub RichTextBox1_Change() If RichTextBox1.SelStart <> 0 Then If Mid(RichTextBox1.Text, RichTextBox1.SelStart, 1) = "<" Then With RichTextBox1 .SelStart = .SelStart - 1 'カーソル位置1つ後退. .SelLength = 1 '1文字だけ範囲選択. .SelColor = RGB(&HFF, 0, 0) '赤色設定. .SelStart = .SelStart + 1 'カーソル位置を元に戻す. End With ElseIf Mid(RichTextBox1.Text, RichTextBox1.SelStart, 1) = ">" Then RichTextBox1.SelColor = RGB(0, 0, 0) '黒色設定. End If End If Text1.Text = RichTextBox1.TextRTF End Sub
1文字だけ取り出すために Mid関数を使っている。使い方は次のとおりである。
Mid(文字列,取り出し開始けた数,取り出し文字数)
文字列のデータはRichTextBox1のTextプロパティに記憶されている。開始けた数はSelStartプロパティにあり、1文字後ろであるから1減じるところであるが、RichTextBoxは0から、Mid関数は1からカウントするので1を減じていない。取り出す文字数は1である。
取り出した1文字が"<"であれば、@ カーソル位置を1つ後退させて A 1文字だけ範囲選択し、B 赤色に設定してから C カーソル位置を元に戻す。カーソル位置を1つ後退させて1文字だけ範囲選択し、赤色に設定しているのは、すでに入力が完了しているからである。
sssIss → < を入力 → sss<Iss → Changeプロシージャが呼び出される → @ sssI<ss → A sssI<ss → B sssI<ss → C sss<Iss Iはカーソルの位置を表している。 |
取り出した1文字が">"であれば、カーソル位置以降が黒色になるように色を設定する。
リッチテキストボックス コントロールは、入力した文字に対して、フォントを変えたり、色を変えたりできるので、特定のデータ(プログラム)入力用にエディタを作成してみるのもおもしろいかもしれない。
例えば、C言語用に予約語(ifやforなど)、標準ライブラリ(scanfやprintfなど)に色を付ける。 などなど.....
VBmaniax さんにご教授いただきました。 (2003.3.11)
先に説明したKeyPressのプロシージャで処理します。
↓このプログラムでは期待通りに動作しない。 Private Sub RichTextBox1_KeyPress(KeyAscii As Integer) If KeyAscii = Asc("<") Then RichTextBox1.SelColor = RGB(&HFF, 0, 0) '赤色設定 ElseIf KeyAscii = Asc(">") Then RichTextBox1.SelStart = RichTextBox1.SelStart + 1 ←※1RichTextBox1.SelAlignment = RGB(0, 0, 0)RichTextBox1.SelColor = RGB(0, 0, 0) '黒色設定 End If End Sub
しかし、上のリストのままでは説明したように不具合が起きます。次のリストのようにします(太字部分)。
Private Sub RichTextBox1_KeyPress(KeyAscii As Integer) If KeyAscii = Asc("<") Then RichTextBox1.SelColor = RGB(&HFF, 0, 0) '赤色設定. ElseIf KeyAscii = Asc(">") Then KeyAscii = 0 RichTextBox1.SelText = ">" RichTextBox1.SelColor = RGB(0, 0, 0) '黒色設定. End If End Sub
入力された(押された)キーボードのデータは引数KeyAsciiに記憶されている。この引数KeyAscii を 0 に設定する(KeyAscii = 0)と、キー操作が取り消され、オブジェクト(ここではRichTextBox1)は文字を受け取らない。そこで、オブジェクトに文字">"を渡すために RichTextBox1.SelText = ">" としてから黒色の設定をする。
期待通りに動作しない上のリストでは、">"を押したとき、KeyAscii
は">"を記憶している。ElseIf文で条件が真となり、次の式でカーソルがひとつ右へ移動し、さらに次の行で黒色に設定される。EndIf,
End Subの行を通過してこのプロシージャが終わった時点で RichTextBox1に入力文字">"が渡される。
入力文字">"がRichTextBox1に渡されてからカーソル移動と色設定をする、という順で動作させたいのだが、入力文字">"はEnd
Subでプロシージャが終わってから渡されるようなので、適切な処理ができなかったようである。今までこのことがわからなかったので強引な対処しか考えつかなかったようである。 KeyAscii
= 0 はヘルプにも書かれていて読んで知っていたのだが、どのタイミングで">"が渡されるかがよくわからなかった。
VBmaniax さん ありがとうございました。 (2003.3.16)
Copyright © 2001 Hiroshi Masuda |