<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE feed [
      <!ENTITY lt "&#38;#60;">
      <!ENTITY gt "&#62;">
      <!ENTITY amp "&#38;#38;">
      <!ENTITY apos "&#39;">
      <!ENTITY quot "&#34;">
      <!ENTITY nbsp "&#160;">
      <!ENTITY copy "&#169;">
]>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title type="text">開発ブログ</title>
    <subtitle type="text">MASA Lab softlab-Software Architecture Laboratory</subtitle>
    <updated>2026-04-17T14:40:38+09:00</updated>
    <id>http://softlab.masa-lab.net/modules/d3blog/index.php</id>
    <link rel="alternate" type="text/xhtml" hreflang="ja" href="http://softlab.masa-lab.net/" />
    <link rel="self" type="application/atom+xml" href="http://softlab.masa-lab.net/modules/d3blog/index.php?page=atom" />
    <rights>Copyright &copy; 2008-2019 by MASA-Lab</rights>
    <generator uri="http://softlab.masa-lab.net/">D3BLOG - XOOPS BLOG MODULE</generator>
    <entry>
        <title>良く忘れる</title>
        <link rel="alternate" type="text/xhtml" href="http://softlab.masa-lab.net/modules/d3blog/details.php?bid=262" />
        <id>http://softlab.masa-lab.net/modules/d3blog/details.php?bid=262</id>
        <published>2017-05-17T22:30:00+09:00</published>
        <updated>2018-02-16T15:23:39+09:00</updated>
        <category term="全般" label="全般" />
        <author>
            <name>masa</name>
        </author>
        <summary type="html" xml:base="http://softlab.masa-lab.net/" xml:lang="ja">TList は無名メソッドでソートできるTObjectList の sortは TComparer を使って行う
uses
  System.Generics.Defaults, System.Generics.Defaults,
  ...

List.Sort(TComparer&lt;TFooBar&gt;.Construct(
    function(const Item1, Item2: ...</summary>
       <content type="html" xml:lang="ja" xml:base="http://softlab.masa-lab.net/">
<![CDATA[<div>TList<T> は無名メソッドでソートできる<br /><br />TObjectList<T> の sortは TComparer を使って行う<br /><br /><pre class="blogCode"><code>
uses
  System.Generics.Defaults, System.Generics.Defaults,
  ...

List.Sort(TComparer&lt;TFooBar&gt;.Construct(
    function(const Item1, Item2: TFooBar): Integer
    begin
      Result := Item1.Prop1 - Item2.Prop1;
    end));
)
</code></pre></div>]]>
       </content>
    </entry>
    <entry>
        <title>C++のサンプルをDelphiで真似ているときのとってもおバカなミス</title>
        <link rel="alternate" type="text/xhtml" href="http://softlab.masa-lab.net/modules/d3blog/details.php?bid=108" />
        <id>http://softlab.masa-lab.net/modules/d3blog/details.php?bid=108</id>
        <published>2014-10-17T22:40:00+09:00</published>
        <updated>2014-12-13T16:55:42+09:00</updated>
        <category term="全般" label="全般" />
        <author>
            <name>masa</name>
        </author>
        <summary type="html" xml:base="http://softlab.masa-lab.net/" xml:lang="ja">
変数定義をするときに、下のようなコードを書いたらエラーが発生しました。


var
hWnd: HWND;


[dcc32 エラー] xxxx.pas(26): E2007 定数または型が必要です


HWND は定義されているのにな...</summary>
       <content type="html" xml:lang="ja" xml:base="http://softlab.masa-lab.net/">
<![CDATA[<div><p>
変数定義をするときに、下のようなコードを書いたらエラーが発生しました。<br />
</p>
<pre class="blogCode"><code>
var
hWnd: HWND;
</code></pre>
<pre class="blogCode"><code>
[dcc32 エラー] xxxx.pas(26): E2007 定数または型が必要です
</code></pre>
<p>
HWND は定義されているのになんでだよ！<br />
みたいに怒っていました。<br />
しまいにはこのコンパイラ壊れている！！！なんて...<br />
</p>
<p>
おバカすぎましたね。<br />
Delphi ですから、大文字小文字とかないし...<br />
まさか変数名側でエラーが起きているとはつゆとも思わなかったのです。<br />
こんなことで10分以上悩むとか...<br />
(いや、実際は HWND ではなくもっとめっちゃ長い識別子だったんですが)
</p></div>]]>
       </content>
    </entry>
    <entry>
        <title>FireMonkey の TBitmap と VCL の TBitmap</title>
        <link rel="alternate" type="text/xhtml" href="http://softlab.masa-lab.net/modules/d3blog/details.php?bid=107" />
        <id>http://softlab.masa-lab.net/modules/d3blog/details.php?bid=107</id>
        <published>2014-10-16T22:30:00+09:00</published>
        <updated>2016-04-26T17:38:12+09:00</updated>
        <category term="全般" label="全般" />
        <author>
            <name>masa</name>
        </author>
        <summary type="html" xml:base="http://softlab.masa-lab.net/" xml:lang="ja">
FireMonkey にも VCL にも TBitmap というクラスがあり、
それぞれ VCL.Graphics, FMX.Graphics に入っています。
同じ名前なので同じようなものと思ってしまうのですが、だいぶ違うんです。
</summary>
       <content type="html" xml:lang="ja" xml:base="http://softlab.masa-lab.net/">
<![CDATA[<div><p>
FireMonkey にも VCL にも TBitmap というクラスがあり、
それぞれ VCL.Graphics, FMX.Graphics に入っています。<br />
同じ名前なので同じようなものと思ってしまうのですが、だいぶ違うんです。
</p>
<p>
FireMonkey の TBitmap はビットマップをカプセル化したものです。<br />
VCL の TBitmap はWindows ビットマップ (HBITMAP) をカプセル化しています。<br />
FireMonkey の TBitmap の親は TInterfacedPersistent です。<br />
VCL の TBitmap の親は TGraphic です。<br />
つまり VCL の TBitmap は、TIcon や TMetafile, TJPEGImageの兄弟です。
</p>

<h3>FMX.Graphics.TBitmap</h3>
<p>
FireMonkey の TBitmap は CreateFromStream や CreateFromFile で、ファイルからビットマップデータを読み込むことができます。<br />
(扱うことのできる画像形式は TBitmapCodecManager を参照)。
</p>

<h3>VCL.Graphics.TBitmap で画像ファイル読み込み？</h3>
<p>
VCL.Graphics.TBitmap の LoadFromFile は BMPファイルからの読み込みしかサポートしません。<br />
VCL.Graphics.TBitmap に 様々な画像ファイルから画像を読み込みたい場合は TPicture を使います。
</p>
<pre class="blogCode"><code>
var
  Picture: TPicture;
  Bitmap: TBitmap;
begin
  Picture := TPicture.Create;
  Picture.LoadFromFile(AFilePath);
  Bitmap := TBitmap.Create;
  Bitmap.Width := Picture.Width;
  Bitmap.Height := Picture.Height;
  Bitmap.Canvas.Draw(0, 0, Picture.Graphic);
  ...
end;
</code></pre>

<p>
TPicture は TGraphic のコンテナで、グラフィックを保持するために使用されます。<br />
TGraphic はアイコン，ビットマップ，およびメタファイルなどのイメージを格納および表示するオブジェクトの抽象基本クラスですから、TPicture はこれらのグラフィックを統合的に扱うことができます。<br />
なお、TPicture の親は TInterfacedPersistent です。<br />
ちなみに FireMonkey には TPicture や TGraphic はありません。<br />
FireMonkey はマルチプラットフォームですから当然ですが...
</p></div>]]>
       </content>
    </entry>
    <entry>
        <title>RAD Studio XE6</title>
        <link rel="alternate" type="text/xhtml" href="http://softlab.masa-lab.net/modules/d3blog/details.php?bid=66" />
        <id>http://softlab.masa-lab.net/modules/d3blog/details.php?bid=66</id>
        <published>2014-05-01T20:43:42+09:00</published>
        <updated>2016-02-25T19:32:00+09:00</updated>
        <category term="全般" label="全般" />
        <author>
            <name>masa</name>
        </author>
        <summary type="html" xml:base="http://softlab.masa-lab.net/" xml:lang="ja">XE6 のバージョン番号は 13 ではなく 14 なんですね...
必要な領域 18,282MB
使用可能なディスク領域 28,556MB
残りのディスク領域 10,273MB
という状態からインストールを開始したのですが「デ...</summary>
       <content type="html" xml:lang="ja" xml:base="http://softlab.masa-lab.net/">
<![CDATA[<div>XE6 のバージョン番号は 13 ではなく 14 なんですね...<br /><br /><pre class="blogCode"><code>
必要な領域 18,282MB
使用可能なディスク領域 28,556MB
残りのディスク領域 10,273MB
</code></pre><br />という状態からインストールを開始したのですが<br /><br />「ディスクの空き領域が不足しています」<br />35,675MB用意しろと...<br />相変わらず謎なインストーラーです<br /><br />結局<br />「ディスク領域が足りません」<br />必要な領域 16MB<br />利用可能な領域 10MB<br />と言われ...<br />どうすればいいんだ？！<br /><br />仕方がないので一時ファイルの展開をするドライブを追加して、環境変数TEMP,TMPにそのドライブを指定してみましたが、やはり領域は足りない...orz<br /><br />セットアップに使用する言語でjapaneseを選んでいるのに French と German の zip も展開されているのね...<br />これらは必要ないかと思って消してみたら、インストール時にエラーになってしまった(涙)やり直し...<br /><br />結局システムドライブの領域を空けられなかったので、圧縮して対応。(あーあ)<br /><br />再インストールして完了しました。<br />毎度インストールでは苦労します。<br /><br />[関連記事]<br /><br /><a href="http://softlab.masa-lab.net/modules/d3blog/details.php?bid=64" >Delphi XE5 update2 のインストールについて</a></div>]]>
       </content>
    </entry>
    <entry>
        <title>deprecated</title>
        <link rel="alternate" type="text/xhtml" href="http://softlab.masa-lab.net/modules/d3blog/details.php?bid=55" />
        <id>http://softlab.masa-lab.net/modules/d3blog/details.php?bid=55</id>
        <published>2014-01-23T21:20:00+09:00</published>
        <updated>2014-12-13T17:15:49+09:00</updated>
        <category term="全般" label="全般" />
        <author>
            <name>masa</name>
        </author>
        <summary type="html" xml:base="http://softlab.masa-lab.net/" xml:lang="ja">
[dcc32 警告] xxxx.pas(n): W1000 シンボル &#039;FileAge&#039; を使用することは推奨されていません 


FileAge の代わりに何を使えば良いのでしょうか？</summary>
       <content type="html" xml:lang="ja" xml:base="http://softlab.masa-lab.net/">
<![CDATA[<div><pre class="blogCode"><code>
[dcc32 警告] xxxx.pas(n): W1000 シンボル &#039;FileAge&#039; を使用することは推奨されていません 
</code></pre>

FileAge の代わりに何を使えば良いのでしょうか？
docwiki によると
<pre class="blogCode"><code>
function FileAge(const FileName: string): Integer;
</code></pre>
が deprecated になって
<pre class="blogCode"><code>
function FileAge(const FileName: string; out FileDateTime: TDateTime;
  FollowLink: Boolean = True): Boolean;
</code></pre>
を使えと...</div>]]>
       </content>
    </entry>
    <entry>
        <title>TInterfacedObject ではまる</title>
        <link rel="alternate" type="text/xhtml" href="http://softlab.masa-lab.net/modules/d3blog/details.php?bid=42" />
        <id>http://softlab.masa-lab.net/modules/d3blog/details.php?bid=42</id>
        <published>2014-01-09T22:00:00+09:00</published>
        <updated>2014-12-13T17:16:40+09:00</updated>
        <category term="全般" label="全般" />
        <author>
            <name>masa</name>
        </author>
        <summary type="html" xml:base="http://softlab.masa-lab.net/" xml:lang="ja">
知ってはいたんですよ。
TInterfacedObject の自動破棄については…
いえ、知っているつもりだったんです。
</summary>
       <content type="html" xml:lang="ja" xml:base="http://softlab.masa-lab.net/">
<![CDATA[<div><p>
知ってはいたんですよ。<br />
TInterfacedObject の自動破棄については…<br />
いえ、知っているつもりだったんです。
</p>
<p>
TInterfacedObject を継承して作ったクラスを使うときには Free をしちゃだめ！<br />
という知識はありました。<br />
ただ、それは局所変数で処理しているから、局所変数がなくなったときに自動破棄されるものだと思っていたのです。
</p>

<h3>知っていたサンプル</h3>
<p>
たとえば下に示すようなクラスを作ったとします。<br />
単に Test というプロシジャだけを持つ interface と、それを実装した TInterfacedObject を継承したクラスです。
</p>
<pre class="blogCode"><code>
interface

uses
  System.Classes;

type
  ITestInterface = interface
    [&#039;{7723B047-28A4-4EF1-8836-0BE06092F2F5}&#039;]
    procedure Test;
  end;

  TTestClass = class(TInterfacedObject, ITestInterface)
  public
    constructor Create;
    destructor Destroy; override;
    procedure Test;
  end;

implementation

uses
  Vcl.Dialogs;

{ TTestClass }

constructor TTestClass.Create;
begin
  inherited;
  ShowMessage(&#039;Create!&#039;);
end;

destructor TTestClass.Destroy;
begin
  ShowMessage(&#039;Destroy!!&#039;);
  inherited;
end;

procedure TTestClass.Test;
begin
  ShowMessage(&#039;Test&#039;);
end;

end.
</code></pre>

<p>
問題が起きるのは次のような書き方をした場合だと思っていました。
</p>

<pre class="blogCode"><code>
procedure Test;
var
  T: TTestClass;
begin
  T := TTestClass.Create;
  (T as ITestInterface).Test;
  T.Free;
end;
</code></pre>

<h3>大丈夫だと思っていたサンプル</h3>
<p>
フォームからこのクラスを使おうとして、フォーム生成時にクラスを作成し、ボタンが押されたら Test メソッドを呼び出す、というコードを書いてみました。
</p>

<pre class="blogCode"><code>
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    FTest: TTestClass;
  public
    { Public 宣言 }
  end;

implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
  FTest := TTestClass.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(FTest);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  (FTest as ITestInterface).Test;
end;

</code></pre>

<p>
このコードを実行すると、２回目にボタンを押すと例外が発生してしまいます。<br />
  (FTest as ITestInterface).Test;
を実行すると、Button1Click を抜けるタイミングで FTest の実体が解放されてしまうためです。<br />
えー！そんなぁ！！！<br />
このサンプルくらいなら FTest を ITestInterface で宣言するという手が使えますが、複数の Interface を持つクラスを保持するためにその数分の変数を用意するのはないなぁ…と思うのです。<br />
やはり TInterfacedObject を Java の Interface 的に使うのは、どんなときでもだめ！ということですね。<br />
</p>

<p>
今回、かなり複雑な仕組みのプロジェクトに、TInterfaceObject と Interface の機構を後から組み込んでしまい、わけのわからないバグに悩まされてしまいました。<br />
もう絶対 TInterfacedObject は使わないことを心に誓いましたよ。
</p>

<h3>解決策は？</h3>
<p>
参考サイトの情報を参照してください〜
</p>

<h4>[参考サイト]</h4>
<p>
<a href="http://tobysoft.net/wiki/index.php?Delphi%2Finterface%A4%F2%BB%C8%A4%AA%A4%A6%2F%B2%BF%A4%AC%CC%E4%C2%EA%A4%CB%A4%CA%A4%EB%A4%AB%A1%A9" target="_blank">Delphi/interfaceを使おう/何が問題になるか？</a><br />
<a href="http://delfusa.blog65.fc2.com/blog-entry-236.html" target="_blank">TInterfacedObject で自動破棄....の前に</a><br />
</p></div>]]>
       </content>
    </entry>
    <entry>
        <title>Delphi XE5 update2 のインストールについて</title>
        <link rel="alternate" type="text/xhtml" href="http://softlab.masa-lab.net/modules/d3blog/details.php?bid=64" />
        <id>http://softlab.masa-lab.net/modules/d3blog/details.php?bid=64</id>
        <published>2014-01-04T17:30:00+09:00</published>
        <updated>2014-12-13T17:16:20+09:00</updated>
        <category term="全般" label="全般" />
        <author>
            <name>masa</name>
        </author>
        <summary type="html" xml:base="http://softlab.masa-lab.net/" xml:lang="ja">
インストールにはシステムドライブに 約18GB必要ということでした。
ぎりぎり入るかなと思ってやってみたのですが、途中で止まってしまいました。
システムドライブの容量を見てみ...</summary>
       <content type="html" xml:lang="ja" xml:base="http://softlab.masa-lab.net/">
<![CDATA[<div><p>
インストールにはシステムドライブに 約18GB必要ということでした。<br />
ぎりぎり入るかなと思ってやってみたのですが、途中で止まってしまいました。<br />
システムドライブの容量を見てみると 0になっていました。<br />
インストール失敗です。<br />
インストールをキャンセルしたのですが、ディスクの空き容量が増えません。<br />
</p>
<p>
インストールの仕組みとしては、radstudio_xe5_upd2_esd.exe が zip ファイルをダウンロードしてきて、それを一時フォルダに展開してからインストールするようです。
</p>

<p>
上記のように インストーラが途中で止まってしまった場合、それらの中間ファイルが削除されないようでした。<br />
zip ファイルがダウンロードされるパスは、デフォルトでは<br />
c:¥ユーザ¥ユーザ名¥マイ ドキュメント¥Rad_Studio_XE5_Upd2_Downloads<br />
で、このパスはインストール時に指定できます。<br />
そこで、まずこれらのダウンロードされたファイルを別のドライブに移動させました。<br />
容量はエンタープライズ版で 2.5GB 程度？でした。
</p>

<p>
これで再度挑戦しようと思いましたが、ディスク容量が減ったままでは気になるので、zip を展開したファイルを削除することにしました。<br />
これらのファイルは c:¥ProgramData¥{GUID?}¥ というフォルダ以下にあるようなので、フォルダごと削除します。
</p>

<p>
これでもまだディスク容量が足りなそうなので、システムドライブの不要なファイルを根こそぎ削除してから、インストールを実行してみました。<br />
今回は順調にいきそう…と思ったら boost をインストールするには最低 3GB 必要などと言われてしまいました。<br />
ドライブを見てみると残り 1.8GB とか…<br />
たしか25GB くらいはあったはずなのに…<br />
それでもなんとかインストールは終わりました。<br />
(boost を除く)<br />
</p>
<p>
システムドライブの残りは 1.4GB になっています。<br />
これではすぐ具合が悪くなりそう。<br />
zip が展開されたフォルダを見てみると、そのまま残っていて 11.8GB も使っています。<br />
えーーーーーー<br />
これは要るのでしょうか？<br />
このままではディスクがすぐに一杯になっていまいそうなので、消してしまうことにします。<br />
消してしまってもとりあえず不具合は起きないようです。<br />
</p>
<p>
それにしても開発環境はディスクを食うなぁ….<br />
あのゴミは一体なんなんだろう...
</p></div>]]>
       </content>
    </entry>
    <entry>
        <title>TObjectList&lt;T&gt; のコンストラクタに注意</title>
        <link rel="alternate" type="text/xhtml" href="http://softlab.masa-lab.net/modules/d3blog/details.php?bid=40" />
        <id>http://softlab.masa-lab.net/modules/d3blog/details.php?bid=40</id>
        <published>2013-12-26T17:17:09+09:00</published>
        <updated>2014-01-21T11:08:31+09:00</updated>
        <category term="全般" label="全般" />
        <author>
            <name>masa</name>
        </author>
        <summary type="html" xml:base="http://softlab.masa-lab.net/" xml:lang="ja">
Generics の TObjectList を使ったプログラムをデバッグしていて気がつきました。
TObjectList のコンストラクタで inherited の書き方によって、動作が違うことがあるの？
</summary>
       <content type="html" xml:lang="ja" xml:base="http://softlab.masa-lab.net/">
<![CDATA[<div><p>
Generics の TObjectList を使ったプログラムをデバッグしていて気がつきました。<br />
TObjectList<T> のコンストラクタで inherited の書き方によって、動作が違うことがあるの？<br />
</p>
<p>
書いていたのはこんなコードです。
</p>

<pre class="blogCode"><code>
TDangerObjectList = class(TObjectList&lt;TBar&gt;)
public
  constructor Create;
  destructor Destroy; override;
end;

constructor TDangerObjectList.Create;
begin
  inherited;   // inherited Create; でなければならない!!
end;

destructor TDangerObjectList.Destroy;
begin
  inherited;
end;

</code></pre>

<p>
コンストラクタで inherited Create と書けば
TObjectList<T>.Create が呼ばれますが、
inherited だけ書くと
TList<T>.Create が呼ばれてしまうようです。<br />
それって子供たちが解放されないってことですよね？
</p>
<p>
inherited とだけ書くと、自分と同じシグネチャのメソッドである Create() を呼び出そうとしますが、TObjectList には Create() はありません。(注)<br />
そのため TObjectList の親の TList.Create() が呼ばれてしまうのでしょう。
</p>
<p>
(注)<br />
TObjectList.Create と書けるじゃないか。と思いますが、実際には<br />
Create(AOwnsObjects: Boolean = True)<br />
が呼ばれているだけで、 Create() はありません。<br />
</p>
<p>
意外にこの辺りは適当に書いてしまうことがあるので注意しなければ...
</p></div>]]>
       </content>
    </entry>
</feed>