- 追加された行はこの色です。
- 削除された行はこの色です。
#title(.NETプログラミング研究 第43号)
#navi(.NETプログラミング研究)
#contents
*.NETプログラミング研究 第43号 [#z0685b9a]
**.NET質問箱 [#ccd73841]
「.NET質問箱」では、「どぼん!のプログラミング掲示板」に書き込まれた.NETプログラミングに関する投稿を基に、さらに考察を加え、Q&A形式にまとめて紹介します。
-[[どぼん!のプログラミング掲示板>http://dobon.net/vb/bbs.html]]
-[[どぼん!のプログラミング掲示板>https://dobon.net/vb/bbs.html]]
***ページ範囲を指定して印刷するには? [#u32b923c]
#column(注意){{
この記事の最新版は「[[ページ範囲を指定して印刷する>http://dobon.net/vb/dotnet/graphics/printrange.html]]」で公開しています。
この記事の最新版は「[[ページ範囲を指定して印刷する>https://dobon.net/vb/dotnet/graphics/printrange.html]]」で公開しています。
}}
''【質問】''
PrintDialogクラスを使って印刷ダイアログを表示する際に、PrintDialog.AllowSomePagesをTrueにして「ページ指定」ができるようにしたのですが、「ページ指定」を選んでもすべてのページが印刷されてしまいます。どのようにすれば指定されたページだけ印刷されるようになりますか?
''【回答】''
PrintDialog.AllowSomePagesをTrueにすることにより、印刷ダイアログでユーザーが印刷範囲を指定できるようになりますが、これだけで指定されたページのみが印刷されるようになるわけではありません。実際に指定されたページのみ印刷されるようにするには、そうなるように自分でコーディングする必要があります。
方法としては、PrinterSettings.PrintRangeがPrintRange.SomePagesとなっている時(つまり、「ページ指定」が指定された時)にPrinterSettings.FromPageとPrinterSettings.ToPageを調べてその範囲のページだけが印刷されるようにします。
次の具体的なサンプルを示します。ここではButton1がクリックされた時に印刷ダイアログが表示され、「OK」がクリックされると印刷が開始されるようにしています。印刷されるページは10ページあり、ページ数が印刷されるようになっています。「ページ指定」が指定されていると、指定されたページのみが印刷されます。
#code(vbnet){{
'現在のページ
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
}}
#code(csharp){{
//現在のページ
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++;
}
}
}}
○この記事の基になった掲示板のスレッド
-[[プリンタ選択ダイアログのページ指定印刷について | 投稿者(敬称略) のぶ, 管理人>http://dobon.net/vb/bbs/log3-3/1505.html]]
-[[プリンタ選択ダイアログのページ指定印刷について | 投稿者(敬称略) のぶ, 管理人>https://dobon.net/vb/bbs/log3-3/1505.html]]
***文字コードを判別するには? [#q9ccef78]
#column(注意){{
この記事の最新版は「[[文字コードを判別する>http://dobon.net/vb/dotnet/string/detectcode.html]]」で公開しています。
この記事の最新版は「[[文字コードを判別する>https://dobon.net/vb/dotnet/string/detectcode.html]]」で公開しています。
}}
''【質問】''
文字コードの分からないテキストファイルを読み込む時に、その文字コードはどのように判別すればよいのでしょうか?
''【回答】''
.NET Frameworkでは文字コードを判別する方法が用意されていませんので、外部DLL、OCX等を使うか、自分でコードを書くかということになるでしょう。
次に示すコードは、私がJcode.pmのgetcodeメソッドを参考にして書かせていただいた(移植したつもり)メソッドです。バイナリ配列で渡されたデータが、JIS、Shift-JIS、EUC、UTF-8(もしくはASCII)のいずれであるかを判別し、結果をEncodingオブジェクトで返します。
-[[Jcode.pm>http://openlab.ring.gr.jp/Jcode/index-j.html]]
#code(vbnet){{
''' <summary>
''' 文字コードを判別する
''' </summary>
''' <remarks>
''' Jcode.pmのgetcodeメソッドを移植したものです。
''' Jcode.pm(http://openlab.ring.gr.jp/Jcode/index-j.html)
''' Jcode.pmのCopyright : Copyright 1999 Dan Kogai.
''' </remarks>
''' <param name="byts">文字コードを調べるデータ</param>
''' <returns>適当と思われるEncodingオブジェクト。
''' 判断できなかった時はnull。</returns>
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
}}
#code(csharp){{
/// <summary>
/// 文字コードを判別する
/// </summary>
/// <remarks>
/// Jcode.pmのgetcodeメソッドを移植したものです。
/// Jcode.pm(http://openlab.ring.gr.jp/Jcode/index-j.html)
/// </remarks>
/// <param name="byts">文字コードを調べるデータ</param>
/// <returns>適当と思われるEncodingオブジェクト。
/// 判断できなかった時はnull。</returns>
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;
}
}}
次にこのメソッドの使い方を示します。このサンプルでは、TextBox1にテキストファイルのパスを入力し、Button1をクリックすると、テキストファイルの文字コードを調べ、デコードし、RichTextBox1にその内容を表示しています。
#code(vbnet){{
'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
}}
#code(csharp){{
//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);
}
}}
またクラスとして、「G-PROJECT」さんが「文字コード判別・変換クラス」を公開されています。判別できる文字コードは、JIS、Shift-JIS、EUC、UTF-8のようです。
-[[■G-PROJECT■ -文字コード判別・変換クラス(C#)>http://kasumi.sakura.ne.jp/~gm/gpj/dev/tips/net/txtenc.shtml]]
外部DLLに頼る方法としては、mlang.dllのIMultiLanguage2::DetectInputCodepageを使用する方法があります。文字コードの判別が必要な大半のアプリで、これが使われているのではないかと思います。(Internet Explorer 5以上で使用できます。)
-[[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にその内容を表示しています。
#code(vbnet){{
'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
''' <summary>
''' IMultiLanguage2.DetectInputCodepageを使って文字コードを判別する
''' </summary>
''' <param name="sbyts">文字コードを調べるデータ</param>
''' <returns>適当と思われるEncodingオブジェクト。</returns>
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
}}
#code(csharp){{
//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);
}
/// <summary>
/// IMultiLanguage2.DetectInputCodepageを使って文字コードを判別する
/// </summary>
/// <param name="sbyts">文字コードを調べるデータ</param>
/// <returns>適当と思われるEncodingオブジェクト。</returns>
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);
}
}}
DetectInputCodepageメソッドにより、複数の候補がtagDetectEncodingInfoとして取得されることがありますが、0番目のtagDetectEncodingInfoを採用するようにしています。また上記の方法では判別するデータをsbyte型配列として指定するため、byte型配列をsbyte型配列に変換しています。
○この記事の基になった掲示板のスレッド
-[[文字コードについて | 投稿者(敬称略) nao, 管理人>http://dobon.net/vb/bbs/log3-4/1733.html]]
-[[文字コードについて | 投稿者(敬称略) nao, 管理人>https://dobon.net/vb/bbs/log3-4/1733.html]]
**コメント [#x91966b6]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2004-10-14 (木) 06:00:00,DOBON!,2010-03-21 (日) 19:40:10,DOBON!)