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