2012年4月3日

RAD Studio/Delphi/C++Builder XE2付属のAQtimeのアップデート

RAD Studio/Delphi/C++Builder XE2(Pro/Ent/Arc SKUのみ)にバンドルされているAQtime 7(AQtime Standard update for Delphi, C++Builder and RAD Studio XE2)が7.30.535.861から7.40.800.861にアップデートされています。

28463 AQtime Standard for Delphi, C++Builder and RAD Studio XE2
Delphi XE2/C++Builder XE2/RAD Studio XE2 向けに AQtime Standard のアップデート版が公開されました。
AQtime Standard update for Delphi, C++Builder and RAD Studio XE2

New AQtime Pro Features

2012年3月30日

[書籍]Windows Sysinternals徹底解説

MARUZEN&ジュンク堂書店 渋谷店Windows Sysinternals Administrator's Reference (amazon)の翻訳である

Windows Sysinternals徹底解説 (amazon)/Mark RussinovichAaron Margosis著/山内和朗訳/日経BP/ISBN 978-4822294649 (ISBN 4822294641)/4,935円

を購入。この本はWindows SysInternalsの各ツールについて、SysInternals生みの親であるMark Russinovichさん自身が徹底解説しています。またMark RussinovichさんのBlogは

Windows の内部を解き明かす | Mark's ブログ

として日本語に翻訳されています(全てのアーティクルではないようですが)。

この本(日本語版)については

Virtualization × Sysinternals (+ちょっとだけPR)|仮想化|ブログ|Computerworld

にも情報があります。

さらにWindows Sysinternalsについては国井傑さんによる"Windows Sysinternalsを使い倒せ(COMPUTERWORLD)"という連載も非常に参考になります。
2012/06/04追記: ITpro(要登録)にWindows Sysinternals徹底解説の一部抜粋が掲載されています。

2012年3月27日

FastReport VCL 4 RAD Edition 4.12.2リリース

CodeCentralにアップロードされているFastReport VCL 4 RAD Edition for Delphi and C++Builder XE2が更新されているようです。

28514 FastReport VCL 4 RAD Edition for Delphi and C++Builder XE2

アップデート前はインストーラのタイムスタンプが2011/09/29でバージョンが4.11.17、アップデート後のインストーラはタイムスタンプが2012/03/26で、インストール後のバージョンは4.12.2となっています。

エンバカデロの高橋さんからの情報によると4.12.2はエージーテックから出ている製品版の日本語版の最新版と同じバージョンとのことです。

2012年3月16日

第21回エンバカデロ・デベロッパーキャンプ 関連リンク

セッション資料ダウンロード
セッションリプレイ (YouTube エンバカデロチャンネル)
  • 【G1】オープニングセッション 「2012年 - エンバカデロの製品戦略」
  • 【T2】テクニカルセッション「実践!Delphiデバッグテクニック」 1/2 2/2
  • 【T3】テクニカルセッション「Delphi/C++Builder + FastReportで作る実用レポート出力」 1/2 2/2
  • 【T4】テクニカルセッション「FireMonkeyファーストインプレッション」 1/2 2/2
  • 【W5】ワークショップ「FireMonkeyアプリケーション構築実習」
  • 【W6】ワークショップ「挑戦!Delphiクイズで実力チェック」 1/2 2/2
  • 【T7】テクニカルセッション「RadPHPでスマホアプリを作ろう!」 1/2 2/2
  • 【T8】テクニカルセッション「Delphi言語再入門」 1/2 2/2
  • 【T9】テクニカルセッション「Delphi/C++BuilderでiOS/Macアプリを作ろう!」 1/2 2/2


(随時更新予定)

2012年3月15日

RAD Studio XE2 Update 4対応TeeChart Standardリリース

RAD Studio/Delphi/C++Builder XE2 Update 4に対応した"TeeChart Standard for RAD XE2 Update 4"がリリースされています。

28780 TeeChart Standard for Delphi, C++Builder, and RAD Studio XE2

2012年3月14日

Microsoft Monthly Update 2012/03

今日はMicrosoftのセキュリティアップデートの日です。
MS12-017
MS12-018
MS12-019
MS12-020
MS12-021
MS12-022

2012年3月10日

第21回エンバカデロ・デベロッパーキャンプ 2日目

本日09:00からデベロッパーキャンプ (edn)の第2日目が行われます。場所は同じく船橋のセミナーハウス クロス ・ウェーブ船橋です。GotoWebinar(要登録)とUSTREAMでオンラインでも参加できます。

今日も午前中はお天気が悪いようです(さすがに船橋は雪ではありません)。終わるころまでに雨がやむといいのですが。

先ほど09:00からセッションが始まっています。あのクイズの問題を英語で出されるのはちとつらいかもしれませんね。

全日程終了しました。セッションスピーカの皆さん、参加者の皆さん、関係者の皆さん、おつかれさまでした。

ところで昨日のW6セッションについていけなかった、という感想をお持ちの方がいらっしゃるようですが、講師の高橋さんによると「無理ですよ、6時間分を圧縮してやるんですから」ということなので気にする必要はないようです。

2012/03/13追記: Team Japanにフォローアップ記事があがっています。

Team Japan » 第21回エンバカデロ・デベロッパーキャンプ あれこれ

Firebird 2.0.7 Release Candidate 1リリース

Firebird 2.0.7 Release Candidate 1がリリースされています。

Firebird: Firebird 2.0.7 Release Candidate 1 Kits
Firebird 2.0.7 Release Notes

元ねたはFirebird News » Firebird 2.07 RC

2012年3月9日

第21回エンバカデロ・デベロッパーキャンプ 1日目

本日14:00から第21回エンバカデロ・デベロッパーキャンプ (edn)の第1日目が行われます。場所は船橋のセミナーハウス クロス ・ウェーブ船橋です。

Team Japan » 第21回 エンバカデロ・デベロッパーキャンプ - 会場へのアクセス

今回もGotoWebinar(要登録)とUSTREAMでオンラインでも参加できます。

東京はあいにくのお天気ですね。明日まで雨の予報で気温も低めのようです。それでは移動開始です。

会場に到着。駅からはやはり10分程度はかかりますね。セッション会場は微妙に狭いような。50~60人で満員になりそう。まもなく開始です。

最初の3セッション(G1/T2/T3)が終了。神様に愛されているのは細川さんだった模様。

1日目は終了。セッションスピーカの皆さん、参加者の皆さん、関係者の皆さん、お疲れさまでした。え?延長戦?どうなんでしょう?

明日のクイズの回答者のみなさん、がんばってくださいね。

2012/03/10追記: 富永さんがT4「FireMonkeyファーストインプレッション」のフォローアップを書いています。

2012年3月1日

2012/03開催のウェブセミナー


2012/03/12追記: 2012/03/16のデベロッパーキャンプ・リキャップのリンクを追加しました。

2012年2月21日

TVirtualMethodInterceptorを使う

Delphi XEの新機能の一つであるTVirtualMethodInterceptorを使用すると、クラスインスタンスの仮想メソッドの呼び出しに外部から介入することができます(メソッドの呼出前呼出後例外の発生に対してそれぞれイベントとして無名メソッドを割り当てることができる)。しかしTVirtualMethodInterceptorの実際の使い方については

TVirtualMethodInterceptorを試す。 - 全力わはー
Entropy Overload: Virtual method interception

ぐらいしか参考になる情報がありません。ということで実際に試してみましょう。
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ActnList, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    ActionList1: TActionList;
    Action1: TAction;
    Action2: TAction;
    Action3: TAction;
    procedure Action1Execute(Sender: TObject);
    procedure Action2Execute(Sender: TObject);
    procedure Action3Execute(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Action1Execute(Sender: TObject);
begin
  MessageDlg('Action1Execute',mtInformation,[mbOk],0)
end;

procedure TForm1.Action2Execute(Sender: TObject);
begin
  MessageDlg('Action2Execute',mtInformation,[mbOk],0)
end;

procedure TForm1.Action3Execute(Sender: TObject);
begin
  MessageDlg('Action3Execute',mtInformation,[mbOk],0)
end;

end.
画面上にボタンがあり、これらのボタンにはActionが割り当てられていてOnClickではこれらのActionが呼び出される、というサンプルプログラムです。ここでボタンをクリックしたときにフォーカスを残したくない、という新たな要求があり、それぞれのActionのOnExecuteの最後に"ActiveControl := nil;"という処理をを追加したいのですが、Actionが多数だと大変です。そこでTVirtualMethodInterceptorを使ってTAction.OnExecuteの呼出後に"ActiveControl := nil;"を実行するようにしてみましょう。まずusesにRTTIユニットを追加し、FormのOnCreateイベントでTVirtualMethodInterceptorを生成してprivate部に用意した変数に格納します。
procedure TForm1.FormCreate(Sender: TObject);
begin
  FVMI := TVirtualMethodInterceptor.Create(TAction);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FVMI.Free;
end;
TVirtualMethodInterceptorのコンストラクタのパラメータは対象となるクラスです。次に生成したTVirtualMethodInterceptorのインスタンスのOnAfterイベントを設定します。
  FVMI.OnAfter :=
    procedure(Instance: TObject; Method: TRttiMethod;
              const Args: TArray<TValue>; var Result: TValue)
    begin
      if Method.Name = 'Execute' then
      begin
        ActiveControl := nil;
      end;
    end;
メソッドを実行したあとで、そのメソッドの名前が"Execute"であれば"ActiveControl := nil;"を実行する、という処理になります(OnAfterに割り当てているのは無名メソッドなので、Form1のActiveControlをキャプチャして使用することができます)。さらにそれぞれのアクション(TActionのインスタンス)をProxifyします。
  for I := 0 to ComponentCount - 1 do
  begin
    if Components[I] is TAction then
    begin
      FVMI.Proxify(TAction(Components[I]));
    end;
  end;
では実行してみましょう…うまくいきませんね。Method.Nameが'Execute'になった状態でOnAfterに入ってこないようです(おまけに終了時にエラーになります)。TAction.OnExecuteTBasicAction.Executeから呼び出されているはずです。ClassesユニットにあるTBasicAction.Executeの定義を見てみましょう。
    function Execute: Boolean; dynamic;
ん?dynamicですと?ヘルプには特定のクラス型の指定されたインスタンスに対する仮想メソッド呼び出しを ユーザーが動的にインターセプトできるようにします。とあります。そもそもTVirtualMethodInterceptorなので、動的(dynamic)メソッドはインターセプトできないのはあたりまえですね。どうしましょう…TAction.OnExecuteの呼出経路を探ってみると、TControlにはprotectedなActionLinkというプロパティがあり、割り当てられたActionはこのActionLinkのExecuteメソッド経由で呼び出されるようになっています。そしてこのTBasicActionLink.Executeはvirtualです。ということでここに介入することにします。とはいってもTControl.ActionLinkはprotectedですので、強引にclass helperでアクセスできるようにします。
type
  TButtonHelper = class helper for TButton
  public
    function GetActionLink: TActionLink;
  end;

function TButtonHelper.GetActionLink: TActionLink;
begin
  Result := Self.ActionLink;
end;
これでActionLink.Executeに介入できるようになります。
procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  FVMI := TVirtualMethodInterceptor.Create(TActionLink);
  FVMI.OnAfter :=
    procedure(Instance: TObject; Method: TRttiMethod;
              const Args: TArray<TValue>; var Result: TValue)
  begin
    if Method.Name = 'Execute' then
    begin
      ActiveControl := nil;
    end;
  end;

  for I := 0 to ControlCount - 1 do
  begin
    if Controls[I] is TButton then
    begin
      FVMI.Proxify(TButton(Controls[I]).GetActionLink);
    end;
  end;
end;
実行してみましょう。…実行時にエラーになりますね。Proxifyで型が一致していないようです。調べてみるとTButtonのActionLinkのインスタンスの型はTActionLinkではなく派生したTPushButtonActionLinkになっています。
  FVMI := TVirtualMethodInterceptor.Create(TPushButtonActionLink);
こんどはうまく動作したようです。ところで終了時は?やはりEPrivilege例外が発生してエラーになります。Talesさんが指摘していますが、インターセプト対象のインスタンスが解放されるときには仮想メソッドであるdestructor Destroyが呼び出されるわけで、この時点までTVirtualMethodInterceptorのインスタンスを解放してはいけないということになります。ここではこの問題をclass destructorで解決します。
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    ActionList1: TActionList;
    Action1: TAction;
    Action2: TAction;
    Action3: TAction;
    procedure Action1Execute(Sender: TObject);
    procedure Action2Execute(Sender: TObject);
    procedure Action3Execute(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    class var
      FVMI: TVirtualMethodInterceptor;
  public
    class constructor Create;
    class destructor Destroy;
  end;
TVirtualMethodInterceptorをclass varとして、class constructorで初期化し、class destructorで解放するようにします(TForm1のOnDestroyイベントの"FVMI.Free;"を削除するのを忘れないように)。
class constructor TForm1.Create;
begin
  FVMI := nil;
end;

class destructor TForm1.Destroy;
begin
  FVMI.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  if FVMI = nil then
  begin
    FVMI := TVirtualMethodInterceptor.Create(TPushButtonActionLink);
    FVMI.OnAfter :=
      procedure(Instance: TObject; Method: TRttiMethod;
                const Args: TArray<TValue>; var Result: TValue)
      begin
        if Method.Name = 'Execute' then
        begin
          ActiveControl := nil;
        end;
      end;
    end;

  for I := 0 to ControlCount - 1 do
  begin
    if Controls[I] is TButton then
    begin
      FVMI.Proxify(TButton(Controls[I]).GetActionLink);
    end;
  end;
end;
これですべてうまく動作しました。終了時もエラーになりません。

TVirtualMethodInterceptorがやっていることは基本的にはtalesさんが指摘しているとおりVMTの差し替えです。従って処理に介入できるのはインスタンスの仮想(virtual)メソッドのみで、動的(dynamic)メソッドや静的メソッド、クラスメソッドは対象になりません。またProxifyしたインスタンスが全て解放されるまではTVirtualMethodInterceptorのインスタンスを解放してはいけません(デストラクタはvirtualなのでVMTを参照する)。もうひとつ気をつけなければならないのはTVirtualMethodInterceptorのコンストラクタで指定しているクラス型が実際にProxifyするクラス型と完全に一致していなければならない(代入互換性があるというのではだめ)という点です。

2012/02/29追記: TVirtualMethodInterceptor.OriginalClassプロパティを使ってVMTを書き戻すか、同じことをしてくれるUnproxify(XE2で追加)で終了時の問題をクリアすることができる、という指摘がLynaさんからありました。ということでこちらも試してみます。まずOriginalClassプロパティに格納されているもともとのVMTを書き戻す方法から。
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    ActionList1: TActionList;
    Action1: TAction;
    Action2: TAction;
    Action3: TAction;
    procedure Action1Execute(Sender: TObject);
    procedure Action2Execute(Sender: TObject);
    procedure Action3Execute(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FVMI: TVirtualMethodInterceptor;
  end;
フォームのクラスコンストラクタ/クラスデストラクタを削除し、TVirtualMethodInterceptorを通常のprivateなフィールドに戻します。またフォームのOnDestroyイベントを用意します。
procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  FVMI := TVirtualMethodInterceptor.Create(TPushButtonActionLink);
  FVMI.OnAfter :=
    procedure(Instance: TObject; Method: TRttiMethod;
              const Args: TArray<TValue>; var Result: TValue)
    begin
    if Method.Name = 'Execute' then
    begin
      ActiveControl := nil;
    end;
  end;

  for I := 0 to ControlCount - 1 do
  begin
    if Controls[I] is TButton then
    begin
      FVMI.Proxify(TButton(Controls[I]).GetActionLink);
    end;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to ControlCount - 1 do
  begin
    if Controls[I] is TButton then
    begin
      PPointer(TButton(Controls[I]).GetActionLink)^ := FVMI.OriginalClass;
    end;
  end;
  FVMI.Free;
end;
フォームのOnDestroyイベントでProxifyしたVMT(OriginalClass)を元に戻しています。うまくいきましたね。

それではDelphi XE2で追加されたUnproxifyを使う方法を。
procedure TForm1.FormDestroy(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to ControlCount - 1 do
  begin
    if Controls[I] is TButton then
    begin
      FVMI.Unproxify(TButton(Controls[I]).GetActionLink);
    end;
  end;
  FVMI.Free;
end;
フォームのOnDestroyイベントでUnproxifyするだけで基本的に同じです。こちらも問題なく動作しました。

2012年2月17日

Visualizing using FireMonkeyシリーズ

エンバカデロ・テクノロジーズのAnders OhlssonさんによるFireMonkeyで数式をビジュアル化する"Visualizing using FireMonkey"シリーズ(勝手に命名)が翻訳されています。
そういえばJim TierneyさんのLiveBindingチュートリアルの3本目(http://blogs.embarcadero.com/jimtierney/2011/10/14/31608)が翻訳されてないのは元記事がednにあがっていない(blogにのみある)から、とのこと。

2012/03/27追記: C++(C++Builder XE2)を使った記事2本のリンクを追加しました。

2012年2月15日

Microsoft Monthly Update 2012/02

今日はMicrosoftのセキュリティアップデートの日です。
MS12-008
MS12-009
MS12-010
MS12-011
MS12-012
MS12-013
MS12-014
MS12-015
MS12-016