タイマーでのフォーム操作のやりかた


教えてください  2004-07-08 16:04:06  No: 84458  IP: [192.*.*.*]

お世話になります。

WindowsXP,VB6の環境です。


フォームを表示して、ボタンを押すと別のフォームを起動し、
20秒別のフォームを表示後、2つともフォームを閉じるという
動作をしたいのですが、指定の秒数だけフォームを表示し、
指定時間経過後、フォームを閉じる(しかも別のフォームも一緒に閉じる)
動作は可能でしょうか?

よろしくお願いします。

編集 削除
ちょこ  2004-07-08 16:34:48  No: 84459  IP: [192.*.*.*]

試す環境がなくて自信がないですが、
form呼び出し時にOwnerFormへ呼び出し元formを設定をすると、
呼び出し元が落ちると呼び出されたformも同時に落ちたような記憶があります。

いい加減な回答でごめんなさいヽ(;´д`)ノ

編集 削除
S.S  2004-07-08 16:57:39  No: 84460  IP: [192.*.*.*]

簡単に考えて・・・
とりあえずボタン押下で呼び出されたフォームはTimerで20秒後にUnloadするように設定してください。
呼び出し元はボタン押下時から20秒後に、両方のフォームがUnloadするように
設定してください。
ただそれだけです。

編集 削除
あいうえおにぎり  2004-07-08 17:31:51  No: 84461  IP: [192.*.*.*]

===== フォーム1のコード =====
Private Sub Command1_Click()
    'コマンドボタン押下でForm2を表示します
    Form2.Show
End Sub

フォーム2にタイマーコントロールを貼り付けて、

===== フォーム2のコード =====
Private Sub Form_Load()
    'タイマーの間隔を20秒にします
    Timer1.Interval = 20000
End Sub
Private Sub Timer1_Timer()
    '2つのフォームを閉じます
    Unload Form1
    Unload Form2
End Sub

こんな感じで

編集 削除
ちょこ  2004-07-08 17:37:45  No: 84462  IP: [192.*.*.*]

やっぱり、その方がいいですよねw

あんな提案をした私は小細工好き(そんな自分が大好きだけど、のちのメンテ者にはいい迷惑ヽ(;´д`)ノ

編集 削除
教えてください  2004-07-08 19:12:38  No: 84463  IP: [192.*.*.*]

ちょこ様、
S.S様、
あいうえおにぎり様、
とても親切にありがとうございます。

まだまだ初心者なので、ちょこ様に教えていただいた方法は難しかったので、
S.S様とあいうえおにぎり様のご意見の両方ともUnload を指定する方法で、
タイマーのIntervalを20秒に設定して実行したら両方ともフォームを閉じれました。

さらに処理を追加してみたいのですが、
フォーム1からボタンを押したタイミングで他のプログラムのEXEをShell関数で
呼び出し、呼び出すまでの間にフォーム2を表示、指定のEXEファイルがLoad
できたらフォーム2に「読込みました」とラベルに表示し、フォーム1とフォーム2を
両方Unloadするということを実行したいです。

ご教授して頂いた方法でフォームを2つ閉じることはできたのですが、
タイマーをつかってShell関数を使用し、EXEが開くまでの間というのが
できませんでした。

同時にEXEを呼び出している間のみフォーム2を表示するということは
不可能でしょうか?

ご教授お願いします。

編集 削除
S.S  2004-07-09 00:38:34  No: 84464  IP: [192.*.*.*]

要するに、他のアプリケーションが起動するまでフォームを維持し、
起動したかどうかの確認を取りたい、ってことでしょうか?
上記の件で良ければ
  Dim wObj As Object
  For Each wObj In UserForms
      'wObj.Nameで起動中のフォーム名を取得
      'wObj.Captionで起動中のフォームのキャプションを取得
  Next wObj
で現在起動中のフォームの一覧が取得できますので、該当フォームが
起動するまでTimerで見てやれば良いと思いますよ。
けれど、無限ループ(Timerで)に陥る可能性がありますので、別Timerで
1分程度監視し、1分を経過しても起動してこなければエラーを返してやる
方が無難かと思います。

編集 削除
教えてください  2004-07-09 09:24:50  No: 84465  IP: [192.*.*.*]

S.S様
ありがとうございます。

条件はS.S様の仰るとおりなので、書いていただきましたFor文を
設定してみました。
UserFormsが定義されていないとエラーになったので、いろんな型で
定義してみたのですが、オブジェクトが設定されていませんと
いわれてしまいます。現在起動中のフォーム名を知る為には何か
プロパティや参照設定を変更する必要があるのでしょうか?

また、複数のアプリケーションが起動中の場合、'wObj.Caption
ですべての起動中アプリケーションが取得できるのでしょうか?

もっといろいろ試してS.S様にご教授いただいたことを調べてみます。

よろしくお願いします。

編集 削除
ちょこ  2004-07-09 10:02:05  No: 84466  IP: [192.*.*.*]

このUserFormsってやつを使ったことないのですが、
これって、同一アプリケーション内のフォームが入ったコレクションでは無いでしょうか?(Formsみたいな感じ)

私は、APIのプロセスの監視系のものを使用するのかなぁと思ったんですけど、
でもファイルの読み込みの終了待ちとか、そのアプリケーションが何か返してくれないと分からないような^^;

ということで、参考にならない話ですみません。

編集 削除
教えてください  2004-07-09 10:02:36  No: 84467  IP: [192.*.*.*]

追記です
Formsだけで定義すると現在VBで起動中のアプリケーションのみ
取得することができました。
しかしUserFormsにするとやはりうまくいきませんでした・・・
よろしくお願いします。

編集 削除
ちょこ  2004-07-09 10:03:05  No: 84468  IP: [192.*.*.*]

すみません。。。一部、変な変換がありました。脳内変換お願いしますorz

編集 削除
S.S  2004-07-09 11:31:47  No: 84469  IP: [192.*.*.*]

うまくいかなかったようですね(^^;
では以下で・・・
  Dim Frm As Form

  For Each Frm in Forms
      'Frm.Name
  Next
> ちょこさん
無理してレスしなくても良いのでは・・・

編集 削除
教えてください  2004-07-09 13:17:18  No: 84470  IP: [192.*.*.*]

ちょこ様
ありがとうございます。
VBの起動中の名前取得でもAPIで取得するということでしょうか?
APIは難しいので、なるべくVBで取得してみたいのですが、
VB以外の起動中アプリケーション名を取得したい場合はAPIを使用すれば
取得できるのでしょうか?
APIは全然わからないので、ご意見いただけるとうれしいです。

編集 削除
教えてください  2004-07-09 13:17:27  No: 84471  IP: [192.*.*.*]

S.S様
ありがとうございます。

Formsでの設定で実行してみた所、現在起動中のフォーム名を
取得できました。
ありがとうございます。ヘルプでもっと詳しくしらべてよく覚えたいと思います。
このForms設定はVBで作成したフォームで現在起動かなのフォームの
名前を取得するということであってますでしょうか?
試しで他のアプリケーションEXE(メモ帳やペイントなど)を
起動後に同じ動作をしてみた所、VB以外のフォームには反応しませんでした。

応用方法でVBの起動中のアプリケーションと、VB以外の起動中のアプリケーション名を
取得することは可能でしょうか?

UserFormだったらそれも可能なのだろうか?といろいろ調べましたが、
ほとんどヒットせず、ここまでご教授していただいたなら他のアプリケーション名も
取得してみたいので、何かご助言よろしくお願いします。

編集 削除
ちょこ  2004-07-09 13:27:22  No: 84472  IP: [192.*.*.*]

S.S様
了解しました〜ヽ(;´д`)ノ
&つっこみアリガトです<(_ _)>

編集 削除
ぴろあき  2004-07-09 13:49:23  No: 84473  IP: [192.*.*.*]

既知のアプリが起動中かどうか調べるには、
FindWindowというAPI関数を使用します。

現在実行中のアプリ(プロセス)の列挙は、
CreateToolhelpSnapshot
Process32First
Process32Next
というAPI関数を使用する方法(NT不可)や、

WMIでWin32_Processクラスを使用する方法(Win2K以降)があると思います。

ですが、やりたい事が
「他アプリを起動して初期化が完了するまでの待機」
のようですので、そういった場合には、
CreateProcess
WaitForInputIdle
というAPI関数を使用するのが正しい方法だと思います。
この方法なら、S.Sさんの言うようなタイムアウトの処理も可能です。

編集 削除
S.S  2004-07-09 14:07:49  No: 84474  IP: [192.*.*.*]

ぴろあきさんの方法で何とかなりそうですね?

とりあえず他のウィンドウの列挙はEnumWindowsを使用してください。

編集 削除