|
Delphi2010 Unicode文字 2010/12/04 |
従来のDelphi6等でも、Unicode文字をプログラム内で扱うだけでしたら、WideString型を利用して使用する事は出来、Canvas上に TextOutで作図する事は出来ましたが、各コンポーネント上にそのまま表示する事は出来ませんでした(「?」と文字化けしていました)。
直前バージョンのDelphi2009より、各コンポーネント上で Unicode文字がそのまま表示出来るようになったようです。私自身は Delphi2009を所持していませんので、その効果を見るのは Delphi2010が初めてです。
テスト30(フォルダ「030」)として新規作成しておきます。
Delphi6での文字列型 string は、ANK文字(アルファベット、数字、カナ)+記号(半角文字)と、2バイト系文字(全角文字;漢字等)を扱う、AnsiString型のことでした。2バイト系文字は、日本語の規格であるJISのコードを PC上で扱いやすくするためコードをずらしたSHIFT-JISコードが利用され、2バイトで1文字を扱うようになっていて、半角文字は1バイトで表しますが、2バイト系文字の第1バイトは、半角文字の主要文字と重ならないよう、グラフ文字のコード部分(80H〜9FH、E0H〜FDH)になっています。
例えば、
というような画面を作って、Edit1に文字を入力し、ボタンをクリックしたらLabel1に1文字ずつ分解して表示するようなプログラムを作成するとします。
procedure TForm1.Button1Click(Sender: TObject);
var
s,t,u : AnsiString ;
i : integer ;
begin
s := AnsiString(Edit1.Text) ;
t := '';
for i:=1 to Length(s) do begin
u := Copy(s,i,1);
t := t + u + '、' ;
end;
Label1.Caption := string(t) ;
end; |
従来のstring=AnsiStringに合わせるため、AnsiString型で宣言してキャスト(型変換)をしています。これを保存・コンパイル(再構築)・実行すると、下記のようになります。
「123あいう」と入力してボタンをクリックすると
↓
案の定、文字化けします。ですので普通は、2バイト系文字を扱う場合、1バイト目をチェックして対策するようにするのが常でした(カウンタを操作するため for文はそのまま使えないのでwhile文を使う)。下記は一例です。
procedure TForm1.Button1Click(Sender: TObject);
var
s,t,u : AnsiString ;
i : integer ;
begin
s := AnsiString(Edit1.Text) ;
t := '';
i := 0 ;
while (i < Length(s)) do begin
Inc(i);
u := Copy(s,i,1);
if (u >= #$80)and(u <= #$9f)
or (u >= #$e0)and(u <= #$fd) then begin
u := Copy(s,i,2);
Inc(i);
end;
t := t + u + '、';
end;
Label1.Caption := string(t) ;
end; |
これを保存・コンパイル(再構築)・実行すると、下記のようになります。
「123あいう」と入力してボタンをクリックすると
↓
こういうのが従来のパターンでした。
なお、文字入力欄で Unicode文字を使用すると、下記のように文字化けします。Delphi6の場合は、Edit1 での表示も文字化けします。
IMEパッドでハングル互換字母から入力
しかし Unicode文字の場合は、状況が全く異なってきます。
Delphi2010での通常の Unicode文字は、UnicodeString型となりますが、string型として宣言すると、UnicodeString型と同じとして扱われます(※Delphi2010デフォルト設定の場合)。
上記を Unicode文字として扱うようにプログラミングしてみます。
procedure TForm1.Button1Click(Sender: TObject);
var
s,t,u : String ;
i : integer ;
begin
s := Edit1.Text ;
t := '';
for i:=1 to Length(s) do begin
u := Copy(s,i,1);
t := t + u + '、' ;
end;
Label1.Caption := t ;
end; |
これを保存・コンパイル(再構築)・実行すると、下記のようになります。
上記同様、IMEパッドでハングル互換字母から入力すると
という感じで大丈夫
まず、Edit1.Text には、Unicode文字で入ってきますので、同じく Unicode文字を扱える変数 s にはそのまま代入できます。文字数を数える関数 Length は、Unicode文字に対応しています。あくまでも文字数であって、バイト数ではありません。ですので、文字「123あいう」は、文字数=6、となります。次に、関数 Copy も同様に、Unicode文字に対応していて、引数は文字位置・文字数として扱います。バイト数ではありません。Delphi2010では、string型=UnicodeString型の文字は、内部で UTF-16のUnicodeとして扱うようになっているとの事で、半角文字であろうと全角文字であろうと1文字は2バイトとして扱うようになっています。「Copy(s,i,1)」の代わりに「s[i]」も使えるようです。但し、従来の短い文字列(ShortString)と混同してしまう可能性もありますし、私的には余りオススメはしません。なお、Char型は、WideChar型になるようで、SizeOf(Char) は1バイトではなく2バイトとなります。
という訳で、Unicode文字を使うことにより、従来のような、半角か全角かのチェックなどは必要とせず、文字列を簡単に扱う事が出来、海外の文字も扱う事が出来るようになります。
各文字列を操作する関数・手続きを見れば、String、UnicodeString として利用出来そうな感じです。
AnsiString型から UnicodeString型へ変換する場合は、単純にキャストすれば良いようです。(us:UnicodeString(String)、as:AnsiString)
us := UnicodeString(as) ;
又は
us := String(as) ;
逆に、UnicodeString型からAnsiString型にキャストする場合は
as := AnsiString(us) ;
のようにしますが、この場合は、UnicodeにはあってShift-JISには無い文字は文字化けしますので推奨されていません。
あと気になるのは、ファイルシステムです。フォルダ名やファイル名に Unicode文字がそのまま使えるのでしょうか? という訳で、試してみました。ボタンを2つ追加します。2つ目(Button2)をクリックしたらフォルダを作るようにします。3つ目(Button3)をクリックしたらファイルを作るようにします。
procedure TForm1.Button2Click(Sender: TObject);
var
s : string ;
begin
s := ExtractFilePath(Application.ExeName);
s := s + Edit1.Text ;
CreateDir(s);
end;
procedure TForm1.Button3Click(Sender: TObject);
var
s : string ;
F : TextFile ;
begin
s := ExtractFilePath(Application.ExeName);
s := s + Edit1.Text + '.txt' ;
AssignFile(F, s);
ReWrite(F);
WriteLn(F, UTF8Encode(s));
CloseFile(F);
end; |
例外処理は入れていませんが、まぁただの簡易サンプルですので。
「Application.ExeName」は、実行プログラムのフルパス名を取得出来ます。関数 ExtractFilePath でパス部分=現在のプログラムのあるフォルダ名を取得出来ますので、その下に、フォルダやテキストファイルを作っています。テキストファイルの中身を書く際に、関数 UTF8Encode を使っていますが、これは、手続き Write、WriteLnでは UnicodeStringが使えない、という事で、Windowsのメモ帳のファイルの種類に「UTF8」があるので、UTF8に変換しています。それでは、保存・コンパイル(再構築)・実行をしてみます。
上記同様、IMEパッドでハングル互換字母から入力します。余り無茶苦茶に入力すると後で面倒になるかもしれないので注意して下さい。
ボタン2をクリックして、エクスプローラで確認
↓
フォルダ名はちゃんと Unicode文字で出来ているようです
※Windows7 です
ボタン3をクリックして、エクスプローラで確認
↓
ファイル名はちゃんと Unicode文字で出来ているようですね
↓
メモ帳を起動して開いてみます
文字コードを「UTF-8」にして開いて下さい
他のものだと文字化けします
↓
という訳で、出来ているようですね。※Windows7 の場合。WindowsXpでもできましたが、Windows2000では文字化けしました。
※CD-R/RWへ ISO9660形式で書き込みをするような場合は、フォルダ名・ファイル名の制限が厳しくなる場合が往々にしてありますので、うまく行かない可能性はあります。
しかし結構不便ですので、Unicode文字を利用してテキストファイルの読み書きを行う場合は、メモ(Memo)コンポーネントやリッチエディット(RichEdit)コンポーネントを経由させてエンコード指定をした方が良いような感じがします。
また、プリンタへの出力の場合、プリンタ内蔵フォントを使うと文字化けする可能性はあると思いますので(※一部のレーザープリンタや大判プリンタの場合)、Windowsフォントを利用するようにして下さい。
それと、全ての Windowsフォントが Unicode文字を持っているわけではありません。もっていない場合もありますが当然その場合、文字化け・文字が表示されない等のような場合も有り得ますので注意が必要かもしれません。
参照:
エディット(Edit) メモ(Memo) リッチエディット(RichEdit) テキストファイルを開く/保存の画面
|
|
バッチファイル
BASIC
C言語のお勉強
拡張子な話
DOSプログラム
Delphi
>Delphi入門編
>Delphi2010
▲2010/12/01
2010/12/04
▼2010/12/05
シェアウェア
Script!World
データベース
|