本投稿は Delphi Advent Calendar 2023 #2 の記事です。
はじめに
Windowsでテキスト加工をしてやり取りするときTMemoを使うことがあります。
あるとき,DelphiのMemoからコピーできるのに,Memoにコピーをすると一行の文字数が少なくなることがありました。そこで,Delphiとテキストエディタを使って文字列のやり取りをして,一行の文字数の制限がどのようになっているかを調べてみました。
実験1 TMemo から テキストエディタ へのコピー
ネットで調べてみるとVCLのTMemoの一行の最大は1024文字だという記述がありましたので,とりあえず1024文字+αで試してみることにしました。Windows VCLフォームのアプリケーションを作成し,TButtonを2つ,TMemoを2つ,Tlabelを1つ配置して以下のようなコードを書きました。
Button1とButton2にそれぞれMemo1に文字を追加するコード,Memoの一行目の文字を数えるコードを書いています。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
s0,s1:string;
i:integer;
begin
s0:='0123456789ABCDEF'; // 16文字
s1:='';
for i:=1 to 64 do begin // 64回加えて1024文字
s1:=s1+s0;
end;
s1:=s1+'++++++++++'; // 1024文字以降は”+”を追加
Memo1.Clear;
Memo1.Lines.Add(s1);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
s:string;
begin
s:=Memo1.Lines[0]; // Memo1の一行目を取り出す
Label1.Caption:=IntToStr(Length(s)); // 文字列の長さをLabel1に表示
end;
end.
実行してButton1をクリックしてMemo1に文字を入力して,表示された文字をCtrl+Aで全て選択してCtrl+Cでコピーし,テキストエディタにペーストすると,出力された文字列が一列で表示されます。
文字数を数えると,1034 文字 確かに全ての文字が一列で渡されています。
では,Button2をクリックしてMemo1で一行が何文字になっているのか調べてみましょう。
94 文字だといいます。あれれ,,
どうやら,Memo1に1列で表示されている文字数が返されているようです。
実験2 TMemoをフォームのサイズに合わせてリサイズしてみる
オブジェクトインスペクタで,Memo1のAnchers
を開いてakRight
とakTop
をTrue
にして,上記のプログラムを実行します。
Button1をクリックして,Memo1に文字列を表示させ,フォームのサイズを変えてButton2をクリックすると,実験1とは違った数がLabel1に表示されることが分かります。
このことから,TMemoでは,表示された文字が保持されているが,画面表示を反映して1行の文字列が取り出されることが分かります。
実験3 TMemoにスクロールバーをつける
フォームにTCheckBox
を追加し,追加したCheckBox1のClickイベントに以下のコードを追加します。
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if Checkbox1.Checked then begin
Memo1.ScrollBars:=ssboth;
end else begin
Memo1.ScrollBars:=ssNone;
end;
end;
プログラムを実行して,Button1をクリックして文字列を追加し,Checkbox1をクリックしてMemo1にスクロールバーを表示させてから,Button2をクリックすると 1024 がLabel1に表示されました。
テキストエディタにペーストしておいた文字列をMemo1にコピーしてButton2をクリックしても1024が表示されます。
このことから,Memo1から取り出せる1行の文字の最大値は1024文字であるということが分かりました。
Delphiはユニコードに対応していますので,全角文字を使っても同様の結果となります。一行の制限はバイト数ではなく文字数です。(もしかすると,これはWindows側の問題で,Delphiの問題ではないかもしれません。)
まとめ
これらの実験から以下のことが分かりました。
- Delphi VCLアプリの
TMemo
からテキストエディタなどの他のアプリケーションへのコピー&ペーストでは,TMemo
に代入された文字列がそのままペースト可能です。文字数の制限は特に意識する必要は無いようです。 - テキストエディタなどの他のアプリケーションからDelphi VCLアプリの
TMemo
にテキストをペーストする場合1024文字の制限があります。その時TMemo
には最低でも横スクロールバーをつけておかねばならず,横スクロールバーがない場合は,表示されたままの文字がその行の一列として扱われます。
ちなみに,TMemoの全行の文字数の制限はMaxLength
で指定できます。
詳細はDocwikiの Vcl.StdCtrls.TCustomEdit.MaxLength から確認していただけます。
この情報が皆様のお役に立てば幸いです。間違いがございましたらお知らせください。