' 也不用上面链接中的那么麻烦。 ' 在工程中添加一个Form1(窗体)和一个Module1(模块)' 在标准模块中添加如下代码就行了,编译后运行看看,无论你把.exe拷到哪,都不会运行多次' 标准模块:Option Explicit Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long Private Const SW_RESTORE = 9Private Sub Main() If App.PrevInstance = True Then ' 如果本程序已经运行, 则将其从任务栏还原 ShowWindow FindWindow("ThunderRT6FormDC", "Form1"), SW_RESTORE SetForegroundWindow FindWindow("ThunderRT6FormDC", "Form1") Else Form1.Show End If End Sub
to rainstormmaster(rainstormmaster): 我的办法就是启动时用Command获得一下参数啊。 Private Sub Main() If App.PrevInstance = True Then ' 如果本程序已经运行, 则将其从任务栏还原 ' 用Command判断一下参数......... ' .............................. ShowWindow FindWindow("ThunderRT6FormDC", "Form1"), SW_RESTORE SetForegroundWindow FindWindow("ThunderRT6FormDC", "Form1") Else[ ShowWindow FindWindow("ThunderRT6FormDC", "Form1"), SW_RESTORE 如果有相同标题的vb程序怎么办,哪怕几率只有亿分之一,是不是也要考虑一下 ] 有理,用我的这个办法确实无法避免这个问题,虽说机率很低吧,但也是应该考虑的。 :) Form1.Show End If End Sub
to goodname008(卢培培,LPP Software): //我的办法就是启动时用Command获得一下参数啊你试试看参数能传递给副本吗?
If App.PrevInstance = True Then …… end if 这个比较简单,不过缺点是如果程序目录改变了,就不起作用了
' 在工程中添加一个Form1(窗体)和一个Module1(模块)' 在标准模块中添加如下代码就行了,编译后运行看看,无论你把.exe拷到哪,都不会运行多次' 标准模块:Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Const SW_RESTORE = 9Private Sub Main()
If App.PrevInstance = True Then ' 如果本程序已经运行, 则将其从任务栏还原
ShowWindow FindWindow("ThunderRT6FormDC", "Form1"), SW_RESTORE
SetForegroundWindow FindWindow("ThunderRT6FormDC", "Form1")
Else
Form1.Show
End If
End Sub
hisofty(瘦马) 的代码在跨平台使用时可能会出现问题vb提供了DDE支持,用DDE实现吧
用DDE实现窗体防止运行多个实例并传递命令
http://wlbookwl.myrice.com/jck/1027dde.htm
不过在适当的位置用Command函数获得一下然后再判断就完美了。to rainstormmaster(rainstormmaster) :
//那就是无法传递command获得的参数
是说我的代码没有考虑到传递参数的情况还是在模块中无法传递Command获得的参数?
我试了试,模块可以用Command获得参数啊? :(
//我的方法没有考虑获得参数的情况。 :)
不过在适当的位置用Command函数获得一下然后再判断就完美了。用什么事件?恐怕只能在Timer控件的Timer事件进行处理,可是,你考虑过系统性能吗?也许,你有什么好的方法,欢迎交流:)这个问题我曾经花过两个月的时间进行研究,尝试过许多种方案,在基于安全、稳定、效率的原则下,我最终选择了dde另外:
ShowWindow FindWindow("ThunderRT6FormDC", "Form1"), SW_RESTORE
如果有相同标题的vb程序怎么办,哪怕几率只有亿分之一,是不是也要考虑一下
我的办法就是启动时用Command获得一下参数啊。
Private Sub Main()
If App.PrevInstance = True Then ' 如果本程序已经运行, 则将其从任务栏还原
' 用Command判断一下参数.........
' ..............................
ShowWindow FindWindow("ThunderRT6FormDC", "Form1"), SW_RESTORE
SetForegroundWindow FindWindow("ThunderRT6FormDC", "Form1")
Else[
ShowWindow FindWindow("ThunderRT6FormDC", "Form1"), SW_RESTORE
如果有相同标题的vb程序怎么办,哪怕几率只有亿分之一,是不是也要考虑一下
]
有理,用我的这个办法确实无法避免这个问题,虽说机率很低吧,但也是应该考虑的。 :)
Form1.Show
End If
End Sub
//我的办法就是启动时用Command获得一下参数啊你试试看参数能传递给副本吗?
……
end if
这个比较简单,不过缺点是如果程序目录改变了,就不起作用了
得想个好办法了.
想ing..........................
我当时想的是进程间传递信息用COPY_DATA,但涉及到改写窗体默认过程和传递字符串的指针(传递数字还好一点),很烦,而且很容易崩溃。看来DDE方法确实很好,比COPY_DATA强。
众位讨论的改变程序运行目录后App.PrevInstance就会失效,我确实还未考虑。看来大家考虑的比我还多,呵呵。实在不行可以将FindWindow和App.PrevInstance结合起来用(用互斥体是不是很杂,涉及到内存映射吧,我还不大了解)。只能帮窗体起一个重复机率很小的标题了,一般来说名字起特别些且长一点重名的很少,而且要同时运行,电脑同时运行的程序不会太多的。在App.PrevInstance=false的情况下,只要FindWindow找到窗体,就认为程序已运行,传递相关信息,如文件名等,然后已经运行的程序收到信息后再传递一个接收到的标志给后打开的程序,收到确认后标志后副本就可关闭。这样就应该没什么问题了吧,因为如果传递到窗体标题相同的其它应用程序,就不会收到确认标志。
以上只是我的一些想法,不当之处还请指正!
hisofty(瘦马) 的代码