2014年9月3日

DelphiのRTLで定義済の属性

Delphi 2010で追加された新しいRTTIに含まれる属性機能ですが、Delphiのバージョンにより違いがあるものの、RTLで予め定義されている属性がいくつかあります。ところがこれらの定義済の属性についてヘルプにはきちんとした記述がありません。ということで調べてみました(XE6/XE7は手元にないので調べていませんが、既存のものについてはXE5と大きく異なる部分はないと思いますDelphi XE6/XE7/XE8/10 Seattle/10.1 Berlinについても確認しました)。

  • System ユニット
    TCustomAttribute
    [2010..13 Florence]カスタム属性のルートクラス
    属性を新たに定義するときはTCustomAttributeから派生させる
    WeakAttribute [Weak]
    [XE3..13 Florence]循環参照などのARCがオブジェクトの破棄を行えないような状況を防ぐ"弱い"参照であることを示す
    10 Seattleおよびそれ以前ではNEXTGENコンパイラのみ
    参考: コンパイラ属性 - RAD Studio
    参考: 弱い参照 (Delphi モバイル コンパイラでの自動参照カウント)
    UnsafeAttribute [Unsafe]
    [XE3..13 Florence]オブジェクトの生成時など参照カウントが0となるような状況でARCによる破棄を防ぐ
    10 Seattleおよびそれ以前ではNEXTGENコンパイラのみ
    参考: コンパイラ属性 - RAD Studio
    参考: Unsafe 属性 (Delphi モバイル コンパイラでの自動参照カウント)
    参考: モバイル開発のためのDelphi言語 (ホワイトペーパ)
    RefAttribute [Ref]
    [XE3..13 Florence]定数パラメータを強制的に参照渡しにする
    ヘルプによればRefAttributeはXE4の新機能だが、実際にはXE3でも使用可能
    参考: コンパイラ属性 - RAD Studio
    参考: 定数パラメータ (パラメータ(Delphi))
    VolatileAttribute [Volatile]
    [XE4..13 Florence]スレッドによって書き換えられる可能性があるフィールドに対して、コード生成時にレジスタまたはその他の一時メモリ領域に値をコピーするような最適化を行わないようにする
    10 Seattleおよびそれ以前ではNEXTGENコンパイラのみ
    参考: コンパイラ属性 - RAD Studio
    参考: Delphi コンパイラの新しい属性 (Delphi XE4 および C++Builder XE4 の新機能)
    参考: volatile (コンパイラ属性)
    StoredAttribute [Stored]
    [XE7..13 Florence]System.Classes.StoredAttributeを参照
    HPPGENAttribute [HPPGEN]
    [XE8..13 Florence]C++Builder用のhppファイル生成時に使用する情報らしいが詳細不明
    HFAAttribute [HFA]
    [XE8..13 Florence]pageId=86770118(なにそれ)に情報があるらしいが詳細不明(For internal use only.とコメントあり)ARM64プラットフォーム向けにレコード型/配列型に対して生成されたRTTI HFA情報をオーバライド
    AlignAttribute [Align]
    [10 Seattle..13 Florence]メモリ上のオブジェクトのアライメントを指定するものらしいが、For internal use only.とコメントあり
  • System.Classes ユニット
    ComponentPlatformsAttribute [ComponentPlatforms(<params>)]
    [XE2..13 Florence]コンポーネントが動作するプラットフォームを指定する
    パラメータ(Word値)にはSystem.Classesで定義されている以下の定数の論理和を指定する
    • pidWin32 [XE2..13 Florence]
    • pidWin64 [XE2..13 Florence]
    • pidOSX32 [XE2..13 Florence]
    • pidiOSSimulator32 [10.3 Rio..13 Florence], pidiOSSimulator [XE3..13 Florence]
    • pidAndroidArm32 [11 Alexandria..13 Florence], pidAndroid32Arm [10.3 Rio..13 Florence], pidAndroid [XE3..13 Florence]
    • pidLinux32 [XE3..13 Florence]
    • pidiOSDevice32 [XE8..13 Florence], pidiOSDevice [XE3..13 Florence]
    • pidLinux64 [XE8..13 Florence]
    • pidWinNX32 [XE3..13 Florence]
    • pidWinIoT32 [XE8..13 Florence] ("Embedded IoT (Internet of Things) Windows w/ Intel Galileo")
    • pidiOSDevice64 [XE8..13 Florence]
    • pidWinARM32 [10.3 Rio..13 Florence], pidWin32ARM [11 Alexandria..13 Florence], pidWinARM [10 Seattle..10.2 Tokyo]
    • pidOSX64 [10.1 Berlin..13 Florence], pidOSXNX64 [10.1 Berlin..10.2 Tokyo]
    • pidLinuxArm32 [11 Alexandria..13 Florence], pidLinux32Arm [10.1 Berlin..10.4 Sydney]
    • pidLinuxArm64 [11 Alexandria..13 Florence], pidLinux64Arm [10.1 Berlin..10.4 Sydney]
    • pidAndroidArm64 [11 Alexandria..13 Florence], pidAndroid64Arm [10.3 Rio..13 Florence], pidAndroid64 [10.1 Berlin..10.2 Tokyo]
    • pidiOSSimulator64 [10.3 Rio..13 Florence]
    • pidOSXArm64 [11 Alexandria..13 Florence]
    • pidWinArm64 [11 Alexandria..13 Florence]
    • pidiOSSimulatorArm64 [11 Alexandria..13 Florence]
    • pidWin64x [12 Athens..13 Florence]
    TDefaultAttributeBase
    [XE3..13 Florence]DefaultAttribute/NoDefaultAttributeの継承元
    DefaultAttribute [Default(<param>)]
    [XE3..13 Florence]プロパティの格納指定子defaultと同等の指定
    パラメータにはデフォルト値(Boolean型、AnsiChar型、Char型、Integer型、Cardinal型、Int64型、UInt64型、String型、Extended型のいずれか)を指定する
    NoDefaultAttribute [NoDefault]
    [XE3..13 Florence]プロパティの格納指定子nodefaultと同等の指定
    StoredAttribute [Stored(<param>)]
    [XE3..XE7]プロパティの格納指定子storedと同等の指定
    パラメータには真偽値(False | True)またはストレージハンドラ(Boolean型のプロパティまたはパラメータを持たずBoolean値を返すメソッド)の名前を指定する(XE8以降はSystemユニットに移動)
    ObservableMemberAttribute [ObservableMember(<param>)]
    [XE3..13 Florence]LiveBinding対応コンポーネントで、LiveBindingコンポーネントが式を生成するときに使用するメンバ名をパラメータで指定する
    ObservableMemberExtAttribute [ObservableMemberExt(<param>)/ObservableMemberExt(<param>,<param>)/ObservableMemberExt(<param>,<param>,<param>)]
    [10.4 Sydney]LiveBinding対応コンポーネントで、LiveBindingコンポーネントが式を生成するときに使用するメンバ名/フレームワーク/トラッキングをパラメータで指定する
  • System.JSON.Types ユニット
    JsonNameAttribute[JsonName<param>]
    [12 Athens..13 Florence]TJsonSerializerでキー名を明示的に指定
    JsonExcludeValueAttribute[JsonExcludeValue<param>]
    [13 Florence]TJsonSerializerでシリアライズから除外
  • System.JSON.Serializers ユニット
    JsonConverterAttribute[JsonConverter<param>]
    [10.3 Rio..13 Florence]TJsonSerializerで使用するコンバータの指定
    JsonIgnoreAttribute[JsonIgnore]
    [10.3 Rio..13 Florence]TJsonSerializerで無視するメンバの指定
    JsonNameAttribute[JsonName<param>]
    [10.3 Rio..11 Alexandria]TJsonSerializerでキー名を明示的に指定(12 Athens以降はSystem.JSON.Typesユニットに移動)
    JsonInAttribute[JsonIn]
    [10.3 Rio..13 Florence]JsonSerialize属性のパラメータにTJsonMemberSerialization.Inを指定したときにTJsonSerializerでシリアライズ/デシリアライズ対象とする
    JsonObjectHandlingAttribute[JsonObjectHandling<param>]
    [10.3 Rio..13 Florence]TJsonSerializerでデシリアライズするときのクラス型のメンバの扱いを指定
    パラメータには列挙型TJsonObjectHandlingから以下のいずれかの値を指定
    • Auto [10.2 Tokyo..13 Florence]
    • Reuse [10.2 Tokyo..13 Florence]
    • Replace [10.2 Tokyo..13 Florence]
    JsonObjectOwnership[JsonObjectOwnership<param>]
    [10.3 Rio..13 Florence]TJsonSerializerでデシリアライズするときにクラス型メンバを生成した場合の元のインスタンスの扱いを指定
    パラメータには列挙型TJsonObjectOwnershipから以下のいずれかの値を指定
    • Auto [10.2 Tokyo..13 Florence]
    • Owned [10.2 Tokyo..13 Florence]
    • NotOwned [10.2 Tokyo..13 Florence]
    JsonSerializeAttribute[JsonSerialize<param>]
    [10.2 Tokyo..13 Florence]TJsonSerializerでシリアライズ/デシリアライズするメンバの指定
    パラメータには列挙型TJsonMemberSerializationから以下のいずれかの値を指定
    • Fields [10.2 Tokyo..13 Florence]
    • Public [10.2 Tokyo..13 Florence]
    • In [10.2 Tokyo..13 Florence]
    JsonValueSerializeAttribute[JsonValueSerializee<param>]
    [13 Florence]TJsonSerializerでシリアライズ/デシリアライズするかどうかの指定
    パラメータには列挙型TJsonValueSerializationから以下のいずれかの値を指定
    • Always [13 Florence]
    • ExcludeDefault [13 Florence]
    • ExcludeSpecial [13 Florence]
    • ExcludeAll [13 Florence]
  • Data.DBXJSONReflect ユニット (XE5でREST.JsonReflect ユニットに置き換えられた)
    JsonReflect [JsonReflect(<params>)]
    [XE..13 Florence]TJSONMarshal/TJSONUnMarshalでオブジェクトをJSON形式でマーシャル/アンマーシャルするときの動作をカスタマイズする
    パラメータにはコンバータタイプ、リバータタイプ、インターセプタの型、ポピュレーションカスタマイザの型、マーシャリングのときに生成される中間オブジェクトを自動的に解放するかどうかを指定する
    JSONBooleanAttribute
    [XE..13 Florence]JSONMarshalled/JSONOwnedの継承元
    JSONMarshalled [JSONMarshalled(<param>)]
    [XE..13 Florence]フィールドや型がマーシャル/アンマーシャルの対象になるかどうかをパラメータ(False | True)で指定する
    JSONOwned [JSONOwned(<param>)]
    [XE..13 Florence]フィールドがアンマーシャルの際に解放されるかどうかをパラメータ(False | True)で指定する
  • Datasnap.DSAuth ユニット
    TRoleAuth [TRoleAuth(<params>)]
    [XE..13 Florence]DataSnapで認証を行ったときに、サーバメソッドクラスやサーバメソッドに対してアクセスを許可/拒否するロールを指定する
    パラメータには許可ロールのリストと拒否ロールのリストを指定する
    参考: ロール (認証と権限付与)
  • REST.Json.Types ユニット
    JSONBooleanAttribute [JSONBoolean]
    [XE6..13 Florence]Data.DBXJSONReflect.JSONBooleanAttributeを参照
    JSONMarshalledAttribute [JSONMarshalled]
    [XE6..13 Florence]Data.DBXJSONReflect.JSONMarshalledを参照
    JSONOwnedAttribute [JSONOwned]
    [XE6..13 Florence]Data.DBXJSONReflect.JSONOwnedを参照
    JSONNameAttribute [JSONName]
    [XE6..13 Florence]12 AthensでSystem.JSON.Types.JsonNameAttributeのエイリアスになった
    JSONSerializeAttribute [JSONSerialize(<param>)]
    [12 Athens..13 Florence]データメンバシリアライズのオブジェクトタイプを指定
    パラメータには列挙型TJsonMemberSerializationから以下のいずれかの値を指定
    • jmFields [12 Athens..13 Florence]
    • jmPublicProps [12 Athens..13 Florence]
    • jmPublishedProps [12 Athens..13 Florence]
    • jmAllPubProps [12 Athens..13 Florence]
  • REST.JsonReflect ユニット
    JsonReflect(XE5)/JsonReflectAttribute(XE6以降) [JsonReflect]
    [XE5..13 Florence]Data.DBXJSONReflect.JsonReflectを参照(XE6でクラス名が変更)
    JSONBooleanAttribute [JSONBoolean]
    [XE5]Data.DBXJSONReflect.JSONBooleanAttributeを参照(XE6以降はREST.Json.Typesユニットに移動)
    JSONMarshalled [JSONMarshalled]
    [XE5]Data.DBXJSONReflect.JSONMarshalledを参照(XE6以降はREST.Json.Typesユニットに移動)
    JSONOwned [JSONOwned]
    [XE5]Data.DBXJSONReflect.JSONOwnedを参照(XE6以降はREST.Json.Typesユニットに移動)
  • EMS.ResourceTypes ユニット
    TResourceCustomAttribute [TResourceCustom]
    [10.1 Berlin..13 Florence] EndPointRequestSummaryAttribute(10.1 Berlin..10.2 Tokyo)/EndPointRequestParameterAttribute(10.1 Berlin..10.2 Tokyo)/EndPointResponseDetailsAttribute(10.1 Berlin..10.2 Tokyo)/EndPointObjectsYAMLDefinitionsAttribute(10.1 Berlin..10.2 Tokyo)/EndPointObjectsJSONDefinitionsAttribute(10.1 Berlin..13 Florence)/AllowAnonymousTenantAttribute(10.1 Berlin..10.2 Tokyo)/ResourceNameAttribute(10.3 Rio..13 Florence)/EndPointObjectsYAMLDefinitionsAttribute(10.3 Rio..13 Florence)の継承元
    TEndpointCustomAttribute [TEndpointCustom]
    [10.3 Rio..13 Florence]ResourceSuffixAttribute/EndpointNameAttribute/EndPointRequestSummaryAttribute/EndPointRequestParameterAttribute/EndPointResponseDetailsAttribute/AllowAnonymousTenantAttribute/EndPointProduceAttribute/EndPointMethodAttributeの継承元
    ResourceSuffixAttribute [ResourceSuffix]
    [XE7..12 Athens]EMSでURLのサフィックスを指定する
    参考: EMS リソースの概要 - RAD Studio
    EndpointHideAttribute [EndpointHide(<param>)]
    [13 Florence]EMSで指定されたサフィックスのエンドポイントを隠す
    ResourceVersionAttribute [ResourceVersion]
    [13 Florence]EMSでリソースのバージョンを指定する
    ResourceNameAttribute [ResourceName]
    [XE7..12 Athens]EMSでリソース名を指定する
    参考: EMS リソースの概要 - RAD Studio
    EndpointNameAttribute [EndpointName]
    [XE7..12 Athens]EMSでエンドポイントメソッド名を指定する
    参考: EMS リソースの概要 - RAD Studio
    EndPointRequestSummaryAttribute [EndPointRequestSummary]
    [10.1 Berlin..12 Athens]EMSでメソッドの説明をAPIドキュメント上に生成する
    参考: カスタム API ドキュメント - RAD Studio
    EndPointRequestParameterAttribute [EndPointRequestParameter]
    [10.1 Berlin..12 Athens]EMSで要求内で使用されるパラメータの説明をAPIドキュメント上に生成する
    参考: カスタム API ドキュメント - RAD Studio
    EndPointResponseDetailsAttribute [EndPointResponseDetails]
    [10.1 Berlin..12 Athens]EMSで要求応答の説明をAPIドキュメント上に生成する
    参考: カスタム API ドキュメント - RAD Studio
    EndPointResponseHeaderAttribute [EndPointResponseHeader]
    [13 Florence]EMSで要求応答のヘッダを指定する
    EndPointObjectsYAMLDefinitionsAttribute [EndPointObjectsYAMLDefinitions]
    [10.1 Berlin..12 Athens]EMSでYAML版のオブジェクトの定義をAPIドキュメント上に生成する
    参考: カスタム API ドキュメント - RAD Studio
    EndPointObjectsJSONDefinitionsAttribute [EndPointObjectsJSONDefinitions]
    [10.1 Berlin..12 Athens]EMSでJSON版のオブジェクトの定義をAPIドキュメント上に生成する
    参考: カスタム API ドキュメント - RAD Studio
    AllowAnonymousTenantAttribute [AllowAnonymousTenant]
    [10.2 Tokyo..12 Athens]EMSでテナント検証の手順をスキップする
    参考: サンプル RAD サーバー マルチテナント アプリケーション - RAD Studio
    EndPointProduceAttribute [EndPointProduce]
    [10.3 Rio..12 Athens]
    参考: RAD Server 拡張 URL マッピング - RAD Studio
    EndPointConsumeAttribute [EndPointConsume]
    [10.3 Rio..12 Athens]
    参考: RAD Server 拡張 URL マッピング - RAD Studio
    EndPointMethodAttribute [EndPointMethod]
    [10.3 Rio..12 Athens]
  • Macapi.ObjectiveC ユニット
    MethodNameAttribute [MethodName]
    [XE4..12 Athens]Delphiで定義したObjective-Cのメソッドに対して、Objective-C上の本来のメソッド名を指定する
  • Androidapi.JNIBridge ユニット
    JavaSignatureAttribute [JavaSignature]
    [XE5..12 Athens]Delphiで定義したAndroid(JNI)のクラス(インタフェース)に対して、Android上の本来のクラス名を指定する
  • System.Win.WinRT ユニット
    WinRTClassNameAttribute [WinRTClassName]
    [10 Seattle..12 Athens]Delphiで定義したWinRT APIのインタフェースに対して、WinRT上の本来のクラス名を指定する
  • Web.HTTPDMethods ユニット
    HTTPDConfigAttribute [HTTPDConfig]
    [13 Florence](調査中)
    HTTPDDirectiveAttribute [HTTPDDirective]
    [13 Florence](調査中)
  • Web.Stencils ユニット
    WebStencilsVarAttribute [WebStencilsVar]
    [12 Athens Update 2..13 Florence](調査中)
Delphiのバージョンごとの違い:
  • Delphi 2010ではシステムで使用する定義済の属性はない。
  • Delphi XEではDataSnap関係でTRoleAuthと、DBX関係でJSONリフレクションのためのJSON...が定義された。
  • Delphi XE2ではマルチプラットフォーム対応のためにComponentPlatformsAttributeが定義された。
  • Delphi XE3ではARC対応としてWeakAttribute/UnsafeAttribute/RefAttributeが、またおそらく将来の旧RTTIから新RTTIへの移行のためにTDefaultAttributeBase/DefaultAttribute/NoDefaultAttribute/StoredAttributeが、LiveBinding対応のためにObservableMemberAttributeが、それぞれ定義された。
  • Delphi XE4ではiOS対応としてMethodNameAttributeが定義された。
  • Delphi XE5ではJSONのリフレクションがDBXから分離されたためData.DBXJSONReflectのJSON...がREST.JsonReflectにも再定義され、Android対応としてJavaSignatureAttributeが定義された。
  • Delphi XE6ではREST.JsonReflect.JsonReflectがREST.JsonReflect.JsonReflectAttributeにクラス名が変更され、JsonReflectAttribute以外のJson...の定義がREST.JsonReflectユニットからREST.Json.Typesユニットに移動した。
  • Delphi XE7ではStoredAttributeの定義がSystem.ClassesユニットからSystemユニットに移動し、EMSのためにResourceSuffixAttribute/ResourceNameAttribute/EndpointNameAttributeが定義された。
  • Delphi XE8ではHPPGENAttributeとHFAAttributeが定義された。
  • Delphi 10 SeattleではAlignAttributeとWinRTClassNameAttributeが定義された。
  • Delphi 10.1 Berlinでは全てのコンパイラで[weak][unsafe][volatile]属性がサポートされるようになった(10 Seattle以前はNEXTGENコンパイラのみ)。またEMS APIリソースの取得で使用するカスタムAPIドキュメント用のTResourceCustomAttribute/EndPointRequestSummaryAttribute/EndPointRequestParameterAttribute/EndPointResponseDetailsAttribute/EndPointObjectsYAMLDefinitionsAttribute/EndPointObjectsJSONDefinitionsAttributeが定義された。
  • Delphi 10.2 TokyoではSystem.JSON.Serializersユニットが追加されてJSONシリアライズ関係のJson...が定義され、EMSのマルチテナントサポートのためにAllowAnonymousTenantAttributeが定義された。System.JSON.Serializersユニットについては現時点(2017/04/10)で正式にドキュメントされていないため、LynaさんのDelphi 10.2 Tokyoのdocwikiに書かれてなさそうな変更点。 - 全力わはーTJsonSerializerの使い方。 - 全力わはーTJsonSerializerの実用例 - 全力わはーあたりを参照のこと。
  • Delphi 10.3 RioではEMS.ResourceTypesユニット上の属性クラスの継承関係が組み替えられた。
  • Delphi 10.4 SydneyではObservableMemberExtAttributeが定義されたが、11 Alexandriaで削除された。
  • Delphi 12 AthensではJsonNameAttributeの定義がSystem.JSON.Typesユニットに移動し、REST.Json.TypesユニットにJSONSerializeAttributeが定義された(System.JSON.SerializersユニットのJSONSerializeAttributeとは別のものらしい?)。またUpdate 2でWebStencilsVarAttributeが定義された。
  • Delphi 13 FlorenceではJsonExcludeValueAttribute、JsonValueSerializeAttribute、EndpointHideAttribute、ResourceVersionAttribute、EndPointResponseHeaderAttribute、HTTPDConfigAttribute、HTTPDDirectiveAttributeが定義された。
なおUnsafe属性のようにメソッドの戻値に属性を指定したい場合は、メソッドの宣言の前に[Result: <attr>]をつけて、
[Result: Unsafe]function Foo: TObject;
のようにします。

2015/06/19追記: Delphi XE6/XE7/XE8に関する情報を追加。
2015/10/05追記: Delphi 10 Seattleに関する情報を追加。
2016/05/02追記: Delphi 10.1 Berlinに関する情報を追加。
2017/04/10追記: Delphi 10.2 Tokyoに関する情報を追加。Lynaさんのところから大量に引用させていただきました。ありがとうございます。
2019/03/07追記: Delphi 10.3 Rioに関する情報を追加。
2023/12/21追記: Delphi 10.4 Sydney/11 Alexandria/12 Athensに関する情報を追加。
2025/10/10追記: Delphi 13 Florenceに関する情報を追加。

2014年9月1日

2014/09開催のセミナー

  • Web Seminar
    • 2014/09/02 15:00-20:00(JST) Webセミナー「RAD Studio次期バージョンいよいよ登場!」
      • 15:00 次期バージョンブリーフィング
      • 15:45 新バージョンの機能を活用するための無料トレーニング◆FireMonkeyフレームワーク基礎
      • 16:15 デブサミ関西先取り情報◆アトラシアンオフィス訪問
      • 16:30 新バージョンの機能を活用するための無料トレーニング◆データアクセス基礎
      • 17:00 デベロッパーTV◆RAD Studio新バージョン特集
      • 18:00 デブサミ関西先取り情報◆もう怖くないモバイルアプリ開発
      • 18:15 新バージョンの機能を活用するための無料トレーニング(再)◆FireMonkeyフレームワーク基礎
      • 18:45 デブサミ関西先取り情報(再)◆アトラシアンオフィス訪問
      • 19:00 エヴァンジェリスト高橋RAD Studio新バージョン徹底デモ
    • 2014/09/17 16:30-19:30(JST) RAD Studio XE7 Webセミナーマラソン「2」「RAD Studio新バージョンの特長総ざらい」
      • 16:30 高橋智宏のDelphi / C++Builder 新機能解説(1) - 最新ライブラリ/言語機能の活用
      • 16:55 お知らせ◆iTuneカードやエンバカデログッズが当たるキーワードを発表
      • 17:00 デベロッパーTV番外編◆大阪から中継!
      • 18:00 高橋智宏のDelphi / C++Builder 新機能解説(2) - データベースアクセスとサーバーサイド開発
      • 18:25 お知らせ◆iTuneカードやエンバカデログッズが当たるキーワードを発表
      • 18:30 伊賀敏樹のシステム設計指南 - みんなDBスキーマ設計どうやってるの?
      • 18:55 お知らせ◆iTuneカードやエンバカデログッズが当たるキーワードを発表
      • 19:00 高橋智宏のDelphi / C++Builder 新機能解説(3) - モバイルアプリ開発 基礎から応用まで
      • 19:25 お知らせ◆iTuneカードやエンバカデログッズが当たるキーワードを発表
  • Live Seminar

2014年8月26日

DDevExtensions 2.82/IDE Fix Pack 5.7

Andreas HausladenさんDDevExtensionsがアップデートされてVersion 2.82になっています。クラス補完関係の機能追加とXE6上での不具合修正が含まれています。またIDE Fix PackもアップデートされてVersion 5.7になっています。こちらはいくつかのfixが追加されています。

DDevExtensions 2.82 and IDE Fix Pack 5.7 released | Andy's Blog and Tools

2014年8月19日

C++14標準規格承認

C++の新しい標準規格(C++1y)のDIS(Draft International Standard)に対する投票が終了し、全会一致で承認された、というニュースが入ってきました。

C++14の仕様策定が完了しました - Faith and Brave - C++で遊ぼう
We have C++14! : Standard C++

これによりC++の標準規格が改定され、年内にもC++14(ISO/IEC 14882:2014(E) Programming Language C++)となります。C++14ではC++11の変更内容を実装した結果として判明した不備や機能不足を補うような、小規模な変更が主とのことです。詳細は高橋晶さんの

C++14の言語拡張まとめ - Faith and Brave - C++で遊ぼう

が参考になります。次の改定は2017年ごろが予定されており、C++1zとかC++17と呼ばれています。

問題はC++BuilderでのC++14サポートと、x86のコンパイラ(BCC32)のClang/LLVM化がいつになるのか、ですね。あまり遅れずに2015/1H予想のXE8に入るとよいのですが。

2014年8月13日

Microsoft Monthly Update 2014/08

今日はMicrosoftのセキュリティアップデートの日です。
MS14-043
MS14-044
MS14-045
MS14-046
MS14-047
MS14-048
MS14-049
MS14-050
MS14-051

2014/08/16追記: MS14-045(KB2982791)を適用するとRAD Studio/Delphi/C++BuilderのIDEが生成する一時的なフォントリソースファイルがIDE終了後もWindowsによりロックされ続けてしまい、Delphi 8-2010が2回以上起動できないという障害が報告されている。回避策として今のところはKB2982791(MS14-045: Description of the security update for kernel-mode drivers: August 12, 2014)とKB2970228(Update to support the new currency symbol for the Russian ruble in Windows)の更新プログラムをアンインストールするか、IDE Fix Pack 2.8以降をインストールするかのいずれか。

2014/08/19追記: MS14-045のKB2982791の更新プログラム、および関連するKB2970228(Windows 7以降)、KB2975719(Windows 8.1/Server 2012 R2)、KB2975331(Windows 8/Windows Server 2012)は取り下げになっています。既に適用済の環境についてもアンインストールが推奨されています。

【リリース後に確認された問題】2014 年 8 月 13 日公開の更新プログラムの適用により問題が発生する場合がある - 日本のセキュリティチーム - Site Home - TechNet Blogs

2014/08/28追記: MS14-045のKB2982791を置き換えるKB2993651の更新プログラムが公開されています。

[MS14-045] 更新プログラム 2982791 の問題を解決する更新プログラム 2993651 を公開 - 日本のセキュリティチーム - Site Home - TechNet Blogs

2014年8月1日

2014/08開催のセミナー

  • Web Seminar
  • Live Seminar
    • 2014/08/05 14:00-16:30(JST) 技術研修セミナー「旧Delphi/C++アプリケーションを最新に!移行のテクニック」(UStream中継あり)
    • 2014/08/26 14:00-16:30(JST) 技術研修セミナー「Appmethod で作る Android / iOS 業務システム開発」 ~ 見積・設計から実装まで ~

2014年7月28日

[書籍]新装版 リファクタリング

ブックファースト 渋谷文化村通り店Refactoring (Amazon.com)の翻訳の改訂版である


新装版 リファクタリング (amazon)/Martin Fowler著/児玉公信、友野晶夫、平澤章、梅澤真史訳/オーム社/ISBN 978-4-274-05019-0/4,536円

を購入。

2014年7月25日

2014年7月20日

Firebird 2.5.3

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

Firebird: Firebird 2.5.3
Firebird 2.5 Release Notes (PDF)

2014年7月9日

Microsoft Monthly Update 2014/07

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

2014/08/16追記: MS14-037(KB2962872)を適用するとMSHTMLの非互換性によりInstall Shield 2008-2014の起動時にエラーが発生する、という不具合があり、Flexeraでは回避策および暫定版のパッチを公開している。

2014/08/20追記: MS14-037(KB2962872)のMSHTMLの非互換性問題はMS14-051(KB2976627)で修正済であることを確認しました。

2014年7月8日

6th anniversary

忘れかかっていましたがこのblogも丸6年になりました。この1年間(2013/07/08-2014/07/07)のエントリは88で、週平均1.7弱でした。ほとんどお知らせのみの状態ですが、ぼちぼち再起動したいところです。続いてアクセス解析の統計情報から月別ページビュー(PV)を。

2013/07: 5,895
2013/08: 5,594
2013/09: 6,215
2013/10: 6,320
2013/11: 5,397
2013/12: 5,654
2014/01: 8,868
2014/02: 3,924
2014/03: 4,804
2014/04: 4,788
2014/05: 4,909
2014/06: 4,121
2013/07-2014/06合計: 66,489

ページ別ではこの一年もWindowsのSNP(Scalable Networking Pack)を無効にするがトップですが、一時よりはアクセス数が減少気味です。これはSNPがWindows 8以降でデフォルト無効になったことが影響しているかもしれません。

この1年はモバイル対応でリリース間隔が半年になったり、Appmethodがリリースされたりと、Windows/VCL中心のプログラマにとってはあまりいい話題がなかった気がしますが、XE6で久しぶりにWindows関係にも新機能が入りましたので、あとは予定通り品質の向上が望まれるところです(XE6はリグレッションが多すぎ)。まぁこのままいくとXE6はスキップになっちゃうんですけどね。C++もいよいよC++14の規格化が目前ですので、NEXTGENコンパイラもアップデートをお願いしたいところです(こんな話題もありますが)。

2014年7月1日

2014/07開催のセミナー

  • Web Seminar
  • Live Seminar
    • 2014/07/08 14:00-16:30(JST) 技術研修セミナー「旧Delphi/C++アプリケーションを最新に!移行のテクニック」
    • 2014/07/17 18:00-19:30(JST) 「RAD Studio XE6 - モバイル開発体験ワークショップ」
    • 2014/07/24 18:00-19:30(JST) 技術研修セミナー「C++で始めるマルチデバイス開発入門」

2014年6月27日

Firebird 2.1.6

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

Firebird: Firebird 2.1.6
Firebird 2.1 Release Notes (PDF)

2014年6月26日

[書籍]LLVM/Clang実践活用ハンドブック

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

LLVM/Clang実践活用ハンドブック (amazon)/出村成和著/ソシム/ISBN 978-4-88337-931-6/2,700円

を購入。積んだ。

2014年6月11日

Microsoft Monthly Update 2014/06

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

2014年6月1日

2014/06開催のセミナー

2014年5月28日

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

第28回エンバカデロ・デベロッパーキャンプ・イン・大阪は2014年06月20日に大阪・京橋で行われます。

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

今回の大阪開催は、4月22日に東京にて開催された第28回 エンバカデロ・デベロッパーキャンプの追加開催です。東京開催の講演内容と一部重複しますが、大阪開催用に新たに作成したコンテンツを中心にお送りする予定です。
とのことです。

2014年5月14日

Microsoft Monthly Update 2014/05

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

2014年5月11日

IDE Fix Pack 5.6

Andreas HausladenさんIDE Fix PackがアップデートされてVersion 5.6になっています。このバージョンではDelphi XE6の対応が行われています。

IDE Fix Pack 5.6 for XE6 released | Andy's Blog and Tools

2014年5月5日

IDE Fix Pack 5.5

Andreas HausladenさんIDE Fix Pack 2009-XE5がアップデートされてVersion 5.5になっています。なおDelphi 2010/XE2/XE3/XE4についてはこのバージョンで更新終了とのことです。

IDE Fix Pack 5.5 (2009-XE5) released | Andy's Blog and Tools

2014年5月3日

InterBase XE3 Update 4 Hotfix 1

InterBase XE3 Update 4 Hotfix 1がリリースされています。Windows x64版で性能が出ない問題などが修正されています。バージョンは11.0.4.816となっています。

InterBase XE3 Update 4 Hotfix 1 Readme

InterBase XE3 Update 4 Hotfix 1 (11.0.4.816) for Windows がリリースされました
InterBase XE3 Update 4 Hotfix 1

29851 InterBase XE3 Update 4 Hotfix 1 (11.0.4.816) for Windows

2014年5月2日

Microsoft OOB Update 2014/05

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

2014年5月1日

2014/05開催のセミナー

2014年4月26日

RAD Studio/Delphi/C++Builder XE6 Hotfix 1

RAD Studio/Delphi/C++Builder XE6のHotfix 1がリリースされています。iOS上でのIMEの問題の修正、いくつかのファイルの不足の解決、2つのVCLテーマのソースの修正が含まれているとのことです。

29847 Hotfix 1 for RAD Studio, Delphi, C++Builder XE6

Hotfix 1 for RAD Studio XE6, Delphi XE6, C++Builder XE6
RAD Studio XE6/Delphi XE6/C++Builder XE6向け Hotfix 1 が公開されました

2014年4月22日

第28回エンバカデロ・デベロッパーキャンプ

本日10:00から第28回エンバカデロ・デベロッパーキャンプが御茶ノ水ソラシティのソラシティカンファレンスセンターで行われます。セッション資料は

ダウンロード | デベロッパーキャンプ

からダウンロードできます(10:00以降ということでまだできませんね順次ダウンロード可能になっています)。またUStreamで全セッションの中継が予定されています。

セッション終了。セッションスピーカのみなさん、参加者のみなさん、関係者のみなさん、おつかれさまでした。次は懇親会です。

懇親会も終了しました。おつかれさまでした。

2014/05/07追記: プレゼンテーション資料がダウンロードできるようになっています。

第28回 エンバカデロ・デベロッパーキャンプ資料ダウンロード

2014/05/08追記: セッションリプレイの公開が始まっています。
  • 第28回 エンバカデロ・デベロッパーキャンプ - YouTube
  • 【C1】チュートリアルセッション「マルチデバイスの荒海にこぎ出す新人エンジニアのためのソフトウェア開発の心得」
  • 【A1】Delphiテクニカルセッション「Delphiによる基幹系システム連携の具体例 ~ SAPシステムとの枯れた連携手法」
  • 【C2】Delphiテクニカルセッション「業務アプリ開発で活かせるDelphiプログラミングテクニック」
  • 【A2】C++テクニカルセッション「C++開発者のための最新プログラミングエッセンス」
  • 【G3】ジェネラルセッション「さらに進化を遂げるエンバカデロのマルチデバイス開発環境」
  • 【C4】Delphi/C++テクニカルセッション「多様化するスマートデバイスをビジネスアプリに活用するためのアーキテクチャと開発のヒント」
  • 【A4】C++テクニカルセッション「Visual C++ユーザーもバッチリ!C++Builderによるマルチデバイス開発」
  • 【C5】Delphiテクニカル/ケーススタディセッション「実例!Delphiによる多層分散型基幹業務システム構築の課題と解決のポイント 」
  • 【A5】テクニカルセッション「RAD Studio で実践する継続的インテグレーション ~ アプリとデベロッパーの価値を拡張するエッセンス」」
  • 【G6】ライトニングトーク「共有!みんなの開発事例、開発経験、テクニック」

2014年4月21日

2014年4月19日

2014年4月15日

RAD Studio/Delphi/C++Builder XE6リリース

RAD Studio/Delphi/C++Builder XE6が正式にリリースされたようです。

エンバカデロ、デスクトップからモバイル、ウェアラブルに対応したビジュアル開発環境「RAD Studio XE6」を発表 | Press Releases
エンバカデロ、デスクトップからモバイル、ウェアラブルに対応したビジュアル開発環境「RAD Studio XE6」を発表 (EDN)
Embarcadero Launches RAD Studio XE6; Enables Developers to Modernize Windows XP Apps and Extend Desktop Apps to Mobile and Wearable Devices

Delphi XE6 | New Features

Delphi® XE6 および C++Builder® XE6 オンライン ヘルプ (en)
XE6 のリリース ノート - RAD Studio (en)
Delphi XE6 および C++Builder XE6 の新機能 - RAD Studio (en)

RAD Studio XE6(Delphi XE6/C++Builder XE6) における不具合修正リスト (en)
Embarcadero® RAD Studio XE6 Software License and Support Terms (EULA)

29820 Delphi XE6 and C++Builder XE6 ISO

29809 VCL Premium Styles Pack for RAD Studio XE6
29808 FireMonkey Premium Styles Pack for RAD Studio XE6
29850 RAD Studio XE6 FireMonkey Accessibility Pack
29911 AdMob replacement hotfix for RAD Studio XE6
29913 BMP Buffer Overflow hotfix - Delphi, C++Builder, RAD Studio XE6

29812 FireDAC ini file utility

29816 FastReport 4 VCL for RAD Studio, Delphi and C++Builder XE6
29818 FastReport FMX for RAD Studio, Delphi and C++Builder XE6
29817 AQtime for RAD Studio, Delphi and C++Builder XE6
29806 IP*Works for Delphi XE6
29807 IP*Works for C++Builder XE6
29844 TMS Modern Windows UI Pack for RAD Studio XE6
29852 Mida Converter for RAD Studio XE6, Delphi XE6 and C++Builder XE6

29835 Jedi Code Library Snapshot Binary Installer for XE6
29836 Jedi Visual Component Library Snapshot Binary Installer XE6

2014年4月9日

Microsoft Monthly Update 2014/04

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

2014年3月29日

RAD Studio/Delphi/C++Builder XE5 Update 2 Hotfix 6

RAD Studio/Delphi/C++Builder XE5 Update 2のHotfix 6がリリースされています。iOS SDK 7.1とXcode 5.1に対応するためのものです。

29795 Hotfix 6 for RAD Studio, Delphi, C++Builder XE5 Update 2

Hotfix 6 for RAD Studio, Delphi, C++Builder XE5 Update 2 is now available

2014/04/18追記: Hotfix 6が2014/04/17付けで更新されています。Mountain Lion(OS X 10.8)上での問題を解決したとのことです。

2014年3月21日

Firebirdロードマップ(2014/03)

久しぶりにFirebirdのロードマップが更新されています。

Firebird: Roadmap

適当な要約:
  • 2.1 - 2.1.5が最新版で、年1回のメンテナンスサイクルでのリリース。次のリリース(2.1.6)は2014年のQ1を予定している。この2.1.6が2.1系の最終版となる予定。
  • 2.5 - 2.5.2が最新版で、年2回のメンテナンスサイクルでバグフィックスを最優先で行っている。次のリリース(2.5.3)は2014年のQ1を予定している。
  • 3.0 - 次のマイルストーンリリースで、現在開発中。キーポイントは以下の通り。
    • 新しい認証サブシステム、構成サブシステムを含む、改訂されたアーキテクチャ
    • 共有ページキャッシュを備えた(SMP/マルチコアと親和性のある)スケーラブルなマルチスレッドエンジン
    • 新しいシステムテーブル、モニタテーブルを備えた新しいODS(Version 12)
    • JavaやC++などによる外部ストアドプロシージャ、トリガ、関数
    • 作り直されたオプティマイザと新しいデータアクセスメソッド
    • セキュリティの強化
    • さまざまなSQL拡張
    ただし最終的な機能セットについてはまだ合意に至っていない。(注:キーポイントについては前回と同じ表現)
    3.0 Alpha 2が最新版で、次のテストバージョン(Beta 1)は2014年のQ2を予定している。なおODS(12)はまだ最終的に確定していないため、非安定版間で非互換の可能性がある(データベースを再作成するか、バックアップ/リストアする必要がある)。

2014年3月19日

RAD Studio/Delphi/C++Builder XE5 Update 2 Hotfix 5

RAD Studio/Delphi/C++Builder XE5 Update 2のHotfix 5がリリースされています。統合トランスレーションマネージャ(ITE)で"Resource not found"が発生する問題(QC119236など)を修正するとのことです。高橋さん、情報ありがとうございます。

29788 Hotfix 5 for RAD Studio, Delphi, C++Builder XE5 Update 2

Hotfix 5 for RAD Studio, Delphi, C++Builder XE5 Update 2 is now available
Delphi XE5/C++Builder XE5でリソースDLLを作成し実行すると「EResNotFound がモジュール Project1.exe の 001A0D35 で発生しました。Resource TForm1 not found.」エラーが発生する

なおreadme(各国語共通)で対象ファイルの一つが"dfm190.bdbg"となっていますが、"dfm190.jdbg"の誤記と思われます。適用の際はご注意ください。

2014年3月12日

Microsoft Monthly Update 2014/03

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

2014年3月11日

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

第28回エンバカデロ・デベロッパーキャンプは2014年04月22日に開催されます。

デベロッパーキャンプ

2014/03/14追記: タイムテーブルが公開され、参加申し込みが開始されています。今回はマーケティング担当副社長のSteve HaneyさんとQA/ドキュメント/ローカライゼーション担当マネージャの新井さんがいらっしゃるようです。

2014年3月7日

Appmethod

エンバカデロ・テクノロジーズから新しい開発環境Appmethodがアナウンスされています。

appmethod | Build Apps for Android, iOS, Windows, and Mac

(あとで追記予定)

2014年3月6日

2014年3月5日

[書籍]Coding In Delphi

CreateSpaceで注文した

Coding in Delphi (leanpub, CreateSpace, amazon US)/Nick Hodges著/CreateSpace/ISBN 9781941266038/39.99USD

が配送されてきました(今回の配送は佐川急便でした)。2014/02/24に注文して9日目の到着(早っ)、39.99USDにShippingの7.38USDで締めて47.37USD=4,850JPY(暫定、1USD=102.40JPY)4,923JPY(1USD=103.927JPY)でした。

2014年3月4日

[書籍]Oracleデータベースポケットリファレンス

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

Oracleデータベースポケットリファレンス (amazon)/若杉司著/技術評論社/ISBN 978-4-7741-6332-1/3,129円

を購入。

[書籍]新訂版 More Effective C++

MARUZEN&ジュンク堂書店 渋谷店More Effective C++ (amazon)の翻訳である

新訂版 More Effective C++ (amazon)/Scott Meyers著/安村通晃、伊賀聡一郎、飯田朱美、永田周一訳/丸善出版/ISBN 978-4-621-06606-5/3,990円

を購入。この本はピアソン桐原の出版事業からの撤退に伴い丸善出版から再出版されたものです(Effective C++は買ってあるのに、なぜかMore Effective C++はなかった)。

2014年2月12日

Microsoft Monthly Update 2014/02

今日はMicrosoftのセキュリティアップデートの日です。
MS14-005
MS14-006
MS14-007
MS14-008
MS14-009
MS14-010
MS14-011

2014年2月1日

2014/02開催のセミナー

2014年1月18日

RAD Studio/Delphi/C++Builder XE5 Update 2 Hotfix 4

RAD Studio/Delphi/C++Builder XE5 Update 2のHotfix 4がリリースされています。コンポーネントの一括置換を支援するreFind.exeが更新されています。

29698 Hotfix 4 for RAD Studio, Delphi, C++Builder XE5 Update 2

2014年1月15日

Microsoft Monthly Update 2014/01

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

2014年1月6日

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

2014/01/24追記: デベロッパーTVの予定を追加しました。

2013年12月26日

[書籍]詳説 Cポインタ

MARUZEN&ジュンク堂書店 渋谷店Understanding and Using C Pointers (amazon)の翻訳である

詳説 Cポインタ (amazon)/Richard Reese著/菊池彰訳/オライリージャパン/ISBN 978-4-87311-656-3/2,310円

を購入。

2013年12月25日

[書籍][ebook]プログラミングの魔導書 〜Programmers' Grimoire〜 vol.3

プログラミングの魔導書 ~Programmers’ Grimoire~ vol.3が発売されて、PDF版のダウンロードが可能になりました。

プログラミングの魔導書 ~Programmers’ Grimoire~ vol.3/ロングゲート/ISBN 978-4-9905296-4-2(書籍版)、ISBN 978-4-9905296-5-9(PDF版)/1,500円(書籍版)、1,000円(PDF版)

書籍版の受付は既に終了しており、現時点(2013/12/25)ではPDF版のみが購入可能です。

次号vol.4のサブタイトルは「The Art of Chaos ~混沌の秘訣~」とのこと。

2014/01/09追記: 書籍版が配送されてきました。

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

RAD Studio/Delphi/C++Builder XE5 Update 2のHotfix 3がリリースされています。

29675 Hotfix 3 for RAD Studio XE5 and Delphi XE5 Update 2

2013/12/27追記: TJPEGImage.Drawがスレッドセーフではないという問題があり、これを修正したJpeg.pasを再コンパイルするのに必要な.objファイル、ということのようです(QC#55871QC#108747QC#111209)。 %ProgramFiles%\Embarcadero\RAD Studio\12.0\source\vcl\jpg\obj あたりに配置するのがよさそうです。

2013年12月14日

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

ブックファースト 新宿店Programming C# 5.0 (amazon)の翻訳である

プログラミングC# 第7版 (amazon)/Ian Griffiths著/鈴木幸敏、風間一洋、木村英一、黒川利明、頃末和義、佐藤嘉一、出葉義治、西山博泰、稲垣達夫訳/オレイリージャパン/ISBN 978-4-87311-650-1/5,040円

を購入。

RAD Studio/Delphi/C++Builder XE5 Update 2 Hotfix 1/2

RAD Studio/Delphi/C++Builder XE5 Update 2のHotfix 1/2がリリースされています。Hotfix 1はDelphi/iOSデバイス用のライブラリファイル(libibtogo.a/libmidas.a/libpcre.a/libsqlib.a)が不足している問題、Hotfix 2はC++Bulder用のヘッダファイル(xmlutil.hpp)が不足している問題をそれぞれ解決します。

29667 Hotfix 1 for RAD Studio XE5 and Delphi XE5 Update 2
29668 Hotfix 2 for RAD Studio XE5, C++Builder XE5 Update 2

Team Japan » Delphi XE5 / C++Builder XE5 Update 2 および Hotfix 1, Hotfix 2 がリリースされました

2013年12月12日

IDE Fix Pack 5.4.1

Andreas HausladenさんIDE Fix Pack 2009-XE5がアップデートされてVersion 5.4.1になっています。RAD Studio XE5 Update 2でのコンパイラの変更に対応しているとのことです。

IDE Fix Pack 5.4.1 – Support for XE5 Updater 2 | Andy's Blog and Tools

2013年12月10日

第27回エンバカデロ・デベロッパーキャンプ

本日10:00から第27回エンバカデロ・デベロッパーキャンプが御茶ノ水ソラシティのソラシティカンファレンスセンターで行われます。セッション資料は

ダウンロード | デベロッパーキャンプ

からダウンロードできます。またUStreamで全セッションの中継が予定されています。

印刷されたセッション資料がないということはノートPCのバッテリが厳しいということでもあります。充電スペースがほしいなぁ。Cのほうの部屋の一番後ろに充電用のスペースが用意されてました。ありがたいですね。

ということで全セッション、懇親会とも無事に終了しました。セッションスピーカ、参加者、関係者の皆さん、おつかれさまでした。エンバカデロ・テクノロジーズさんは今週末お引っ越しとのことで大変なようですが、来週(2013/12/18)には迷惑を顧みずエンバカデロさん新オフィス見学会とDelphi 2013 忘年会などというものも企画されています。

2013/12/20追記: セッション資料がダウンロードできるようになっています。

第27回 エンバカデロ・デベロッパーキャンプ資料ダウンロード

2013/12/24追記: セッションリプレイの公開が始まっています。
  • 第27回 エンバカデロ・デベロッパーキャンプ - YouTube
  • 【C1】Delphi/C++チュートリアルセッション「RAD Studio XE5によるマルチ言語/マルチデバイス開発の進め方」
  • 【B1】Delphi/C++テクニカルセッション「誰でも始められるカンタンFireMonkey 3D入門」
  • 【C2】Delphiテクニカルセッション「基礎から学ぶビジュアルAndroidアプリ開発。今日からあなたもAndroidデベロッパー」
  • 【B2】Delphiテクニカルセッション「Delphiのマイグレーションを行うのであれば、これだけは知っておこう!」
  • 【G3】ジェネラルセッション「マルチ言語に広がるエンバカデロのマルチデバイス開発ソリューション」
  • 【C4】C++テクニカルセッション「C++Builderでモバイル開発にトライ!ベータ評価レポート」
  • 【B4】Delphi/C++テクニカルセッション「DataSnapユースケース研究 - 多層技術の概要と最適化、実践テクニック」
  • 【C5】モバイルセッション「PC向け開発からモバイル開発へ!実践モバイルファースト」
  • 【B5】C++テクニカルセッション「マルチデバイスプラットフォームを意識したC++アプリケーション設計」
  • 【G6】ライトニングトーク「共有!みんなの開発事例、開発経験、テクニック」

2013年12月3日

RAD Studio/Delphi/C++Builder XE5 Hotfix 2

RAD Studio/Delphi/C++Builder XE5のHotfix 2がリリースされています。Android上でアクセント付きの大文字が正しく描画されない問題とTListBoxGroupHeaderでドイツ語のß(U+00DF)を使用するとEArgumentOutOfRangeExceptionがraiseされる問題が修正されるとのことです。

29644 Hotfix 2 for RAD Studio XE5, Delphi XE5 and C++Builder XE5

2013年12月1日

2013/12開催のウェブセミナー

2013/12開催のウェブセミナーはありません。

2013年11月22日

RAD Studio/C++Builder XE4 Hotfix 2

RAD Studio/C++Builder XE4のHotfix 2がリリースされています。Mac OS X 10.9 SDK上でFMX/C++アプリケーションのコンパイルに失敗する問題を解決するものです(XE5のHotfix 1と同じ問題でしょうか?)。

29627 Hotfix 2 for C++Builder and RAD Studio XE4

Team Japan » C++Builder XE4 Update1向け「Hotfix2 for OS X 10.9(Mavericks)」

2013年11月15日

DDevExtensions 2.8

Andreas HausladenさんDDevExtensionsがアップデートされてVersion 2.8になっています。RAD Studio XE5対応とバグフィックスが含まれています。

DDevExtensions 2.8 released (2009-XE5) | Andy's Blog and Tools

2013年11月13日

Microsoft Monthly Update 2013/11

今日はMicrosoftのセキュリティアップデートの日です。
MS13-088
MS13-089
MS13-090
MS13-091
MS13-092
MS13-093
MS13-094
MS13-095

2013年11月11日

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

第27回エンバカデロ・デベロッパーキャンプは2013年12月10日に開催されます。

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

今回はRAD StudioプロダクトディレクタのJohn Thomas(JT@Embarcadero)さんがいらっしゃるとのことです。目玉はC++BuilderのiOS/Android対応でしょうか。全体としてモバイル関係の比率が高い感じです。

2013年11月6日

RAD Studio/C++Builder XE5 Hotfix 1

RAD Studio/C++Builder XE5のHotfix 1がリリースされています。Mac OS X 10.9 SDK上でFMX/C++アプリケーションをコンパイルするときの問題を解決するものです。

Hotfix 1 for RAD Studio and C++Builder XE5 now available

29621 Hotfix 1 for RAD Studio and C++Builder XE5

2013年11月2日

IDE Fix Pack 5.4

Andreas HausladenさんIDE Fix Pack 2009-XE5がアップデートされてVersion 5.4になっています。RAD Studio XE5対応のほか、いくつかのバグフィックスとコンパイラの最適化が含まれているとのことです。

IDE Fix Pack 5.4 for 2009-XE5 released | Andy's Blog and Tools

2013年10月17日

2013年10月9日

Microsoft Monthly Update 2013/10

今日はMicrosoftのセキュリティアップデートの日です。
MS13-080
MS13-081
MS13-082
MS13-083
MS13-084
MS13-085
MS13-086
MS13-087

2013年9月30日

[書籍]世界測地系と座標変換

Amazon.co.jpで注文した

世界測地系と座標変換 (amazon)/飛田幹男著/日本測量協会/ISBN 978-4-88941-014-3/1,600円

が配送されてきました(堺配送センター発で今回の配送は日本郵政)。

2013年9月13日

第26回エンバカデロ・デベロッパーキャンプ

本日10:00から第26回エンバカデロ・デベロッパーキャンプが東京ビッグサイトの会議棟6Fで行われます。今回もハンズオンのセッション(B4)を除く全てのセッションがUStreamで中継されるとのことです。

全セッション、懇親会とも無事終了しました。セッションスピーカの皆さん、参加者、関係者の皆さん、おつかれさまでした。

2013/09/18追記: セッション資料がダウンロードできるようになっています。

第26回 エンバカデロ・デベロッパーキャンプ資料ダウンロード

2013/09/24追記: セッションリプレイの公開が始まっています。
  • 【A1】Delphiチュートリアルセッション「Windows開発者のためのFireMonkeyモバイル開発入門」
  • 【B1】HTML5テクニカルセッション「オフラインで"待ちなし"、 500倍を超えるアクセスパフォーマンス!」
  • 【A2】Delphi/C++Builderテクニカルセッション「はじめてのFireDAC」
  • 【B2】C++Builderテクニカルセッション「いまどきのC++開発をもっと楽にする3つの武器」
  • 【G3】ジェネラルセッション「マルチデバイス開発を強化するエンバカデロのRADテクノロジー」
  • 【G3】ジェネラルセッション(後半戦)「アプリソムリエお薦めアプリ、Delphiならどう作る?教えて高橋さん!」
  • 【A4】テクニカルケーススタディ「RAD Studioによるマルチデバイス開発への道」
  • 【B4】Delphi iOSワークショップ「アプリソムリエと作るDelphi iOSアプリ」
  • 【A5】Delphi/C++Builderテクニカルセッション「脱Windows XPから一気にマルチデバイス対応を目指す実践テクニック」
  • 【G6】クロージングアプリソムリエと語るモバイル開発への取り組み」

2013年9月11日

RAD Studio/Delphi/C++Builder XE5リリース

RAD Studio/Delphi/C++Builder XE5が正式にリリースされたようです。

エンバカデロ、AndroidおよびiOS向けネイティブ開発をサポートしたRAD Studio XE5を本日より販売開始 | Press Releases
Embarcadero Launches RAD Studio XE5 with True Native Android and iOS Support, Allowing Developers to Reach the Largest Addressable Mobile Markets

RAD Studio XE5(Delphi XE5/C++Builder XE5) における不具合修正リスト (en)

29543 Delphi XE5 and C++Builder XE5 ISO
29546 RAD Studio XE5 HTML5 Builder ISO

29525 AQtime for Delphi XE5, C++Builder XE5, and RAD Studio XE5
29526 IP*Works for Delphi XE5 29707 IP*Works for Delphi XE5 Update 2
29527 IP*Works for C++Builder XE5 29706 IP*Works for C++Builder XE5 Update 2
29549 Jomitech PlatinumGrid Lite Pack for HTML5 Builder XE5
29524 FastReport FMX - Embarcadero Edition for XE5
29598 FireMonkey Premium Style Pack 3 for RAD Studio XE5 FireMonkey Premium Style Pack for RAD Studio XE5 (v4 Oct 2013) (Team Japan » FireMonkey Premium Style Pack 3 for RAD Studio XE5 が公開されました)
29613 InfoPower for Delphi FireMonkey (2013/12/11更新あり) 29712 InfoPower FM for RAD Studio, Delphi and C++Builder XE5 Update 2
29610 Mida Converter for RAD Studio, Delphi and C++Builder XE5
29645 Documentation Insight Express for RAD Studio XE5
29695 FastReport 4 VCL - Embarcadero Edition for XE5
29708 TeeChart Lite for RAD Studio, Delphi, C++Builder XE5 Update 2

29548 iOS 7 Style Update for Delphi XE5 and RAD Studio XE5 (Delphi XE5およびRAD Studio XE5向け iOS 7スタイルアップデート / Using the iOS 7 Update for XE5)
29701 Android 4.4 KitKat Style for RAD Studio and Delphi XE5 (Team Japan » KitKat(4.4.x)専用のFireMonkeyスタイルを試す)
29716 FireDAC.Phys.IBBase Patch for XE2 Update2 参考: FireDACでFireBirdへ接続時、入力する文字数によってエラーが発生する症状について
29772 Updated REST Debugger

29769 AQtime 8.20 Standard update

Delphi® XE5 および C++Builder® XE5 オンライン ヘルプ (en)
XE5 のリリース ノート (en)

2013/12/11追記: InfoPower for Delphi FireMonkeyが更新されているとのことです。

Team Japan » ボーナスパック - InfoPower社のFireMonkeyコンポーネント集

2014/01/17追記: Fast Report 4 VCLがダウンロードできるようになっています。

2014/01/30追記 IP*WorksがUpdate 2対応版に更新されています。

2014/02/01追記: TeeChart LiteとInfoPower FireMonkeyがUpdate 2対応版に更新されています。

Team Japan » RAD Studio XE5(Delphi/C++Builder) Update2向け、サードパーティライブラリ更新版

2014/02/04追記: FireDAC.Phys.IBBaseのパッチが公開されています。

2014/02/24追記: REST Debuggerが更新されています。またAQtime 8.20 Standard updateも公開されています。

Microsoft Monthly Update 2013/09

今日はMicrosoftのセキュリティアップデートの日です。
MS13-067
MS13-068
MS13-069
MS13-070
MS13-071
MS13-072
MS13-073
MS13-074
MS13-075
MS13-076
MS13-077
MS13-078
MS13-079

2013年8月22日

Win32APIのSetPriorityClass関数でプロセスの優先順位を指定する

実行中のプロセスの優先順位クラス (Priority class)を取得/設定するにはWin32APIのGetPriorityClass関数 (en)およびSetPriorityClass関数 (en)を使用します。このとき自プロセスの優先順位クラスを指定するのであればGetCurrentProcess関数 (en)で取得した擬似ハンドルを使用することができます(他のプロセスの優先順位クラスの場合、PROCESS_SET_INFORMATIONアクセス権を持ったプロセスハンドルが必要です)。

まずBELOW_NORMAL_PRIORITY_CLASSとABOVE_NORMAL_PRIORITY_CLASSの定義を追加します。
{$IF RTLVersion < 24}
const
  BELOW_NORMAL_PRIORITY_CLASS = $00004000;
  {$EXTERNALSYM ABOVE_NORMAL_PRIORITY_CLASS}
  ABOVE_NORMAL_PRIORITY_CLASS = $00008000;
  {$EXTERNALSYM ABOVE_NORMAL_PRIORITY_CLASS}
{$IFEND}
フォームに優先順位クラスを表示するComboBox(StyleはcsDropDownList)と優先順位クラスを取得、設定するButtonを配置し、フォームのOnCreateイベントでComboBoxに優先順位クラスの表示文字列と値を格納します。
procedure TForm1.FormCreate(Sender: TObject);
begin

  with ComboBox1.Items do
  begin
    BeginUpdate;
    try
      Clear;
      AddObject(Format('%s (0x%8.8X)',['IDLE',IDLE_PRIORITY_CLASS]),
                TObject(IDLE_PRIORITY_CLASS));
      AddObject(Format('%s (0x%8.8X)',['BELOW_NORMAL',BELOW_NORMAL_PRIORITY_CLASS]),
                TObject(BELOW_NORMAL_PRIORITY_CLASS));
      AddObject(Format('%s (0x%8.8X)',['NORMAL',NORMAL_PRIORITY_CLASS]),
                TObject(NORMAL_PRIORITY_CLASS));
      AddObject(Format('%s (0x%8.8X)',['ABOVE_NORMAL',ABOVE_NORMAL_PRIORITY_CLASS]),
                TObject(ABOVE_NORMAL_PRIORITY_CLASS));
      AddObject(Format('%s (0x%8.8X)',['HIGH',HIGH_PRIORITY_CLASS]),
                TObject(HIGH_PRIORITY_CLASS));
      AddObject(Format('%s (0x%8.8X)',['REALTIME',REALTIME_PRIORITY_CLASS]),
                TObject(REALTIME_PRIORITY_CLASS));

    finally
      EndUpdate;
    end;
  end;

end;
自プロセスの優先順位クラスを取得して表示します。
{$WARN SYMBOL_PLATFORM OFF}

procedure TForm1.Button1Click(Sender: TObject);
var
  PriorityClass: DWORD;
  I: Integer;
begin

  PriorityClass := GetPriorityClass(GetCurrentProcess);

  with ComboBox1 do
  begin
    for I := 0 to Items.Count - 1 do
    begin
      if DWORD(Items.Objects[I]) = PriorityClass then
      begin
        ItemIndex := I;
        Exit;
      end;
    end;

    ItemIndex := -1;
  end;

end;
今度は選択された優先順位クラスを自プロセスに設定します。
procedure TForm1.Button2Click(Sender: TObject);
var
  PriorityClass: DWORD;
begin

  with ComboBox1 do
  begin
    if ItemIndex < 0 then
    begin
      Exit;
    end;

    PriorityClass := DWORD(Items.Objects[ItemIndex]);
    Win32Check(SetPriorityClass(GetCurrentProcess,PriorityClass));
  end;

end;
Windowsにおけるスケジューリングのメカニズムは非常に複雑で、優先順位が実行中に動的に変更されるなど、単純に優先順位クラスなどで決まるわけではありません。このあたりをきちんと理解するためにはAdvanced Windows 第5版 上 (amazon)の"7.8 スレッドの優先度"、"7.9 優先度クラスの概要"、"7.10 プログラミングの優先度"やインサイドWindows 第6版 上 (amazon) の"5.7 スレッドのスケジューリング"などを読むことをお勧めします。

GetPriorityClassとSetPriorityClassで優先順位クラスを取得/設定する (Gist)

2013年8月21日

CreateProcessで優先順位を指定してプログラムを起動する

優先順位クラス (Priority class)を指定してプロセスを起動するにはWin32APIのCreateProcess関数 (en)の第6パラメータ(dwCreationFlags)に優先順位クラスを指定します。

Delphi XE2およびそれ以前のバージョンではWindows.pasにBELOW_NORMAL_PRIORITY_CLASSとABOVE_NORMAL_PRIORITY_CLASSが定義されていないので、まずこれらを定義します。
{$IF RTLVersion < 24}
const
  BELOW_NORMAL_PRIORITY_CLASS = $00004000;
  {$EXTERNALSYM ABOVE_NORMAL_PRIORITY_CLASS}
  ABOVE_NORMAL_PRIORITY_CLASS = $00008000;
  {$EXTERNALSYM ABOVE_NORMAL_PRIORITY_CLASS}
{$IFEND}
フォームにEditとComboBox、Buttonをひとつずつ配置し、フォームのOnCreateイベントでEditとComboBoxに値を格納します。
procedure TForm1.FormCreate(Sender: TObject);
begin

  Edit1.Text := '%windir%\notepad.exe';

  with ComboBox1.Items do
  begin
    BeginUpdate;
    try
      Clear;
      AddObject(Format('%s (0x%8.8X)',['IDLE',IDLE_PRIORITY_CLASS]),
                TObject(IDLE_PRIORITY_CLASS));
      AddObject(Format('%s (0x%8.8X)',['BELOW_NORMAL',BELOW_NORMAL_PRIORITY_CLASS]),
                TObject(BELOW_NORMAL_PRIORITY_CLASS));
      AddObject(Format('%s (0x%8.8X)',['NORMAL',NORMAL_PRIORITY_CLASS]),
                TObject(NORMAL_PRIORITY_CLASS));
      AddObject(Format('%s (0x%8.8X)',['ABOVE_NORMAL',ABOVE_NORMAL_PRIORITY_CLASS]),
                TObject(ABOVE_NORMAL_PRIORITY_CLASS));
      AddObject(Format('%s (0x%8.8X)',['HIGH',HIGH_PRIORITY_CLASS]),
                TObject(HIGH_PRIORITY_CLASS));
      AddObject(Format('%s (0x%8.8X)',['REALTIME',REALTIME_PRIORITY_CLASS]),
                TObject(REALTIME_PRIORITY_CLASS));

    finally
      EndUpdate;
    end;
  end;

  with ComboBox1 do
  begin
    ItemIndex := Items.IndexOfObject(TObject(NORMAL_PRIORITY_CLASS));
  end;

end;
優先順位を指定してプロセスを起動します。
{$WARN SYMBOL_PLATFORM OFF}

procedure TForm1.Button1Click(Sender: TObject);
var
  ApplicationName: String;
  CreationFlags: DWORD;
  StartupInfo: TStartupInfo;
  ProcessInformation: TProcessInformation;
  Length: Integer;
begin

  Length := ExpandEnvironmentStrings(PChar(Edit1.Text),nil,0);
  SetLength(ApplicationName,Length);
  ExpandEnvironmentStrings(PChar(Edit1.Text),PChar(ApplicationName),Length);
  UniqueString(ApplicationName);

  with ComboBox1 do
  begin
    if ItemIndex < 0 then
    begin
      Exit;
    end;

    CreationFlags := DWORD(Items.Objects[ItemIndex]);
  end;

  FillChar(StartupInfo,SizeOf(StartupInfo),0);
  StartupInfo.cb := SizeOf(StartupInfo);

  FillChar(ProcessInformation,SizeOf(ProcessInformation),0);

  Win32Check(CreateProcess(PChar(ApplicationName),nil,nil,nil,False,
                           CreationFlags,nil,nil,
                           StartupInfo,ProcessInformation));

  CloseHandle(ProcessInformation.hProcess);
  CloseHandle(ProcessInformation.hThread);

end;
ここではEditに入力された起動対象プログラムに%windir%などの環境変数を使用することを前提としているため、Win32APIのExpandEnvironmentStrings関数 (en)で展開しています。

優先順位クラスを指定してプロセスを起動する (Gist)

2013年8月20日

コマンドプロンプトのSTARTコマンドで優先順位を指定してプログラムを起動する

プログラムを実行するときに、そのプロセスの優先順位クラス (Priority class)を外部から指定するには、コマンドプロンプト(cmd.exe)のSTARTコマンドを使用します。
start /<PriorityClass> <program>

ここで/<PriorityClass>には

/REALTIME
REALTIME_PRIORITY_CLASS (リアルタイム/24)
/HIGH
HIGH_PRIORITY_CLASS (高/13)
/ABOVENORMAL
ABOVE_NORMAL_PRIORITY_CLASS (通常以上/10)
/NORMAL
NORMAL_PRIORITY_CLASS (通常/8)
/BELOWNORMAL
BELOW_NORMAL_PRIORITY_CLASS (通常以下/6)
/LOW
IDLE_PRIORITY_CLASS (低/4)
を指定可能です(括弧内の数字は同一の優先順位クラス内の相対的な優先順位を表す優先順位レベル (Priority level)をTHREAD_PRIORITY_NORMALに指定したときのベースプライオリティ)。

2013年8月18日

2013年8月14日

Microsoft Monthly Update 2013/08

今日はMicrosoftのセキュリティアップデートの日です。
MS13-059
MS13-060
MS13-061
MS13-062
MS13-063
MS13-064
MS13-065
MS13-066

2013年8月13日

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

しばらく前にジェネリックス版の列挙型と列挙子名の相互変換について書きましたが、これを多少改善してみました。まず整数から列挙値への変換を追加しました(GetEnumValueのInteger引数版)。整数から列挙値への変換は普通は型キャストですませてしまいますが、これだと(デフォルトの設定である){$RANGECHECKS OFF}の状態で範囲外の値が格納されることを防げないため、列挙型の最小値、最大値の確認を行うようにしています。あとはエラーが発生したときに例外を生成するのではなく戻値で区別する関数(Try...)を追加しました。
uses
  TypInfo, SysUtils, SysConst;

type
  TEnumHelper = record
    class function TryGetEnumName<T: record>(Value: T; out S: String): Boolean; static;
    class function GetEnumName<T: record>(Value: T): String; static;
    class function TryGetEnumValue<T: record>(const Name: String; out Enum: T): Boolean; overload; static;
    class function GetEnumValue<T: record>(const Name: String): T; overload; static;
    class function TryGetEnumValue<T: record>(Value: Integer; out Enum: T): Boolean; overload; static;
    class function GetEnumValue<T: record>(Value: Integer): T; overload; static;
  end;

class function TEnumHelper.TryGetEnumName<T>(Value: T; out S: String): Boolean;
var
  P: PTypeInfo;
  IValue: Integer;
begin

  Result := False;
  S := '';

  P := TypeInfo(T);
  if (P = nil) or (P^.Kind <> tkEnumeration) then
  begin
    Exit;
  end;

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

end;

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

  P := TypeInfo(T);
  if (P = nil) or (P^.Kind <> tkEnumeration) then
  begin
    raise EInvalidOpException.CreateRes(@SVarNotImplemented);
  end;

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

end;

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

  Result := False;
  Enum := Default(T);

  P := TypeInfo(T);
  if (P = nil) or (P^.Kind <> tkEnumeration) then
  begin
    Exit;
  end;

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

  with GetTypeData(P)^ do
  begin
    if (IValue < MinValue) or (IValue > MaxValue) then
    begin
      Exit;
    end;
  end;

  Move(IValue,Enum,SizeOf(T));
  Result := True;

end;

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

  Result := Default(T);

  P := TypeInfo(T);
  if (P = nil) or (P^.Kind <> tkEnumeration) 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;
  end;

  Move(IValue,Result,SizeOf(T));

end;

class function TEnumHelper.TryGetEnumValue<T>(Value: Integer; out Enum: T): Boolean;
var
  P: PTypeInfo;
begin

  Result := False;
  Enum := Default(T);

  P := TypeInfo(T);
  if (P = nil) or (P^.Kind <> tkEnumeration) then
  begin
    Exit;
  end;

  with GetTypeData(P)^ do
  begin
    if (Value < MinValue) or (Value > MaxValue) then
    begin
      Exit;
    end;
  end;

  Move(Value,Enum,SizeOf(T));
  Result := True;

end;

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

  Result := Default(T);

  P := TypeInfo(T);
  if (P = nil) or (P^.Kind <> tkEnumeration) then
  begin
    raise EInvalidOpException.CreateRes(@SVarNotImplemented);
  end;

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

  Move(Value,Result,SizeOf(T));

end;
こんな感じで使います。
var
  S: String;
begin

  if TEnumHelper.TryGetEnumName(0,S) = True then  // Error (0 is not enumeration)
  begin
    Label1.Caption := S;
  end
  else
  begin
    Label1.Caption := '(Error)';
  end;

  S := TEnumHelper.GetEnumName(taLeftJustify);  // taLeftJustify -> 'taLeftJustify'
  Label2.Caption := S;

  S := TEnumHelper.GetEnumName(False);  // False -> 'False'
  Label3.Caption := S;

end;
元ねたはDelphi XE2 Foundations

列挙型と列挙子名(文字列)または整数の相互変換(ジェネリックス版) (Gist)

2013年8月7日

CopyFileExを無名メソッドで使う

前回はWin32APIのCopyFileEx関数 (en)でファイルをコピーする処理を作成しましたが、Delphi 2009以降ではやはりコールバックを無名メソッドで記述したいところです。ということでCopyFileExの無名メソッド版です。

まず無名メソッドの定義から。
type
  TCopyProgressCallbackFunc = reference to function
                                (TotalFileSize: Int64;
                                 TotalBytesTransferred: Int64;
                                 StreamSize: Int64;
                                 StreamBytesTransferred: Int64;
                                 dwStreamNumber: DWORD;
                                 dwCallbackReason: DWORD;
                                 hSourceFile: THandle;
                                 hDestinationFile: THandle): DWORD;
無名メソッドは実際にはコンパイラが自動的に生成する(メンバにメソッドInvokeだけを持つ)TInterfacedObjectの派生クラスのインスタンスなので、これをCopyFileEx関数の第4パラメータ(lpData)経由でコールバック関数に渡して、そこから無名メソッドを呼び出せばいい…はずなのですが、無名メソッドそのままだとどうやってもうまくいかないので、無名メソッドをレコード型の変数に格納してそのアドレスを受け渡すようにします。そのレコード型の定義は
type
  TCopyProgressCallbackRec = record
    FCallback: TCopyProgressCallbackFunc;
  end;
  PCopyProgressCallbackRec = ^TCopyProgressCallbackRec;
となります。このレコード型のポインタ(PCopyProgressCallbackRec)を使い、CopyFileEx関数のコールバックでは
function CopyProgressFunc(TotalFileSize: Int64;
                          TotalBytesTransferred: Int64;
                          StreamSize: Int64;
                          StreamBytesTransferred: Int64;
                          dwStreamNumber: DWORD;
                          dwCallbackReason: DWORD;
                          hSourceFile: THandle;
                          hDestinationFile: THandle;
                          lpData: Pointer): DWORD; stdcall;
var
  PCallback: PCopyProgressCallbackRec;
begin

  PCallback := PCopyProgressCallbackRec(lpData);
  Result := PCallback^.FCallback(TotalFileSize,
                                 TotalBytesTransferred,
                                 StreamSize,
                                 StreamBytesTransferred,
                                 dwStreamNumber,
                                 dwCallbackReason,
                                 hSourceFile,
                                 hDestinationFile);

end;
と無名メソッドを呼び出すようにします。あとはコールバックとして無名メソッドを受け取るファイルコピー関数を作成します。
procedure CopyFile(const ExistingFileName: String; const NewFileName: String;
                   FailIfExists: Boolean; NoBuffering: Boolean;
                   Callback: TCopyProgressCallbackFunc);
var
  Canceled: BOOL;
  CopyFlags: DWORD;
  CallbackRec: TCopyProgressCallbackRec;
begin

  Canceled := False;

  CopyFlags := 0;
  if FailIfExists = True then
  begin
    CopyFlags := CopyFlags or COPY_FILE_FAIL_IF_EXISTS;
  end;
  if (NoBuffering = True) and CheckWin32Version(6,0) then
  begin
    CopyFlags := CopyFlags or COPY_FILE_NO_BUFFERING;
  end;

  CallbackRec.FCallback := Callback;
  Win32Check(CopyFileEx(PChar(ExistingFileName),PChar(NewFileName),
                        @CopyProgressFunc,@CallbackRec,@Canceled,CopyFlags));

end;
前回同様にフォーム上にコピー元ファイル名とコピー先ファイル名を入力するためのEditを2つとコピー開始/コピー中断のButton、途中経過表示用のLabelを配置して、コピー開始のButtonのOnClickイベントとコピー中断のButtonのOnClickイベントを記述します。
procedure TForm1.Button1Click(Sender: TObject);
begin

  FAborted := False;

  Button1.Enabled := False;
  try
    CopyFile(Edit1.Text,Edit2.Text,True,True,
             function (TotalFileSize: Int64;
                       TotalBytesTransferred: Int64;
                       StreamSize: Int64;
                       StreamBytesTransferred: Int64;
                       dwStreamNumber: DWORD;
                       dwCallbackReason: DWORD;
                       hSourceFile: THandle;
                       hDestinationFile: THandle): DWORD
             var
               TBT: Extended;
               TFS: Extended;
             begin
               TFS := TotalFileSize;
               TBT := TotalBytesTransferred;

               if (TotalFileSize = 0) or (TotalBytesTransferred = 0) then
               begin
                 Label1.Caption := '';
               end
               else
               begin
                 Label1.Caption := Format('%.0n / %.0n bytes',[TBT,TFS]);
               end;

               Result := PROGRESS_CONTINUE;

               Application.ProcessMessages;
               if FAborted = True then
               begin
                 FAborted := False;
                 if MessageDlg('ファイルコピーを中断しますか?',
                               mtConfirmation,[mbYes,mbNo],0) = mrYes then
                 begin
                   Result := PROGRESS_CANCEL;
                 end;
               end;
             end);

  finally
    Button1.Enabled := True;
  end;

end;

procedure TForm1.Button2Click(Sender: TObject);
begin

  FAborted := True;

end;
ここではコピー中止のButtonをクリックすると中断するかどうか確認するダイアログを表示するようにしています。

Win32APIのCopyFileExのコールバックから無名メソッドを呼び出す (Gist)

2013年8月5日

CopyFileExを使う

DelphiでファイルをコピーするときはWin32APIのCopyFile関数 (en)か、これをラッピングした(System.)IOUtilsのTFile.Copyなどを使うのが普通ですが、大きめのファイルだったり遅いデバイスだったり、あるいはその両方で、ファイルコピーに5秒以上かかるとWindowsに"応答なし"と判断されてしまうことになります。ファイルコピーを別スレッドで行ってもよいのですが(TFile.DoCopyの実装を見る限りPOSIX環境ではこれしかなさそう)、Windows環境であればWin32APIのCopyFileEx関数 (en)を使い、コールバック関数内でApplication.ProcessMessagesを呼び出すことでこの問題を回避することができます。ではまず(Winapi.)Windows.pas上のCopyFileExの定義を見てみましょう。
type
  TFNProgressRoutine = TFarProc;

function CopyFileEx(lpExistingFileName, lpNewFileName: LPWSTR;
  lpProgressRoutine: TFNProgressRoutine; lpData: Pointer; pbCancel: PBool;
  dwCopyFlags: DWORD): BOOL; stdcall;
コールバック関数の型はTFNProgressRoutine=TFarProcと定義されていますが、TFarProcはというと、
TFarProc = Pointer;
となっており、やる気のなさ満点です(間違っちゃいないけど)。そこでまずCopyProgressRoutineコールバック関数 (en)の定義から用意します。
type
  TCopyProgressRoutine = function (TotalFileSize: Int64;
                                   TotalBytesTransferred: Int64;
                                   StreamSize: Int64;
                                   StreamBytesTransferred: Int64;
                                   dwStreamNumber: DWORD;
                                   dwCallbackReason: DWORD;
                                   hSourceFile: THandle;
                                   hDestinationFile: THandle;
                                   lpData: Pointer): DWORD; stdcall;
これを使ってCopyFileEx関数を再定義します。
function CopyFileEx(lpExistingFileName: PChar;
                    lpNewFileName: PChar;
                    lpProgressRoutine: TCopyProgressRoutine;
                    lpData: Pointer;
                    pbCancel: PBool;
                    dwCopyFlags: DWORD): BOOL; stdcall; external kernel32
{$IFDEF UNICODE}
                    name 'CopyFileExW';
{$ELSE}
                    name 'CopyFileExA';
{$ENDIF}
{$EXTERNALSYM CopyFileEx}

これらの定義を使ってファイルをコピーしてみましょう。まずフォーム上にコピー元ファイル名とコピー先ファイル名を入力するためのEditを2つとコピー開始のButton、途中経過表示用のLabelを配置します。
{$WARN SYMBOL_PLATFORM OFF}
const
  COPY_FILE_NO_BUFFERING = $00001000;

function CopyProgressFunc(TotalFileSize: Int64;
                          TotalBytesTransferred: Int64;
                          StreamSize: Int64;
                          StreamBytesTransferred: Int64;
                          dwStreamNumber: DWORD;
                          dwCallbackReason: DWORD;
                          hSourceFile: THandle;
                          hDestinationFile: THandle;
                          lpData: Pointer): DWORD; stdcall;
var
  TBT: Extended;
  TFS: Extended;
begin

  TFS := TotalFileSize;
  TBT := TotalBytesTransferred;

  with TObject(lpData) as TForm1 do
  begin
    if (TotalFileSize = 0) or (TotalBytesTransferred = 0) then
    begin
      Label1.Caption := '';
    end
    else
    begin
      Label1.Caption := Format('%.0n / %.0n bytes',[TBT,TFS]);
    end;
  end;

  Application.ProcessMessages;

  Result := PROGRESS_CONTINUE;

end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Canceled: BOOL;
  CopyFlags: DWORD;
begin

  Button1.Enabled := False;
  try
    Canceled := False;

    CopyFlags := COPY_FILE_FAIL_IF_EXISTS;
    if CheckWin32Version(6,0) then
    begin
      CopyFlags := CopyFlags or COPY_FILE_NO_BUFFERING;
    end;

    Win32Check(CopyFileEx(PChar(Edit1.Text),PChar(Edit2.Text),
               CopyProgressFunc,Self,@Canceled,CopyFlags));

  finally
    Button1.Enabled := True;
  end;

end;
これでファイルのコピー中に途中経過を表示できるようになります。またApplication.ProcessMessagesを呼び出すことでWindowsに"応答なし"と判定されることもなくなります(ただしイベントハンドラへの再入には十分注意が必要です)。

ここでは大きいファイルをコピーすることを想定しているため、Windows Vista以降ではdwCopyFlagsにCOPY_FILE_NO_BUFFERINGを追加指定しています(COPY_FILE_NO_BUFFERINGには功罪両面ありますが)。またファイルの上書きを許す場合はCopyFlagsにCOPY_FILE_FAIL_IF_EXISTSではなくて0を指定します(CopyFlagsにCOPY_FILE_FAIL_IF_EXISTSを指定したときにコピー先ファイルが存在しているとCopyFileExの戻値は0となり、GetLastError (en)はERROR_FILE_EXISTSを返します)。

さらにコピーの途中でキャンセルできるようにしてみます。フォームにキャンセル用のButtonと、privateメンバにBoolean型のフィールドFAbortedを追加します。
function CopyProgressFunc(TotalFileSize: Int64;
                          TotalBytesTransferred: Int64;
                          StreamSize: Int64;
                          StreamBytesTransferred: Int64;
                          dwStreamNumber: DWORD;
                          dwCallbackReason: DWORD;
                          hSourceFile: THandle;
                          hDestinationFile: THandle;
                          lpData: Pointer): DWORD; stdcall;
var
  TBT: Extended;
  TFS: Extended;
begin

  TFS := TotalFileSize;
  TBT := TotalBytesTransferred;

  with TObject(lpData) as TForm1 do
  begin
    if (TotalFileSize = 0) or (TotalBytesTransferred = 0) then
    begin
      Label1.Caption := '';
    end
    else
    begin
      Label1.Caption := Format('%.0n / %.0n bytes',[TBT,TFS]);
    end;

    Result := PROGRESS_CONTINUE;

    Application.ProcessMessages;
    if FAborted = True then
    begin
      Result := PROGRESS_CANCEL;
    end;
  end;

end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Canceled: BOOL;
  CopyFlags: DWORD;
begin

  FAborted := False;

  Button1.Enabled := False;
  try
    Canceled := False;

    CopyFlags := COPY_FILE_FAIL_IF_EXISTS;
    if CheckWin32Version(6,0) then
    begin
      CopyFlags := CopyFlags or COPY_FILE_NO_BUFFERING;
    end;

    Win32Check(CopyFileEx(PChar(Edit1.Text),PChar(Edit2.Text),
               CopyProgressFunc,Self,@Canceled,CopyFlags));

  finally
    Button1.Enabled := True;
  end;

end;

procedure TForm1.Button2Click(Sender: TObject);
begin

  FAborted := True;
  
end;
こんな感じです。コールバック関数がPROGRESS_CANCELを返してファイルコピーをキャンセルしたときはCopyFileExの戻値は0(エラー)となり、GetLastErrorはERROR_REQUEST_ABORTEDを返します。

さて、Delphi 2009以降でコールバックといえば無名メソッド、という連想が働きますが、それはまた次回

Win32APIのCopyFileExのコールバックを受け入れる (Gist)