Help us understand the problem. What is going on with this article?

Delphi Starter Edition でメモ帳クローンを作る - 番外編

begin { はじめに

昨年末の Delphi Advent Calendar 2017 において、Delphi Starter Edition でメモ帳クローンを作るって記事を書きました。

image.png

そしてこんな記事を見つけました。

へぇぇ!そうなんだ!!...という事でこの機能を追加してみたいと思います。

実装

前回までのソースコードのダウンロード

前回終了時点のソースコードは以下から DL できます。

リファクタリング

ファイルを読み込んでいる場所が 3 箇所ありますので、これを一つにまとめます。

frmuMain.pas
  ...

  // キャプションを変更
  UpdateCaption;
  // エンコーディングを指定して読み込み
  Memo1.Lines.LoadFromFile(FFileName, GetEditorEncoding);

  ...

まずクラスの定義部に LoadFromFile() というメソッドを作ります。

frmuMain.pas
  ...

  private
    { Private 宣言 }
    FFileName: String;
    FEncodingIndex: Integer;
    FHeaderStr: string;
    FFooterStr: string;
    FMarginTop: Integer;
    FMarginBottom: Integer;
    FMarginLeft: Integer;
    FMarginRight: Integer;
    function DetectEncodingFromFile(FileName: string): Integer;
    procedure DispRowCol;
    function GetEditorEncoding: TEncoding;
    function GetTextFileName: string;
    procedure Init(AFileName: string = '');
    procedure LoadFromFile; // <- 追加
    procedure PrintText(const HeaderStr, FooterStr: string);
    procedure SaveFile;
    procedure UpdateCaption;
    procedure WmDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;
  public
    { Public 宣言 }
  end;
  ...

実装部は以下のようになります。implementation より下に記述します。

frmuMain.pas
procedure TForm1.LoadFromFile;
begin
  // キャプションを変更
  UpdateCaption;
  // エンコーディングを指定して読み込み
  Memo1.Lines.LoadFromFile(FFileName, GetEditorEncoding);
end;

そして Memo1.Lines.LoadFromFile() になっている箇所を、この LoadFromFile() で置き換えます。まずは WmDropFiles() メッセージハンドラの中。

frmuMain.pas
procedure TForm1.WmDropFiles(var Msg: TWMDropFiles);
var
  Buf: array [0..MAX_PATH] of Char;
begin
  // ドロップされた (最初の) ファイル名を取得
  DragQueryFile(Msg.Drop, 0, Buf, MAX_PATH);
  DragFinish(Msg.Drop);
  // ファイル名を保存
  FFileName := StrPas(Buf);
  // エンコーディングを判定
  FEncodingIndex := DetectEncodingFromFile(FFileName);
  // ファイルを読み込み
  LoadFromFile; // 修正
end;

FormShow() イベントハンドラの中。

frmuMain.pas
procedure TForm1.FormShow(Sender: TObject);
// フォーム表示時
var
  FileName, Msg: string;
  ret: Integer;
  reg: TRegistryIniFile;
begin
  ...

  FileName := ParamStr(1);
  if TFile.Exists(FileName) then
    begin
      // ファイルが存在する
      FFileName := FileName;
      // エンコーディングを判定
      FEncodingIndex := DetectEncodingFromFile(FFileName);
      // ファイルを読み込み
      LoadFromFile; // 修正
    end
  else
    begin

    ...

acOpenExecute() イベントハンドラの中。

frmuMain.pas
procedure TForm1.acOpenExecute(Sender: TObject);
// Action: 開く(O)...
begin
  OpenTextFileDialog1.EncodingIndex := FEncodingIndex;
  if OpenTextFileDialog1.Execute then
    begin
      // 値を保存
      FFileName := OpenTextFileDialog1.FileName;
      FEncodingIndex := OpenTextFileDialog1.EncodingIndex;
      // ファイルを読み込み
      LoadFromFile; // 修正
    end;
end;

これでリファクタリングは完了です。ファイルを開くロジックが一箇所に集約されました。

日付挿入ロジックの追加

日付挿入ロジックは以下のようになります。

  1. ファイルを読み取ってみる。
  2. 先頭行が ".LOG" で始まっていれば日付文字列 + 改行を追加

先頭行が ".LOG" というのは大文字で .LOG から始まっているという意味で、小文字ではダメですが、.LOGCABIN は受け付けます。星を散りばめた甘い夜を今も思い出しますね (?)。

先頭行は Memo1 (TMemo) の Lines プロパティの最初の要素です。つまり Memo1.Lines[0] が先頭行の文字列となります。これを調べればいいのですが、Memo1 が空の場合にはアクセスできません。つまり、まずは最低でも一行存在するかどうかを判定しなくてはなりません。Memo1 の行数は Lines.Count プロパティで調べられます。

  if Memo1.Lines.Count > 0 then
    begin
      // ここに処理
    end;

先頭行が ".LOG" で始まっているかどうかは、System.Pos() 関数で調べられます。System.Pos() は大文字小文字を区別します。単純な比較なので、正規表現を使うまでもないでしょう。

  if Pos('.LOG', Memo1.Lines[0]) = 1 then
    begin
      // ここに処理
    end;

TMemo の末尾に行を追加するには、Lines.Add() メソッドを使います。以下のコードは Memo1 の末尾に 'ABC' という行を追加します。

  Memo1.Lines.Add('ABC');

これらを踏まえると、LoadFromFile() メソッドの中身はこうなります。

frmuMain.pas
procedure TForm1.LoadFromFile;
begin
  // キャプションを変更
  UpdateCaption;
  // エンコーディングを指定して読み込み
  Memo1.Lines.LoadFromFile(FFileName, GetEditorEncoding);
  // 日付の追加
  if (Memo1.Lines.Count > 0) and (Pos('.LOG', Memo1.Lines[0]) = 1) then
    begin
      Memo1.Lines.Add(FormatDateTime('hh:nn yyyy/mm/dd', Now));
      Memo1.Lines.Add('');
    end;
end;

おわりに } end.

小改造なのでプロパティやメソッドを知っていれば簡単でしたね。

Delphi Starter Edition は現在 10.2 Tokyo Release 3 (10.2.3) がリリースされています。無償でアップデートできますので、Starter Edition をお使いの方は是非アップデートしてみてください。

image.png

新規インストールすると最初から 10.2.3 となります。

See also:

ht_deko
とある熊本の障害復旧(トラブルシューター)
https://ht-deko.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした