テキストデータ内に,部分文字に着色付ける方法は在りますか?

タグの編集
投稿者 佐久 誠  (社会人) 投稿日時 2023/8/28 11:11:34
(テキストオブジェクト内の)テキストデータの中の,選択部分の文字に着色付ける,プログラミングプロシージャー(記述プログラム)は存在しますか?
在れば,その具体的プロシージャーを御指導頂けませんか。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/8/28 13:05:49
Windows Forms の場合は、TextBox の代わりに RichTextBox を使ってください。
SelectionColor プロパティで、選択されている範囲の文字色を指定することができます。

richTextBox1.SelectionColor = Color.Red
https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.richtextbox.selectioncolor

WinForms 以外のプラットフォーム(WPF や Web アプリなど)の場合は、別途お知らせください。
投稿者 佐久 誠  (社会人) 投稿日時 2023/8/28 14:57:14
"魔界の仮面弁士"様,アドバイス有難うございました。
唯,「TextBox の代わりに RichTextBox を使って...」とありますが,VB6である為か,
TextBoxのみで,RichTextBoxは,見付かりませんでしたが。
投稿者 とくま  (社会人) 投稿日時 2023/8/28 15:13:56
いまだにVB6を使い続けるという事は、.NETの情報とより分け、消滅しつつある情報から、自力で探し出せる実力のある
者にのみ許された行為だと思います。「VB6、richtextbox」程度の検索で取得できるような情報が探せないならVB6なんて
やめたほうがいい。

必要なライブラリを追加して下さい。
http://hanatyan.sakura.ne.jp/vb6/richtextbox01.htm
>プロジェクト→コンポーネント→コントロールで Microsoft Rich Textbox Control 6.0 
投稿者 (削除されました)  () 投稿日時 2023/8/28 19:11:59
(削除されました)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/8/28 19:15:10
VB6 の場合は、コンポーネントの追加で、 "Microsoft Rich Textbox Control 6.0"
(C:\Windows\SysWOW64\RICHTX32.OCX) を加えると、
ツールボックスに RichTextBox が現れるはずです。

選択された範囲のテキストの色を変えるには、 SelColor プロパティを使います。
RichTextBox1.SelColor = vbRed


特定の範囲を選択状態にしたい場合は、SelStart プロパティと SelLength プロパティを使います。
RichTextBox1.SelStart = 開始文字位置 '0以上 
RichTextBox1.SelLength = 選択したい文字数


その他の機能について、こちらを参考にしてみてください。
http://hanatyan.sakura.ne.jp/vbhlp/rithfram.htm


とはいえ、VB6 が登場したのは 25 年前のことで、サポートも切れています。
今となっては、開発環境として利用するのは避けた方が無難です。

仮に既存コードの保守のために残しているという状況であったとしても、
ライセンスの入手性も悪いですし、流石に VB.NET への移行が検討されるべきかと…。

ちなみに Visual Basic 6.0 や Visual Studio 6.0 の単体ライセンスの新規購入は現状できません。
サブスクリプション 契約であれば入手できますが、当時よりも高くつきます。

また、Visual Basic 6.0 や Visual Studio 6.0 のライセンスを、既存利用者から譲り受けることは
一応可能ですが、委託(オークション サイトなど)を通じた譲渡は禁止されていますし、
過去に譲渡された製品を再譲渡することも禁止されています。
投稿者 佐久 誠  (社会人) 投稿日時 2023/8/29 13:16:30
魔界の仮面弁士様,とくま様,色々御指導下さり,誠に有難うございます。

私は,現在83歳になりますが,
FACOM R等のミニコンピューターやIBM360等の大型計算機など,コンピューターが,
日本に入って来て間もない頃からコンピューターに触れて来ました。
ソフトウェアとして,アセンブラー(機械)言語や,フォートラン,コボル等のマクロ(上位)言語による,ソフトウェア開発が最初でした。
コンピューターも,大型計算機の時代~ワープロ~PC~通信との融合(インターネット)~ビジュアル機能の時代へと,
変遷を辿る中で,
VB6は,テレワークとして携わった「技術関連調査」のお仕事の作業の効率化と結果の精度向上を
図るべく,約17年前頃から始めた,ソフトウェア開発としての私にとっては,最後のソフトウェア言語となっています。
VB6の有する,機能も最少限の機能を利用してのソフトウェア開発であって,
寧ろ,この17年間は,「技術関連調査」のお仕事上の作業機能改善の為のソフトウェア開発(というか,プログラム修正)でした。
何せもう,この歳ですから,VB6の機能をグレードアップすることや,PC機種のグレードアップは,全く考えませんでした
(仕事上,最善のPC機種である為OSも,Windows Xpを使用,上位機種はクリックなどの操作回数が倍加する等,
仕事上,年寄りにとっては極めて使い辛い)。
VB6で以って何百万ステップもプログラミングしていても,VB6に,RichTextBoxが在ることや,コンポーネントの追加機能が
備わっていることなど,全く知りませんでした。


折角,教えて頂いたのですから又,VB6の機能をグレードアップすることに挑戦して見たい思いも出て参りました。
本当に,有難うございました。
投稿者 佐久 誠  (社会人) 投稿日時 2023/8/29 13:25:26
VB6にて,
asc1=Asc(xxxxxx)
とした場合,
xxxxxxが,複数文字であっても,asc1には,先頭の1文字分しか,16進数変換されないようですが,
xxxxxx全ての,16進数変換は出来る方法はないのでしょうか(10進数表示でなく,16進数表示とか)?
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/8/29 15:34:02
> 日本に入って来て間もない頃からコンピューターに触れて来ました。

とすると、'70年代ですかね?
当時はネット環境は無いし、周りに聞ける人も居ないし、大変ですよね。

自分がはじめたのは '84年で、すがやみつる先生の「こんにちはマイコン」がバイブルだった世代。
その当時、プログラミングの技術情報源といえば
「付属のマニュアル」と、図書館に僅かにあった類似言語の「入門書」ぐらいしか無かったです。
しょうがないので、当時は、開発ツール付属のマニュアル群を完読したものです。あぁ懐かしや。


> VB6に,RichTextBoxが在ることや,コンポーネントの追加機能が
> 備わっていることなど,全く知りませんでした。

!?
その分だと、\Samples\VB98\ ディレクトリにあったサンプル群はおろか、
付属のマニュアルさえ、殆ど目を通したことが無いのでは…?

TextBox などは「標準コントール」と呼ばれており、VB 本体が持つ機能です。
RichTextBox などは「ActiveX コントロール」と呼ばれ、追加のライブラリで提供されます。

※16bit 時代の旧バージョンの VB では、後者を「カスタム コントロール」と呼んでおり、
 32bit 化された後は「OLE カスタム コントロール」と名前を変えましたが、
 VB5 や VB6 の時代になると「ActiveX コントロール」と名前を変えました。


VB6 の場合は、ヘルプ(MSDN Library)が、VB 本体とは、
別媒体(CD-ROM 等)で提供されています。インストール時には
 ・ヘルプをインストールしない
 ・利用時に CD-ROM が必要な形でインストール
 ・CD-ROM の内容をすべてハードディスクにインストールして利用
のいずれかを選択できますが、まだ入れていないのならインストールしましょう。

まずは目次から辿って、このあたりに目を通してみてください。

[Visual Basic ドキュメント]
└[Visual Basic の使用方法]
 └[コンポーネント ツール ガイド]
  └[ActiveX コントロールの使い方]
   └[ActiveX コントロールの使い方]
    └[リッチテキスト ボックス (RichTextBox) コントロールの使い方]
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/8/29 16:45:44
> xxxxxxが,複数文字であっても,asc1には,先頭の1文字分しか,16進数変換されないようですが,

違いますよ?

Asc 関数が「先頭の 1 文字」を対象とする点に関しては、確かにそのとおりです。
(なので、長さゼロの文字列を変換しようとするとエラーになります)

しかしながら「16進数変換」する機能は持ち合わせていません。
単に、その 1 文字を表す「整数値」を返すだけです。

数値を16進数文字列に変換するのは、Hex 関数の仕事ですし、
数値を8進数文字列に変換するのは、Oct 関数の仕事です。

MsgBox CStr(2023)  ' … "2023" 
MsgBox Oct(2023)  ' … "3747" 
MsgBox Hex(2023)  ' … "7E7" 

MsgBox CStr(&O3747)  ' … "2023" 
MsgBox Oct(&O3747)  ' … "3747" 
MsgBox Hex(&O3747)  ' … "7E7" 

MsgBox CStr(&H7E7)  ' … "2023" 
MsgBox Oct(&H7E7)  ' … "3747" 
MsgBox Hex(&H7E7)  ' … "7E7" 




> xxxxxx全ての,16進数変換は出来る方法はないのでしょうか

たとえば、こんな感じに書けます。
第二引数には文字コードを指定してください。省略時には "Shift_JIS" とみなします。

Public Function ToHexString(ByVal Text As StringOptional ByVal Charset As String = "Shift_JIS"As String
    Dim x As Object, y As Object
    Set x = CreateObject("ADODB.Stream")
    x.Open
    x.Charset = Charset
    x.WriteText Text
    x.Position = 0
    x.Type = 1
    Set y = CreateObject("Msxml2.DOMDocument").createElement("x")
    y.DataType = "bin.hex"
    y.NodeTypedValue = x.Read(-1&)
    x.Close
    ToHexString = y.Text
End Function


Debug.Print ToHexString("佐久 誠", "Shift_JIS")     '8db28b76814090bd
Debug.Print ToHexString("佐久 誠", "EUC-KR")        'f1a5cef9a1a1e1a4
Debug.Print ToHexString("佐久 誠", "EUC-JP")        'bab4b5d7a1a1c0bf
Debug.Print ToHexString("佐久 誠", "iso-2022-jp")   '1b24423a3435572121403f1b2842
Debug.Print ToHexString("佐久 誠", "UTF-16BE")      '4f504e4530008aa0
Debug.Print ToHexString("佐久 誠", "UTF-16LE")      'fffe504f454e0030a08a
Debug.Print ToHexString("佐久 誠", "UTF-8")         'efbbbfe4bd90e4b985e38080e8aaa0
Debug.Print ToHexString("佐久 誠", "UTF-7")         '2b5431424f525441416971412d



CreateObject などの外部ライブラリに頼らない手法としては、
 Len 関数で文字数を数えて、
 For ~ Next ステートメントで文字数分だけのループ処理を行い、
 Mid 関数で先頭から 1 文字ずつ切り出した上で、
 Asc 等で変換した結果を、Hex 関数で繋いでいく
という実装手順がしばしば用いられます。

Integer 値を Hex 関数に渡した場合、結果が 1~4文字の可変長になりますので、
必要に応じて、不足した桁に "0" を補ってやる処理も必要ですね。


> asc1=Asc(xxxxxx)

AscB 関数は、バイナリデータの先頭バイトの値を返します。
Asc 関数は、既定の文字集合(日本語圏だと Shift_JIS 相当) における文字コードの値を返します。
AscW 関数は、Unicode の文字集合における該当文字のコードポイントを返します。

AscB の結果は Byte 型(0~255 の範囲)ですが、
Asc や AscW の結果は Integer 型であり、負数が返されることもあります。
投稿者 佐久 誠  (社会人) 投稿日時 2023/8/30 13:17:32
魔界の仮面弁士様,色々御指導下さり,誠に有難うございます。
結局,(数字,非数字混合の)複数文字列"xxxxxx"を全文字16進数変換するには,1文字ずつ,asc1=Asc(x)として,1文字分の,asc1値(非数字文字は,コード値)を16進数変換し,全文字(バイト数は各々異なるが)を構成させるようなに,(自分の適用目的に沿った)カスタマイズ化したプログラミングを実施するのが,(アセンブラー言語で鍛えられた)自分にとっては,一番楽のようです。
投稿者 (削除されました)  () 投稿日時 2023/8/30 15:26:23
(削除されました)
投稿者 (削除されました)  () 投稿日時 2023/8/30 15:59:49
(削除されました)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/8/30 16:10:33
> 1文字分の,asc1値(非数字文字は,コード値)を16進数変換し,全文字(バイト数は各々異なるが)を構成させるようなに,

そうですね。X = Hex(Asc(S)) で 16 進数変換した場合、
 S = vbTab の場合は 1 文字
 S = "ヲ"   の場合は 2 文字
 S = "を"  の場合は 4 文字
といった感じで、桁数が可変になります。

そこで桁数をそろえるため、お手軽な方法として
 「先頭にゼロを補ってから、Right 関数で右から必要な桁数を切り出す」
という手法が良く利用されています。例えばこんな感じですね。

Public Function DumpText(ByVal Text As StringAs String
    Dim P As Long
    Dim S As String
    Dim A As Integer
    For P = 1 To Len(Text)
        A = Asc(Mid$(Text, P, 1))
        S = S & Right$("0000" & Hex(A), IIf(A And &HFF00, 4, 2))
    Next
    DumpText = S
End Function


上記は Shift_JIS を想定したものですが、もしも Unicode で扱う場合は、
Asc 関数の代わりに AscW 関数を使うことになります。
たとえば S = "⑨" あるいは S = ChrW(&H2468) な文字列を渡すと
X = Hex(AscW(S)) で "2468" が得られます。

この場合、エンディアンに注意が必要となります。Unicode 扱いで変換する場合、
 UTF-16BE としては "2468"
 UTF-16LE としては "6824"
な結果が求められるわけですが、Windows では UTF-16 は通常 Little Endian を想定するため
後者の結果となるように、バイト順を入れ替えた文字列にしてやる必要があります。
投稿者 佐久 誠  (社会人) 投稿日時 2023/8/31 16:58:45
魔界の仮面弁士様,色々御指導下さり,誠に有難うございます。

お蔭で,Rich Textboxにより,文字に色付けする方法は判りましたが,
Textbox或いは,Rich Textboxには,選択文字の背景を色付けする(xxxxxx.BackColor = &HFような)機能も在りますでしょうか?
若し,存在してましたら,是非御指導くださいませ。
宜しくお願い申し上げます。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/8/31 17:48:32
> 選択文字の背景を色付けする(xxxxxx.BackColor = &HFような)機能も在りますでしょうか

プロパティ一発で…というわけにはいきませんが、
SendMessage API で EM_SETCHARFORMAT メッセージを送出することで可能です。
CHARFORMAT2 に対しては、dwMask のビットフラグに CFM_BACKCOLOR を立てて、
crBackColor メンバーに色情報を渡してやれば OK です。
https://learn.microsoft.com/ja-jp/windows/win32/api/richedit/ns-richedit-charformat2w_1
http://hanatyan.sakura.ne.jp/patio/read.cgi?no=126
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/8/31 18:31:06
これが VB6 ではなく VB.NET であれば、文字単位の背景色指定を
とても簡単に書けるのですけれどね。
RichTextBox1.SelectionBackColor = Color.Yellow


VB6 にも SelBackColor プロパティなんてものが欲しいところですが、
残念ながら、その機能がカプセル化されていないため、
先述の API 頼りになってしまいます。


ですが一応 VB6 でも、API を使わずに背景色をセットする方法があります。

具体的には、SelRTF プロパティ(あるいは TextRTF プロパティ) で
示される RTF 文字列を、直接書き換えるという手法です。

RTF 文字列の仕様は下記を参照。
http://ja.wikipedia.org/wiki/Rich_Text_Format
https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxrtfex/411d0d58-49f7-496c-b8c3-5859b045f6cf

RTF で指定する場合は、たとえば {\f1\cb1\cf2 Sample Text} などのようにします。
\cb というのが背景色で、 \cf というのは文字色の指定です。
その後に続く番号は、カラーパレットのインデックスを表しています。
カラーパレットというのは、使用する色を
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red192\green192\blue192;}
などの形式で並べたものです。
ちなみに \f はフォントの番号であり、{\fonttbl } に対応しています。

といっても、直接 RTFを作りこむのは面倒ですので、プロパティから既知の RTF を取得した後で、
Replace 関数なり正規表現なりで、\cb を補ってから、プロパティに書き戻す形の実装で。