┏第43号━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ .NETプログラミング研究 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
──<メニュー>───────────────────────
■.NET質問箱
・ページ範囲を指定して印刷するには?
・文字コードを判別するには?
───────────────────────────────
───────────────────────────────
■.NET質問箱
───────────────────────────────
「.NET質問箱」では、「どぼん!のプログラミング掲示板」に書き込
まれた.NETプログラミングに関する投稿を基に、さらに考察を加え、
Q&A形式にまとめて紹介します。
[URL]どぼん!のプログラミング掲示板
http://dobon.net/vb/bbs.html
───────────────────────────────
●ページ範囲を指定して印刷するには?
【質問】
PrintDialogクラスを使って印刷ダイアログを表示する際に、
PrintDialog.AllowSomePagesをTrueにして「ページ指定」ができるよ
うにしたのですが、「ページ指定」を選んでもすべてのページが印刷
されてしまいます。どのようにすれば指定されたページだけ印刷され
るようになりますか?
【回答】
PrintDialog.AllowSomePagesをTrueにすることにより、印刷ダイアロ
グでユーザーが印刷範囲を指定できるようになりますが、これだけで
指定されたページのみが印刷されるようになるわけではありません。
実際に指定されたページのみ印刷されるようにするには、そうなるよ
うに自分でコーディングする必要があります。
方法としては、PrinterSettings.PrintRangeがPrintRange.SomePages
となっている時(つまり、「ページ指定」が指定された時)に
PrinterSettings.FromPageとPrinterSettings.ToPageを調べてその範
囲のページだけが印刷されるようにします。
次の具体的なサンプルを示します。ここではButton1がクリックされ
た時に印刷ダイアログが表示され、「OK」がクリックされると印刷が
開始されるようにしています。印刷されるページは10ページあり、ペー
ジ数が印刷されるようになっています。「ページ指定」が指定されて
いると、指定されたページのみが印刷されます。
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
'現在のページ
Private currentPage As Integer = 1
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'PrintDocumentオブジェクトの作成
Dim pd As New System.Drawing.Printing.PrintDocument
'PrintPageイベントハンドラの追加
AddHandler pd.PrintPage, AddressOf pd_PrintPage
'PrintDialogクラスの作成
Dim pdlg As New PrintDialog
'PrintDocumentを指定
pdlg.Document = pd
'ページ指定できるようにする
pdlg.AllowSomePages = True
'ページ指定の最小値と最大値を指定する
pdlg.PrinterSettings.MinimumPage = 1
pdlg.PrinterSettings.MaximumPage = 10
'印刷開始と終了ページを指定する
pdlg.PrinterSettings.FromPage = pdlg.PrinterSettings.MinimumPage
pdlg.PrinterSettings.ToPage = pdlg.PrinterSettings.MaximumPage
'印刷の選択ダイアログを表示する
If pdlg.ShowDialog() = DialogResult.OK Then
'OKがクリックされた時は印刷する
pd.Print()
End If
End Sub
Private Sub pd_PrintPage(ByVal sender As Object, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs)
'ページ範囲が指定されており、始めのページのときは、
'印刷開始ページまで飛ばす
If e.PageSettings.PrinterSettings.PrintRange = _
System.Drawing.Printing.PrintRange.SomePages AndAlso _
currentPage = 1 Then
currentPage = e.PageSettings.PrinterSettings.FromPage
End If
'currentPageで指定されたページを描画する
Dim f As New Font("Arial", 100)
e.Graphics.DrawString(currentPage.ToString(), f, Brushes.Black, 0, 0)
f.Dispose()
'次のページがあるか調べる
If currentPage >= 10 OrElse _
(e.PageSettings.PrinterSettings.PrintRange = _
System.Drawing.Printing.PrintRange.SomePages AndAlso _
e.PageSettings.PrinterSettings.ToPage <= currentPage) Then
'次のページがないことを通知する
e.HasMorePages = False
currentPage = 1
Else
e.HasMorePages = True
currentPage += 1
End If
End Sub
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
//現在のページ
private int currentPage = 1;
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArgs e)
{
//PrintDocumentオブジェクトの作成
System.Drawing.Printing.PrintDocument pd =
new System.Drawing.Printing.PrintDocument();
//PrintPageイベントハンドラの追加
pd.PrintPage +=
new System.Drawing.Printing.PrintPageEventHandler(pd_PrintPage);
//PrintDialogクラスの作成
PrintDialog pdlg = new PrintDialog();
//PrintDocumentを指定
pdlg.Document = pd;
//ページ指定できるようにする
pdlg.AllowSomePages = true;
//ページ指定の最小値と最大値を指定する
pdlg.PrinterSettings.MinimumPage = 1;
pdlg.PrinterSettings.MaximumPage = 10;
//印刷開始と終了ページを指定する
pdlg.PrinterSettings.FromPage = pdlg.PrinterSettings.MinimumPage;
pdlg.PrinterSettings.ToPage = pdlg.PrinterSettings.MaximumPage;
//印刷の選択ダイアログを表示する
if (pdlg.ShowDialog() == DialogResult.OK)
{
//OKがクリックされた時は印刷する
pd.Print();
}
}
private void pd_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
//ページ範囲が指定されており、始めのページのときは、
//印刷開始ページまで飛ばす
if (e.PageSettings.PrinterSettings.PrintRange ==
System.Drawing.Printing.PrintRange.SomePages &&
currentPage == 1)
{
currentPage = e.PageSettings.PrinterSettings.FromPage;
}
//currentPageで指定されたページを描画する
Font f = new Font("Arial", 100);
e.Graphics.DrawString(currentPage.ToString(),
f, Brushes.Black, 0, 0);
f.Dispose();
//次のページがあるか調べる
if (currentPage >= 10 ||
(e.PageSettings.PrinterSettings.PrintRange ==
System.Drawing.Printing.PrintRange.SomePages &&
e.PageSettings.PrinterSettings.ToPage <= currentPage))
{
//次のページがないことを通知する
e.HasMorePages = false;
currentPage = 1;
}
else
{
e.HasMorePages = true;
currentPage++;
}
}
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
○この記事の基になった掲示板のスレッド
[題名] プリンタ選択ダイアログのページ指定印刷について
[投稿者(敬称略)] のぶ, 管理人
[URL] http://dobon.net/vb/bbs/log3-3/1505.html
───────────────────────────────
●文字コードを判別するには?
【質問】
文字コードの分からないテキストファイルを読み込む時に、その文字
コードはどのように判別すればよいのでしょうか?
【回答】
.NET Frameworkでは文字コードを判別する方法が用意されていません
ので、外部DLL、OCX等を使うか、自分でコードを書くかということに
なるでしょう。
次に示すコードは、私がJcode.pmのgetcodeメソッドを参考にして書
かせていただいた(移植したつもり)メソッドです。バイナリ配列で
渡されたデータが、JIS、Shift-JIS、EUC、UTF-8(もしくはASCII)
のいずれであるかを判別し、結果をEncodingオブジェクトで返します。
[URL]Jcode.pm
http://openlab.ring.gr.jp/Jcode/index-j.html
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
'''
''' 文字コードを判別する
'''
'''
''' Jcode.pmのgetcodeメソッドを移植したものです。
''' Jcode.pm(http://openlab.ring.gr.jp/Jcode/index-j.html)
''' Jcode.pmのCopyright : Copyright 1999 Dan Kogai.
'''
''' 文字コードを調べるデータ
''' 適当と思われるEncodingオブジェクト。
''' 判断できなかった時はnull。
Public Shared Function GetCode(ByVal byts() As Byte) As System.Text.Encoding
Const bESC As Byte = &H1B
Const bAT As Byte = &H40
Const bDollar As Byte = &H24
Const bAnd As Byte = &H26
Const bOP As Byte = &H28 '(
Const bB As Byte = &H42
Const bD As Byte = &H44
Const bJ As Byte = &H4A
Const bI As Byte = &H49
Dim len As Integer = byts.Length
Dim [binary] As Integer = 0
Dim ucs2 As Integer = 0
Dim sjis As Integer = 0
Dim euc As Integer = 0
Dim utf8 As Integer = 0
Dim b1, b2 As Byte
Dim i As Integer
For i = 0 To len - 1
If byts(i) <= &H6 OrElse byts(i) = &H7F OrElse byts(i) = &HFF Then
''binary'
[binary] += 1
If len - 1 > i AndAlso _
byts(i) = &H0 AndAlso byts(i - 1) <= &H7F Then
'smells like raw unicode
ucs2 += 1
End If
End If
Next i
If [binary] > 0 Then
If ucs2 > 0 Then
'JIS
'ucs2(Unicode)
Return System.Text.Encoding.Unicode
'binary
Else
Return Nothing
End If
End If
For i = 0 To len - 2
b1 = byts(i)
b2 = byts(i + 1)
If b1 = bESC Then
If b2 >= &H80 Then
'not Japanese
'ASCII
Return System.Text.Encoding.ASCII
Else
If len - 2 > i AndAlso _
b2 = bDollar AndAlso byts(i + 2) = bAT Then
'JIS_0208 1978
'JIS
Return System.Text.Encoding.GetEncoding(50220)
ElseIf len - 2 > i AndAlso _
b2 = bDollar AndAlso byts(i + 2) = bB Then
'JIS_0208 1983
'JIS
Return System.Text.Encoding.GetEncoding(50220)
ElseIf len - 5 > i AndAlso _
b2 = bAnd AndAlso byts(i + 2) = bAT AndAlso _
byts(i + 3) = bESC AndAlso byts(i + 4) = bDollar AndAlso _
byts((i + 5)) = bB Then
'JIS_0208 1990
'JIS
Return System.Text.Encoding.GetEncoding(50220)
ElseIf len - 3 > i AndAlso _
b2 = bDollar AndAlso byts(i + 2) = bOP AndAlso _
byts(i + 3) = bD Then
'JIS_0212
'JIS
Return System.Text.Encoding.GetEncoding(50220)
ElseIf len - 2 > i AndAlso b2 = bOP AndAlso _
(byts(i + 2) = bB OrElse byts(i + 2) = bJ) Then
'JIS_ASC
'JIS
Return System.Text.Encoding.GetEncoding(50220)
ElseIf len - 2 > i AndAlso _
b2 = bOP AndAlso byts(i + 2) = bI Then
'JIS_KANA
'JIS
Return System.Text.Encoding.GetEncoding(50220)
End If
End If
End If
Next i
For i = 0 To len - 2
b1 = byts(i)
b2 = byts(i + 1)
If ((b1 >= &H81 AndAlso b1 <= &H9F) OrElse _
(b1 >= &HE0 AndAlso b1 <= &HFC)) AndAlso _
((b2 >= &H40 AndAlso b2 <= &H7E) OrElse _
(b2 >= &H80 AndAlso b2 <= &HFC)) Then
sjis += 2
i += 1
End If
Next i
For i = 0 To len - 2
b1 = byts(i)
b2 = byts(i + 1)
If ((b1 >= &HA1 AndAlso b1 <= &HFE) AndAlso _
(b2 >= &HA1 AndAlso b2 <= &HFE)) OrElse _
(b1 = &H8E AndAlso (b2 >= &HA1 AndAlso b2 <= &HDF)) Then
euc += 2
i += 1
ElseIf len - 2 > i AndAlso b1 = &H8E AndAlso _
(b2 >= &HA1 AndAlso b2 <= &HFE) AndAlso _
(byts(i + 2) >= &HA1 AndAlso byts(i + 2) <= &HFE) Then
euc += 3
i += 2
End If
Next i
For i = 0 To len - 2
b1 = byts(i)
b2 = byts(i + 1)
If (b1 >= &HC0 AndAlso b1 <= &HDF) AndAlso _
(b2 >= &H80 AndAlso b2 <= &HBF) Then
utf8 += 2
i += 1
ElseIf len - 2 > i AndAlso _
(b1 >= &HE0 AndAlso b1 <= &HEF) AndAlso _
(b2 >= &H80 AndAlso b2 <= &HBF) AndAlso _
(byts(i + 2) >= &H80 AndAlso byts(i + 2) <= &HBF) Then
utf8 += 3
i += 2
End If
Next i
If euc > sjis AndAlso euc > utf8 Then
'EUC
Return System.Text.Encoding.GetEncoding(51932)
ElseIf sjis > euc AndAlso sjis > utf8 Then
'SJIS
Return System.Text.Encoding.GetEncoding(932)
ElseIf utf8 > euc AndAlso utf8 > sjis Then
'UTF8
Return System.Text.Encoding.UTF8
End If
Return Nothing
End Function
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
///
/// 文字コードを判別する
///
///
/// Jcode.pmのgetcodeメソッドを移植したものです。
/// Jcode.pm(http://openlab.ring.gr.jp/Jcode/index-j.html)
///
/// 文字コードを調べるデータ
/// 適当と思われるEncodingオブジェクト。
/// 判断できなかった時はnull。
public static System.Text.Encoding GetCode(byte [] byts)
{
const byte bESC = 0x1B;
const byte bAT = 0x40;
const byte bDollar = 0x24;
const byte bAnd = 0x26;
const byte bOP = 0x28; //(
const byte bB = 0x42;
const byte bD = 0x44;
const byte bJ = 0x4A;
const byte bI = 0x49;
int len = byts.Length;
int binary = 0;
int ucs2 = 0;
int sjis = 0;
int euc = 0;
int utf8 = 0;
byte b1, b2;
for (int i = 0; i < len; i++)
{
if (byts[i] <= 0x06 || byts[i] == 0x7F || byts[i] == 0xFF)
{
//'binary'
binary++;
if (len - 1 > i && byts[i] == 0x00 && byts[i - 1] <= 0x7F)
{
//smells like raw unicode
ucs2++;
}
}
}
if (binary > 0)
{
if (ucs2 > 0)
//JIS
//ucs2(Unicode)
return System.Text.Encoding.Unicode;
else
//binary
return null;
}
for (int i = 0; i < len - 1; i++)
{
b1 = byts[i];
b2 = byts[i + 1];
if (b1 == bESC)
{
if (b2 >= 0x80)
//not Japanese
//ASCII
return System.Text.Encoding.ASCII;
else if (len - 2 > i &&
b2 == bDollar && byts[i + 2] == bAT)
//JIS_0208 1978
//JIS
return System.Text.Encoding.GetEncoding(50220);
else if (len - 2 > i &&
b2 == bDollar && byts[i + 2] == bB)
//JIS_0208 1983
//JIS
return System.Text.Encoding.GetEncoding(50220);
else if (len - 5 > i &&
b2 == bAnd && byts[i + 2] == bAT && byts[i + 3] == bESC &&
byts[i + 4] == bDollar && byts[i + 5] == bB)
//JIS_0208 1990
//JIS
return System.Text.Encoding.GetEncoding(50220);
else if (len - 3 > i &&
b2 == bDollar && byts[i + 2] == bOP && byts[i + 3] == bD)
//JIS_0212
//JIS
return System.Text.Encoding.GetEncoding(50220);
else if (len - 2 > i &&
b2 == bOP && (byts[i + 2] == bB || byts[i + 2] == bJ))
//JIS_ASC
//JIS
return System.Text.Encoding.GetEncoding(50220);
else if (len - 2 > i &&
b2 == bOP && byts[i + 2] == bI)
//JIS_KANA
//JIS
return System.Text.Encoding.GetEncoding(50220);
}
}
for (int i = 0; i < len - 1; i++)
{
b1 = byts[i];
b2 = byts[i + 1];
if (((b1 >= 0x81 && b1 <= 0x9F) || (b1 >= 0xE0 && b1 <= 0xFC)) &&
((b2 >= 0x40 && b2 <= 0x7E) || (b2 >= 0x80 && b2 <= 0xFC)))
{
sjis += 2;
i++;
}
}
for (int i = 0; i < len - 1; i++)
{
b1 = byts[i];
b2 = byts[i + 1];
if (((b1 >= 0xA1 && b1 <= 0xFE) && (b2 >= 0xA1 && b2 <= 0xFE)) ||
(b1 == 0x8E && (b2 >= 0xA1 && b2 <= 0xDF)))
{
euc += 2;
i++;
}
else if (len - 2 > i &&
b1 == 0x8E && (b2 >= 0xA1 && b2 <= 0xFE) &&
(byts[i + 2] >= 0xA1 && byts[i + 2] <= 0xFE))
{
euc += 3;
i += 2;
}
}
for (int i = 0; i < len - 1; i++)
{
b1 = byts[i];
b2 = byts[i + 1];
if ((b1 >= 0xC0 && b1 <= 0xDF) && (b2 >= 0x80 && b2 <= 0xBF))
{
utf8 += 2;
i++;
}
else if (len - 2 > i &&
(b1 >= 0xE0 && b1 <= 0xEF) && (b2 >= 0x80 && b2 <= 0xBF) &&
(byts[i + 2] >= 0x80 && byts[i + 2] <= 0xBF))
{
utf8 += 3;
i += 2;
}
}
if (euc > sjis && euc > utf8)
//EUC
return System.Text.Encoding.GetEncoding(51932);
else if (sjis > euc && sjis > utf8)
//SJIS
return System.Text.Encoding.GetEncoding(932);
else if (utf8 > euc && utf8 > sjis)
//UTF8
return System.Text.Encoding.UTF8;
return null;
}
‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
次にこのメソッドの使い方を示します。このサンプルでは、TextBox1
にテキストファイルのパスを入力し、Button1をクリックすると、テ
キストファイルの文字コードを調べ、デコードし、RichTextBox1にそ
の内容を表示しています。
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'テキストファイルを開く
Dim fs As New System.IO.FileStream(TextBox1.Text, _
System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim bs(fs.Length - 1) As Byte
'byte配列に読み込む
fs.Read(bs, 0, bs.Length)
fs.Close()
'文字コードを取得する
Dim enc As System.Text.Encoding = GetCode(bs)
'デコードして表示する
RichTextBox1.Text = enc.GetString(bs)
End Sub
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArgs e)
{
//テキストファイルを開く
System.IO.FileStream fs = new System.IO.FileStream(
TextBox1.Text, System.IO.FileMode.Open,
System.IO.FileAccess.Read);
byte[] bs = new byte[fs.Length];
//byte配列に読み込む
fs.Read(bs, 0, bs.Length);
fs.Close();
//文字コードを取得する
System.Text.Encoding enc = GetCode(bs);
//デコードして表示する
RichTextBox1.Text = enc.GetString(bs);
}
‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
またクラスとして、「G-PROJECT」さんが「文字コード判別・変換ク
ラス」を公開されています。判別できる文字コードは、JIS、Shift
-JIS、EUC、UTF-8のようです。
[URL]■G-PROJECT■ -文字コード判別・変換クラス(C#)
http://kasumi.sakura.ne.jp/~gm/gpj/dev/tips/net/txtenc.shtml
外部DLLに頼る方法としては、mlang.dllのIMultiLanguage2::
DetectInputCodepageを使用する方法があります。文字コードの判別
が必要な大半のアプリで、これが使われているのではないかと思いま
す。(Internet Explorer 5以上で使用できます。)
[URL]IMultiLanguage2::DetectInputCodepage Method
http://msdn.microsoft.com/workshop/misc/mlang/reference/ifaces/imultilanguage2/detectinputcodepage.asp
以下に.NETでIMultiLanguage2::DetectInputCodepageメソッドを使う
ための方法を簡単に説明します。
mlang.dllを使うため、VS.NETの「参照の追加」でCOMを探してみても、
mlang.dllは通常見つかりません。これは、mlang.dllにタイプライブ
ラリがないためです。よってまず"MIDL.EXE"を使用して、"MLang.Idl
"から"MLang.tlb"を作成し、これを"regtlib.exe"を使って登録しま
す。(VS.NET 2003 をインストールしたフォルダが"C:\Program
Files\Microsoft Visual Studio .NET 2003"であるならば、"MIDL.
EXE"は"C:\Program Files\Microsoft Visual Studio .NET 2003
\Common7\Tools\Bin\Midl.Exe"に、"MLang.Idl"は"C:\Program Files
\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include
\MLang.Idl"にあるでしょう。)これで「参照の追加」の「COM」で
"mlang.dll"(MultiLanguage Object Model)を選択できるようにな
ります。(VS.NETを使わない場合は、"Tlbimp.exe"を使ってinterop
assembly(相互運用機能アセンブリ)を作成します。)
これで、DetectInputCodepageメソッドを使う準備ができました。次
にDetectInputCodepageメソッドを使って文字コードを判別するサン
プルを紹介します。このサンプルでも先と同じく、TextBox1にテキス
トファイルのパスを入力し、Button1をクリックすると、テキストフ
ァイルの文字コードを調べ、デコードし、RichTextBox1にその内容を
表示しています。
‥‥▽VB.NET ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'テキストファイルを開く
Dim fs As New System.IO.FileStream(TextBox1.Text, _
System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim bs(fs.Length - 1) As Byte
'byte配列に読み込む
fs.Read(bs, 0, bs.Length)
fs.Close()
'sbyte型配列に変換する
Dim sbs(bs.Length - 1) As System.SByte
System.Buffer.BlockCopy(bs, 0, sbs, 0, bs.Length)
'文字コードを判別する
Dim enc As System.Text.Encoding = DetectEncoding(sbs)
'デコードして表示する
RichTextBox1.Text = enc.GetString(bs)
End Sub
'''
''' IMultiLanguage2.DetectInputCodepageを使って文字コードを判別する
'''
''' 文字コードを調べるデータ
''' 適当と思われるEncodingオブジェクト。
Public Shared Function DetectEncoding(ByVal sbyts() As System.SByte) _
As System.Text.Encoding
'準備
Dim ml As New MultiLanguage.CMultiLanguageClass
Dim scores As Integer = 10
Dim detects(scores - 1) As MultiLanguage.tagDetectEncodingInfo
Dim len As Integer = sbyts.Length
'文字コードを判別
ml.DetectInputCodepage(Convert.ToUInt32(0), Convert.ToUInt32(0), _
sbyts(0), len, detects(0), scores)
'一番初めのtagDetectEncodingInfoのEncodingを返す
Return System.Text.Encoding.GetEncoding( _
Convert.ToInt32(detects(0).nCodePage))
End Function
‥‥△VB.NET ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
‥‥▽C# ここから▽‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArgs e)
{
//テキストファイルを開く
System.IO.FileStream fs = new System.IO.FileStream(
TextBox1.Text, System.IO.FileMode.Open,
System.IO.FileAccess.Read);
byte[] bs = new byte[fs.Length];
//byte配列に読み込む
fs.Read(bs, 0, bs.Length);
fs.Close();
//sbyte型配列に変換する
sbyte[] sbs = new sbyte[bs.Length];
System.Buffer.BlockCopy(bs, 0, sbs, 0, bs.Length);
//文字コードを判別する
System.Text.Encoding enc = DetectEncoding(sbs);
//デコードして表示する
RichTextBox1.Text = enc.GetString(bs);
}
///
/// IMultiLanguage2.DetectInputCodepageを使って文字コードを判別する
///
/// 文字コードを調べるデータ
/// 適当と思われるEncodingオブジェクト。
public static System.Text.Encoding DetectEncoding(sbyte [] sbyts)
{
//準備
MultiLanguage.IMultiLanguage2 ml = new
MultiLanguage.CMultiLanguageClass();
int scores = 10;
MultiLanguage.tagDetectEncodingInfo[] detects =
new MultiLanguage.tagDetectEncodingInfo[scores];
int len = sbyts.Length;
//文字コードを判別
ml.DetectInputCodepage(
0, 0, ref sbyts[0], ref len, ref detects[0], ref scores);
//一番初めのtagDetectEncodingInfoのEncodingを返す
return System.Text.Encoding.GetEncoding(
(int) detects[0].nCodePage);
}
‥‥△C# ここまで△‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
DetectInputCodepageメソッドにより、複数の候補が
tagDetectEncodingInfoとして取得されることがありますが、0番目の
tagDetectEncodingInfoを採用するようにしています。また上記の方
法では判別するデータをsbyte型配列として指定するため、byte型配
列をsbyte型配列に変換しています。
○この記事の基になった掲示板のスレッド
[題名] 文字コードについて
[投稿者(敬称略)] nao, 管理人
[URL] http://dobon.net/vb/bbs/log3-4/1733.html
===============================
■このマガジンの購読、購読中止、バックナンバー、説明に関しては
次のページをご覧ください。
http://www.mag2.com/m/0000104516.htm
■発行人・編集人:どぼん!
(Microsoft MVP for Visual Basic, Oct 2004-Oct 2005)
http://dobon.net
dobon_info@yahoo.co.jp
■ご質問等はメールではなく、掲示板へお願いいたします。
http://dobon.net/vb/bbs.html
■上記メールアドレスへのメールは確実に読まれる保障はありません
(スパム、ウィルス対策です)。メールは下記URLのフォームメール
から送信してください。
http://dobon.net/mail.html
Copyright (c) 2003 - 2004 DOBON! All rights reserved.
===============================