MDIの子フォーム

解決


りゅう  2013-04-12 02:53:02  No: 44250

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

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

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


Mr.XRAY  URL  2013-04-12 03:19:54  No: 44251

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

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


Mr.XRAY  URL  2013-04-12 03:22:41  No: 44252

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

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


りゅう  2013-04-12 03:30:10  No: 44253

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

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


  2013-04-12 03:45:59  No: 44254

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


Mr.XRAY  URL  2013-04-12 03:58:36  No: 44255

レスして,やりとりしている時間がもったいないので,サンプル作りました.
動作確認環境は,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-12 04:12:10  No: 44256

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

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


りゅう  2013-04-12 04:14:43  No: 44257

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

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

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-12 04:34:13  No: 44258

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

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

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


  2013-04-12 04:36:04  No: 44259

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


りゅう  2013-04-12 04:54:33  No: 44260

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

間違いがありました.

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


Mr.XRAY  URL  2013-04-12 05:25:52  No: 44261

>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 17:07:54  No: 44262

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


Mr.XRAY  URL  2013-04-12 17:33:52  No: 44263

>解決しました。

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

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


Mr.XRAY  2013-04-12 17:37:45  No: 44264

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

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


Mr.XRAY  URL  2013-04-13 01:37:47  No: 44265

テストしてみました.
質問された方のコードとは違うと思いますが.
動作確認環境も質問された方と違い,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 に対する読み取り違反がおきました。.
---------------------------


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

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






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