テキストファイルを取り込んで加工して保存するプログラムを書いているのですが、一部の日本語ファイルが文字化けすることに困っています。
具体的には、既存のファイル(複数選択可)して、それらを使って別のテキストを作り(主にAppendメソッドなど)、最後にそれを別名で保存しています。
ファイルのロード・セーブにはともにTStringListのLoadFromFileとSaveToFileを使っています。
この時、作られたファイルの一部が文字化けすることに悩まされています。
ご意見をうかがいたいと思います。
いくつかの実験の結果、ファイルのエンコードによって不具合が生じるのではないかと思ったのですがいかがでしょうか。
・文字化けした部分をメモ帳へコピーしてASCI形式で保存してみると今度は文字化けしなかった。
・文字化けしたファイルを単独で(複数のファイルを開かずに)使う場合には文字化けしなかった。
・ちなみに、文字化けしたファイルはUTF-8という形式になっている(と思われる)。これはじつはメモ帳ではなくTextTreeというフリーソフトで作ったものです。
うまく状況説明できなくて申し訳ないのですが、ぜひどんなことでもご意見うかがいたいと思っています。よろしくお願いします。
森
テキストファイルの文字化けの件ですが、
Delphi2007までのTStringListはUNICODE非対応です。
というか、使えるのは日本語WindowsではShilt-JISのみです。
そのため他のエンコードを扱うときは自力だと相当な努力が必要かと思います。
現状ですとTNTWareというサイトが Unicode対応コンポーネントを公開しておりま
す。
赤尾鉄平
赤尾さんも仰っていますが、次あたりのバージョンまで Unicode は自力
になります。
こちらのサイトも参考になります↓
カルト・ドラン -「Delphi ローテクTips」
http://cult-drang.com/program/tips/
o(^^ )o--------⊆^U)┬┬~...
Terry
ご回答ありがとうございました。
テキストファイルにもいろいろあるんですね。。
勉強になりました。
当面は、形式さえ整えば読み込めるのだし、また日本語ファイルを扱うことはそこまで多くないので、「場合によっては文字化けが発生する。その場合には形式を修正して保存しなおせばよい」ということにしてバージョンの改訂を待ちたいと思います。
自分でUnicodeへの対応を用意するのは少し費用対効果が見合わないので、それは機会があればということにいたします。
どうもありがとうございました。
森
> 自分で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には詳しくなく、「あるものは使ってしまえ」程度の感覚ですが・・・(^_^;)
情報ありがとうございます。
まだ試してはいないのですが、バージョンは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
=======================
追加です。
試してみたところ、やはりUTF-8で書いたと思われるファイルのみは正常に表示することが出来ましたが、その他のファイルがおかしくなりました。
というわけですので、UTF-8で書かれているならその関数を用いて、そうでないならそのまま、というのが良さそうな気がするのですが、しかしテキストファイルの形式を取得する方法が分からないでいます。
そのようなことは可能なのでしょうか。
森。
2008/05/12 0:57 石川元太郎 <gisi...@aqua.plala.or.jp>:
--
対象の文章がある程度の長さを持ち、期待されるキーワードがあるのであれば、そのまま読み込んでS-JISとして検索しヒットすればそのまま
検索にヒットしないテキストは、UTF-8から変換して検索、両者で駄目ならば、両者で検索できない形式として、手動で変換するのが良いのでは?
> というわけですので、UTF-8で書かれているならその関数を用いて、そうでないならそのまま、というのが良さそうな気がするのですが、しかしテキストファイルの形式を取得する方法が分からないでいます。
> そのようなことは可能なのでしょうか。
関口
中村といいます。
>というわけですので、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
>しかしテキストファイルの形式を取得する方法が分からないでいます。
> そのようなことは可能なのでしょうか。
IMultiLanguage2 COMオブジェクトのDetectInputCodepageメソッドを
使うのが正攻法のようです。
以下のXRAYさんのホームページにDelphiでの使用例がありました。
http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/886_ChangeCodePage.htm#04
仕事で時間がないので試していませんが、時間を見つけて確認したいと思います。
確認できたら、またご報告いたします。
なるほど。そういう感じの方法もあるんですね。勉強になります。
今回は、期待されるキーワードというのが必ずしも思いつかないですが、しかし今後どこかで利用する機会がありそうです。
ありがとうございました。
森
2008/05/12 9:04 関口申一 <mu...@ops.dti.ne.jp>:
--
なるほど。どういう仕組みなのか正確には分からないですが、なんとなくやっていることは分かります。
2,3質問があります(むろん中村さん以外の方でも構いません)。
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>:
--
>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は1バイト目を見るとその文字が何バイトで構成されているかがわかりま
す。それでコード毎に進み具合が変わるのですね。最大6バイトで構成されるこ
ともあるようなのですが,日本語の場合は3バイトまでのようですので,それだ
けしかコーディングしてません。この判定方法では,1バイト目にUTF-8で許さ
れていない文字が出てくるかどうかで判定しています。非常に乱暴な判定方法な
んですが,S-JISの日本語文字列を入れるとほとんどFALSEが返りますので,なん
とかそれなりに判定できているようです。
先日お話した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.
近いうちに試してみたいと思いますが、しばらくお待ちください。
とりあえず、お礼が遅れては失礼なので、とりあえずお礼まで。
森
2008/05/17 2:51 石川元太郎 <gisi...@aqua.plala.or.jp>:
--