Delphiのフォーマッタ(コードの整形)でDataMoudleが壊れる

TDataMoudleにはClassGroupプロパティがあります。
このプロパティで、データモジュールがVCL用かFMX用かフレームワークに依存しないかを設定します。

たとえばTTimerコンポーネントはVCL用のVcl.ExtCtrls.TTimerとFMX用のFMX.Types.TTimerがあります。
使用するコンポーネントとClassGroupで設定したフレームワークを一致させる必要があります。

formatter01

オブジェクトインスペクタでClassGroupプロパティを設定すると、ユニットファイルには次のような指令が追加されます。

ClassGroupがFMX.Controls.TControlの場合:

{%CLASSGROUP 'FMX.Controls.TControl'}

フォーマッタのコメントスペースの設定の「{ および (* コメントスペースの設定」は初期値が「内側と外側」になっています。
この設定でコードを整形すると、ClassGroupプロパティによって追加された指令が次のようになります。

{ %CLASSGROUP 'FMX.Controls.TControl' }

「{」「}」の間に空白が追加されました。

このように空白が追加されると、ClassGroupプロパティの値は未設定の状態になります。

ClassGroupプロパティの値が設定されていない状態になると、コンポーネントとフレームワークに不一致が生じます。
その結果、IDEでデータモジュールを読み込むときにエラーが発生します。

エラーが発生した場合は、ClassGroupプロパティの指令を修正すれば、元の状態に戻ります。

TMemIniFileに変更があれば自動的に保存する

Delphi 10.1 BerlinではTMemIniFileにAutoSaveプロパティが追加されました。

AutoSaveプロパティがTrueのときは、インスタンスの破棄時に変更があれば自動的に保存されます。

var
  Ini: TMemIniFile;
begin
  Ini := TMemIniFile.Create('C:\temp\test.ini', // ファイル名
    TEncoding.UTF8, // エンコーディング
    True); // セクションとキーの名前の大文字小文字を区別するか
  try
    Ini.AutoSave := True; // 変更があれば自動的に保存する
    …
  finally
    Ini.Free; // 変更があれば自動的に保存されます
  end;
end;

Delphi 10.1 BerlinでDOSCommandコンポーネントを使う

TurboPackDOSCommandコンポーネントは、バッチファイルを実行し、出力された文字を受け取ることができるコンポーネントです。
VCLアプリケーションとFireMonkeyアプリケーションの両方で使用できます。
対応しているOSはWindowsのみです。

DOSCommand-2

GetItに登録されているので、簡単にインストールできます。

DOSCommand-1

コマンドラインを実行する

実行するコマンドラインをCommandLineプロパティに設定して、Executeメソッドでプロセスを実行します。

DosCommand1.CommandLine := 'C:\Users\yamamoto\Documents\dir.bat';
DosCommand1.Execute;

カレントディレクトリを設定するにはCurrentDirプロパティを使用します。

DosCommand1.CurrentDir := 'C:\Users\yamamoto\';

出力を取得する

OnNewCharイベントで新しく出力された文字を取得できます。

OnNewLineイベントで出力された行を取得できます。

procedure TForm1.DosCommand1NewLine(ASender: TObject; const ANewLine: string;
  AOutputType: TOutputType);
begin
  case AOutputType of
    otEntireLine:
      Memo1.Lines.Add(ANewLine);
  end;
end;

memoやricheditに出力を直接渡したいときは、OutputLinesプロパティを使います。

DosCommand1.OutputLnes := Memo1.Lines;

Linesプロパティでコマンドのすべての出力を取得できます。

Memo2.Lines.AddStrings(DosCommand1.Lines);

入力を送信する

SendLine関数でDOSプロセスに入力を送信できます。

DosCommand1.SendLine('', True);

プロセスを中止する

OnTerminatedイベントでコマンドの終了を取得できます。

procedure TForm1.DosCommand1Terminated(Sender: TObject);
begin
  Memo1.Lines.Add('終了しました。');
end;

プロセスが終わる前に止めたいときは、Stopメソッドを使います。
※未確認

X秒間実行した後にプロセスを止めたいときは、MaxTimeAfterBeginningプロパティを使います。
※未確認

X秒間出力がなければプロセスを止めたい場合は、MaxTimeAfterLastOutputプロパティを使います。
※未確認

その他の設定

Priorityプロパティでプロセスの優先度を変更できます。

uses Winapi.Windows;

DosCommand1.Priority := HIGH_PRIORITY_CLASS;

優先度には次の値を設定します。

  • HIGH_PRIORITY_CLASS
  • IDLE_PRIORITY_CLASS
  • NORMAL_PRIORITY_CLASS
  • REALTIME_PRIORITY_CLASS

TerminatedプロパティがTrueのとき、入力された文字を出力します。
※未確認

サンプルアプリケーション

フォームにTDosCommandコンポーネントと、TButtonコンポーネント、TMemoコンポーネントを配置します。

DOSCommand-3

Button1を押すと、カレントディレクトリを「C:\Users\yamamoto\」にして、バッチファイル「C:\Users\yamamoto\Documents\dir.bat」を実行します。

出力された内容ははMemo1に表示します。

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Clear;
  DosCommand1.CurrentDir := 'C:\Users\yamamoto\';
  DosCommand1.CommandLine := 'C:\Users\yamamoto\Documents\dir.bat';
  DosCommand1.Execute;
end;

procedure TForm1.DosCommand1NewLine(ASender: TObject; const ANewLine: string;
  AOutputType: TOutputType);
begin
  // 出力された文字を1行ずつ受け取る
  case AOutputType of
    otEntireLine:
      Memo1.Lines.Add(ANewLine);
  end;
end;

procedure TForm1.DosCommand1Terminated(Sender: TObject);
begin
  Memo1.Lines.Add('終了しました。');
end;

TStringListの要素を文字列の長さでソートする

DelphiのTStringListには、リスト内の文字列を昇順でソートするSortメソッドの他に、任意の条件でソートするCustomSortメソッドがあります。
TStringListのCustomSortメソッドを使って、文字列の長さでソートする方法を紹介します。

CustomSortメソッドは引数にTStringListSortCompare型の関数をとります。
TStringListSortCompare型は次のように定義されています。

TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer;

TStringListSortCompare型の文字列の長さを比較する関数を作成します。

function StringLengthCompare(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := List[Index1].Length - List[Index2].Length;
end;

TStringListのCustomSortメソッドの引数にこの関数を渡すと、文字列の長さ順にソートします。

次のサンプルアプリケーションでは、ボタンを押すとTStringListの文字列をソートして結果をメモに表示します。

フォームにTButtonとTMemoを配置します。
ボタンを押すと、ソート結果を表示します。

function StringLengthCompare(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := List[Index1].Length - List[Index2].Length;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  stli: TStringList;
begin
  stli := TStringList.Create;

  // お試しデータ格納
  stli.Add('aa');
  stli.Add('a');
  stli.Add('aaaaa');
  stli.Add('aaaa');
  stli.Add('aaa');

  stli.CustomSort(StringLengthCompare);
  Memo1.Text := stli.Text;

  stli.Free;
end;

sort01

AFSoft さんの記事を読みやすくする HTML ファイル

Delphi/C++Builderには大量のコンポーネントが用意されています。
たくさんありすぎで、すべてのコンポーネントを把握するのは困難です。
使ったことのないコンポーネントもたくさんあります。

AFSoftさんのサイトでは、VCL/FireMonkeyのたくさんのコンポーネントを画面キャプチャ付きで説明されています。
AFSoftさんの記事を読んで、コンポーネントの概略を知るだけでも、開発効率はぐっと上がると思います。
斜め読みでもいいので、一度目を通しておくといいかもしれません。

Delphi Forumトピック: ごくごく基本的な VCL の使い方AFSoftさんの記事を読みやすくするHTMLファイルが公開されています。

AFsoft

このHTMLファイルでは、VCLとFireMonkeyのコンポーネントがカテゴリ別に整理されています。
目的のコンポーネントを見つけやすくなっていて、知りたいコンポーネントの解説記事が読みやすっくなっています。
興味のあるカテゴリーから読んでみてはいかがでしょうか。

Delphi XE6のVCLフォームアプリケーションで、グリッドのセル入力に入力規則を適用する

グリッドのOnGetEditMaskイベントハンドラを記述すると、ユーザーがセルに入力できる有効な入力文字列を示す編集マスクをインプレースエディタに提供できます。

次のコードは、ユーザーが3列目を入力するときは編集マスクを提供します。

procedure TForm1.StringGrid1GetEditMask(Sender: TObject; ACol, ARow: Integer;
  var Value: string);
begin
  if ACol = 1 then
    Value := '9999/99/99';
end;

OnGetEditMask

Windows Vista以降で使用できるVCLの機能のまとめ

Windows XPが終了して、Windows Vistaの新機能を気兼ねなく使用できるようになった。

Delphi XE6/C++Builder XE6の修正リストのメモ

Delphi XE6/C++Builder XE6の修正リストより。

タスクダイアログ(TTaskDialog)を使うには

タスクダイアログ(TTaskDialog)の使い方をまとめました。

タスクダイアログ(TTaskDialog)はWindows Vista以降で使用できます。

00

Captionプロパティ・Titleプロパティ・Textプロパティ

Captionプロパティはタスクダイアログのキャプション、
Titleプロパティはタスクダイアログのタイトル、
Textプロパティはタスクダイアログのメインテキスト
を格納します。

01

ExpandedTextプロパティ

ExpandedTextプロパティはタスクダイアログが展開されているときに表示されるテキストを格納します。

07

08

ExpandButtonCaptionプロパティ

ExpandButtonCaptionプロパティはキャプションが展開されているときに表示される追加テキストを格納します。

09

10

MainIconプロパティ

MainIconプロパティで表示するアイコンを設定します。
有効な値にはtdiNone、tdiWarning、tdiError、tdiInformation、tdiShieldがあります。

tdiNone

02

tdiWarning

03

tdiError

04

tdiInformation

05

tdiShield

06

CustomMainIconプロパティ

CustomMainIconプロパティでメインアイコンを設定できます。
設定したアイコンを表示するにはFlagsプロパティのtfUseHiconMainをTrueにする必要があります。

13

FooterTextプロパティ

FooterTextプロパティはタスクダイアログのフッター領域で使用する文字列を格納します。

11

FooterIconプロパティ

FooterIconプロパティで表示するアイコンを設定します。
有効な値にはtdiNone、tdiWarning、tdiError、tdiInformation、tdiShieldがあります。

12

CustomFooterIconプロパティ

CustomFooterIconプロパティでフッターアイコンを設定できます。
設定したアイコンを表示するにはFlagsプロパティのtfUseHiconFooterをTrueにする必要があります。

14

VerificationTextプロパティ

VerificationTextプロパティは確認チェックボックスのラベルに使用されるテキストを格納します。

15

確認チェックボックスがチェックされるとOnVerificationClickedイベントが発生します。

ProgressBarプロパティ

ProgressBarプロパティで進捗バーの設定ができます。
進捗バーを表示するにはFlagsプロパティのtfShowProgressBarをTrueにします。

16

FlagsプロパティのtfShowMarqueeProgressBarをTrueにするとマーキー進捗バーを表示します。

17

CommonButtonsプロパティ

CommonButtonsプロパティは、タスクダイアログ共通のプッシュボタンを指定します。

TaskDialog1.CommonButtons := [tcbOk, tcbYes, tcbNo, tcbCancel, tcbRetry, tcbClose];

18

Buttonsプロパティ

Buttonsプロパティでタスクダイアログにボタンを登録できます。
どのボタンが押されたのかを知るにはModalResultプロパティを使用します。

19

RadioButtonsプロパティ

RadioButtonsプロパティでタスクダイアログにラジオボタンを登録できます。
ラジオボタンが選択されるとOnRadioButtonClickedイベントが発生します。

20

選択されたラジオボタンはRadioButtonプロパティのIndexプロパティで取得できます。

TaskDialog1.Execute;
ShowMessage(Format('%d番目のラジオボタンが選択されました。', [TaskDialog1.RadioButton.Index]));

FlagsプロパティのtfUseCommandLinks

FlagsプロパティのtfUseCommandLinksをTrueにすると、ボタンはコマンドリンクとして表示されます。
ボタンはButtonsプロパティでボタンを設定します。

21

Aeroのグラス効果でウィンドウを透けさせる

フォーム(TForm)のGlassFrameプロパティを設定すると、Aeroのグラス効果でウィンドウを透けさせることができます。

GlassFrameプロパティのEnabledプロパティをTrueにするとグラス効果が有効になります。

Bottom・Left・Right・Topの各プロパティでグラス効果を適用する範囲を設定します。

TGlassFrame00
TGlassFrame01

TGlassFrame02

SheetOfGlassプロパティをTrueにすると、フォーム全体にグラス効果が適用されます。

TGlassFrame03