アクティブのフォーム以外を全て最小化する

解決


久美子  2009-11-28 11:28:05  No: 36330  IP: 192.*.*.*

エクスプローラからのドラッグ&ドロップを使用するプログラムを作成しています。画面を広く使いたいため、現在開いている以外のFormを閉じたいのですが、簡単に済ます方法は無いでしょうか?
イメージとしては
MainMenuForm
⇒Form2.ShowModal
  ⇒Form3.ShowModal
    ⇒Form4.ShowModal
の状態で、Form4以外を最小化して目的のフォルダーを開きたい。
またForm4を閉じるときには、Form3以前を通常のサイズにしたい。
よろしくお願いします。

編集 削除
 2009-11-28 12:10:07  No: 36331  IP: 192.*.*.*

普通に閉じたほうが早いと思いますが、閉じられない理由はあるのでしょうか。
普通に最小化で対応するなら、ShowModalではなくShowで開くべきだと思います。

編集 削除
KHE00221  2009-11-28 12:54:19  No: 36332  IP: 192.*.*.*

こうかね
Form1.Hide;
Form2.Hide;
Form3.Hide;
Form4.ShowModal;
Form3.Show;
Form2.Show;
Form1.Show;

編集 削除
久美子  2009-11-28 13:05:17  No: 36333  IP: 192.*.*.*

ありがとうございました。
Form4はプログラムの数箇所から呼び出されることになります。
できれば、完結に書きたいのですが。
Application.Minimizeでは、全てのフォームが最小化されてしまいますが、似たようにスマートに1つのコマンドで自分以外のFormを最小化することはできないのでしょうか。

編集 削除
 2009-11-28 14:43:07  No: 36334  IP: 192.*.*.*

そこまで都合のよい関数はないと思います。
複数個所から呼び出すということであれば、関数化しておいてそれを
呼び出せば問題はないかと。

編集 削除
D  2009-11-28 15:04:07  No: 36335  IP: 192.*.*.*

こんなのは

procedure TForm4.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to Screen.FormCount-1 do begin
    if (Screen.Forms[i] <> Self) then begin
      Screen.Forms[i].Visible := False;
    end;
  end;
end;

procedure TForm4.FormDestroy(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to Screen.FormCount-1 do begin
    if (Screen.Forms[i] <> Self) then begin
      Screen.Forms[i].Visible := True;
    end;
  end;
end;

編集 削除
久美子  2009-11-28 16:22:05  No: 36336  IP: 192.*.*.*

皆さんありがとうございます
Dさんのソースを試したのですが、Screen.Forms[i].Visible := True;によって、プログラムで使用しているけれど、まだ開いていない全てのFormまで開いてしまいました。
でも、Screen.Forms[i]については大変参考になりました。いつか使えそうな気がします。

編集 削除
それなら  2009-11-28 16:44:20  No: 36337  IP: 192.*.*.*

Visibleプロパティを切り替えるのではなくて、
WindowStateプロパティを切り替えればいいんじゃないの?

編集 削除
D  2009-11-28 17:14:27  No: 36338  IP: 192.*.*.*

>プログラムで使用しているけれど、まだ開いていない全てのFormまで開いてしまいました。

  では、単純に。


procedure TForm4.FormCreate(Sender: TObject);
begin
  Form1.Show;
  Form2.Show;
  Form3.Show;
end;

procedure TForm4.FormDestroy(Sender: TObject);
begin
  Form1.Hide;
  Form2.Hide;
  Form3.Hide;
end;

編集 削除
D  2009-11-28 17:21:04  No: 36339  IP: 192.*.*.*

あ、Form1じゃなくてMainMenuFormだったか。
おまけにShowとHideが逆だった。

procedure TForm4.FormCreate(Sender: TObject);
begin
  MainMenuForm.Hide;
  Form2.Hide;
  Form3.Hide;
end;

procedure TForm4.FormDestroy(Sender: TObject);
begin
  MainMenuForm.Show;
  Form2.Show;
  Form3.Show;
end;

編集 削除
よくわからんが  2009-11-28 19:28:01  No: 36340  IP: 192.*.*.*

「ShowModal」は「Show」でも要件を満たすのかが分からない。
「最小化」は「非表示」でも用をなすのかも分からない。
これらによっては、そもそもD氏の提示してくれているコードそのものが
無駄になるんだが。
用が足りるとして、この程度であれば、Visibleの概念1つで自己解決でき
る程度の問題だと思うが。一体何をしたいんだ?

編集 削除
ttt  2009-11-28 20:21:43  No: 36341  IP: 192.*.*.*

> プログラムで使用しているけれど、まだ開いていない全てのFormまで開いてしまいました。
そういう要件あるんだったら、Ownerで呼び出し元をたどっていけばいいんじゃないの。
フォームが自動作成だったらOwnerがApplicationになるから使えないけど。

Dさんの最初の方法でも、もともとVisibleだったかどうかをTagにでも覚えさせておくとか
工夫の余地はあるんじゃない?

編集 削除
D  2009-11-29 00:47:15  No: 36342  IP: 192.*.*.*

ちょっと工夫してみました。


procedure FormVisible(Forms: array of TForm; bVisible: Boolean);
var
  i: Integer;
begin
  for i := 0 to High(Forms) do begin
    Forms[i].Visible := bVisible;
  end;
end;

procedure TForm4.FormCreate(Sender: TObject);
begin
  FormVisible([MainMenuForm, Form2, Form3], False);
end;

procedure TForm4.FormDestroy(Sender: TObject);
begin
  FormVisible([MainMenuForm, Form2, Form3], True);
end;


>画面を広く使いたいため、現在開いている以外のFormを閉じたい
  とのことなので最小化よりはKHE00221さんがやってるように見えなくした方が良かろうと思いVisibleのセットにしましたが、最小化の方が良いのであれば

  for i := 0 to High(Forms) do begin
    if (bVisible) then begin
      Forms[i].WindowState := wsNormal;
    end else begin
      Forms[i].WindowState := wsMinimized;
    end;
  end;

のようにするとか。

編集 削除
KHE00221  2009-11-29 11:58:39  No: 36343  IP: 192.*.*.*

FormCreateの中で他のフォームの
WindowState := wsMinimized;とかHide
とか実行される?

編集 削除
KHE00221  2009-11-29 12:10:48  No: 36344  IP: 192.*.*.*

あとShowModal元のフォームを最小化するとタスクバーには
格納されないで左下に最小化されるだけだよね

編集 削除
最小化でOK  2009-11-29 12:39:15  No: 36345  IP: 192.*.*.*

>Form4以外を最小化して...
質問者が最初にこう書いているし、質問のタイトルも「アクティブのフォーム以外を全て最小化する」だし、
FormCreateにおいて、Screen.Forms[i]での他のフォームの最小化も問題なく実行されるからいいんじゃないのかな?
まだ開いていないフォームのWindowStateを変えても実害はないし。

編集 削除
ダソク  2009-11-29 12:51:27  No: 36346  IP: 192.*.*.*

Form4を実行時に作成するのではなく、コンパイル時に自動生成してる場合は、
OnCreate,OnDestroyでなくて、OnShow,OnCloseイベントだね。

編集 削除
久美子  2009-11-29 14:29:57  No: 36347  IP: 192.*.*.*

皆さんありがとうございました。
Dさんのアイディアを参考にして、かつ、まだ開いていない全てのFormまでが開かないようにするため、次のようにして解決をしました。
今後ともよろしくお願いします。

implementation

var
  j: Integer;

procedure TPhotSetForm.FormShow(Sender: TObject);
var
  i: Integer;
begin
  j := 1;
  for i := 0 to Screen.FormCount-1 do
  begin
    if (Screen.Forms[i] <> Self)
    then begin
      if Screen.Forms[i].Visible = True
      then begin
        arrForms[j] := Screen.Forms[i];
        j := j+1;
        Screen.Forms[i].Visible := False;
      end;
    end;
  end;
end;

procedure TPhotSetForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
  i: Integer;
begin
  for i := 1 to j-1 do  arrForms[i].Visible := True;
end

編集 削除
久美子  2009-11-29 14:32:30  No: 36348  IP: 192.*.*.*

追加  配列の宣言が抜けていました。

implementation
var
  j: Integer;
  arrForms: Array[1..256] of TForm;

編集 削除