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 プロパティなどをを使用して,個別に処理する必要があります.