フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: 1 2 [3] 4
トピック: Delphi Advent Calendar 2013
DEKO
管理者
投稿数: 2649
12/11 Assertの話(2)
on: 2013/12/11 23:59 Wed

[Assertの話(2)]
http://uskz.hatenablog.com/entry/2013/12/13/131814

DEKO
管理者
投稿数: 2649
12/12 FireMonkeyのTImageは画像変換が超カンタン!
on: 2013/12/12 08:37 Thu

[FireMonkeyのTImageは画像変換が超カンタン!]
http://worktoolsmith.com/2013/12/delphi-advent-2013/

DEKO
管理者
投稿数: 2649
Re: 12/10 プロパティエディタを作ってみる (1/3)
on: 2013/12/12 11:30 Thu

今更気付いたのですが… "Delphi 2.0J コンポーネントセット 服部誠著 (ISBN: 4756110576)" に TMultCapProperty という TLabel 用のプロパティエディタが付いとったwww

  • FDELPHI で公開されていた改訂版は {$IFDEF DELPHI3} により、Delphi 4 以降では TMultCapProperty がインストールされない。
  • ダイアログ形式のプロパティエディタではない。オブジェクトインスペクタ中で \n を入力すると改行になるというものだった。
  • 書籍中には TMultCapProperty に関する記述がない (CD-ROM の readme.txt には記述がある)

上記理由により忘れ去られていたようです。探せば TMultCapProperty のようなひっそりと隠れているプロパティエディタがあるのかもしれませんね。

See Also:
[Delphi 関連書籍一覧]
http://ht-deko.minim.ne.jp/Delphi/books.html

DEKO
管理者
投稿数: 2649
Re: Re: 12/10 プロパティエディタを作ってみる (1/3)
on: 2013/12/12 18:57 Thu

オブジェクトインスペクタに入力したプロパティの値を加工してセットしたり、逆にプロパティの値を加工してオブジェクトインスペクタに表示したい場合には、

  • GetValue()
  • SetValue()

をオーバーライドします。詳細については DocWiki を参照してください。

[プロパティエディタの追加 (DocWiki)]
http://docwiki.embarcadero.com/RADStudio/ja/%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF%E3%81%AE%E8%BF%BD%E5%8A%A0

え?コンポーネントの作り方?それはこのフォーラムで既にやっているのでそちらを参照してください。

[コンポーネントの作り方の概要]
http://ht-deko.minim.ne.jp/delphiforum/?vasthtmlaction=viewtopic&t=22

[LightReport2 Unicode 版を 64bit 対応にしてみる]
http://ht-deko.minim.ne.jp/delphiforum/?vasthtmlaction=viewtopic&t=1222

[コンポーネント開発者ガイド:インデックス (DocWiki)]
http://docwiki.embarcadero.com/RADStudio/ja/%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E9%96%8B%E7%99%BA%E8%80%85%E3%82%AC%E3%82%A4%E3%83%89%EF%BC%9A%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9

DEKO
管理者
投稿数: 2649
12/13 ボロノイ/ドロネー図の描き方
on: 2013/12/13 04:18 Fri

[ボロノイ/ドロネー図の描き方]
http://www.luxidea.net/delphi-lab/delauney2d/

DEKO
管理者
投稿数: 2649
12/14 Bingo! シャッフル機能の実現。(年末ビンゴ大会までに間に合うのか・・?)
on: 2013/12/14 00:33 Sat

[Bingo! シャッフル機能の実現。(年末ビンゴ大会までに間に合うのか・・?)]
http://i65000.blogspot.jp/2013/12/bingo.html

DEKO
管理者
投稿数: 2649
12/15 全天球画像の俯瞰
on: 2013/12/15 16:53 Sun

[全天球画像の俯瞰]
http://www.luxidea.net/delphi-lab/sphericalview/

DEKO
管理者
投稿数: 2649
12/16 dfmファイルを弄る
on: 2013/12/16 16:13 Mon

[dfmファイルを弄る]
http://thinksoft.sblo.jp/article/82615231.html

DEKO
管理者
投稿数: 2649
12/17 コンポーネントエディタを作ってみる
on: 2013/12/17 00:01 Tue

{ これは Delphi Advent Calendar 2013 の 12/17 分の記事です }

前回はプロパティエディタの記事でしたので、今回はコンポーネントエディタの作り方です。

まずおさらいです。

  • コンポーネント
  • コンポーネントエディタ
  • プロパティエディタ

これらのファイル構成と関係は以下の図のようになります。

通常、コンポーネントとコンポーネントエディタ、プロパティエディタは "同じ製作者によるもの" なので、一緒に配布される事が多いのですが、プロパティエディタは先述の通り "後でポン付け" が可能です…しかしながら、コンポーネントエディタの場合には必ずしもポン付けできるとは限りません。

ちょっと例を出してみましょう。

例えば TStringGrid (VCL) ですが、動的にデータを表示させるのではなく、単なる表としてデータを表示させたい事もあると思います。しかしながら、オブジェクトインスペクタで TStringGrid の値を設定する事はできません…なので、TStringGrid 用のコンポーネントエディタを作ってみたいと思います。

では、コンポーネントエディタを…イヤマテ。それはいいけど、DFM にデータを保持できましたっけ?そうなんです、TStringGrid はデータを DFM に保持できないのです。これではコンポーネントエディタを作った所で意味がありません。

まずは TStringGrid を派生させて DFM にデータを保持できるようにしなければなりません。

{*******************************************************}
{ }
{ TEzStringGrid コンポーネント }
{ }
{*******************************************************}
unit uEzStringGrid;

interface

uses
Classes, Vcl.Grids;

type
TEzStringGrid = class(TStringGrid)
private
procedure ReadCellData(Reader: TReader);
procedure WriteCellData(Writer: TWriter);
protected
procedure DefineProperties(Filer: TFiler); override;
end;

implementation

{ TEzStringGrid }

procedure TEzStringGrid.DefineProperties(Filer: TFiler);
// セルデータの読み書きを登録
begin
inherited;
Filer.DefineProperty('CellData', ReadCellData, WriteCellData, True);
end;

procedure TEzStringGrid.ReadCellData(Reader: TReader);
// DFM からセルデータを読み込み
var
Col, Row: Integer;
begin
Reader.ReadListBegin;
try
while not Reader.EndOfList do
begin
Col := Reader.ReadInteger; // 列
Row := Reader.ReadInteger; // 行
Cells[Col, Row] := Reader.ReadString; // セルデータ
end;
finally
Reader.ReadListEnd;
end;
end;

procedure TEzStringGrid.WriteCellData(Writer: TWriter);
// DFM へセルデータを書き込む
var
Col, Row: Integer;
begin
Writer.WriteListBegin;
try
for Row := 0 to RowCount - 1 do
for Col := 0 to ColCount - 1 do
if Cells[Col, Row] <> '' then
begin
Writer.WriteInteger(Col); // 列
Writer.WriteInteger(Row); // 行
Writer.WriteString(Cells[Col, Row]); // セルデータ
end;
finally
Writer.WriteListEnd;
end;
end;

end.

 
具体的な実装はこのようになります。オリジナルのデータを DFM へ吐くようにするには DefineProperties() をオーバーライドします。TEzStringGrid という安直なコンポーネント名にツッコミを入れるのはやめてくださいね (^^;A

次に TEzStringGrid の設計時パッケージと実行時パッケージを作ってコンポーネントとして登録されるようにするのですが、既に別のスレッドで書いているので省略します。

[コンポーネントの作り方の概要]
http://ht-deko.minim.ne.jp/delphiforum/?vasthtmlaction=viewtopic&t=22

[LightReport2 Unicode 版を 64bit 対応にしてみる]
http://ht-deko.minim.ne.jp/delphiforum/?vasthtmlaction=viewtopic&t=1222

コンポーネントとして登録できるようになったら、次はいよいよコンポーネントエディタです。

{*******************************************************}
{ }
{ TEzStringGrid コンポーネントエディタ }
{ }
{*******************************************************}
unit uEzStringGridCompEditor;

interface

uses
Vcl.Controls, Vcl.Dialogs, Vcl.Forms, Vcl.Grids, DesignEditors;

type

TEzStringGridEditor = class(TComponentEditor)
// procedure Copy; override;
procedure Edit; override;
procedure ExecuteVerb(Index: Integer); override;
function GetVerb(Index: Integer): string; override;
function GetVerbCount: Integer; override;
end;

implementation

uses
uEzStringGrid,
frmuEzStringGridEditor;

resourcestring
StrMSG_CLEAR = 'クリアしてよろしいですか?';
StrMENU_EDIT = '編集(&E)...';
StrMENU_CLEAR = 'クリア(&C)';

{
procedure TEzStringGridEditor.Copy;
// クリップボードを拡張
// http://docwiki.embarcadero.com/RADStudio/ja/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%97%E3%83%9C%E3%83%BC%E3%83%89%E5%BD%A2%E5%BC%8F%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B
begin
inherited;
// Do Something
end;
}

procedure TEzStringGridEditor.Edit;
// コンポーネントの編集
// http://docwiki.embarcadero.com/RADStudio/ja/%E3%83%80%E3%83%96%E3%83%AB%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E6%99%82%E3%81%AE%E5%8B%95%E4%BD%9C%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B
var
Grid: TEzStringGrid;
begin
Application.CreateForm(TEzStringGridForm, EzStringGridForm);
try
Grid := TEzStringGrid(Self.Component);
if EzStringGridForm.ShowModal(Grid) = mrOK then
Designer.Modified;
finally
EzStringGridForm.Free;
end;
end;

procedure TEzStringGridEditor.ExecuteVerb(Index: Integer);
// コマンドの実行
// http://docwiki.embarcadero.com/RADStudio/ja/%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B
var
Col, Row: Longint;
Grid: TEzStringGrid;
begin
case index of
0:begin
// 編集
Edit;
end;
1:begin
// クリア
if not MessageDlg(StrMSG_CLEAR, mtConfirmation, [mbYES, mbNo], 0) = mrYES then
Exit;
Grid := TEzStringGrid(Component);
for Row := 0 to Grid.RowCount - 1 do
for Col := 0 to Grid.ColCount - 1 do
Grid.Cells[Col, Row] := '';
Designer.Modified;
end;
end;
end;

function TEzStringGridEditor.GetVerb(Index: Integer): string;
// メニューのキャプションを返す
// http://docwiki.embarcadero.com/RADStudio/ja/%E3%83%A1%E3%83%8B%E3%83%A5%E3%83%BC%E9%A0%85%E7%9B%AE%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B
begin
case Index of
0: result := StrMENU_EDIT;
1: result := StrMENU_CLEAR;
end;
end;

function TEzStringGridEditor.GetVerbCount: Integer;
// 追加メニュー (コマンド) 数を返す
// http://docwiki.embarcadero.com/RADStudio/ja/%E3%83%A1%E3%83%8B%E3%83%A5%E3%83%BC%E9%A0%85%E7%9B%AE%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B
begin
result := 2;
end;

end.

 
コンポーネントエディタは TComponentEditor から派生して、

  • Copy()
  • Edit()
  • ExecuteVerb()
  • GetVerb()
  • GetVerbCount()

これらをオーバライドして実装するだけです。Edit() メソッドがコンポーネントエディタのキモで、TComponentEditor.Component プロパティに対して読み書きして Designer.Modified() メソッドを呼び出せば変更が反映されます。ソースコードのコメントにそれぞれのメソッドのドキュメントへのリンクがありますので、詳細はそちらを確認してください。

{*******************************************************}
{ }
{ TEzStringGrid コンポーネント/エディタ登録用ユニット }
{ }
{*******************************************************}
unit uEzStringGridReg;

interface

uses
SysUtils, Classes, Types;

procedure register;

implementation

uses
Vcl.Controls,
DesignIntf,
uEzStringGrid, // TEzStringGrid コンポーネント
uEzStringGridCompEditor; // TEzStringGrid コンポーネントエディタ

procedure register;
begin
RegisterComponents('Additional', [TEzStringGrid]); // コンポーネントの登録
RegisterComponentEditor(TEzStringGrid, TEzStringGridEditor); // コンポーネントエディタの登録
end;

end.

 
最後にコンポーネント登録用ユニットに RegisterComponentEditor() でコンポーネントエディタを登録して完了です。パッケージをインストールし、コンポーネントパレットにある EzStringGrid を貼り付けてコンポーネントをダブルクリックするか、EzStringGrid を右クリックして [編集(E)...] を選択するとコンポーネントエディタが起動します。

繰り返しますが、DFM に保存されるプロパティだけを設定するコンポーネントエディタであれば "ポン付け" が可能ですが、そうでないものに関しては DefineProperties() をオーバーライドする必要があります。実際、コンポーネントエディタだけを作って登録もできるのですが DFM に値が保持されないので意味はありません。

この記事で紹介した EzStringGrid のアーカイブは以下にあります。

ダウンロード:
http://ht-deko.minim.ne.jp/software/EzStringGrid_100.zip

このコンポーネントエディタのデザイナ部分は "Delphi 2.0J コンポーネントセット 服部誠著 (ISBN: 4756110576)" に含まれる TComboGrid のデザイナをインスパイアした劣化コピーですので、正直ライセンス的に問題があるかもしれません。気になる方は (気になるでしょうけど) コンポーネントエディタの作り方のサンプル程度の利用に留めておくか、"Delphi 2.0J コンポーネントセット" を入手してください。

コンポーネントとコンポーネントエディタ/プロパティエディタをまとめて一つのユニットにする事もできますが、それだと設計時/実行時パッケージを分離できなくなります。コンポーネント (or プロパティ) エディタとエディタ用のフォームをまとめる事もできますが、メンテナンス性を考えるとできるだけユニットは分割した方がいいように思います。

EzStringGrid のアーカイブを解凍し EzStringGrid.groupproj を Delphi で開いて (XE2 以降で開けると思います)、最初の方にあった図と見比べてみればコンポーネントとパッケージ、コンポーネントエディタ / プロパティエディタの関係が見えてくると思います。

コンポーネントの作り方についてのドキュメントについては以下にリンクを貼っておきますので確認してみてください。

See Also:

[コンポーネント開発者ガイド (DocWiki)]
http://docwiki.embarcadero.com/RADStudio/ja/%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E9%96%8B%E7%99%BA%E8%80%85%E3%82%AC%E3%82%A4%E3%83%89%EF%BC%9A%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9

[プロパティエディタの追加 (DocWiki)]
http://docwiki.embarcadero.com/RADStudio/ja/%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF%E3%81%AE%E8%BF%BD%E5%8A%A0

[コンポーネント エディタの追加 (DocWiki)]
http://docwiki.embarcadero.com/RADStudio/ja/%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88_%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF%E3%81%AE%E8%BF%BD%E5%8A%A0

[コンポーネントの登録 (DocWiki)]
http://docwiki.embarcadero.com/RADStudio/ja/%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%AE%E7%99%BB%E9%8C%B2

[パッケージとコンポーネントの操作 (DocWiki)]
http://docwiki.embarcadero.com/RADStudio/ja/%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%A8%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%AE%E6%93%8D%E4%BD%9C%EF%BC%9A%E6%A6%82%E8%A6%81

[Delphi 関連書籍一覧]
http://ht-deko.minim.ne.jp/Delphi/books.html

DEKO
管理者
投稿数: 2649
12/18 Assertの話(3)
on: 2013/12/18 23:43 Wed

Coming soon…

ページ: 1 2 [3] 4
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.073 sec.