[Delphi:90385] テキストファむルの文字化け。

3,295 views
Skip to first unread message

Kohta Mori

unread,
May 10, 2008, 4:07:03 AM5/10/08
to Del...@ml.users.gr.jp
皆様。お䞖話になっおいたす。

テキストファむルを取り蟌んで加工しお保存するプログラムを曞いおいるのですが、䞀郚の日本語ファむルが文字化けするこずに困っおいたす。

具䜓的には、既存のファむル耇数遞択可しお、それらを䜿っお別のテキストを䜜り䞻にAppendメ゜ッドなど、最埌にそれを別名で保存しおいたす。
ファむルのロヌド・セヌブにはずもにTStringListのLoadFromFileずSaveToFileを䜿っおいたす。
この時、䜜られたファむルの䞀郚が文字化けするこずに悩たされおいたす。
ご意芋をうかがいたいず思いたす。

いく぀かの実隓の結果、ファむルの゚ンコヌドによっお䞍具合が生じるのではないかず思ったのですがいかがでしょうか。
・文字化けした郚分をメモ垳ぞコピヌしおASCI圢匏で保存しおみるず今床は文字化けしなかった。
・文字化けしたファむルを単独で耇数のファむルを開かずに䜿う堎合には文字化けしなかった。
・ちなみに、文字化けしたファむルはUTF-8ずいう圢匏になっおいるず思われる。これはじ぀はメモ垳ではなくTextTreeずいうフリヌ゜フトで䜜ったものです。

うたく状況説明できなくお申し蚳ないのですが、ぜひどんなこずでもご意芋うかがいたいず思っおいたす。よろしくお願いしたす。

森

Teppei Akao

unread,
May 11, 2008, 12:40:05 AM5/11/08
to Del...@ml.users.gr.jp
森さんこんにちは。

テキストファむルの文字化けの件ですが、
Delphi2007たでのTStringListはUNICODE非察応です。
ずいうか、䜿えるのは日本語WindowsではShilt-JISのみです。
そのため他の゚ンコヌドを扱うずきは自力だず盞圓な努力が必芁かず思いたす。
珟状ですずTNTWareずいうサむトが Unicode察応コンポヌネントを公開しおおりた
す。

赀尟鉄平


Terry

unread,
May 11, 2008, 1:10:06 AM5/11/08
to Del...@ml.users.gr.jp
森 さん、こんにちは。Terry寺田です(^-^)

赀尟さんも仰っおいたすが、次あたりのバヌゞョンたで Unicode は自力
になりたす。

こちらのサむトも参考になりたす↓
カルト・ドラン -「Delphi ロヌテクTips」
http://cult-drang.com/program/tips/

o(^^ )o--------⊆^U)┬┬~...
Terry

Kohta Mori

unread,
May 11, 2008, 5:49:58 AM5/11/08
to Del...@ml.users.gr.jp
赀尟さん、Terryさん。

ご回答ありがずうございたした。
テキストファむルにもいろいろあるんですね。。
勉匷になりたした。

圓面は、圢匏さえ敎えば読み蟌めるのだし、たた日本語ファむルを扱うこずはそこたで倚くないので、「堎合によっおは文字化けが発生する。その堎合には圢匏を修正しお保存しなおせばよい」ずいうこずにしおバヌゞョンの改蚂を埅ちたいず思いたす。
自分でUnicodeぞの察応を甚意するのは少し費甚察効果が芋合わないので、それは機䌚があればずいうこずにいたしたす。

どうもありがずうございたした。

森

石川元倪郎

unread,
May 11, 2008, 11:57:53 AM5/11/08
to Del...@ml.users.gr.jp
こんにちは。
石川ず申したす。

> 自分でUnicodeぞの察応を甚意するのは少し費甚察効果が芋合わないので、
>それは機䌚があればずいうこずにいたしたす。

System.Utf8ToAnsiルヌチンを䜿っお䜕ずかなりたせんでしょうか。

以䞋はアプリケヌションフォルダヌ内に.NET Frameworkのアプリで䜜成した
UTF-8のテキストファむル'Test.txtをTMemoコンポヌネントに衚瀺するためのコヌドです。

//これは文字化けしたす。
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Test.txt');
end;

//以䞋のコヌドでは正垞に衚瀺されたす。
procedure TForm1.Button2Click(Sender: TObject);
var
sl: TStringList;
begin
sl := TStringList.Create;
try
sl.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Test.txt');
Memo1.Text := Utf8ToAnsi(sl.Text);
finally
sl.Free;
end;
end;

テストした環境は Windows XP SP2 + Delphi2005 です。
Delphi2005より前のバヌゞョンでUtf8ToAnsiルヌチンがあるのかどうかは調べおいたせん。

私自身もUnicodeには詳しくなく、「あるものは䜿っおしたえ」皋床の感芚ですが・・・(^_^;)

Kohta Mori

unread,
May 11, 2008, 12:07:53 PM5/11/08
to Del...@ml.users.gr.jp
石川さん。

情報ありがずうございたす。

ただ詊しおはいないのですが、バヌゞョンは6.0なので䜿えるのではないかず思いたす。
ずころで、その方法を䜿うにあたっおはそのファむルがどの圢匏で曞かれおいるのかを知る必芁があるのではないかず思うのですが、その点はいかかでしょうか。
UTF-8で曞かれおいないファむルをその関数に入れおしたっおは逆におかしい結果になるのではないかず思うのですが、この点はどうなのでしょうか。

よろしくお願いしたす。

森。


2008/05/12 0:57 石川元倪郎 <gisi...@aqua.plala.or.jp>:

--
=======================
Kohta Mori
Graduate School of Economics
University of Tokyo
kmo...@yahoo.co.jp
=======================

Kohta Mori

unread,
May 11, 2008, 12:21:22 PM5/11/08
to Del...@ml.users.gr.jp
石川さん。

远加です。
詊しおみたずころ、やはりUTF-8で曞いたず思われるファむルのみは正垞に衚瀺するこずが出来たしたが、その他のファむルがおかしくなりたした。

ずいうわけですので、UTF-8で曞かれおいるならその関数を甚いお、そうでないならそのたた、ずいうのが良さそうな気がするのですが、しかしテキストファむルの圢匏を取埗する方法が分からないでいたす。
そのようなこずは可胜なのでしょうか。

森。

2008/05/12 0:57 石川元倪郎 <gisi...@aqua.plala.or.jp>:

--

関口申䞀

unread,
May 11, 2008, 8:04:46 PM5/11/08
to Del...@ml.users.gr.jp
石川様

  察象の文章がある皋床の長さを持ち、期埅されるキヌワヌドがあるのであれば、そのたた読み蟌んでS-JISずしお怜玢しヒットすればそのたた
怜玢にヒットしないテキストは、UTF-8から倉換しお怜玢、䞡者で駄目ならば、䞡者で怜玢できない圢匏ずしお、手動で倉換するのが良いのでは

> ずいうわけですので、UTF-8で曞かれおいるならその関数を甚いお、そうでないならそのたた、ずいうのが良さそうな気がするのですが、しかしテキストファむルの圢匏を取埗する方法が分からないでいたす。
> そのようなこずは可胜なのでしょうか。

関口


Sunvisor

unread,
May 11, 2008, 10:03:33 PM5/11/08
to Del...@ml.users.gr.jp
森さん

䞭村ずいいたす。

>ずいうわけですので、UTF-8で曞かれおいるならその関数を甚いお、そうでないならそ
>のたた、ずいうのが良さそうな気がするのですが、しかしテキストファむルの圢匏を
>取埗する方法が分からないでいたす。
>そのようなこずは可胜なのでしょうか。

UTF-8の文字䜓系からUTF8であるかどうかをだいたい怜蚎付けられる簡易刀定
ルヌチンを䜜っおみたした。

function TForm1.isUTF(AStr: String): Boolean;
var
I: Integer;
begin
I := 1;
while I <= Length(AStr) do
begin
case AStr[I] of
#$00..#$7f: inc(I);
#$c2..#$df: inc(I,2);
#$e0..#$ef: inc(I,3);
else begin
Result := false;
exit;
end;
end;
end;
Result := true;
end;

むっちゃアバりトなルヌチンですがわりず正解を出すず思いたす。UTF-8か
SJISしかない堎合だったらこのルヌチンで刀定可胜ず思いたす。UTF16やらEUC
-JPも入っおくるずなるずお手䞊げです。

┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏┏
┏┏┏
┏┏┏ 䞭村 久叞 (NAKAMURA, Hisashi)
┏┏┏ sunv...@sta.tenri-u.ac.jp

石川元倪郎

unread,
May 12, 2008, 8:33:08 PM5/12/08
to Del...@ml.users.gr.jp
森さん、こんにちは。
石川です。

>しかしテキストファむルの圢匏を取埗する方法が分からないでいたす。
> そのようなこずは可胜なのでしょうか。


IMultiLanguage2 COMオブゞェクトのDetectInputCodepageメ゜ッドを
䜿うのが正攻法のようです。

以䞋のXRAYさんのホヌムペヌゞにDelphiでの䜿甚䟋がありたした。

http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/886_ChangeCodePage.htm#04

仕事で時間がないので詊しおいたせんが、時間を芋぀けお確認したいず思いたす。
確認できたら、たたご報告いたしたす。

Kohta Mori

unread,
May 13, 2008, 12:09:49 AM5/13/08
to Del...@ml.users.gr.jp
石川さん。

ありがずうございたす
自分も目を通しおみたす。

森

2008/05/13 9:33 石川元倪郎 <gisi...@aqua.plala.or.jp>:

--

Kohta Mori

unread,
May 13, 2008, 12:13:28 AM5/13/08
to Del...@ml.users.gr.jp
関口さた

なるほど。そういう感じの方法もあるんですね。勉匷になりたす。
今回は、期埅されるキヌワヌドずいうのが必ずしも思い぀かないですが、しかし今埌どこかで利甚する機䌚がありそうです。

ありがずうございたした。

森

2008/05/12 9:04 関口申䞀 <mu...@ops.dti.ne.jp>:

--

Kohta Mori

unread,
May 13, 2008, 12:31:45 AM5/13/08
to Del...@ml.users.gr.jp
䞭村様。

なるほど。どういう仕組みなのか正確には分からないですが、なんずなくやっおいるこずは分かりたす。

質問がありたすむろん䞭村さん以倖の方でも構いたせん。

1. #$00 ずいうのはどういう意味ですか $は16進法を瀺すのだったず思いたすが、#を぀けるずどうなるのでしょうか。

2.


> #$00..#$7f: inc(I);
> #$c2..#$df: inc(I,2);
> #$e0..#$ef: inc(I,3);

ずいう颚に、コヌドごずに文字列の怜玢䜍眮の進み具合が異なるのはなぜですか。これは半角・党角ずいう違いですか。

3.


> #$00..#$7f: inc(I);
> #$c2..#$df: inc(I,2);
> #$e0..#$ef: inc(I,3);

ずいうように、おそらくこれは文字が想定されるものであるかを刀定しおいるのだず思うのですが、この察象文字は網矅的なのでしょうか。数字の意味では、7fずc2の間に間隔があいおいるように思うのですが、これはなぜですか。

4.
最埌に、ここに珟れおいるコヌドUTF-8だず思いたすがの䞀芧衚を掲茉しおいるサむトがあれば教えおください。いろいろあっおどれがどれなのか少し混乱しおいたす。

森

2008/05/12 11:03 Sunvisor <sunv...@sta.tenri-u.ac.jp>:

--

Sunvisor

unread,
May 13, 2008, 3:31:49 AM5/13/08
to Del...@ml.users.gr.jp
森さん
䞭村です。

>1. #$00 ずいうのはどういう意味ですか $は16進法を瀺すのだったず思いたすが、
>#を぀けるずどうなるのでしょうか。

文字キャラクタずいうこずです。#9ならタブ#13なら改行ずいう感じでよく䜿
いたすよね。

>2.
>> #$00..#$7f: inc(I);
>> #$c2..#$df: inc(I,2);
>> #$e0..#$ef: inc(I,3);
>ずいう颚に、コヌドごずに文字列の怜玢䜍眮の進み具合が異なるのはなぜですか。こ
>れは半角・党角ずいう違いですか。
>
>3.
>> #$00..#$7f: inc(I);
>> #$c2..#$df: inc(I,2);
>> #$e0..#$ef: inc(I,3);
>ずいうように、おそらくこれは文字が想定されるものであるかを刀定しおいるのだず
>思うのですが、この察象文字は網矅的なのでしょうか。数字の意味では、7fずc2の間
>に間隔があいおいるように思うのですが、これはなぜですか。
>
>4.
>最埌に、ここに珟れおいるコヌドUTF-8だず思いたすがの䞀芧衚を掲茉しおいるサ
>むトがあれば教えおください。いろいろあっおどれがどれなのか少し混乱しおいたす。

このcase文はWikipediaに茉っおいるUTF-8の項目から䜜りたした。

http://ja.wikipedia.org/wiki/UTF-8

UTF-8はバむト目を芋るずその文字が䜕バむトで構成されおいるかがわかりた
す。それでコヌド毎に進み具合が倉わるのですね。最倧バむトで構成されるこ
ずもあるようなのですが日本語の堎合はバむトたでのようですのでそれだ
けしかコヌディングしおたせん。この刀定方法ではバむト目にUTF-8で蚱さ
れおいない文字が出おくるかどうかで刀定しおいたす。非垞に乱暎な刀定方法な
んですがS-JISの日本語文字列を入れるずほずんどFALSEが返りたすのでなん
ずかそれなりに刀定できおいるようです。

石川元倪郎

unread,
May 16, 2008, 1:51:35 PM5/16/08
to Del...@ml.users.gr.jp
森さん、こんにちは。
石川です。

先日お話したIMultiLanguage2 COMオブゞェクトのDetectInputCodepageメ゜ッドを
を䜿っおテキストファむルの゚ンコヌドを調べる方法ですが、XRAYさんのホヌムペヌゞ
に曞かれおいる内容を参考に、テキストファむル゚ンコヌドのコヌドペヌゞを取埗
する関数(GetTextFileCodePage)を䜜っおみたした。

個人的には、「これは䜿える」ず思うのですが・・・。
是非ずも確認しおください。

ものすごく長文になりたすが、党コヌドを掲茉したす。

たず、コピペタによりMyWindows.pasを䜜成しおください。
次に、メむンフォヌムにボタンずSaveDialogをドロップしお、フォヌムのOnCreate、
OnDestroyむベントずボタンのOnClickむベントハンドラの䞭身をコピペタしおください。

ボタンのOnClickむベントではコヌドペヌゞの名前を参照するためにGetCPInfoEx APIを
䜿甚しおいたすが、GetCPInfoEx APIはVCLで宣蚀されおいないので、MyWindows.pas内で
宣蚀したした。

実行しおみるず、Shift-JISのテキストファむルの堎合は
  CodePage = 932
  CodePageName = 932 (ANSI/OEM - 日本語 Shift-JIS)
ず衚瀺されたす。GetTextFileCodePageの戻り倀が932であればShift-JISのテキスト
ファむルだずいうこずです。

UTF-8のテキストファむルの堎合は
  CodePage = 65001
  CodePageName = 65001 (UTF-8)
ず衚瀺されたす。GetTextFileCodePageの戻り倀が65001であればUTF-8で゚ンコヌド
されたテキストファむルだずいうこずです。

GetTextFileCodePageの戻り倀が65001の堎合だけUtf8ToAnsiルヌチンをかたしおやり、
その他の堎合は、通垞の凊理ずいうのはどうでしょうか。

もちろん、Shift-JISずUTF-8以倖の圢匏のテキストファむルは文字化けしおしたいたすが、
そういうケヌスはレアであるものずしお・・・。

ちなみに、PCにむンストヌルされおいるコヌドペヌゞをリストアップするには、
EnumSystemCodePages APIを䜿いたす。これはWindowsナニットに宣蚀されおいたす。

参考にしたMultiLanguageタむプラむブラリながめながらMSDNを調べおみるず、
任意の圢匏のテキストファむルをShift-JISに倉換する方法が芋぀かるのかもしれたせんが、
ちょっずそこたでする気力はありたせん。

でも、.NET Frameworkのアプリが幅を利かせおきたら、UniCodeのテキストファむルず
Shift-JISのテキストファむルが氟濫しお、森さんがやっおおられるような凊理が必芁
になるこずになるような気がいたしたす。

少しでも、森さんの参考になりたしたら幞いです。

それでは。

//
// MyWindows.pas
//
unit MyWindows;

interface

uses
Windows, ActiveX, Classes;

{
MultiLanguageタむプラむブラリからの抜粋
出兞http://www.delphikingdom.com/asp/answer.asp?IDAnswer=16895
}
const
CLASS_CMultiLanguage: TGUID
= '{275C23E2-3747-11D0-9FEA-00AA003F8646}';
IID_IMultiLanguage2: TGUID
= '{DCCFC164-2B38-11D2-B7EC-00C04F8F5D9A}';

type
tagMIMECPINFO = packed record
dwFlags: LongWord;
uiCodePage: SYSUINT;
uiFamilyCodePage: SYSUINT;
wszDescription: array[0..63] of Word;
wszWebCharset: array[0..49] of Word;
wszHeaderCharset: array[0..49] of Word;
wszBodyCharset: array[0..49] of Word;
wszFixedWidthFont: array[0..31] of Word;
wszProportionalFont: array[0..31] of Word;
bGDICharset: Byte;
end;

tagMIMECSETINFO = packed record
uiCodePage: SYSUINT;
uiInternetEncoding: SYSUINT;
wszCharset: array[0..49] of Word;
end;

tagRFC1766INFO = packed record
lcid: LongWord;
wszRfc1766: array[0..5] of Word;
wszLocaleName: array[0..31] of Word;
end;

tagDetectEncodingInfo = packed record
nLangID: SYSUINT;
nCodePage: SYSUINT;
nDocPercent: SYSINT;
nConfidence: SYSINT;
end;

__MIDL_IWinTypes_0009 = record
case Integer of
0: (hInproc: Integer);
1: (hRemote: Integer);
end;

_RemotableHandle = packed record
fContext: Integer;
u: __MIDL_IWinTypes_0009;
end;

tagMIMECONTF = TOleEnum;

tagSCRIPTINFO = packed record
ScriptId: Byte;
uiCodePage: SYSUINT;
wszDescription: array[0..47] of Word;
wszFixedWidthFont: array[0..31] of Word;
wszProportionalFont: array[0..31] of Word;
end;

IEnumCodePage = interface(IUnknown)
['{275C23E3-3747-11D0-9FEA-00AA003F8646}']
function Clone(out ppEnum: IEnumCodePage): HResult; stdcall;
function Next(
celt: LongWord;
out rgelt: tagMIMECPINFO;
out pceltFetched: LongWord): HResult; stdcall;
function Reset: HResult; stdcall;
function Skip(celt: LongWord): HResult; stdcall;
end;

IEnumRfc1766 = interface(IUnknown)
['{3DC39D1D-C030-11D0-B81B-00C04FC9B31F}']
function Clone(out ppEnum: IEnumRfc1766): HResult; stdcall;
function Next(
celt: LongWord;
out rgelt: tagRFC1766INFO;
out pceltFetched: LongWord): HResult; stdcall;
function Reset: HResult; stdcall;
function Skip(celt: LongWord): HResult; stdcall;
end;

IMLangConvertCharset = interface(IUnknown)
['{D66D6F98-CDAA-11D0-B822-00C04FC9B31F}']
function Initialize(
uiSrcCodePage: SYSUINT;
uiDstCodePage: SYSUINT; dwProperty: LongWord): HResult; stdcall;
function GetSourceCodePage(out puiSrcCodePage: SYSUINT): HResult; stdcall;
function GetDestinationCodePage(out puiDstCodePage: SYSUINT): HResult; stdcall;
function GetProperty(out pdwProperty: LongWord): HResult; stdcall;
function DoConversion(
var pSrcStr: Byte;
var pcSrcSize: SYSUINT;
var pDstStr: Byte;
var pcDstSize: SYSUINT): HResult; stdcall;
function DoConversionToUnicode(
var pSrcStr: Shortint;
var pcSrcSize: SYSUINT;
var pDstStr: Word;
var pcDstSize: SYSUINT): HResult; stdcall;
function DoConversionFromUnicode(
var pSrcStr: Word;
var pcSrcSize: SYSUINT;
var pDstStr: Shortint;
var pcDstSize: SYSUINT): HResult; stdcall;
end;

IEnumScript = interface(IUnknown)
['{AE5F1430-388B-11D2-8380-00C04F8F5DA1}']
function Clone(out ppEnum: IEnumScript): HResult; stdcall;
function Next(
celt: LongWord;
out rgelt: tagSCRIPTINFO;
out pceltFetched: LongWord): HResult; stdcall;
function Reset: HResult; stdcall;
function Skip(celt: LongWord): HResult; stdcall;
end;

IMultiLanguage2 = interface(IUnknown)
['{DCCFC164-2B38-11D2-B7EC-00C04F8F5D9A}']
function GetNumberOfCodePageInfo(
out pcCodePage: SYSUINT): HResult; stdcall;
function GetCodePageInfo(
uiCodePage: SYSUINT;
LangId: Word;
out pCodePageInfo:
tagMIMECPINFO): HResult; stdcall;
function GetFamilyCodePage(
uiCodePage: SYSUINT;
out puiFamilyCodePage: SYSUINT): HResult; stdcall;
function EnumCodePages(
grfFlags: LongWord;
LangId: Word;
out ppEnumCodePage:
IEnumCodePage): HResult; stdcall;
function GetCharsetInfo(
const Charset:
WideString;
out pCharsetInfo: tagMIMECSETINFO): HResult; stdcall;
function IsConvertible(
dwSrcEncoding: LongWord;
dwDstEncoding: LongWord): HResult; stdcall;
function ConvertString(
var pdwMode: LongWord;
dwSrcEncoding: LongWord;
dwDstEncoding: LongWord;
var pSrcStr: Byte;
var pcSrcSize: SYSUINT;
var pDstStr: Byte;
var pcDstSize: SYSUINT): HResult; stdcall;
function ConvertStringToUnicode(
var pdwMode: LongWord;
dwEncoding: LongWord;
var pSrcStr: Shortint;
var pcSrcSize: SYSUINT;
var pDstStr: Word;
var pcDstSize: SYSUINT): HResult; stdcall;
function ConvertStringFromUnicode(
var pdwMode: LongWord;
dwEncoding: LongWord;
var pSrcStr: Word;
var pcSrcSize: SYSUINT;
var pDstStr: Shortint;
var pcDstSize: SYSUINT): HResult; stdcall;
function ConvertStringReset: HResult; stdcall;
function GetRfc1766FromLcid(
locale: LongWord;
out pbstrRfc1766: WideString): HResult; stdcall;
function GetLcidFromRfc1766(
out plocale: LongWord;
const bstrRfc1766: WideString): HResult; stdcall;
function EnumRfc1766(
LangId: Word;
out ppEnumRfc1766: IEnumRfc1766): HResult; stdcall;
function GetRfc1766Info(
locale: LongWord;
LangId: Word;
out pRfc1766Info: tagRFC1766INFO): HResult; stdcall;
function CreateConvertCharset(
uiSrcCodePage: SYSUINT;
uiDstCodePage: SYSUINT;
dwProperty: LongWord;
out ppMLangConvertCharset: IMLangConvertCharset): HResult; stdcall;
function ConvertStringInIStream(
var pdwMode: LongWord;
dwFlag: LongWord;
var lpFallBack: Word;
dwSrcEncoding: LongWord;
dwDstEncoding: LongWord;
const pstmIn: ISequentialStream;
const pstmOut: ISequentialStream): HResult; stdcall;
function ConvertStringToUnicodeEx(
var pdwMode: LongWord;
dwEncoding: LongWord;
var pSrcStr: Shortint;
var pcSrcSize: SYSUINT;
var pDstStr: Word;
var pcDstSize: SYSUINT;
dwFlag: LongWord;
var lpFallBack: Word): HResult; stdcall;
function ConvertStringFromUnicodeEx(
var pdwMode: LongWord;
dwEncoding: LongWord;
var pSrcStr: Word;
var pcSrcSize: SYSUINT;
var pDstStr: Shortint;
var pcDstSize: SYSUINT;
dwFlag: LongWord;
var lpFallBack: Word): HResult; stdcall;
function DetectCodepageInIStream(
dwFlag: LongWord;
dwPrefWinCodePage: LongWord;
const pstmIn: ISequentialStream;
var lpEncoding: tagDetectEncodingInfo;
var pnScores: SYSINT): HResult; stdcall;
function DetectInputCodepage(
dwFlag: LongWord;
dwPrefWinCodePage: LongWord;
var pSrcStr: Char; //ShortIntからCharに倉曎
var pcSrcSize: SYSINT;
var lpEncoding: tagDetectEncodingInfo;
var pnScores: SYSINT): HResult; stdcall;
function ValidateCodePage(
uiCodePage: SYSUINT;
var hwnd: _RemotableHandle): HResult; stdcall;
function GetCodePageDescription(
uiCodePage: SYSUINT;
lcid: LongWord;
lpWideCharStr: PWideChar;
cchWideChar: SYSINT): HResult; stdcall;
function IsCodePageInstallable(uiCodePage: SYSUINT): HResult; stdcall;
function SetMimeDBSource(dwSource: tagMIMECONTF): HResult; stdcall;
function GetNumberOfScripts(out pnScripts: SYSUINT): HResult; stdcall;
function EnumScripts(
dwFlags: LongWord;
LangId: Word;
out ppEnumScript: IEnumScript): HResult; stdcall;
function ValidateCodePageEx(
uiCodePage: SYSUINT;
var hwnd: _RemotableHandle;
dwfIODControl: LongWord): HResult; stdcall;
end;

{
テキストファむルのコヌドペヌゞを取埗する関数
参考http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/886_ChangeCodePage.htm#04
}
function GetTextFileCodePage(const FileName: string): Integer;

{
kernel32.dllのGetCPInfoExAを静的にリンク
}
type
PCpInfoEx = ^TCpInfoEx;
TCpInfoEx = record
MaxCharSize: UINT;
DefaultChar: array [0..MAX_DEFAULTCHAR - 1] of BYTE;
LeadByte: array [0..MAX_LEADBYTES - 1] of BYTE;
UnicodeDefaultChar: WCHAR;
CodePage: UINT;
CodePageName: array [0..MAX_PATH - 1] of CHAR;
end;

function GetCPInfoEx(
CodePage: UINT;
dwFlags: DWORD;
lpCPInfoEx: PCpInfoEx): BOOL; stdcall;

implementation

function GetTextFileCodePage(const FileName: string): Integer;
var
hr : HRESULT;
ms : TMemoryStream;
mLang : IMultiLanguage2;
dwFlag : DWORD;
arSrcStr : array of Char;
srcSize : SYSINT;
encoding : tagDetectEncodingInfo;
scores : SYSINT;
begin
Result := 0;

hr := CoCreateInstance(
CLASS_CMultiLanguage,
nil,
CLSCTX_INPROC_SERVER,
IID_IMultiLanguage2,
mLang);
if hr = S_OK then
begin
ms := TMemoryStream.Create;
try
ms.Clear;
ms.LoadFromFile(FileName);
srcSize := ms.Size + 2;
SetLength(arSrcStr, srcSize);
ms.Position :=0;
ms.Read(arSrcStr[0], ms.Size);
dwFlag := 0;
scores := 1;
hr := mLang.DetectInputCodepage(
dwFlag, 0, arSrcStr[0], srcSize, encoding, scores);
if hr = S_OK then begin
Result := Encoding.nCodePage;
end;
finally
ms.Free;
mLang := nil;
end;
end;
end;

function GetCPInfoEx; external kernel32 name 'GetCPInfoExA';

end.

//
// テスト甚メむンフォヌム
// ボタンずSaveDialogあり
//
unit FormTest;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm4 = class(TForm)
OpenDialog1: TOpenDialog;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private 宣蚀 }
public
{ Public 宣蚀 }
end;

var
Form4: TForm4;

implementation

uses
ActiveX, MyWindows;

{$R *.dfm}

procedure TForm4.FormCreate(Sender: TObject);
begin
CoInitialize(nil);
OpenDialog1.InitialDir := ExtractFileDir(Application.ExeName);
end;

procedure TForm4.FormDestroy(Sender: TObject);
begin
CoUninitialize;
end;

procedure TForm4.Button1Click(Sender: TObject);
var
codePage: Integer;
codePageInfo: TCpInfoEx;
codePageName: string;
begin
if OpenDialog1.Execute then
begin
codePage := GetTextFileCodePage(OpenDialog1.FileName);
if GetCPInfoEx(codePage, 0, @codePageInfo) then
codePageName := codePageInfo.CodePageName
else
codePageName := '䞍明';
MessageDlg('CodePage = ' + IntToStr(codePage) + sLineBreak
+ 'CodePageName = ' + codePageName, mtInformation, [mbOK], 0);
end;
end;

end.

Kohta Mori

unread,
May 17, 2008, 11:05:53 AM5/17/08
to Del...@ml.users.gr.jp
石川さん、ありがずうございたす。

近いうちに詊しおみたいず思いたすが、しばらくお埅ちください。
ずりあえず、お瀌が遅れおは倱瀌なので、ずりあえずお瀌たで。

森

2008/05/17 2:51 石川元倪郎 <gisi...@aqua.plala.or.jp>:

--

Reply all
Reply to author
Forward
0 new messages