2012年7月4日

Why did Borland fail?

以前BorlandでDelphiのIDEやVCLを担当していたDanny Thorpeさんによる「なぜBorlandは失敗したのか?」という疑問に対する考察。興味深い。とりあえずメモ。

Danny Thorpe's answer to Borland (company): Why did Borland fail? - Quora

元ねたはHadi Haririさんtweet(RANさん経由)。

2012年6月24日

[書籍]リーダブルコード

ブックファースト 新宿店The Art of Readable Code (amazon)の翻訳である

リーダブルコード (amazon)/Dustin Boswell、Trevor Foucher著/角征典訳/オライリージャパン/ISBN 978-4-87311-565-8/2,520円

を購入。

Firebird 2.1.5

Firebird Ver2.1.5がリリースされています。

Firebird: Firebird 2.1.5
Firebird 2.1 Release Notes (PDF)

元ねたはFirebird News » Firebird 2.1.5 sub-release is available

2012年6月13日

Microsoft Monthly Update 2012/06

今日はMicrosoftのセキュリティアップデートの日です。
MS12-036
MS12-037
MS12-038
MS12-039
MS12-040
MS12-041
MS12-042

2012年6月7日

第22回エンバカデロ・デベロッパーキャンプ(東京)まとめ

第22回エンバカデロ・デベロッパーキャンプ(東京)の個人的なまとめです。なお以下の内容については無保証ですのでご注意ください

【G1】キーノートセッション「エンバカデロ2012年製品戦略」
  • 公式レポート: 第22回 エンバカデロ・デベロッパーキャンプ キーノートセッションレポート

  • 2011年の業績は好調で、売り上げは10%成長して約75億円だった。手元資金は潤沢である。

  • 2012年以降に向けて3つのことを考えている。
    1. 既存製品: RAD Studio XE3、ER/Studio portal
    2. 買収: 資金的な余裕があり、景気の低迷で相対的に安く買収を行えるため、年内に1~3社程度の買収を目指している
    3. AppWave

  • 2012年の製品計画
    • 新世代コンパイラアーキテクチャ
      • LLVMをベースとし、

        Delphi F/EまたはC++ F/E(=Clang+PME) → LLVM IR → LLVM Intel/ARM/Other CPU Code Gen

        という構成にコンパイラを再構築する(コンパイラにおけるフロントエンド、バックエンドについてはwikipediaのコンパイラの設計の項を参照)。
    • XE3
      • Delphi/C++: iOSにネイティブ対応
      • C++Builder: x64対応
      • FireMonkey: Hyper-Real 3D UI、ホログラフィック 3D UI
      • HTML5: ビジュアルHTML5/CSS3クライアント開発 - Delphi/C++Builder/RadPHP

  • C++Builder 2012ロードマップ
    • 64bitツールチェーン: IISシェルエクステンション、SQL Serverインタフェース、64bitデバイスドライバ
    • C++11: BoostACEに対応
    • ARM: iOS/Andriodサポート、ARMv7バイナリの出力、FireMonkeyでデバイス(GPSや加速度計などのセンサ)のネイティブサポート
    • スケジュール:
      • 現在ベータ1で、まもなくベータ2が始まる
      • 2012年後半(Q3): C++11、x64、Hyper-Real Holographic(HRH)
      • 2013年初め: ARM iOS/Android

  • ER/Studio
    • データガバナンス、クロスモデルトレーサビリティ
    • メタデータのソーシャライズ
    • Social Portal
    • 最大の競合先であるCA(おそらくERWinシリーズ)が日本語へのローカライズを今年からやめる(注:本当かどうかは確認できませんでした)のでチャンスと考えている

  • AppWave: 今年も積極的にバージョンアップを進める

【T2】Delphi/C++Builderテクニカルセッション「RAD Studio次期バージョンプレビュー ~ 64-bit化を進めるC++Builder」
  • C++Builder
    • C99C++11標準への準拠度の向上
    • LLVMベース(ベータ1ではまだx64のみ)
    • ARM上ではGDBでデバッグすることになる
    • STL(Dinkumware)、Boost(BoostPro)、ACE(ADAPTIVE Communication Environment)、CORBA(TAO)をサポートする予定
    • Windows x64、iOS(シミュレータ、デバイス)、Android

  • Delphi XE3
    • FireMonkeyの強化
      • アクションリスト
      • ジェスチャ
      • アンカー
      • レイアウトマネージャ
      • Audio/Video: DirectShow/QuickTime
      • 物理エンジン
      • Indy for iOS
      • dbExpress for iOS
    • FPCベースからLLVMベースへの移行

  • C++11: C++で追加された便利な機能の紹介 - autoによる型推論lambdaなど

【T3】Delphi/C++Builderテクニカルセッション「FireMonkey道場」
【T4】Delphi/C++Builderテクニカルセッション「アプリの肥大化、チームメンバーの増大など!プロジェクトの拡大にRAD環境でどう対応するか?」
【G5】Q&Aセッション「何でも質問!アスク・エンバカデロ」
  • エンバカデロ・テクノロジーズの全世界における日本の売り上げの比率は8%程度
  • Clang/LLVMはおそらくオープンソースプロジェクトのものからフォークした独自のものとなる(ような雰囲気のことを言っていた)
  • PC上のIDEのシェアはMicrosoftが80%、Embarcaderoが10%、それ以外が10%程度と認識している

【G6】ライトニングトーク「共有!みんなの開発事例、開発経験、テクニック」
個人的な感想など:
  • これからの1年は筑木さんのターンらしいです。C++11とかBoostとか。
  • ClangやLLVMをベースに、とはいっても、いまどきのモダンなIDEではコンパイラから非常に多くの情報を取り出しており、それらの部分はまったく新規に作り込みが必要なので結構大変らしいです。
  • コンパイラの再構築についてはXE3で全部まとめて、という形にはならないのかも。デモで使用していたベータ1ではC++Builder/x64(=Clang+PME、x64 CodeGen)のみが新しくなっており、RTMまでにDelphi F/Eやx86/ARM CodeGenが出揃うかどうかは…。(以下自粛)
  • 資金的な余裕があるのならインストーラのメーカを買収するとかオープンソースのインストーラに出資するとか考えてほしいですね。
  • 参加されたある方から『午前中にキーノートなどの偉い人向けのものをやっても偉い人は朝っぱらから来られるわけがない、ましてや五十日(ごとおび)や月末なんて無理、偉い人の理解がなければ下っ端はこんなところに1日中いられないんだからそこのところを考えてほしい』というお話を聞きました(懇親会で)。確かにそのとおりですよね。"デベロッパー"キャンプとはいえ、勤務時間中に自由に行動できる人はそれほど多くはないわけで(自分は勝手気ままにやらせてもらってますけどね)。キーノートは夕方ラス前くらいに設定して、それ以前の時間にテクニカル系のセッションをやるというのもひとつの考え方かもしれません。

2012/06/08追記: セッション資料のダウンロードが可能になっています(T3、G6のみ)。ライトニングトークは時間の関係で説明されなかった部分などがあるのでダウンロードして確認がお勧め。

第22回 エンバカデロ・デベロッパーキャンプ - セッション資料ダウンロード

2012/06/11追記: キーノートの公式レポートのリンクを追加しました。

2012/06/15追記: CodeZineに関連記事が掲載されています。

次期C++Builderはアーキテクチャを刷新 ~「エンバカデロ・デベロッパーキャンプ東京」レポート(1/3):CodeZine
開発ツールベンダーの老舗が語る C++によるソフトウェア開発の今と将来性(1/3):CodeZine

2012/07/02追記: IT Leadersに関連記事が掲載されています。

コンパイラを全面改良、異機種クライアント向けアプリの生産性向上へ~米エンバカデロ・テクノロジーズ | IT Leaders

2012年6月6日

指定されたビットを交換する

整数型の値の指定された任意の2つのビットを交換する方法。
function ExchangeBits(Value: Integer; Pos1: Integer; Pos2: Integer): Integer;
var
  n: Integer;
  t: Integer;
begin

  Result := Value;

  n := Pos1 - Pos2;
  if n = 0 then
  begin
    Exit;
  end;
  if n < 0 then
  begin
    Pos2 := Pos1;
    n := -n;
  end;

  t := ((Value shr n) xor Value) and (1 shl Pos2);
  Result := Result xor t;
  Result := Result xor (t shl n);

end;
元ねたはびびすけさんのビット交換 (RunRunDietOnline)。昔からある(バッド)ノウハウのひとつであるXORによる値の交換の応用ですね。

2012年6月1日

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

2012年5月31日

第22回エンバカデロ・デベロッパーキャンプ(東京)

本日10:00から第22回エンバカデロ・デベロッパーキャンプ(東京)が行われます。場所は新宿の新宿NSビルの30階、スカイカンファレンスルーム1です。今回は一部のセッションを除いてUStreamで中継があります。

USTREAM: developer-camp-japan: エンバカデロ・デベロッパーキャンプのライブ中継をご覧いただけます。

Nigel BrownさんのG1終了。Delphi/C++BuilderをCLang(or Delphi F/E)+LLVM上で再構築とな。CLang+PMEの話はJTさんが書いてましたね。

高橋さんのT2も終了。RAD Studio(C++Builder) XE3のベータ版でデモ。x86とx64でコンパイラが違うのかぁ(現時点での話です)。

午後は高橋さんのT3からです。FireMonkeyは面白そうだけど、画面描画を伴う処理を処理系非依存でどう作るのかとか、そもそもクロスプラットフォームの必要性とか、微妙ですよね。XE3からが本番だと思いますけど。

パネルディスカッションのT4も終了。エンバカデロで使ってるツールを外販するとかオープンソース化するとかいかがですかね?

Nigel BrownさんのQ&AのG5も終了。営業の人は話が長いな…。

まもなくラスト、T6のライトニングトークです。今日は8人だとか。時間厳守ですって。

懇親会を含め全て終了。参加者のみなさん、セッションスピーカのみなさん、エンバカデロ・テクノロジーズのみなさん、お疲れさまでした。

2012/06/08追記: まとめはこちら

2012年5月25日

[書籍]PDF構造解説

ジュンク堂書店 吉祥寺店PDF Explained (amazon)の翻訳である

PDF構造解説 (amazon)/John Whitington著/村上雅章訳/オライリージャパン/ISBN 978-4-87311-549-8/2,310円

を購入。

2012年5月19日

RAD Studio roadmap 2012 Q2版

RAD Studio XE2のリリース以来長らく放置状態だったロードマップがRADプロダクトマネージメントディレクタのJohn Ray Thomasさんによって更新されています。

C++向けRAD IDEで、近い将来64-bit、C++11、ARM、iOS、Androidをサポート!
Coming soon to a RAD IDE near you, the future of C++ - 64bit, C++11, ARM, iOS and Android

てきとうな要約:
  • 主要な目標はWindows x64対応、C++11対応、ARM(iOSおよびAndroid)対応で、多くの機能は2012年H2に、そのほかについても2013年H1にかけてのリリースを予定している。
  • C++の新しいコンパイラのターゲットプラットフォームはWindows x64、iOS(ARM)、Android(ARM)。Windows x64では当然VCLとFireMonkeyの両方をサポートする。
  • C++ツールチェーンは新しいプラットフォームのサポートを予定しており、まずはARMプロセッサのシェアドコードベースでのネイティブ開発(iOS、Android)について作業している。新しいコンパイラはネイティブなARM v7バイナリを生成する。FireMonkeyもC++によるiOS/Androidプラットフォームへの対応(GPS、カメラ、加速度などのセンサを含む)のため更新される。
  • 新しいC++コンパイラはC++11およびC99標準とBoostやACEなどの重要なライブラリの最新版に対応する。
  • このロードマップは現時点のもので(以下略)といういつものお約束。現在はBeta 1で、まもなくBeta 2フェーズに入る予定。現在の計画ではC++11、Windows x64、iOSは2012年の後半、Androidは2013年の前半を予定している。


またC++Builderを含む製品とメンテナンス契約でプレビュープログラムに参加できるというキャンペーンも始まったようです(メンテナンス契約なのでXE3も自動的に含まれる)。2012/04/20から2012/06/29が対象期間のようです。

Michael Swindell » Avalanche of C++ news - C++11, Win 64-bit, iOS and Android
Get your ticket to the future of C++ and save an additional 20%

2012/05/22追記: 日本語版のリンクを追加しました。

2012/05/30追記: キャンペーン(C++Builder XE2 Future Ticket版)の件が日本でも発表されています。

エンバカデロ、64-bit、iOS、AndroidをサポートするC++Builderの将来バージョンへのパスを提供 | Press Releases
C++Builder XE2を将来バージョンへのチケットと一緒に購入すれば20% OFF

RAD Studio/Delphi/C++Builder XE2 Update 4 Hotfix 1

RAD Studio/Delphi/C++Builder XE2 Update 4のHotfix 1がリリースされています。適用後のバージョンは16.0.4504.48759です。主にUpdate 4で生じたFireMonkey関係の問題を修正するもののようです。

28881 RAD Studio XE2 Update 4 Hotfix for FireMonkey and C++
28882 Delphi XE2 and C++Builder XE2 ISO (includs Update 4 Hotfix)
Delphi XE2/C++Builder XE2/RAD Studio XE2 Update 4 Hotfix 1 が公開されました
Update 4 Hotfix 1 now available for Delphi, C++Builder and RAD Studio XE2

2012年5月16日

Prism XE2.5

Prism XE2.5がリリースされています。RAD Studio XE2のメンテナンス契約をしているか、2012/05/15から2012/09/01の間にRAD Studio XE2を購入した場合(2012/09/15まで有効)にのみ使用できるようです。またこのキャンペーンが日本でも有効なのかどうかは今のところ不明です。

Buy RAD Studio XE2, get Embarcadero Prism XE2.5 Free! | Landing Pages

28871 Embarcadero Prism XE2.5 ISO
28872 Embarcadero Prism XE2.5 ISO
28873 Embarcadero Prism XE2.5 Full Installer (Japanese)
28876 Embarcadero Prism XE2.5 Full Installer (English)

2012/05/17追記: Prism XE2.5の関連リンクです。

Embarcadero Announces Support for Windows 8 Metro Development with Release of Embarcadero Prism XE2.5
Delphi Insider: Embarcadero Prism XE2.5 is now available - develop Windows 8 apps
Announcing Oxygene 5.1 and Embarcadero Prism XE2.5 | RemObjects Blogs

2012年5月9日

Microsoft Monthly Update 2012/05

今日はMicrosoftのセキュリティアップデートの日です。
MS12-029
MS12-030
MS12-031
MS12-032
MS12-033
MS12-034
MS12-035

2012年5月8日

列挙型と列挙子名(文字列)の相互変換(ジェネリックス版)

ずいぶん前に列挙型の値と列挙子の名前を相互変換する方法について取り上げましたが、これを関数化しようとすると結局のところ必要な列挙型すべてについて個別に実装の必要がありました。ところがLynaたんさん(talesさん)ジェネリクスを使って少しだけ手軽に列挙型の値を文字列に変換する。 - 全力わはーではDelphi 2009の新機能のジェネリックスを利用することでこれを単一の実装で実現しています。ということでLynaたんさんが提示した手法で列挙型と列挙子名の相互変換を関数化してみました(単なるパクリですいません)。ここではクラスではなく高度なレコード型を使用します。またジェネリックスを使いますので当然のことながらDelphi 2009以降でのみ有効です。
uses
  TypInfo, SysUtils, SysConst;

type
  TEnumHelper = record
    class function GetEnumName<T>(Value: T): String; static;
    class function GetEnumValue<T>(const Name: String): T; static;
  end;

class function TEnumHelper.GetEnumName<T>(Value: T): String;
var
  P: PTypeInfo;
  IValue: Integer;
begin

  P := TypeInfo(T);
  if P = nil then
  begin
    raise EInvalidOpException.CreateRes(@SVarNotImplemented);
  end;

  IValue := 0;
  Move(Value,IValue,SizeOf(T));
  Result := TypInfo.GetEnumName(P,IValue);

end;

class function TEnumHelper.GetEnumValue<T>(const Name: String): T;
var
  P: PTypeInfo;
  IValue: Integer;
begin

  P := TypeInfo(T);
  if P = nil then
  begin
    raise EInvalidOpException.CreateRes(@SVarNotImplemented);
  end;

  IValue := TypInfo.GetEnumValue(P,Name);

  with GetTypeData(P)^ do
  begin
    if (IValue < MinValue) or (IValue > MaxValue) then
    begin
      raise ERangeError.CreateRes(@SRangeError);
    end;

    Result := Default(T);
    Move(IValue,Result,SizeOf(T));
  end;

end;
TEnumHelper.GetEnumNameの型パラメータは省略可能です(引数の型から自動的に推論されます)が、TEnumHelper.GetEnumValueについては型パラメータが必須となります。
var
  Alignment: TAlignment;
begin

  Alignment := TEnumHelper.GetEnumValue<TAlignment>('taLeftJustify');

end;

var
  S: String;
begin

  S := TEnumHelper.GetEnumName(taLeftJustify);

end;
こんな感じで使うことができます。

2012年5月1日

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


2012/05/03追記: Developer Direct Webセミナーシリーズのリンクを追加。毎週火曜日の13:00-14:00ですね。

2012/06/12追記: 2012/05/15分のリプレイビデオのリンクを追加しました。

2012/06/18追記: 2012/05/29分のリプレイビデオのリンクを追加しました。

2012年4月26日

IDE Fix Pack 4.9.1リリース

Andreas HausladenさんIDE Fix Pack 2009/2010/XE/XE2がアップデートされてVersion 4.9.1になっています。自動保存をoffにしている場合の不具合の修正のようです。

IDE Fix Pack 4.9.1 restores AutoSave=off support | Andy’s Blog and Tools

2012年4月19日

TRegistryを拡張する

DelphiのTRegistryはWin32APIのレジストリ (ja)のラッパですが、よく見てみるとRegistry Value Types(RegEnumValueに日本語の説明あり)のうちREG_BINARY(バイナリ)、REG_DWORD(32bit整数)、REG_SZ(文字列)、REG_EXPAND_SZ(展開可能文字列)しかサポートしておらず、REG_MULTI_SZ(複数行文字列)やREG_QWORD(64bit整数)の値を直接読み書きすることはできません。もちろんREG_SZやREG_BINARYで代用することは可能ですが、レジストリエディタで値を操作するときはやはりREG_MULTI_SZやREG_QWORDになっていたほうが何かと便利です。そこで今回はクラスヘルパを使ってこれらのデータ型のサポートを追加してみます。

まずクラスヘルパの宣言です。
uses
  Windows, Classes, Registry;

type
  TRegistryHelper = class helper for TRegistry
    function  ReadInt64(const Name: string): Int64;
    procedure WriteInt64(const Name: string; Value: Int64);
    procedure ReadStrings(const Name: String; Value: TStrings); overload;
    function  ReadStrings(const Name: String): String; overload;
    procedure WriteStrings(const Name: String; Value: TStrings); overload;
    procedure WriteStrings(const Name: String; Value: String); overload;
    class function  StringsToDoubleNulTerminated(Strings: TStrings): String; static;
    class procedure DoubleNulTerminatedToStrings(const Str: String; Strings: TStrings); static;
  end;
またWindowsユニットにREG_QWORDの定義が不足していますのでこれも定義しておきます。
const
  REG_QWORD = 11;
  {$EXTERNALSYM REG_QWORD}
最初にInt64の読み書きです。TRegistryの実装を見てみると、Delphi 2009まではRegQueryValueEx (ja)およびRegSetValueEx (ja)の戻値を直接確認していましたが、Delphi 2010以降ではLastErrorプロパティを追加した関係からCheckResultを使用するように変更されているので、ここではこれに従います。またエラー時に生成する例外のメッセージのためにRTLConstsユニットをusesに追加する必要があります。
uses
  RTLConsts;

function TRegistryHelper.ReadInt64(const Name: string): Int64;
var
  BufSize: Integer;
  DataType: Integer;
begin

  DataType := REG_NONE;
  BufSize := SizeOf(Int64);

{$IF RTLVersion >= 21.0}
  if CheckResult(RegQueryValueEx(CurrentKey,PChar(Name),nil,@DataType,PByte(@Result),@BufSize)) = False then
{$ELSE}
  if RegQueryValueEx(CurrentKey,PChar(Name),nil,@DataType,PByte(@Result),@BufSize) <> ERROR_SUCCESS then
{$IFEND}
  begin
    raise ERegistryException.CreateResFmt(@SRegGetDataFailed, [Name]);
  end;

  if DataType <> REG_QWORD then
  begin
    raise ERegistryException.CreateResFmt(@SInvalidRegType,[Name]);
  end;

end;

procedure TRegistryHelper.WriteInt64(const Name: string; Value: Int64);
var
  DataType: Integer;
begin

DataType := REG_QWORD;

{$IF RTLVersion >= 21.0}
  if CheckResult(RegSetValueEx(CurrentKey,PChar(Name),0,DataType,@Value,SizeOf(Int64))) = False then
{$ELSE}
  if RegSetValueEx(CurrentKey,PChar(Name),0,DataType,@Value,SizeOf(Int64)) <> ERROR_SUCCESS then
{$IFEND}
  begin
    raise ERegistryException.CreateResFmt(@SRegSetDataFailed, [Name]);
  end;

end;
次に複数行文字列です。RegQueryValueExとRegSetValueExでREG_MULTI_SZの値を読み書きする場合は、各行がNUL文字で終端されていて、最後に空行(NUL文字だけ)が付加される"double null terminated string"が使われるため、まずTStringsとの間の変換を行う処理を用意します。
class function TRegistryHelper.StringsToDoubleNulTerminated(Strings: TStrings): String;
var
  Index: Integer;
begin

  if Strings.Count > 0 then
  begin
    Result := '';
    for Index := 0 to Strings.Count - 1 do
    begin
      Result := Result + Strings.Strings[Index] + #0;
    end;
    Result := Result + #0;
  end
  else
  begin
    Result := #0 + #0;
  end;

end;

class procedure TRegistryHelper.DoubleNulTerminatedToStrings(const Str: String; Strings: TStrings);
var
  P: PChar;
  Start: PChar;
  S: String;
begin

  Strings.BeginUpdate;
  try
    Strings.Clear;

    P := PChar(Str);
    while P^ <> #0 do
    begin
      Start := P;
      while (P^ <> #0) do
      begin
        Inc(P);
      end;
      SetString(S,Start,P - Start);
      Strings.Add(S);
      Inc(P);
    end;

  finally
    Strings.EndUpdate;
  end;

end;
これらのメソッドを利用してTStringsを読み書きします。
procedure TRegistryHelper.ReadStrings(const Name: String; Value: TStrings);
var
  Len: Integer;
  Data: String;
  DataType: Integer;
begin

  Len := GetDataSize(Name);
  if Len > 0 then
  begin
    SetString(Data,nil,Len div SizeOf(Char));

    DataType := REG_NONE;
{$IF RTLVersion >= 21.0}
    if CheckResult(RegQueryValueEx(CurrentKey,PChar(Name),nil,@DataType,PByte(Data),@Len)) = False then
{$ELSE}
    if RegQueryValueEx(CurrentKey,PChar(Name),nil,@DataType,PByte(Data),@Len) <> ERROR_SUCCESS then
{$IFEND}
    begin
      raise ERegistryException.CreateResFmt(@SRegGetDataFailed,[Name]);
    end;

    if DataType <> REG_MULTI_SZ then
    begin
      raise ERegistryException.CreateResFmt(@SInvalidRegType,[Name]);
    end;

    SetLength(Data,Len div SizeOf(Char));

    DoubleNulTerminatedToStrings(Data,Value);
  end;

end;

procedure TRegistryHelper.WriteStrings(const Name: String; Value: TStrings);
var
  Data: String;
begin

  Data := StringsToDoubleNulTerminated(Value);

{$IF RTLVersion >= 21.0}
  if CheckResult(RegSetValueEx(CurrentKey,PChar(Name),0,REG_MULTI_SZ,
                 PChar(Data),Length(Data) * SizeOf(Char))) = False then
{$ELSE}
  if RegSetValueEx(CurrentKey,PChar(Name),0,REG_MULTI_SZ,
                   PChar(Data),Length(Data) * SizeOf(Char)) <> ERROR_SUCCESS then
{$IFEND}
  begin
    raise ERegistryException.CreateResFmt(@SRegSetDataFailed,[Name]);
  end;

end;
またTStringsではなく改行文字(#13#10)を含む通常のStringで読み書きするoverloadも用意してみました。
function TRegistryHelper.ReadStrings(const Name: String): String;
var
  SL: TStringList;
begin

  SL := TStringList.Create;
  try
    ReadStrings(Name,SL);
    Result := SL.Text;

  finally
    SL.Free;
  end;

end;

procedure TRegistryHelper.WriteStrings(const Name: String; Value: String);
var
  SL: TStringList;
begin

  SL := TStringList.Create;
  try
    SL.Text := Value;
    WriteStrings(Name,SL);

  finally
    SL.Free;
  end;

end;

2012年4月18日

第22回エンバカデロ・デベロッパーキャンプ開催決定

第22回エンバカデロ・デベロッパーキャンプは2012年05月30日に大阪で、2012年05月31日に東京で開催されます。

エンバカデロ・デベロッパーキャンプ | 大阪 | Embarcadero Technologies
エンバカデロ・デベロッパーキャンプ | ホーム

今回はエンバカデロ・テクノロージーズ 海外担当副社長兼ジェネラルマネージャのNigel BrownさんがXE3を含む今後の製品戦略について講演したり質問を受け付けたりするそうです。

2012年4月16日

[書籍]ソフトウェアテストの教科書

MARUZEN&ジュンク堂書店 渋谷店

ソフトウェアテストの教科書 (amazon)/石原一宏、田中英和著/田中真史監修/ソフトバンククリエイティブ/ISBN 978-4-7973-6581-8(ISBN 4797365811)/2,625円

を購入。

2012年4月14日

IDE Fix Pack 4.8.2リリース

Andreas HausladenさんIDE Fix Pack 2009がアップデートされてVersion 4.8.2になっています(Delphi 2009における問題の修正のみ)。

IDE Fix Pack 4.8.2 for RAD Studio 2009 only | Andy’s Blog and Tools

2012年4月13日

Firebird 2.0.7リリース

Firebird Ver2.0.7がリリースされています。

Firebird: Firebird 2.0.7
Firebird 2.0.7 Release Notes (PDF)

元ねたはFirebird News » Firebird V2.0.7 has been released – likely to be the last for the 2.0-series

2012/07/04追記: Firebird 2.0はこのリリース(2.0.7)をもってEOL(End Of Life)となりました。

Firebird: Firebird 2.0.x series discontinued

InterBase XE Update 4リリース

InterBase XE Update 4がリリースされています(2012/04/13現在で英語版のみ2012/05/15現在で日本語版がリリースされ始めています)。バージョンは10.0.4.590となっています。

InterBase XE Update 4 Readme (en)

Team Japan » InterBase XE 日本語版 Update 4 がリリースされました

28860 InterBase XE 32-bit Update 4 (10.0.4.590) for Windows, Japanese
28794 InterBase XE 32-bit Update 4 (10.0.4.590) for Windows, English
28861 InterBase XE 64-bit Update 4 (10.0.4.590) for Windows, Japanese
28795 InterBase XE 64-bit Update 4 (10.0.4.590) for Windows, English
28798 InterBase XE Update 4 (10.0.4.590) for Mac OS X, English
28862 InterBase XE Update 4 (10.0.4.590) for Linux, Japanese
28799 InterBase XE Update 4 (10.0.4.590) for Linux, English
28801 InterBase XE Update 4 (10.0.4.590) for Solaris, English

28828 InterBase XE Server Edition for Windows (English)
28869 InterBase XE Server Edition multi-platform (10.0.4.590,Japanese)
28827 InterBase XE Server Edition multi-platform (10.0.4.590,Apr-2012), English

28870 InterBase XE Desktop Edition for Windows (Japanese)
28829 InterBase XE Desktop Edition for Windows (English)

28864 InterBase XE 32-bit Developer Edition for Windows - Japanese
28804 InterBase XE 32-bit Developer Edition for Windows - English
28866 InterBase XE 64-bit Developer Edition for Windows - Japanese
28806 InterBase XE 64-bit Developer Edition for Windows - English
28818 InterBase XE (10.0.4.590) 32-bit Developer Edition, Mac OS X, English
28868 InterBase XE (10.0.4.590) 32-bit Developer Edition, Linux, Japanese
28814 InterBase XE (10.0.4.590) 32-bit Developer Edition, Linux, English
28816 InterBase XE (10.0.4.590) 32-bit Developer Edition, Solaris, English

28807 InterBase XE Update 4 (10.0.4.590) ToGo Edition, Windows/MacOSX

2012/06/08追記: Update 4を適用した場合でもガーディアンのバージョンは以前のまま(ガーディアンは更新されていないため)とのことです。

InterBase XE Update 4を実施しても Guardian のバージョンが更新されない

2012年4月11日

Microsoft Monthly Update 2012/04

今日はMicrosoftのセキュリティアップデートの日です。
MS12-023
MS12-024
MS12-025
MS12-026
MS12-027
MS12-028

2012年4月5日

FireMonkeyクイックスタートガイド

FireMonkeyのクイックスタートガイドの日本語版が公開されています。後で読む。とりあえずメモ。

FireMonkey クイック スタート ガイド - はじめに - RAD Studio XE2
FireMonkey Quick Start Guide - Introduction - RAD Studio XE2

元ねたはエンバカデロの新井さんtweet

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

2012年2月9日

例外チェーン

Delphi 2009の新機能の一つに例外チェーン、あるいはネストした例外オブジェクトというものがあります。従来の(Delphi 2007およびそれ以前の)例外処理では、発生した例外をtry...except文で捕捉した場合に、そのままendに到達することで例外処理を終了させるか、別の例外オブジェクトを生成して送出することで例外処理をさらに上位に向かって継続するか、例外を再生成("raise;")することで例外処理を継続するか、のいずれかになります。しかし、別の例外を送出する場合は元の例外オブジェクトの持つ情報は消滅してしまいますし、例外を再生成する場合は新たな情報を付け加えることができません。そこでこの例外チェーンという機能を使うことで、元の例外オブジェクトの持つ情報に新たな情報を加えて上位の処理に送出することができます。

例として、あるテキストファイルの1行目に書かれている文字列を10進数とみなして取り込む、という関数を考えてみます。
type
  EFileIsEmpty = class(Exception);

function ReadIntegerValueFromFile(const Path: String): Integer;
var
  Filename: String;
  SL: TStringList;
begin

  Filename := IncludeTrailingPathDelimiter(Path) + 'FOO.TXT';
  SL := TStringList.Create;
  try
    SL.LoadFromFile(Filename);
    if SL.Count = 0 then
    begin
      raise EFileIsEmpty.Create('File is empty.');
    end;

  Result := StrToInt(SL.Strings[0]);

  finally
    SL.Free;
  end;

end;
ここで例外が送出される状況には、1.何らかの理由でファイルを開けない(EFOpenError)、2.ファイルが空(0行)だった(EFileIsEmpty)、3.1行目に10進数に変換できない文字があった(EConvertError)の3つがあります(正確にはリソース不足でTStringList.Createが失敗する状況を含め4つですが、今回は考えないことにします)。それぞれの原因に対応した例外クラスがあるため、呼び出し元ではエラーの理由を例外オブジェクトのクラスの違いで知ることができます。
procedure TForm1.Button1Click(Sender: TObject);
begin

  try
    ReadIntegerValueFromFile('C:\BAR');

  except
    on E: EFOpenError do
    begin
      MessageDlg('ファイルを開けませんでした。' + sLineBreak + E.Message,
                 mtInformation,[mbOk],0);
      Exit;
    end;

    on E: EFileIsEmpty do
    begin
      MessageDlg('ファイルが空でした。' + sLineBreak + E.Message,
                 mtInformation,[mbOk],0);
      Exit;
    end;

    on E: EConvertError do
    begin
      MessageDlg('不正な文字列が入っていました。' + sLineBreak + E.Message,
                 mtInformation,[mbOk],0);
      Exit;
    end;
  end;

end;
ここでエラーメッセージにファイル名を表示したい、ということになったとします。ところが呼出元のレベルではファイルの存在するパスはわかっていますがフルパス名はReadIntegerValueFromFileの内部に隠蔽されてしまっています。そこで
type
  EFileIsEmpty = class(Exception);
  EFileReadError = class(Exception)
  private
    FFilename: String;
  public
    constructor Create(const Msg: string; const AFilename: String);
    property Filename: String read FFilename;
  end;

function ReadIntegerValueFromFile(const Path: String): Integer;
var
  Filename: String;
  SL: TStringList;
begin

  Filename := IncludeTrailingPathDelimiter(Path) + 'FOO.TXT';
  SL := TStringList.Create;
  try
    try
      SL.LoadFromFile(Filename);
      if SL.Count = 0 then
      begin
        raise EFileIsEmpty.Create('File is empty.');
      end;
      Result := StrToInt(SL.Strings[0]);

    except
      raise EFileReadError.Create('Error!',Filename);
    end;

  finally
    SL.Free;
  end;

end;

constructor EFileReadError.Create(const Msg, AFilename: String);
begin

  inherited Create(Msg);

  FFilename := AFilename;

end;
とすることで
procedure TForm1.Button1Click(Sender: TObject);
begin

  try
    ReadIntegerValueFromFile('C:\BAR');

  except
    on E: EFileReadError do
    begin
      MessageDlg(Format('ファイル ''%s'' の読み込みでエラーが発生しました。' + 
                        sLineBreak  + '%s',
                        [E.Filename,E.Message]),
                 mtInformation,[mbOk],0);
      Exit;
    end;
  end;

end;
のようにエラーがあったときにそのファイルのフルパス名を知ることができます。が、エラーの原因はわからなくなってしまいました。そこで例外チェーンの登場です。クラスプロシージャException.RaiseOuterExceptionを使用することで、その例外ハンドラで受け取った例外オブジェクトを消滅させることなく新たな例外を送出することができます。
type
  EFileIsEmpty = class(Exception);
  EFileReadError = class(Exception)
  private
    FFilename: String;
  public
    constructor Create(const Msg: string; const AFilename: String);
    property Filename: String read FFilename;
  end;

function ReadIntegerValueFromFile(const Path: String): Integer;
var
  Filename: String;
  SL: TStringList;
begin

  Filename := IncludeTrailingPathDelimiter(Path) + 'FOO.TXT';
  SL := TStringList.Create;
  try
    try
      SL.LoadFromFile(Filename);
      if SL.Count = 0 then
      begin
        raise EFileIsEmpty.Create('File is empty.');
      end;
      Result := StrToInt(SL.Strings[0]);

    except
      Exception.RaiseOuterException(EFileReadError.Create('Error!',Filename));
    end;

  finally
    SL.Free;
  end;

end;

constructor EFileReadError.Create(const Msg, AFilename: String);
begin

  inherited Create(Msg);

  FFilename := AFilename;

end;
ここで送出される例外オブジェクトはEFileReadErrorのままです。しかし
procedure TForm1.Button1Click(Sender: TObject);
begin

  try
    ReadIntegerValueFromFile('C:\BAR');

  except
    on E: EFileReadError do
    begin
      if E.InnerException is EFOpenError then
      begin
        MessageDlg(Format('ファイル ''%s'' を開けませんでした。' + 
                          sLineBreak + '%s',
                          [E.Filename,E.InnerException.Message]),
                   mtInformation,[mbOk],0);
      end
      else if E.InnerException is EFileIsEmpty then
      begin
        MessageDlg(Format('ファイル ''%s'' が空でした。' + 
                          sLineBreak + '%s',
                          [E.Filename,E.InnerException.Message]),
                   mtInformation,[mbOk],0);
      end
      else if E.InnerException is EConvertError then
      begin
        MessageDlg(Format('ファイル ''%s'' の1行目に不正な文字列が入っていました。' + 
                          sLineBreak + '%s',
                          [E.Filename,E.InnerException.Message]),
                   mtInformation,[mbOk],0);
        Exit;
      end;

      Exit;
    end;
  end;

end;
と例外オブジェクトのInnerExceptionプロパティでException.RaiseOuterExceptionを呼び出した時点での例外オブジェクトを参照することができます。

この例外チェーンに関係するメソッド、プロパティには
  • RaiseOuterException: 例外ブロック内で使用し、新しく生成した例外オブジェクトをパラメータとして呼び出すことでその時点での例外オブジェクトをチェーンした例外を送出するExceptionクラスのクラスプロシージャ。
  • ThrowOuterException: RaiseOuterExceptionと同じ。C++では例外はraiseするものではなくthrowするものなのでこの名前のクラスプロシージャも用意されている。
  • InnerException: 最も近いRaiseOuterExceptionを送出した時点での例外オブジェクトを格納しているプロパティ。通常の例外の送出(raise EXXXX.Create)ではnilとなる。またRaiseOuterExceptionがネストして呼び出されている場合はE.InnerException.InnerException...のようにさかのぼって例外オブジェクトを参照することができる。
  • BaseException: ネストしてRaiseOuterExceptionが呼び出された場合に最初に送出された例外オブジェクトを格納しているプロパティ。通常の例外の送出(raise EXXXX.Create)ではnilとなる。また1段階しかRaiseOuterExceptionが呼び出されていない場合はInnerException=BaseExceptionとなる。
  • ToString例外チェーン上の全ての例外オブジェクトのMessageプロパティをCR+LFで連結したプロパティ。
があります。

元ねたはDELPHI 2009 HANDBOOK

2012年2月2日

[書籍]世界一わかりやすいSQLの授業

同じくMARUZEN&ジュンク堂書店 渋谷店

世界一わかりやすいSQLの授業 (amazon)/Lepton著/ソシム/ISBN 978-4-88337-801-2/2,079円

を購入。

[書籍]Clean Coder

MARUZEN&ジュンク堂書店 渋谷店The Clean Coderの翻訳である

Clean Coder (amazon)/Robert C. Martin著/角征典訳/アスキー・メディアワークス/ISBN 978-4-04-886069-7/2,100円

を購入。プロフェッショナルなプログラマ(またはそれを目指す人)は読んでおくべきです。

2012年2月1日

第21回エンバカデロ・デベロッパーキャンプ開催決定

第21回エンバカデロ・デベロッパーキャンプは2012年03月09日~2012年03月10日の2日間で開催されます。

エンバカデロ・デベロッパーキャンプ
【3/9~10】第21回 エンバカデロ・デベロッパーキャンプ

今回は全セッションオンラインで中継あり、懇親会あり、そして宿泊ありと盛り沢山で行われます。

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



2012/02/23追記: リプレイビデオのリンクを追加しました。

2012年1月27日

Firebirdロードマップ(2012/01)

ちょっと前のことになりますが、Firebirdのロードマップが更新されています。

Firebird: Roadmap

てきとうな要約:
  • 1.5 - 1.5.6が最終版で、今後公式にリリースされることはない。ただし新しいバージョンからバックポートされたバグフィックスを含む修正版が必要と判断した場合はIBPhoenixから商用製品としてリリースされるかもしれない。
  • 2.0 - 2.0.6(2010/06)が最新版で、年1回のメンテナンスサイクルでのリリースが宣言されている。次のリリース(2.0.7)は2012年のQ1を予定。
  • 2.1 - 2.1.4(2011/03)が最新版で、こちらも年1回のメンテナンスサイクルでのリリースが宣言されている。次のリリース(2.1.5)は2012年のQ3を予定。
  • 2.5 - 2.5.1(2011/10)が最新版で、年2回のメンテナンスサイクルでのリリースが宣言されている。次のリリース(2.5.2)は2012年のQ2を予定。
  • 3.0 - 現在開発中の最新版で、Alpha 1は2012年のQ1にリリースを予定。キーポイントは以下のとおり。
    • 新しい認証サブシステム、構成サブシステムを含む、改訂されたアーキテクチャ
    • 共有ページキャッシュを備えたスケーラブルなマルチスレッドエンジン
    • 新しいシステムテーブル、モニタテーブルを備えた新しいODS(Version 12)
    • JavaやC++などによる外部ストアドプロシージャ、トリガ、関数
    • 作り直されたオプティマイザと新しいデータアクセスメソッド
    • セキュリティの強化
    • さまざまなSQL拡張

元ねたはFirebird News » Firebird Roadmap updated for January 2012

2012/03/18追記: Firebird News » Firebird roadmap has been updatedからの情報で、ロードマップが一部変更されています。具体的には、
  • 2.0は現在2.0.7がRC1(これは変更なし)
  • 2.1は若干早まって2.1.5を2012年のQ2に予定
  • 2.5も若干早まって2.5.2を2012年のQ2に予定
  • 3.0は逆にAlpha 1を2012年のQ2に遅らせる
ということで、3.0の開発を遅らせてその分のリソースを2.1/2.5に振り分けることにした、という話のようです。

2012年1月26日

TMS Aurelius

Delphiで使用できるORMとしてちょっと前にDORM (Delphi ORM)を取り上げましたが、TMS Softwareから

TMS Aurelius

という製品がリリースされています。Delphi 2010/XE/XE2で動作し、
  • 対応プラットフォーム: Windows x86/x64、Mac OS X
  • 対応RDBMS: Firebird、Interbase、Microsoft SQL Server、MySQL、NexusDB、Oracle、SQLite、PostgreSQL、DB2
  • 対応データアクセスコンポーネント: dbExpress、dbGo(ADO)、Interbase Express(IBX)、SQLite、AnyDac、NexusDB、SQL-Direct
となっています。ライセンスはシングルデベロッパライセンス(1ユーザ)が195EUR(=19,800JPY)、スモールチームライセンス(2ユーザ)が295EUR(=30,000JPY)、サイトライセンス(ユーザ数無制限)が695EUR(=70,600JPY)となっています(2012/02/29までの限定で20%のディスカウント中)。

2012年1月17日

IBSurgeon Log Viewer

InterBase/Firebird用の各種ツールで有名なIBSurgeonからIBSurgeon Log ViewerというツールがFREEWAREとして公開されています。

IBSurgeon Log Viewer

InterBase(interbase.log)やFirebird(firebird.log)のログファイルには(いつもではないにしても)ときどき有用な情報が記録されています。しかしログそのものが場当たり的に拡張されてきたため、メモ帳やエディタなどで開いてもなかなか必要な情報にたどりつくことができません(また必要な情報が記録されていないことも多々あります)。このIBSurgeon Log Viewerはこれらのログを見やすく表示するだけでなく、可能であればそのログの原因となるような状況についても解説を表示してくれる("Message Description"ペイン)というツールです。現時点(2012/01/17)の最新バージョンは2.0.0.5となっています。

元ねたはFirebird News » IBSurgeon Log Viewer 2.0 – free tool for viewing and analyzing firebird.log

2012年1月11日

Microsoft Monthly Update 2012/01

今日はMicrosoftのセキュリティアップデートの日です。
MS12-001
MS12-002
MS12-003
MS12-004
MS12-005
MS12-006
MS12-007

2012年1月5日

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


2012/02/08追記: リプレイビデオのリンクを追加しました。

2012年1月4日

IDE Fix Pack 4.6.5/4.6.6リリース

Andreas HausladenさんIDE Fix Pack 2009/2010/XE/XE2がアップデートされてVersion 4.6.5になっています。

IDE Fix Pack 4.6.5 released | Andy’s Blog and Tools

追記: IDE Fix Pack 2009/2010/XE/XE2 Version 4.6.5にはデバッガが相対パス指定のソースファイルを見つけられないという問題があり、これを修正したVersion 4.6.6がリリースされています。

IDE Fix Pack 4.6.6 – bug fix release | Andy’s Blog and Tools

2011年12月30日

Microsoft OOB Update 2011/12

Microsoftの定例外のセキュリティアップデートがリリースされています。
MS11-100

2011年12月28日

IDE Fix Pack 4.6.1リリース

Andreas HausladenさんIDE Fix Pack 2009/2010/XE/XE2がアップデートされてVersion 4.6.1になっています。このバージョンではバグフィックス2件のみで機能的な追加変更は含まれていないとのことです。

IDE Fix Pack 4.6.1 – bugfix release | Andy’s Blog and Tools

2011年12月20日

RAD Studio/Delphi/C++Builder XE2 Update 3 Hotfix 2

RAD Studio/Delphi/C++Builder XE2 Update 3のHotfix 2(Ent/Arc/Ult SKUのみ)がリリースされています。
  • QC101807 Update 3適用後にAndroid用モバイルコネクタのDSRESTSSLFactory.javaが不足する
という問題を修正するものです。

28672 HotFix 2 for Delphi, C++Builder and RAD Studio XE2
C++Builder XE2/Delphi XE2/RAD Studio XE2 向け Hotfix 2
Hotfix 2 for C++Builder XE2, Delphi XE2 and RAD Studio XE2 is now available

2011年12月19日

FastReport 4 VCL日本語版

Delphi/C++Builder XE2ではFastReport 4 RAD Editionが標準でバンドルされるようになりましたが、先週のデベロッパーTVでもちょっと話が出ていた製品版の日本語版が2012/01/13に発売されるようです。

レポーティングソリューション FastReport VCL | 製品概要
リオスe-Shop/商品一覧ページ

エージーテックさんのページでは1月中旬以降正式リリースとなっていますが、リオスe-Shopさんでは2012/01/13発売と日付まで出ています。またリオスe-Shopさんでは2011/11/21から

キャンペーン期間中にご成約いただきますと、まずは英語版をお送りし、日本語版販売時に優先して、日本語版をお送りします。
(同じライセンス番号で動作しますので、日本語か英語のどちらかでご利用できます)
という「先行販売割引キャンペーン」(42,000円)をやっています。ちなみにこれはEnterprise Edition/Single license相当(Fast Reports Inc.から直接買えば349.00USD=27,000JPY)ですので、日本語に翻訳されていることに15,000円出せるかどうか、ということになるのかと。実際に仕事で使うなら許容範囲でしょうか。

2012/01/16追記: FastReport VCLの日本語版がリオスe-Shopで販売開始になっています。

レポーティングソリューション FastReport VCL | 製品概要
リオスe-Shop/商品一覧ページ

2012/01/18追記: 製品版のFastReportをインストールするためにバンドル版をアンインストールするとコンポーネントの登録が全て削除されるという不具合(QC102274)が報告されており、Team Japanに詳細と対応策が解説されています。

Team Japan » Delphi/C++Builder/RAD Studio XE2のUpdate3 で FastReportをアンインストールすると..

2011年12月16日

IDE Fix Pack 4.6リリース

Andreas HausladenさんIDE Fix Pack 2009/2010/XE/XE2がアップデートされてVersion 4.6になっています。

IDE Fix Pack 4.6 (supports XE2 Update 3) | Andy’s Blog and Tools

Delphi/C++Builder XE2 Update 3

かねてからの噂どおりDelphi/C++Builder XE2のUpdate 3がリリースされています。

28670 Update 3 for Delphi, C++Builder and RAD Studio XE2
Update 3 for Delphi XE2, C++Builder XE2 and RAD Studio XE2
XE2 Update 3 のリリース ノート - RAD Studio XE2 (en)
Delphi XE2/C++Builder XE2 Update 3 における不具合修正リスト (en)

Update 3ではTButtonのModalResultプロパティで使用するいくつかの値の定義が変更されています。またコンパイラ内の一部の構造体の変更に伴いAndreas HausladenさんIDE Fix Pack 2009/2010/XE/XE2 4.5が動作しなくなっています(既に4.6がリリースされています)。

TButtonのModalResultプロパティで使用する値の件はUpdate 3のリリースノートに明記されただけで、実際にはXE2 RTMにおける変更のようです(QC100283)。まずTButto.ModalResultの型はTModalResultですが、TModalResultは列挙型ではなく単に
  TModalResult = Low(Integer) .. High(Integer);
と実質的にIntegerであり、それぞれの値(mr...)は該当するボタンのID(ID_...)と同値で、XEおよびそれ以前ではControls.pasで、XE2ではSystem.UITypes.pasで定義されています。Update 3のリリースノートからリンクしているBob SwartさんのXE2 values of mrAll, mrNoToAll, mrYesToAll and mrCloseというアーティクルで詳しく考察されていますが、XEではmrCloseがmr...の最後(mrYesToAllの次)になるように定義されているのに対し、XE2ではmrHelp、mrTryAgain、mrContinueと共にmrNoの次になるように移動し、その後にmrAll、mrNoToAll、mrYesToAllとmrYesToAllが最後になるように定義が変更されています。さらにTModalResultは列挙型でないためdfm上は数値として記録されているため、XEまでのコード(フォームデータ)でModalResultにmrAll、mrNoToAll、mrYesToAll、mrClose(8~11)と設定していたものをXE2に取り込むとmrClose、mrHelp、mrTryAgain、mrContinueに変化してしまう、ということになります(あるいはソースを共用している場合は逆のことも起きます)。基本的にbreaking changeということであり、個別に対策するしかないのですが、上記のBob Swartさんのアーティクルにはこの問題を指摘してくれるScanDFMというツールがリンクされています。

2012/02/10追記: ModalResultの定義値の変更の件を補足しました。高橋さん、情報ありがとうございます。

2011年12月14日

2011年12月7日

Asphyre Sphinx 2

Delphi/C++Builder上で2D/3Dグラフィックスを扱うライブラリとして以前取り上げたAsphyre Sphinxですが、メジャーバージョンアップした2.0.0がリリースされています。

Asphyre Sphinx 2

Delphi XE2 Update 1に対応しており、Windows x86/x64およびMacOS X/iOS上のDirectX 7/DirectX 9/DirectX 10/DirectX 10.1/DirectX 11/OpenGLをサポートしています。ライセンスは以前と同じくMPL 1.1です。

またVer1も最新版は1.1.0となっており、Delphi 2006/Turbo Delphi/Delphi 2007に加えてDelphi XEにも対応しています。

Asphyre Sphinx

元ねたは2ちゃんねるのくだすれDelphi(超初心者用)その53の902

2011年12月1日

dbExpressのODBCドライバでPostgreSQLに接続

オープンソースのRDBとして日本では人気のPostgreSQL (日本PostgreSQLユーザ会)ですが、世界的に見るとあまり重要視されておらず、dbExpressでも以前からMySQLはサポートされています(Ent/Ult/Arc SKUのみ)がPostgreSQLは予定すらない、という状況でした。しかしDelphi XE2では(これもEnt/Ult/Arc SKUのみですが)dbExpressのODBCドライバが新しく追加されました。このdbExpressのODBCドライバを経由してPostgreSQLに接続する方法についてラテンアメリカ・カリブ地域担当プロダクトラインマネージャ・リードエバンジェリストのAndreano Lanusseさんが解説しています。興味深い。とりあえずメモ。

Connecting to PostgreSQL through dbExpress ODBC driver | Andreano Lanusse Blog | Technology and Software Development | C++Builder

ODBCデータソースアドミニストレータ(odbcad32.exe)でPostgreSQLのODBCドライバを指定したデータソースを作成しておいて、dbExpressのSQLConnectionのDriverNameに'ODBC'を、ParamsのDatabaseにそのデータソース名(DSN)を指定することで、Delphi/C++Builder-dbExpress-dbExpress ODBCドライバ-ODBC-PostgreSQL ODBCドライバ-PostgreSQLサーバという形で接続できる、ということのようです。なおx64環境ではODBCデータソースアドミニストレータ(odbcad32.exe)もx86、x64の両方が存在するので、クライアントのターゲットプラットフォームによって使い分ける必要があります。

日本語だと第20回 エンバカデロ・デベロッパーキャンプの【B4】 Delphi/C++Builderテクニカルセッション 「dbExpressとマルチプラットフォーム開発」プレゼンテーション資料あたりが参考になります。

2012/02/10追記: デベロッパーキャンプのプレゼンテーション資料のリンクを追記しました。高橋さん、情報ありがとうございます(遅くなりましたが)。

2011年11月30日

[書籍]プログラミングC# 第6版

MARUZEN&ジュンク堂書店 渋谷店Programming C# 4.0の翻訳である

プログラミングC# 第6版 (amazon)/Ian Griffiths、Matthew Adams、Jesse Liberty著/鈴木幸敏、首藤一幸、株式会社情報技研訳/オライリージャパン/ISBN 978-4-87311-517-7/5,040円

を購入。

2011年11月28日

JVCL 3.45リリース

JVCL(JEDI Visual Component Library)がアップデートされてVersion 3.45(JCL Version 2.3.1)になっています。

JEDI VCL for Delphi - Browse /JVCL 3/JVCL 3.45 at SourceForge.net

またAndreas HausladenさんがコマンドラインコンパイラDCC32/DCC64が付属していないDelphi/C++Builder XE2 Starter SKUのためのコンパイル済バイナリのインストーラをCodeCentralにアップロードしています(上記のリリースバージョンそのものではなく、JCLはsvn revision 3634、JVCLはsvn revision 13184から作成したものとのことです)。

28636 Jedi Code Library 2.4.0.4198r3634 BinaryInstaller for XE2
28637 Jedi Visual Component Library 3.45r13184 BinaryInstaller for XE2

元ねたはUpdated JCL and JVCL Binary Installers for XE2 | Andy’s Blog and Tools

2011年11月22日

DORM (Delphi ORM)

Delphi XEの新機能の新しい(拡張された)RTTIと属性の利用方法として考えられるもののひとつとしてORM(Object-relational mapping)があります。新しいRTTIでクラスの持つプロパティと型情報を参照してデータベースとのマッピングに利用し、属性で個別の細かい制御を行う、というアイデアはわりと一般的なものかもしれません。実験的な実装はいくつかあるようですが、一応実用に耐えるレベルのもの、となるといまのところDaniele TetiさんによるDORM (Delphi ORM)ぐらいでしょうか。

DORM, the Delphi ORM

Delphi XE/XE2で使用可能で、対応データベースはいまのところdbExpress経由のFirebird (2.1+)またはInterBase (2009+)です。ライセンスはApache License 2.0 (en)となっています。

先日のITDevCon 2011のDaniele Tetiさんのセッションのプレゼンテーション資料

DORM, the Delphi ORM

が参考になります。

元ねたはwhile true do; » Blog Archive » dorm, “The Delphi ORM”, officially published at ITDevCon