C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: Re: リッチテキストボックスに貼り付けすると、半角数字が消える


(過去ログ 92 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■54599 / inTopicNo.1)  リッチテキストボックスに張り付けすると、半角数字が消える
  
□投稿者/ hiro (1回)-(2010/10/27(Wed) 11:43:36)

分類:[.NET 全般] 

VisualStudio2005/VB

初めまして、hiroと申します。
ソースを書くための簡易的なエディタを制作しているのですが、リッチテキストボックスへの文字貼り付け時に妙な動作をしてしまいます。

@VisualStudio上のソースをコピー
Aフォームのリッチテキストボックスへペースト

⇒すると、全角文字の直後の半角数字がペーストされないのです。

わかりにくいと思いますので具体例を挙げますと、

VisualStudio上のソース
s1 = "0あ123a4a5a6a7a8a9a0a"
s2 = "あ01a2a3a4a5a6a7a8a9a0"
s3 = "0あ1234567890"
s4 = "あ01234567890a"

ペースト後
s1 = "0あa4a5a6a7a8a9a0a"
s2 = "あa2a3a4a5a6a7a8a9a0"
s3 = "0あ"
s4 = "あ


リッチテキストに対して入力制御などは実装していません。
コントロールを配置して、そのままの状態です。


どうかよろしくお願いします。




引用返信 編集キー/
■54601 / inTopicNo.2)  Re: リッチテキストボックスに貼り付けすると、半角数字が消える
□投稿者/ 魔界の仮面弁士 (1895回)-(2010/10/27(Wed) 12:51:56)
# タイトルの "張り付け"を "貼り付け" に改題しています。

No54599 (hiro さん) に返信
> リッチテキストに対して入力制御などは実装していません。
> コントロールを配置して、そのままの状態です。

コーディングの問題ではありません。「ワードパッド」等にペーストした場合も
文字化けの可能性があると思います。同じ化け方かどうかは別として。


> ソースを書くための簡易的なエディタを制作しているのですが、
> リッチテキストボックスへの文字貼り付け時に妙な動作をしてしまいます。

ソリューション エクスプローラーで、コピー元のソースファイル(*.vb)を選択し、
[ファイル]-[名前をつけて何某の保存]を選択してください。

そこで、[保存]ボタン横の▼ボタンを押して、「エンコード付きで保存」を選択し、
たとえばコードページ 65001 (BOM 無しの UTF-8)を選択してみてください。

この状態で、先のソースをコピーしてワードパッドに貼り付けても、
文字化けする事はありませんでした。当方は WinXP/SP3 + VS2005/SP1 です。



> s1 = "0あ123a4a5a6a7a8a9a0a"
> s2 = "あ01a2a3a4a5a6a7a8a9a0"
> s3 = "0あ1234567890"
> s4 = "あ01234567890a"

コピーされたデータの中身を調べてみたところ、プレーンテキストについては

 CF_UNICODETEXT : UTF-16 な文字列、末尾 00 00 終端
 CF_OEMTEXT : CP932 な文字列、末尾 00 終端
 CF_TEXT : VB2005側のコードページに応じた文字列

となっており、特に問題なさそうでした。ちなみに CF_LOCALE は、
当方環境では日本語を表す 1041 という数値(11,04,00,00)固定のようです。


問題のリッチテキスト (CF_RTFTEXT)については、コピー元のコードページによって
\noproof や段落データに差異が生じるようですが、データが化けているかどうかまでは
まだ調査していません。おそらくは、VS が出力するリッチテキストに誤りがあるか、
リッチテキストボックス側が RTF データを正しく解釈していないかのいずれかだと思いますが…。
引用返信 編集キー/
■54607 / inTopicNo.3)  Re[2]: Re: リッチテキストボックスに貼り付けすると、半角数字が消える
□投稿者/ hiro (2回)-(2010/10/27(Wed) 14:07:13)
魔界の仮面弁士 さん、回答有難うございます。

> コーディングの問題ではありません。「ワードパッド」等にペーストした場合も
> 文字化けの可能性があると思います。同じ化け方かどうかは別として。

確認してみたところ、
・NotePad ⇒ 問題なくペースト出来ました。
・WordPad ⇒ 同じ文字化けを起こしました。



> ソリューション エクスプローラーで、コピー元のソースファイル(*.vb)を選択し、
> [ファイル]-[名前をつけて何某の保存]を選択してください。
>
> そこで、[保存]ボタン横の▼ボタンを押して、「エンコード付きで保存」を選択し、
> たとえばコードページ 65001 (BOM 無しの UTF-8)を選択してみてください。
>
> この状態で、先のソースをコピーしてワードパッドに貼り付けても、
> 文字化けする事はありませんでした。当方は WinXP/SP3 + VS2005/SP1 です。
>

上記の方法で確認してみたところ、確かに問題なくそのままペーストすることが出来ました。




となるとやはり、文字化けが原因のようですね。
文字化けを起こさず、リッチテキストボックスに受け入れさせる方法を調べてみることにします。




引用返信 編集キー/
■54612 / inTopicNo.4)  Re[3]: Re: リッチテキストボックスに貼り付けすると、半角数字が消える
□投稿者/ 魔界の仮面弁士 (1896回)-(2010/10/27(Wed) 14:49:27)
No54607 (hiro さん) に返信
> ・NotePad ⇒ 問題なくペースト出来ました。
> ・WordPad ⇒ 同じ文字化けを起こしました。

問題が発生しているのは、今のところ、リッチテキストデータだけですね。
プレーンテキストデータは文字化けを起こしていないようなので、メモ帳では問題が出ないのでしょう。


> 文字化けを起こさず、リッチテキストボックスに受け入れさせる方法を調べてみることにします。

状況からすると、Visual Studio 2005 側の問題のように思えます。

有効な回避策は見つかりませんでしたが、データ内容を追ってみたところ、
どうやら、バイト数の切り替えがうまくいっていないようです。

-------------
元データとなる
 「s4 = "あ01234567890a"」
のコピー結果を見てみると、クリップボードには
 『\cf0 s4 = \cf3 "\uc2\u12354 \'82\'a0\uc101234567890a"』
 『\cf0 s4 = \cf3 "\u12354 ?01234567890a"』
というリッチテキストデータが出力されていました。

# 前者は、コピー元ファイルがコードページ 932 の場合、
# 後者は、65001 (UTF-8, BOM なし) の場合です。

なお、"あ" という文字は、Unicode では U+3042 (=12354)です。
CP932 では 82A0、UTF-8 では E38182 にエンコードされます。
-------------

「\'ff」や「\u数値」は、文字データを表すエスケープ表記、
「\cf値」という部分は、色指定(カラーテーブルのN番目の色)で、
「\uc値」は、後続の「\u値」部のバイト数を切り替える制御語です。


そして、この \uc でのバイト数切り替えが、
 \uc2「あ」\uc1「01234567890a」
と行われているわけですが、Visual Studio の出力結果では
「\uc1」と「01234567890a」がくっついてしまっているため、
1 バイトへの切り替えが正しく行われないようです。


生成される RTF データが、
 『\cf0 s4 = \cf3 "\uc2\u12354 \'82\'a0\uc101234567890a"』
ではなく、
 『\cf0 s4 = \cf3 "\uc2\'82\'a0\uc1 01234567890a"』
 『\cf0 s4 = \cf3 "\uc2\u12354\'82\'a0\uc1 01234567890a"』
 『\cf0 s4 = \cf3 "\uc2\u12354 \'82\'a0\uc1 01234567890a"』
 『\cf0 s4 = \cf3 "\'82\'a001234567890a"』
などで出力されていれば、既定のコードページ(932)の場合でも化けないようですが、
Visual Studio エディタが生成するデータがそうなっていない以上、こちらからは
手が出せそうにないですね。コピー後に勝手に加工すれば化けなくなりますが、
そういうわけにもいかないでしょうし。

# そもそも RTF の仕様として、どのように出力されるべきなのだろう?


ちなみに、Word や VS2005 からコピーした場合、クリップボードにコピーされる
RTF 形式は "Rich Text Format" 1 種類だけのようですが、
ワードパッドからコピーした場合には、
 "Rich Text Format"
 "Rich Text Format Without Objects"
 "RTF As Text"
 "RTF in UTF8"
 "RTF with NCRs for nonASCII"
といった、複数形式の RTF データが用意されるようです。
引用返信 編集キー/
■54643 / inTopicNo.5)  Re[3]: Re: リッチテキストボックスに貼り付けすると、半角数字が消える
□投稿者/ 魔界の仮面弁士 (1897回)-(2010/10/28(Thu) 11:57:02)
2010/10/28(Thu) 12:01:14 編集(投稿者)
No54607 (hiro さん) に返信
> 文字化けを起こさず、リッチテキストボックスに受け入れさせる方法を調べてみることにします。

クリップボードの内容を加工する方向で考えてみました。

RichTextBox に貼り付ける直前に、下記の処理を呼び出しておくと、
今回の現象(半角数字の欠損)がおきなくなると思います。

――どのタイミングで呼び出すべきかが悩ましいところですが。


Public Sub FixRTF()
    Dim baseData As IDataObject = Clipboard.GetDataObject()
    If Not baseData.GetDataPresent(DataFormats.Rtf) Then
        Return
    End If

    Dim oldRTF As String = baseData.GetData(DataFormats.Rtf).ToString()
    Dim newRTF As String = System.Text.RegularExpressions.Regex.Replace( _
        oldRTF, "(?<uc>\\uc\d)(?<num>\d)", "${uc}{}${num}")
    If newRTF <> oldRTF Then
        'Debug.Print(newRTF)
        Dim cloneData As New DataObject()
        For Each fmt As String In baseData.GetFormats(False)
            If fmt = DataFormats.Rtf Then
                cloneData.SetData(DataFormats.Rtf, newRTF)
            Else
                cloneData.SetData(fmt, baseData.GetData(fmt, False))
            End If
        Next
        'Clipboard.Clear()
        Clipboard.SetDataObject(cloneData, True)
    End If
End Sub

引用返信 編集キー/
■54758 / inTopicNo.6)  Re[4]: Re: リッチテキストボックスに貼り付けすると、半角数字が消える
□投稿者/ hiro (4回)-(2010/11/01(Mon) 15:34:26)
出張続きで返答できず申し訳ありませんでした。


> RichTextBox に貼り付ける直前に、下記の処理を呼び出しておくと、
> 今回の現象(半角数字の欠損)がおきなくなると思います。

教えていただいた処理を実行することで、仰られた通り文字化けが発生しなくなりました。


> ――どのタイミングで呼び出すべきかが悩ましいところですが。

Loadイベントで実行してみましたが、やはり正常には動作されませんでした。
KeyDownイベントでとも思いましたが、マウス操作によるペーストには適用できないのですよね。
結局初期フォーカスをリッチテキストボックスから外し、Enterイベント内で処理を行うことで解決しました。


ご丁寧に教えていただき、有難うございました。
非常に分かりやすかったです。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -