TForm1とTForm2からTForm_Selを呼び出したとします。
Tform_SelはTForm_Editを呼び出します。
このときTForm_EditはもともとTForm1から呼ばれたものかTForm2から呼ばれたものかをTForm_Edit内で判別する方法ありますか?
引数やグローバル変数等では判断せず、呼び出し元のクラス名?とかで判別したいです。
よろしくお願いします。
こんにちは.
あるフォームから,別の,他のフォームを「呼び出す」というのが,どんな動作を
意味するのか,よくわからないのですが.
どのように呼び出すのでしょうか?
同じく「呼び出す」の意味がわからないのですが・・・
procedure TForm1.Button1Click(Sender: TObject);
var
formsel: TForm_Sel;
begin
formsel := TForm_Sel.Create(Self);
formsel.ShowModal;
formsel.Free;
end;
procedure TForm2.Button1Click(Sender: TObject);
var
formsel: TForm_Sel;
begin
formsel := TForm_Sel.Create(Self);
formsel.ShowModal;
formsel.Free;
end;
procedure TForm_Sel.Button1Click(Sender: TObject);
var
formEdit:TForm_Edit;
begin
formEdit := TForm_Edit.Create(Owner); //Case.1
//formEdit := TForm_Edit.Create(Self); //Case.2
formEdit.ShowModal;
formEdit.Free;
end;
procedure TForm_Edit.Button1Click(Sender: TObject);
begin
ShowMessage(Owner.ClassName); //Case.1
//ShowMessage(Owner.Owner.ClassName); //Case.2
end;
「呼び出す」とはShowModalです。
TForm1
TForm2
TForm_Sel
TForm_Edit
は全てApplication.CreateFormにて生成されたFormです。
この場合通りすがりさんのようにできませんよね?
このときはOwner.ClassNameとしてもTApplicationが返ってきてしまっていたので、困っていました。
現在このような状況です
すでに生成済みの「Form_Edit」は「Form1」や「Form2」から
ShowModalにて呼び出されるが
「Form_Edit」側の処理で、「Form1」/「Form2」の
どちらから呼び出されたかが知りたい。
で、よろしいでしょうか?
クラス名で、しっかりと判定したいのであれば、
クラスの管理も「Application.CreateForm」ではなくて
自分でしないと・・・
クラスを管理しない場合、自分なら簡単にこんな感じで
クラス名に関係なく数値で管理しちゃいますけどね
// Form1から呼び出し
formSel.Tag := 1;
formSel.ShowModal;
// Form2から呼び出し
formSel.Tag := 2;
formSel.ShowModal;
TForm_SelからTForm_Editを呼ぶところで
formEdit.Tag := Tag;
formEdit.ShowModal;
// TForm_Edit側での判定
if (tag = 1) then begin
end;
例えば,以下のような方法もあります.参考までに.
>TForm_Selを呼び出したとします
TForm_Selを呼び出したとします ---> TFrom_SelをShowModalで表示します.ですね.
具体的な用語を使用した方がいいですよね.皆様... (えっ!? 大きなお世話...? )
それと,環境を忘れずに(また,書いてしまった... 汗)
ShowModal を実行したフォームが非アクティブになることを利用した方法です.
Form1, Form2, Form3 を新規プロジェクトで作成します.
-------------------- Form1 --------------------
メインフォームです.
TButtonを2つと,TEditを配置し,Buttonのクリックを以下のようにします.
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.ShowModal;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Form3.ShowModal;
end;
-------------------- Form2 --------------------
TButtonを1つと,TEditを配置し,Buttonのクリックを以下のようにします.
procedure TForm1.Button1Click(Sender: TObject);
begin
Form3.ShowModal;
end;
-------------------- Form3 --------------------
何も配置しません.以下のコードにします.
unit Unit3;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm3 = class(TForm)
Memo1: TMemo;
private
{ Private 宣言 }
protected
procedure WMActivate(var Message: TWMActivate); message WM_ACTIVATE;
public
{ Public 宣言 }
end;
var
Form3: TForm3;
implementation
uses Unit1, Unit2;
{$R *.dfm}
//=============================================================================
// このフォームがアクティブになる時のWM_ACTIVATEメッセージ処理
// このフォームがアクティブになる時に,非アクティブになるウィンドウを検出
// 検出可能なのは,このフォームが属するアプリのものに限る
//=============================================================================
procedure TForm3.WMActivate(var Message: TWMActivate);
var
Control : TWinControl;
begin
if Message.Active <> WA_INACTIVE then begin
Control := FindControl(Message.ActiveWindow);
//他のアプリから[Alt]+[TAB]でアクティブになる時はControl = nilとなる
if Control <> nil then begin
if Control.Name = 'Form1' then begin
Form1.Edit1.Text := 'Form1 成功!!';
end else
if Control.Name = 'Form2' then begin
Form2.Edit1.Text := 'Form2 成功!!';
end;
end;
end;
end;
end.
動作確認環境は,質問された方と多分同じでしょう.
んだば、全部自動生成で、Unit3がForm_Selのユニットの場合・・・
uses
Unit1, Unit2, Unit3;
procedure TForm_Edit.Button1Click(Sender: TObject);
var
nwh: THandle;
begin
if Form1.Visible and Form2.Visible then begin
nwh := GetNextWindow(Form_Sel.Handle, GW_HWNDNEXT);
while (nwh <> 0) and
(nwh <> Form1.Handle) and (nwh <> Form2.Handle) do begin
nwh := GetNextWindow(nwh, GW_HWNDNEXT);
end;
if nwh = Form1.Handle then ShowMessage('Form1ですよ')
else if nwh = Form2.Handle then ShowMessage('Form2ですよ');
end
else if Form1.Visible then ShowMessage('Form1ですよ')
else if Form2.Visible then ShowMessage('Form2ですよ');
end;
スミマセン.間違えました.
私の提示したコードは,全く思い違いをしていました.
>TForm1とTForm2からTForm_Selを呼び出したとします。
>Tform_SelはTForm_Editを呼び出します。
TForm1またはTForm2で,
TForm_Sel.ShowModal;
TForm_Selで
TForm_Edit.ShowModal;
このとき,TForm_Selが,どのフォーム(TForm1またはTForm2)から表示されたか?
でしたね.つまり,2つ前の祖先ですね.
失礼しました.
FormShow で Application.ActiveFormHandle
いろいろな方法があるものですね・・・(すごい)
わたしは、普段こんな感じです・・・
まぁローカル変数も使ってはいけないなら、お呼びじゃないですが・・・(^^;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Form_Sel.Inst := Cardinal(Form1);
Form_Sel.ShowModal;
end;
**************************************************
type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
Form_Sel.Inst := Cardinal(Form2);
Form_Sel.ShowModal;
end;
**************************************************
type
TForm3 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
Inst : Cardinal;
end;
procedure TForm3.Button1Click(Sender: TObject);
begin
Form_Edit.Inst := Inst;
Form_Edit.ShowModal;
end;
**************************************************
type
TForm_Edit = class(TForm)
Edit1: TEdit;
procedure FormShow(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
Inst : Cardinal;
end;
procedure TForm_Edit.FormShow(Sender: TObject);
begin
Edit1.Text := TForm(Inst).Name;
end;
皆様ありがとうございます。
現在色々な方法で試しています。
私なりに判断ですが、最悪Tform_Selでどちらかから呼び出されたか判断できれば、あとは全てTform_SelでTForm_Editに処理をしてしまえばよいと思いました。
なぜグローバル変数を使いたくないかというとプログラマ自身が設定のし忘れ等で、TForm_Editが思わぬ表示や動作にならないようにしたいからです。
なので Tform_Selでハンドル等で判断できればもともとあるForm1,2は変数の設定を気にせずTform_Selを呼べるわけです。
そこで、通りすがりさんの
GetNextWindowをTform_Selで行いましたが、Form1,2のハンドルを取得できませんでした。↓
GetNextWindow(self.Handle, GW_HWNDNEXT);
TForm1はShowModalでTForm_Selを読んでいるのですが、この場合GetNextWindowは使えると思ったのですが...
また、KHE00221さんのActiveFormHandleはFormsに存在しませんので、使用できませんでした。(Delphi7です)
>ActiveFormHandleはFormsに存在しませんので、
GetActiveWindowで代用できるかもです。
みなさん色々な意見ありがとうございました。
1つのことに対してこれだけアプローチの方法があるのだと勉強になりました。
やりたいことはGetActiveWindowでできましたので、解決とします。
ありがとうございます。
ツイート | ![]() |