begin { はじめに
昨年末の Delphi Advent Calendar 2017 において、Delphi Starter Edition でメモ帳クローンを作るって記事を書きました。
- Delphi Starter Edition でメモ帳クローンを作る (前編)
- Delphi Starter Edition でメモ帳クローンを作る (後編)
- Delphi Starter Edition でメモ帳クローンを作る - 2nd Edition -
そしてこんな記事を見つけました。
へぇぇ!そうなんだ!!...という事でこの機能を追加してみたいと思います。
実装
前回までのソースコードのダウンロード
前回終了時点のソースコードは以下から DL できます。
リファクタリング
ファイルを読み込んでいる場所が 3 箇所ありますので、これを一つにまとめます。
...
// キャプションを変更
UpdateCaption;
// エンコーディングを指定して読み込み
Memo1.Lines.LoadFromFile(FFileName, GetEditorEncoding);
...
まずクラスの定義部に LoadFromFile() というメソッドを作ります。
...
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 より下に記述します。
procedure TForm1.LoadFromFile;
begin
// キャプションを変更
UpdateCaption;
// エンコーディングを指定して読み込み
Memo1.Lines.LoadFromFile(FFileName, GetEditorEncoding);
end;
そして Memo1.Lines.LoadFromFile() になっている箇所を、この LoadFromFile() で置き換えます。まずは WmDropFiles() メッセージハンドラの中。
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() イベントハンドラの中。
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() イベントハンドラの中。
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;
これでリファクタリングは完了です。ファイルを開くロジックが一箇所に集約されました。
日付挿入ロジックの追加
日付挿入ロジックは以下のようになります。
- ファイルを読み取ってみる。
- 先頭行が ".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() メソッドの中身はこうなります。
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 をお使いの方は是非アップデートしてみてください。
新規インストールすると最初から 10.2.3 となります。
See also: