出来あがっている普通のフォームを、後から「継承後フォーム」として扱うには?

解決


もじゃもじゃ  2011-02-09 23:28:34  No: 39997

いつもお世話になります。

windows7
Delphi2007

新規作成→フォーム 等でフツーに作成したフォームが沢山あります。(Form1,Form2,Form3・・・)
コンポーネントの配置、コーディングはほぼ済んでいます。

ここに、処理の共通化を目的としたフォームを追加し、(BaseForm)
作成済みのフォーム達の継承元フォームとしたいのです。

1.正規の手段で作成した継承フォームのソースと見比べ、以下の変更を加えました。

pasファイルのフォームの宣言部
  TForm1 = class(TForm)
  ↓
  TForm1 = class(TBaseForm)

dfmファイルの先頭
  object Form1: TForm1
  ↓
  inherited Form1: TForm1

これで継承できた様に見えますが、正しいでしょうか?

2.他に変更すべき点として
  ・記述済みのイベントに inherited; をくっつける
が必要かと思っていますが、正しいでしょうか?また他にありますでしょうか?

3.ここまでファイルを無理矢理変更しましたが、IDEのメニュー等から継承を変更することはできるのでしょうか?

以上、よろしくお願いします。


テスト  2011-02-10 13:52:22  No: 39998

普通にそのフォームをリポジトリに追加したらダメなのかな?


もじゃもじゃ  2011-02-14 18:17:06  No: 39999

遅くなって申し訳ありません。

リボジトリというのを使ったことがないもので付け焼刃な知識ですので
間違いはご容赦ください。
リポジトリとは、ある程度設計したフォームを登録しておくと、
「次回新規作成時」、そのフォームが出来上がった状態から始められるという機能ではないですか?
しかも継承のように、親を変えると子も変わってくれないという認識です。

「新規作成時」ではなく、既に作成してしまったフォームに後付けしたいのです。

よろしくお願いします。


Mr.XRAY  2011-02-14 20:22:20  No: 40000

こんにちは,Mr.XRAYです.
どんな動作仕様が望みなのかは,よく理解できませんが,継承ということでしたら,
以下のようなことになるのではないかと思います.

   TAAA1 = class(TAA0);
   
この時,TAA0は継承元,TAA1は,TAA0を継承したクラスということになります.

フォームであれば,例えば,

(1) 新規プロジェクトを作成.Unit1.pasのForm1ができる.
(2) このTForm1を継承フォームを作成してテストするために,例えば
    TMemoとTButtonを配置する
(3) このプロジェクトに,新規にフォームを作成する.
    Unit2.pasのFrom2ができる.
(4) このフォームのusesにUnit1を追加して.以下のように変更する

  ---  変更前 ----
  type
    TForm2 = class(TForm)
    以下省略

  ---  変更後 ----
  type
    TForm2 = class(TForm1) // これでこのTForm2というフォームはTForm1を継承したフォームとなる

(5) Form1に戻って.[ファイル][ユニットを使う]でUnit2を選択する
(6) Button1のクリックイベントを以下のようにする.

   procedure TForm1.Button2Click(Sender: TObject);
   begin
     Form2.ShowModal;
   end;
   
(7) コンパイルしてForm1のButton1をクリックする
(8) Form2には,継承元のTMemoとTButtonが表示される

リポジトリに登録したフォームは,そのまま使用することも,継承して使用することもできます.
参考記事.以下の図6参照

http://mrxray.on.coocan.jp/Delphi/CompoInstall/Repository2007.htm#04

継承フォームは,この他,現在作成中のプロジェクトのフォームからも,
[新規作成][その他][継承可能項目]から選択して作成できます.


Mr.XRAY  2011-02-14 20:34:03  No: 40001

長々と書いていますが,つまり,継承というのは,

   TAAA1 = class(TAA0);
   
とするだけのことです.
フォームの場合,同じフォームを使い回しする時には,リポジトリに登録しておくと
便利だということです.
また,コンポーネントも,ほとんどが,他のコンポーネントから継承して作成しますが,
これも,継承したコンポーネントを,コンポーネントとして登録しておくと使いやすい
ということです.


tor  2011-02-14 22:35:15  No: 40002

質問者さんは別に新しくフォームを継承するやり方を聞いているわけではなくて、
すでに作ってあるフォームの継承元を変更したいんですよね?

であれば、最初の投稿にある
・クラスの宣言部の書き換え
・dfmの冒頭をinheritedに書き換え
でいいのではないかと思います。
(私も後付で継承元を変える必要に迫られたときはそうしています)

一応注意すべき点として、継承先と継承元に同じコンポーネントがある場合
継承元のプロパティを変更しても、継承先には変更が反映されないことがあります。
このような場合、継承先でコンポーネントを右クリックして「継承元の値に戻す」を選べば、また同期するようになります。
(もちろん、継承先で意図的にプロパティを別の値にしている場合は
継承元の値に戻してはいけません。ケースバイケースで判断することになります)

>・記述済みのイベントに inherited; をくっつける
というのは必ずしも必要とは限りません。
継承元のフォームでもそのイベントハンドラを実装しているけれど、
継承先ではそれを上書きして別の動作をさせたい、という場合にはinheritedは不要です。


もじゃもじゃ  2011-02-14 22:37:26  No: 40003

お世話になります。

> 長々と書いていますが,つまり,継承というのは,
>    TAAA1 = class(TAA0);
> とするだけのことです.

1番の質問が○ということでよいでしょうか。
ご提示頂いたサンプルではdfmファイルにinheritedが付きませんが
無くても動くのですね。
(そのままだと設計画面が継承元のデザインを反映してくれないようだったので修正しました)

> リポジトリに登録したフォームは,そのまま使用することも,継承して使用することもできます.
リポジトリ元をコピーして自プロジェクトに持ってくるのか、
リポジトリ元を参照してそれを継承したフォームを作るのか、の違いですね。
勉強になります。


もじゃもじゃ  2011-02-14 22:44:42  No: 40004

torさん
お世話になります。

> 質問者さんは別に新しくフォームを継承するやり方を聞いているわけではなくて、
> すでに作ってあるフォームの継承元を変更したいんですよね?
その通りです…お手数かけます。

ご投稿頂いた内容、納得です。ありがとうございます。

やはりIDEからは継承を後付けで変更出来ないようですね。
しばらく他の方のご意見をお待ちした後、解決済みにしたいと思います。


Mr.XRAY  2011-02-14 23:42:46  No: 40005

こんにちは.

大変失礼しました.
「設計時」に継承状態を反映するには,
.dfmファイルに設定がないとどうしようもないですね.


もじゃもじゃ  2011-02-15 17:59:54  No: 40006

ご回答頂いた皆さんありがとうございました。
解決に致します。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加