当用户尝试在vb6中打开新实例时,返回已打开的应用程序

时间:2012-07-26 12:34:06

标签: vb6

假设用户将我的visual basic应用程序最小化到任务栏通知图标。现在我想要当用户打开一个新实例时,旧实例应该恢复。

2 个答案:

答案 0 :(得分:12)

通常,用于创建单实例应用程序的策略是向应用程序初始化添加一些代码,以确定实例是否已在运行。如果是,它将获得其主窗口的句柄,将焦点传递给它,然后静默地死亡。如果不是,则继续运行并照常完成剩余的初始化序列。

你会发现许多旧的VB 6文章通过迭代所有顶级窗口来完成这一点,寻找一个标题与你期望的标题相匹配的窗口。但这是一个非常脆弱的解决方案,它不需要花很多时间就把它扔掉。

App.PrevInstance property相同。这非常简单易用,但实现起来也非常简单。它基于可执行文件的名称工作,并查找名称匹配的正在运行的进程。但是,如果用户创建并重命名可执行文件的副本,则很容易失败。如果这对您来说是可以接受的,您可以通过查询App.PrevInstance属性来轻松实现。否则,您将需要使用更强大的解决方案。

一种可能性是在应用程序的第一个实例启动时创建并注册一个命名的互斥锁。然后,当后续实例尝试注册相同的互斥锁时,它们将失败,表明实例已在运行。您可以在this question的答案中找到有关在VB 6中使用互斥锁的说明。

使用互斥锁的几个重要注意事项:

  • 您需要确保在应用程序关闭时调用ReleaseMutexCloseHandle函数,以释放您创建的互斥锁的所有权并销毁它。

  • 当您在VB 6 IDE中运行程序(例如,进行调试)并注册互斥锁时,互斥锁属于IDE,在您关闭IDE并重新启动它之前不会释放该互斥锁。为防止这种情况,您可以使用条件编译在IDE /调试器内部运行时禁止创建互斥锁。如果采用这种方法,请确保在调试器的外部测试程序,以确保与互斥锁相关的功能正常工作!您不应该向尚未经过全面测试的客户发货。

您可以使用VB 6安装捆绑的API Viewer程序找到这些Windows API函数的所有VB 6声明。

有关处理VB 6应用程序的多个实例的更多信息,请访问here on Karl Peterson's site。在this article on VB Accelerator中还有一个完整的示例实现 - 专门针对第2步,您不需要其余的代码。

答案 1 :(得分:7)

你通常可以简单地以简并的方式使用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