ユーザーが私の Visual Basic アプリケーションをタスクバー通知アイコンに最小化したとします。ユーザーが新しいインスタンスを開いたときに、古いインスタンスを復元する必要があります。
2 に答える
一般に、単一インスタンス アプリケーションを作成するために使用される戦略は、インスタンスが既に実行されているかどうかを判断するコードをアプリケーションの初期化に追加することです。存在する場合は、メイン ウィンドウへのハンドルを取得し、それにフォーカスを渡し、黙って終了します。そうでない場合は、実行を継続し、通常どおり残りの初期化シーケンスを完了します。
古い VB 6 の記事の多くは、トップ レベルのすべてのウィンドウを反復処理し、キャプションが期待するものと一致するものを探すことによってこれを達成しました。しかし、これは非常に脆弱なソリューションであり、破棄するのにそれほど時間はかかりません。
App.PrevInstance
プロパティと同じ取引。これは使い方が非常に簡単ですが、実装も非常に簡単です。実行可能ファイルの名前に基づいて機能し、名前が一致する実行中のプロセスを探します。ただし、ユーザーが実行可能ファイルのコピーを作成して名前を変更すると、これは簡単に無効になります。これが許容できる場合は、プロパティを照会することで非常に簡単に実装できApp.PrevInstance
ます。それ以外の場合は、より堅牢なソリューションを使用する必要があります。
そのような可能性の 1 つは、アプリケーションの最初のインスタンスの起動時に、名前付きミューテックスを作成して登録することです。その後、後続のインスタンスが同じミューテックスを登録しようとすると失敗し、インスタンスが既に実行されていることを示します。VB 6 でミューテックスを使用する方法については、この質問への回答を参照してください。
ミューテックスの使用に関するいくつかの重要な注意事項:
所有権を解放し、作成したミューテックスを破棄するために、アプリケーションを閉じるときに 関数
ReleaseMutex
と関数を呼び出す必要があります。CloseHandle
VB 6 IDE でプログラムを実行している場合 (デバッグなど)、プログラムがミューテックスを登録すると、ミューテックスは IDE に属し、IDE を閉じて再起動するまで解放されません。これを防ぐには、条件付きコンパイルを使用して IDE/デバッガー内で実行するときにミューテックスの作成を抑制することができます。このアプローチを採用する場合は、デバッガーの外でプログラムをテストして、ミューテックス関連の機能が期待どおりに機能していることを確認してください。十分にテストしていないものを顧客に出荷するべきではありません。
これらの Windows API 関数のすべての VB 6 宣言は、VB 6 インストールにバンドルされている API ビューアー プログラムを使用して見つけることができます。
VB 6 アプリケーションの複数インスタンスの処理に関する詳細については、Karl Peterson のサイト を参照してください。VB Accelerator に関するこの記事には、完全な実装例もあります。具体的にはステップ 2 に注目してください。残りのコードは必要ありません。
多くの場合、これは、DDE を縮退した方法で使用することでかなり簡単に行うことができます。
Form1.frm
Option Explicit
'This is Form1. To use as DDE source at design time we set:
' Form1.LinkMode = 1 (Source, i.e. vbLinkSource).
' Form1.LinkTopic = "Form1" (default).
'
'Note we use (hidden) Label1 on this Form as a DDE destination.
Private PrevState As Integer
Private Sub Form_LinkExecute(CmdStr As String, Cancel As Integer)
'Got a "command" so restore Form1 and accept the command.
WindowState = PrevState
Caption = "I am awake!"
Cancel = False
End Sub
Private Sub Form_Load()
PrevState = WindowState
End Sub
Private Sub Form_Resize()
If WindowState <> vbMinimized Then PrevState = WindowState
End Sub
Module1.bas
Option Explicit
Private Sub Main()
Load Form1
'After Form1 is loaded (hidden), try DDE link to possible prior copy.
With Form1.Label1
.LinkTopic = App.EXEName & "|Form1"
On Error Resume Next
.LinkMode = vbLinkManual
If Err.Number = 0 Then
On Error GoTo 0
'Link succeeded. Wake up prior copy via pushback to
'the DDE source, then unload Form1 and terminate.
.LinkExecute "Wake up!"
Unload Form1
Else
On Error GoTo 0
'Link failed, so we're 1st. Show Form1.
Form1.Show vbModal
End If
End With
End Sub