11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Delphi] Vcl TMemoの1行の文字制限について

Last updated at Posted at 2023-12-01

本投稿は 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の一行目の文字を数えるコードを書いています。

Unit1.pas
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を開いてakRightakTopTrueにして,上記のプログラムを実行します。
Button1をクリックして,Memo1に文字列を表示させ,フォームのサイズを変えてButton2をクリックすると,実験1とは違った数がLabel1に表示されることが分かります。
このことから,TMemoでは,表示された文字が保持されているが,画面表示を反映して1行の文字列が取り出されることが分かります。

実験3 TMemoにスクロールバーをつける

フォームにTCheckBoxを追加し,追加したCheckBox1のClickイベントに以下のコードを追加します。

Unit1.pas
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 から確認していただけます。
この情報が皆様のお役に立てば幸いです。間違いがございましたらお知らせください。

11
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?