Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2023年01月03日] [更新 2023年01月04日] Delphi 一般・その他
テキスト保存 / 開くダイアログのエンコード設定
動作確認等 Windows 10 ビルド 19043 Pro 64 bit + Delphi XE5(UP2) Pro VCL-32
[整理番号 - 0840]







TSaveTextFileDialog / TOpenTextFileDialog のエンコード設定


TSaveTextFileDialog / TOpenTextFileDialog を使用して、テキストをファイルに保存する時と、ファイルからテキストを読み込む時のエンコードの設定方法のサンプルです。






01_EncodingIndex プロパティと Encodings プロパティ


TSaveTextFileDialog / TOpenTextFileDialog ダイアログには、[エンコーディング] の項目かあり、デフォルトで下図のような文字列がセットされています。
下図は、TSaveTextFileDialog ダイアログの下部の部分です。



図1

[エンコーディング] の項目のインデックスは、EncodingIndex プロパティで設定、取得できます。項目の文字列は、Encodings プロパティで設定、取得できます。
これらの値を使用して、テキストを保存、または読み込む時のエンコードの設定ができます。



リスト1
//=============================================================================
//  TSaveTextFileDialog の EncodingIndex プロパティと Encodings プロパティ
//  TOpenTextFileDialog も同じ
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LEncIndex : Integer;
  LEncText  : string;
begin
  if SaveTextFileDialog1.Execute then begin
    LEncIndex := SaveTextFileDialog1.EncodingIndex;
    LEncText := SaveTextFileDialog1.Encodings[LEncIndex];

    // エンコードのインデックスまたはエンコードの文字列に応じた処理
    ShowMessage(LEncText);
  end;
end;




02_Encodings.Objects プロパティを使用する


Encodings プロパティは、TStrings 型のプロパティです。AddObjects メソッドで TEncoding を格納しておけば、ダイアログで選択した [エンコーディング] に相当する TEncoding のポインタを取得できます。
その TEndoding の値を、TMemo.Linse.SaveToFile メソッド、あるいは TMemo.Lines.LoadFromFile メソッドなどの引数に使用すると便利です。その例です。



図2
[テキスト] をクリックしてから [保存]
  • TMemo にテキストを表示
  • これを保存して [開く] で読み込む

このサンプルでは、ダイアログの下部の [エンコーディング] は下図のようになります。
これは、TSaveTextFileDialog の場合ですが、TOpenTextFileDialog でも同じです。[保存] が [開く] になるだけです。



図3

LEncodings.AddObject の Shift_JIS の部分は、以下でも同じです。日本語 Windows の環境では、Ansi の指定は、自動的に Shift_JIS になります。


LEncodings.AddObject('Ansi', TEncoding.ANSI);


リスト2
//=============================================================================
//  保存するテキストを Memo1 ( TMemo ) に表示
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Clear;

  //文字列をセット
  Memo1.Lines.Add(#$4F60#$597D + ' !!');
  Memo1.Lines.Add(#$D842#$DFB7 + ' (サロゲートペアな文字)');
  Memo1.Lines.Add('テキストの保存と読み出し');
end;

//=============================================================================
//  テキストの保存
//  TSaveTextFileDialog におむるエンコードリストの作成
//
//  この場合の Unicode は UTF-16
//  この場合の UTF-8 は BOM 付き
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LEncodings : TStringList;
  LEncIndex  : Integer;
  LEncoding  : TEncoding;
begin
  // エンコードオブジェクトの作成
  LEncodings := TStringList.Create;
  try
    LEncodings.AddObject('Shift_JIS', TEncoding.GetEncoding(932));
    LEncodings.AddObject('Unicode',   TEncoding.Unicode);
    LEncodings.AddObject('UTF-8',     TEncoding.UTF8);

    SaveTextFileDialog1.Encodings.Assign(LEncodings);
  finally
    FreeAndNil(LEncodings);
  end;


  SaveTextFileDialog1.Filter := 'テキストファイル (*.txt)|*.txt|)';
  SaveTextFileDialog1.FileName := ExpandFileName('.\000.txt');
  SaveTextFileDialog1.EncodingIndex := 2;

  if SaveTextFileDialog1.Execute then begin
    // ダイアログで選択した TEncoding を取得
    LEncIndex := SaveTextFileDialog1.EncodingIndex;
    LEncoding := SaveTextFileDialog1.Encodings.Objects[LEncIndex] as TEncoding;

    Memo1.Lines.SaveToFile(SaveTextFileDialog1.FileName, LEncoding);
  end;
end;

//=============================================================================
//  テキストの読み込み
//  TOpenTextFileDialog におむるエンコードリストの作成
//
//  この場合の Unicode は UTF-16
//  この場合の UTF-8 は BOM 付き
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
var
  LEncodings : TStringList;
  LEncIndex  : Integer;
  LEncoding  : TEncoding;
begin
  Memo1.Lines.Clear;

  // エンコードオブジェクトのリストを作成
  LEncodings := TStringList.Create;
  try
    LEncodings.AddObject('Shift_JIS', TEncoding.GetEncoding(932));
    LEncodings.AddObject('Unicode',   TEncoding.Unicode);
    LEncodings.AddObject('UTF-8',     TEncoding.UTF8);

    OpenTextFileDialog1.Encodings.Assign(LEncodings);
  finally
    FreeAndNil(LEncodings);
  end;


  OpenTextFileDialog1.Filter := 'テキストファイル (*.txt)|*.txt|)';
  OpenTextFileDialog1.FileName := ExpandFileName('.\000.txt');
  OpenTextFileDialog1.EncodingIndex := 2;

  if OpenTextFileDialog1.Execute then begin
    // ダイアログで選択した TEncoding を取得
    LEncIndex := OpenTextFileDialog1.EncodingIndex;
    LEncoding := OpenTextFileDialog1.Encodings.Objects[LEncIndex] as TEncoding;

    Memo1.Lines.LoadFromFile(OpenTextFileDialog1.FileName, LEncoding);
  end;
end;


Windows が動作する環境では、ほとんどの場合リトルエンディアンと思われますが、コードページを指定して、強制的にリトルエンディアン、またはビッグエンディアンにすることもできます。
単に Unicode と書いた場合は、リトルエンディアンを意味します。リトルエンディアンは、LE、ビッグエンディアンは BE と表記することもあります。


    // Unicoede リトルエンディアン
    LEncodings.AddObject('Unicode (Little endian)', TEncoding.GetEncoding(1200));

    // Unicoede ビッグエンディアン
    LEncodings.AddObject('Unicode (Big endian)', TEncoding.GetEncoding(1201));


BOM 付き (BOM あり) と BOM なしにはコードページの区別はありません。EncodingIndex プロパティなどをを使用して、個別に処理する必要があります。