MDIの子フォーム

解決


りゅう  2013-04-11 17:53:02  No: 44250  IP: 192.*.*.*

MDIの子フォームから別の子フォームのあるeditのtextを変更する事はできるのでしょうか?

procedure 子フォーム1.BTNCLICK(Sender: TObject);
begin
   子フォーム2.BUHINNO.TEXT := 'HELLO';
end;

上記でコンパイルは通るのですが、実行時にエラーとなってしまいます。
どなたかよろしくお願いします。

編集 削除
Mr.XRAY  URL  2013-04-11 18:19:54  No: 44251  IP: 192.*.*.*

>MDIの子フォームから別の子フォームのあるeditのtextを変更する事はできるのでしょうか?

MDI アプリの子フォームも,普通のフォームと同じようにアクセスできまよ.
もちろん,対象の子フォームが作成されていればの話ですが.

編集 削除
Mr.XRAY  URL  2013-04-11 18:22:41  No: 44252  IP: 192.*.*.*

>MDI アプリの子フォームも,普通のフォームと同じようにアクセスできまよ.

もちろん,MDI の子フォーム同士もです.
当然,対象の子フォームが存在しなければできません.

編集 削除
りゅう  2013-04-11 18:30:10  No: 44253  IP: 192.*.*.*

さっそくの回答ありがとうございます。

MDIの子フォーム同士ですと実行時にeaccessviolationエラーとなってしまいます。子フォームは2つ存在してます。

編集 削除
 2013-04-11 18:45:59  No: 44254  IP: 192.*.*.*

具体的に、どのように参照していますか。
その処理を起こしている子フォームのイベントと実際の処理内容を
提示されると、原因ははっきりすると思います。

編集 削除
Mr.XRAY  URL  2013-04-11 18:58:36  No: 44255  IP: 192.*.*.*

レスして,やりとりしている時間がもったいないので,サンプル作りました.
動作確認環境は,Windows 7 U64(SP1) + Delphi XE です.

http://mrxray.on.coocan.jp/Delphi/zipothers/MDI_TEST.zip

参考リンク
http://ht-deko.minim.ne.jp/tech045.html#tech095

編集 削除
Mr.XRAY  URL  2013-04-11 19:12:10  No: 44256  IP: 192.*.*.*

>レスして,やりとりしている時間がもったいないので,サンプル作りました.

こういうやり方は,本当は反則技です.
レスのやりとりで,お互いが勉強していくのが,このような掲示板の利用方法です.
良い子の皆さんは真似しないでください.

編集 削除
りゅう  2013-04-11 19:14:43  No: 44257  IP: 192.*.*.*

サンプルプログラムありがとうございました。
動作も確認しました。
自分の環境でも同じように作成し問題無く動作しました。

ただ、
子フォームの自動作成は行わずにメイン画面から
子フォームを作成するとエラーになってしまいます。

WINDOWS XP DELPHI2006の環境です。

プロジェクトFTEST
FTEST1 fsMDIForm
FTEST2 fsMDIChild    自動作成フォームから使用可能フォームへ
FTEST3 fsMDIChild    自動作成フォームから使用可能フォームへ

procedure TFTEST1.BTNCLICK(Sender: TObject);
begin
   CHILD_OPEN;

end;

PROCEDURE TFTEST1.CHILD_OPEN;
VAR
   CFRM2 : TFTEST2;
   CFRM3 : TFTEST3;
BEGIN
   CFRM2 := TFTEST2.CREATE(APPLICATION);
   CFRM3 := TFTEST3.CREATE(APPLICATION);

END;

procedure TFTEST3.Button1Click(Sender: TObject);
begin
  FTEST3.Edit2.Text := 'テストです';
end;

何度もやり取り申し訳ありません。

編集 削除
Mr.XRAY  URL  2013-04-11 19:34:13  No: 44258  IP: 192.*.*.*

提示のコードでは,間違いなくエラーとなりますね.
で,これから説明を考えます.
それまでに,他の方からレスがあるかも知れません.

>子フォームを作成するとエラーになってしまいます。

の参考リンク
http://mrxray.on.coocan.jp/Delphi/Others/RunError.htm#03

編集 削除
 2013-04-11 19:36:04  No: 44259  IP: 192.*.*.*

FTest3にはオブジェクト代入されてないですね。
だからアクセス違反が起こる。何も参照してないのですから、
アクセス違反が起こって当然だと思います。
もう一度よく、どの変数が何を参照しているか確認すれば、
すぐ解決するでしょう。

編集 削除
りゅう  2013-04-11 19:54:33  No: 44260  IP: 192.*.*.*

皆様色々ありがとうございます。

間違いがありました.

procedure TFTEST3.Button1Click(Sender: TObject);
          ↓↓↓↓です
procedure TFTEST2.Button1Click(Sender: TObject);
begin
  FTEST3.Edit2.Text := 'テストです';
end;

編集 削除
Mr.XRAY  URL  2013-04-11 20:25:52  No: 44261  IP: 192.*.*.*

>FTest3にはオブジェクト代入されてないですね。
>だからアクセス違反が起こる。何も参照してないのですから、
>アクセス違反が起こって当然だと思います。

ですね.

>もう一度よく、どの変数が何を参照しているか確認すれば、すぐ解決するでしょう。

なんですが,こんなところですか ?
コードでの,子フォームの具体的宣言が不明なので,通常のフォームで説明します.

Form2: TForm2;

というのがあったとします.この Form2 というのは TForm2 という「型」の
具体的なオブジェクト,インスタンス(実体) です.

自動作成フォームにしておくと,このインスタンスは自動的に生成されます.
一方,使用可能フォームにした場合は,コードで,このインスタンスを生成しなければなりません.

提示のコードの中に

  CFRM2 := TFTEST2.CREATE(APPLICATION);
  CFRM3 := TFTEST3.CREATE(APPLICATION);

というのがあります.これは,確かに,TFTEST2, TFTEST3 の具体的なインスタンスを生成
してはいますが,そのインスタンスの名前は,CFRM2, CFRM3 となっています.
しかも,これらは,ローカルな変数になってしまっています.

ローカルな変数とは,CHILD_OPEN というメソッド内だけで有効になっているということです.
りゅうさんの場合,

  FTEST3.Edit2.Text := 'テストです';
  
とするわけですから,以下のように,FTEST2, FTEST3 という変数名で,
TFTEST2 と TFTEST3 のインスタンス(実体)を生成する必要があります.

  FTEST2 := TFTEST2.CREATE(APPLICATION);
  FTEST3 := TFTEST3.CREATE(APPLICATION);
  
>間違いがありました.  

コードは,実際のプログラムのをコピペする方がいいですね.
間違いの元です.
そのためには,実際に開発中のアプリそのものではなく,エラーが発生する,
最低限のプロジェクトを作成してテストすることです.
そうすると,他の人も見慣れた,Form1 とか Form2 という名前になって,
もしかしたら,掲示板を観ている人がテストしてくれるかも知れません.
特別な名前になっていると,面倒なのでやってくれないかも知れません(多分やらないでしょう)
こうやって,説明を書くのも面倒ですもん.

  
# 昔は Fortran で大文字ばっか使っていたけど,Delphiで全て大文字というのは
# なんか違和感がありますね (笑)

編集 削除
りゅう  2013-04-12 08:07:54  No: 44262  IP: 192.*.*.*

ありがとうございました。
解決しました。

編集 削除
Mr.XRAY  URL  2013-04-12 08:33:52  No: 44263  IP: 192.*.*.*

>解決しました。

それは良かったです.
で,何をどうやることによって何が解決したのでしょうか ?
もし,差支えなければ教えて頂けませんか ?
少なくとも,どんなエラーだったのかでも分かれば,後で同じような質問が
あった場合の参考になるのですが・・・

会社から機密事項と言われているのであればあきらめます(笑).

編集 削除
Mr.XRAY  2013-04-12 08:37:45  No: 44264  IP: 192.*.*.*

>少なくとも,どんなエラーだったのかでも分かれば,後で同じような質問が

人によっては,問題解決の際に,エラーの内容でネットや掲示板を検索する
方もいます.

編集 削除
Mr.XRAY  URL  2013-04-12 16:37:47  No: 44265  IP: 192.*.*.*

テストしてみました.
質問された方のコードとは違うと思いますが.
動作確認環境も質問された方と違い,Windows 7 U64(SP1) + Delphi XE です.


------------  メインフォーム Unit1.pas のコード  ---------------------------
              FormStyle を fsMDIFormにしておく

var
  FTEST1: TFTEST1;

implementation

uses Unit2, Unit3;

{$R *.dfm}

{ TTFEST1 }

procedure TFTEST1.Button1Click(Sender: TObject);
begin
  CHILD_OPEN;
end;

procedure TFTEST1.CHILD_OPEN;
VAR
   CFRM2 : TFTEST2;
   CFRM3 : TFTEST3;
BEGIN
   CFRM2 := TFTEST2.CREATE(APPLICATION);
   CFRM3 := TFTEST3.CREATE(APPLICATION);
end;


------------  子フォーム Unit2.pas のコード  ---------------------------
              自動生成から場外し,FormStyle を fsMDIChildにしておく

var
  FTEST2: TFTEST2;

implementation

uses Unit3;

{$R *.dfm}

procedure TFTEST2.Button1Click(Sender: TObject);
begin
  FTEST3.Edit2.Text := 'テストです';
end;


------------  子フォーム Unit2.pas のコード  ---------------------------
              自動生成から場外し,FormStyle を fsMDIChildにしておく
              TEdit (Edit2) を配置しているだけ

var
  FTEST3: TFTEST3;

implementation

{$R *.dfm}

end.  


コードは以上です.
コンパイルして実行して,メインフォームのボタンをクリック
子フォームのボタンをクリックすると,以下のエラーが発生します.
「オブジェクトが何とかという」を期待したのですが,そうですよね.ハハハッ (汗)

---------------------------
モジュール 'Project1.exe' のアドレス 004B0C57 でアドレス 00000388 に対する読み取り違反がおきました。.
---------------------------

編集 削除