フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: [1]
トピック: "Application.OnIdle と TQueue<T> の組み合わせ" とは?
DEKO
管理者
投稿数: 2651
"Application.OnIdle と TQueue<T> の組み合わせ" とは?
on: 2013/06/15 06:43 Sat

細川さんと高橋さんの会話に食いついてみました。
https://twitter.com/pik/status/345370408607952897

つまりは…

unit Unit1;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, Generics.Collections,
System.Actions, FMX.ActnList;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
private
{ private 宣言 }
FQueue: TQueue<TAction>;
protected
{ protected 宣言 }
procedure UpdateActions; override;
public
{ public 宣言 }
property Queue: TQueue<TAction> read FQueue write FQueue;
end;

var
Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormCreate(Sender: TObject);
// フォーム作成時
begin
// キューを作成
FQueue := TQueue<TAction>.Create;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
// フォーム終了確認時
begin
// キューが存在する場合には終了しない(念のため)
CanClose := (FQueue.Count = 0);
end;

procedure TForm1.FormDestroy(Sender: TObject);
// フォーム破棄時
begin
// キューを破棄
FQueue.Free;
end;

procedure TForm1.UpdateActions;
begin
inherited;
// キュー内のアクションを実行
if FQueue.Count > 0 then
FQueue.Dequeue.Execute;
end;

end.

 
このような記述をして TActionList をフォームに貼り、実行したいアクションを

procedure TForm1.Button1Click(Sender: TObject);
begin
Queue.Enqueue(Action1);
end;

 
こんな感じで突っ込めばいいという事なのでしょう…多分。いや、TAction でなくてはならない訳ではありませんが。

※ TActionList (FMX) は XE3 以降で使えます。

DEKO
管理者
投稿数: 2651
Re: "Application.OnIdle と TQueue<T> の組み合わせ" とは?
on: 2013/06/15 07:17 Sat

余談ですが、例えば FireMonkey HD アプリケーションでボタンを "ダブルクリックした時の処理" を以下のように記述すると、ボタンが押されたままのグラになります。

procedure TForm1.Button1DblClick(Sender: TObject);
begin
ShowMessage('Hello,World.');
end;

 
比較用にダミーのボタンを別に貼っておくと判りやすいです。

この問題はダブルクリックのイベントで ShowMessage() にフォーカスを奪われ、MouseUp の描画イベントが発生しないから起こるのだと思われます。

ダブルクリックのイベントは
▽MouseDown (1st)
△MouseUp (1st)
▽MouseDown (2nd)
△MouseUp (2nd) <- コレの描画処理が発生しない
二回目の MouseDown で発生しますので。

この問題は先述の TQueue で回避できます。

procedure TForm1.Action1Execute(Sender: TObject);
begin
ShowMessage('Hello,World.');
end;

procedure TForm1.Button1DblClick(Sender: TObject);
begin
Queue.Enqueue(Action1);
Sleep(150); // ボタンが描画されるまで待つ
end;

 
See Also:
[さらに FireMonkey のフォーム (HD / 3D) でクリック / ダブルクリックイベントを検出してみる ]
http://ht-deko.minim.ne.jp/ft1209.html#120920_01

DEKO
管理者
投稿数: 2651
[Delphi][FireMonkey]TMessageManagerってこんなの。
on: 2013/06/22 19:45 Sat

[Delphi][FireMonkey]TMessageManagerってこんなの。 (全力わはー)
http://d.hatena.ne.jp/tales/20130622/1371894728

らいなタンさんによる FireMonkey におけるメッセージング処理の解説です。
なるホド、なるホド…φ(・ω・ )メモメモ

ページ: [1]
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.031 sec.