2012年11月14日水曜日

TFindDialogEx と class helper

DEKO さんから class helper を使うと private なメンバにアクセスできちゃうよ!という情報をいただきました。
詳細はリンク先の Owl's perspective さんの所でご覧頂くとして、先日記事した TFindDialogEx を、class helper に書き換えてみました。

まず、TCommonDialogTFindDialogclass helper を書きます。

type
TCommonDialogHelper = class helper for TCommonDialog
public
procedure ReleaseRedirector;
end;
 
TFindDialogHelper = class helper for TFindDialog
public
procedure ReleaseHandle;
end;
 
{ TCommonDialogHelper }
 
procedure TCommonDialogHelper.ReleaseRedirector;
begin
Self.FRedirector.Free;
end;
 
{ TFindDialogHelper }
 
procedure TFindDialogHelper.ReleaseHandle;
begin
Self.FFindHandle := 0;
end;

TCommonDialog のヘルパが必要なのは FRedirector は TCommonDialog のメンバだからです。

TFindDialog は TCommonDialog と同じ Unit 内にあるので、特に何もせず FRedirector を参照できます。

コードで Self を強調表示してありますが、それは Self を外すとコンパイルが通らないためです。
注意してください。

これらのヘルパメソッドを実際に使う部分は以下のようになります。

function TFindDialogEx.Execute(ParentWnd: HWND): Boolean;
var
TId: DWORD;
begin
// 無効なウィンドウハンドルでは 0 が返る
TId := GetWindowThreadProcessId(Handle);
if (TId = 0) then begin
ReleaseHandle;
ReleaseRedirector;
end;
 
Result := inherited;
end;

RTTI を使った場合より大分すっきりしました。

どのメンバを操作しなくてはいけないのかが判っている場合は、class helper の方が良さそうです。

0 件のコメント:

コメントを投稿