[リストへもどる]
一括表示

投稿時間:2004/07/21(Wed) 14:12
投稿者名:
Eメール:
URL :
タイトル:
アプリの複数起動を禁止したい
お世話になります。

とあるデータの検索アプリを作成して本番で運用しているのですが、
ユーザさんがPCに慣れていないため同じアプリをぽこぽこ複数起動しては
「どの画面を見てたっけ?」と悩むことがままある状況です。

そこで、複数のアプリを起動できないようにしたいのですが、どのようにすればよろしいでしょうか?
2つ目のアプリを起動しようとしたときに2つ目のアプリは起動せず、1つ目のものが最前面にくれば最高です。
または1つ目のアプリを終了して2つ目のアプリが新規で起動するというものでもOKです。

よろしくお願いします。

投稿時間:2004/07/21(Wed) 14:34
投稿者名:
Eメール:
URL :
タイトル:
Re: アプリの複数起動を禁止したい
起動時の最初に
    If App.PrevInstance = True Then
        End
    End If

と書けば複数起動は禁止できます

投稿時間:2004/07/21(Wed) 16:14
投稿者名:
Eメール:
URL :
タイトル:
Re^2: アプリの複数起動を禁止したい
ゆ 様。さっそくのご回答ありがとうございました。

教えていただいた構文をForm_Loadに置くことで複数起動されなくなりました。

さて、これで既に立ち上がっているアプリが最前面にくるようになれば完璧なのですが、
Endする前に起動済みアプリを操作する必要がでてくるのですが、
SetWindowPosなどでできるのでしょうか?
ちょっと調べてみましたが別アプリを操作というのは分かりませんでした。

何かいい方法がありましたらご教示ください。

投稿時間:2004/07/21(Wed) 18:31
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^3: アプリの複数起動を禁止したい
どちらもここの逆引きヘルプにありますよ!
又、掲示板のログや当サイト内の検索を使っても簡単に見つけられるかと思います。

投稿時間:2004/07/22(Thu) 16:27
投稿者名:
Eメール:
URL :
タイトル:
Re^4: アプリの複数起動を禁止したい
管理人様、ご回答ありがとうございます。

> どちらもここの逆引きヘルプにありますよ!
Googleとかばかり見ていてここのサンプルを見ていませんでした。灯台下暗し。お恥ずかしい。
さて、サンプルの「APIを使って Window を操作する」を参考にさせていただきました。
ゆ様からのご回答とあわせて

Private Sub Form_Load()
    If App.PrevInstance = True Then
        strCaptionName = "検索画面"
        lnghwnd = FindWindow(vbNullString, strCaptionName )
        retValue = SetForegroundWindow(lnghwnd)
        End
    End If
End Sub

こんな感じで作ってみたのですが、うまく動いてくれません。
strCaptionName の値を別のアプリに変更するとそちらは最前面にでてくるところから
既に起動しているアプリではなく二重起動したアプリ(自分自身)をアクティブにしているようです。
で、その直後にアプリを終了している。

最初のアプリを明示的に指定したいのですが、同じアプリなのでキャプション名もクラス名も同じ。
ない頭を絞って考えてみましたが思いつきませんでした。
プロセスIDとか取得できたとしてもそれは2番目のアプリのプロセスIDになりそうですし。
読んでいる場所が見当はずれだったら申し訳ありません。

> 又、掲示板のログや当サイト内の検索を使っても簡単に見つけられるかと思います。
う〜ん、「最前面」とか「ウィンドウ アクティブ」とかいろいろ入れていたのですが
めぼしい項目はなかなか出てこなくて・・・
探し方が下手だったようです。

投稿時間:2004/07/22(Thu) 17:33
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^5: アプリの複数起動を禁止したい
そうそうすべてどんぴしゃのサンプルは転がっていませんよ。
名前が同じで区別できなければ変更すればいいだけの事です。
Private Sub Form_Load()
    Dim strCaptionName As String
    Dim retValue As Long
    Dim lnghwnd  As Long
    If App.PrevInstance = True Then
        Me.Caption = "2重起動"
        strCaptionName = "検索画面"
        lnghwnd = FindWindow(vbNullString, strCaptionName)
        retValue = IsIconic(lnghwnd)
        If retValue Then
            retValue = OpenIcon(lnghwnd)
         End If
        retValue = SetForegroundWindow(lnghwnd)
        Unload Me
    End If
End Sub

最小化されている場合の処理が抜けていましたので追加

又、End ステートメント は使用しない方がいいかと。

投稿時間:2004/07/22(Thu) 19:18
投稿者名:
Eメール:
URL :
タイトル:
Re^6: アプリの複数起動を禁止したい
管理人様、魔界の仮面弁士様、ご回答ありがとうございます。

う〜ん、モノは考えようですね。自分のCaptionを変えることは全く考えていませんでした。
おかげさまでうまくいくようになりました。

なお、
>
> 又、End ステートメント は使用しない方がいいかと。
こちらの件ですが、Unload Meを使用した場合は前面に出したウィンドウがアクティブでなくなった場合
なぜかウィンドウがチカチカと点滅してうるさい感じがしました。(わかりにくい表現ですみません)
タスクマネージャを見ると二重起動したアプリのプロセスも残っているようでした。

そのため今回の処理ではEndを使って対応しました。
魔界の仮面弁士様のリンク先にあるMSのサンプルでもEndが使われているのですが、
どのような理由なのか差し支えなければお教え願えないでしょうか?

投稿時間:2004/07/22(Thu) 19:46
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^7: アプリの複数起動を禁止したい
> > 又、End ステートメント は使用しない方がいいかと。
> こちらの件ですが、Unload Meを使用した場合は前面に出したウィンドウがアクティブでなくなった場合
> なぜかウィンドウがチカチカと点滅してうるさい感じがしました。(わかりにくい表現ですみません)
> タスクマネージャを見ると二重起動したアプリのプロセスも残っているようでした。

http://www.gj.il24.net/~nakasima/vb/trap/index.htm#VBTRAP4

投稿時間:2004/07/22(Thu) 20:04
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^7:確認してみたら
> なぜかウィンドウがチカチカと点滅してうるさい感じがしました。(わかりにくい表現ですみません)
> タスクマネージャを見ると二重起動したアプリのプロセスも残っているようでした。

私の環境では、上記は確認できません。
Load イベントやUnload 以降に他の処理を書いておられるのでしょうか?
Unload Me の後のコードが実行されるみたいなので、Exit Sub を入れて見て下さい

        retValue = SetForegroundWindow(lnghwnd)
        Unload Me
        Exit Sub  'ここを追加
    End If

それでも改善できなければ
OS は何をお使いですか? SetForegroundWindow だけではアクティブにならない場合があった
のですが。

> そのため今回の処理ではEndを使って対応しました。
> 魔界の仮面弁士様のリンク先にあるMSのサンプルでもEndが使われているのですが、
> どのような理由なのか差し支えなければお教え願えないでしょうか?

魔界の仮面弁士さんから回答があったようですが、下記のような理由です。

http://www.bcap.co.jp/hanafusa/VBHLP/Fil_AllEnd.htm

投稿時間:2004/07/22(Thu) 20:37
投稿者名:
Eメール:
URL :
タイトル:
Re^8: アプリの複数起動を禁止したい
う〜ん、なるほど。

実は、確かにUnload Meの後にもコードがあります。2つのフレームを使っていまして、
なくても良かったのですが初期表示を明示的にしておく意味でフレームの表示・非表示を書いていました。
結果、こんなコードで落ち着きました。

Private Sub Form_Load()

        If App.PrevInstance = True Then
            captionName = "検索画面"
            Me.Caption = "二重起動"
            lnghwnd = FindWindow(vbNullString, captionName)
            retValue = SetForegroundWindow(lnghwnd)
            'End
            Unload Me
            Exit Sub
        End If
        
        Frame1.Enabled = True
        Frame2.Enabled = False
        Frame1.Visible = True
        Frame2.Visible = False
End Sub

画面のチラつきがなくなり、プロセスも残らなくなりました。
どうもありがとうございました。

魔界の仮面弁士様
私はン年前の入社時にASPで開発をしていて、会社の先輩から
「ページ処理が終わればメモリから開放されるからNothingしなくてもいいけど
 わかりやすくするためにもNothingするのが礼儀だ」
ということを言われていて深く考えずに使っていました。
(Response.Redirectするときはメモリが残るからそのときは注意、とも言われていましたが)
紹介いただいたサイトを読んで身につまされる思いです。初心に帰ってじっくり考えてみます。
ありがとうございました。

投稿時間:2004/07/23(Fri) 10:48
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^9: アプリの複数起動を禁止したい
> 結果、こんなコードで落ち着きました。

スタートアップフォームに組み込んでしまうと、フォームがLoadされてからUnloadされる事になり、
処理の無駄が生じます。Sub Main()を使って、フォームの起動前に判定した方が良いでしょう。

処理のイメージとしては、
  '標準モジュール
  Private Sub Main()
    If 『多重起動では無かった時』 Then
       Form1.Show
    End If
  End Sub
のような感じです。これなら、Unload も End も使わずに済みますよ。

投稿時間:2004/07/22(Thu) 18:04
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re: アプリの複数起動を禁止したい
> 2つ目のアプリを起動しようとしたときに2つ目のアプリは起動せず、1つ目のものが最前面にくれば最高です。

http://support.microsoft.com/default.aspx?kbid=185730