1、不能直接结束进程
2、由于两个程序都是自己做的所以源代码必要时都可以改,所以需要两个程序互相配合才能达成目的的方法、代码也可以给我
3、不用互相关,只要甲程序要求乙程序关闭,乙在处理完一些工作(如提示用户保存文件等,放开引用的一些dll)然后关闭就可以了
35 个解决方案
#1
谢谢大家帮忙!!!!!!!!!!!!!
#2
up
#3
关注
#4
上网的朋友一定都用过网络蚂蚁(Net Ants)的吧?不知你在使用过程中有没有注意过,
那就是如果你想调动两个“蚂蚁”为您效力是不可能的——它总会把新运行的关闭。
而“蚂蚁”程序的妙处就在于:在重复运行“蚂蚁”时它不仅拒绝运行,而且能把已经运
行的“蚂蚁”激活,这样用上面的程序就无能为力了。但事实上实现拒绝运行并激活已运行的
程序有多种方法:
1、用FindWindow函数得到已经运行窗体的句柄(HWND),然后用SetActiveWindow等API函
数将其激活。其缺点也很明显,那就是没法传递参数。
2、用FindWindow函数得到已运行窗体的句柄后用SendMessage的方法给窗体传送一个自定义
消息(附带参数),然后在窗体中拦截并进行处理,但这样做要修改窗体的标准消息处理
程序,用在VC,BC或DELPHI编写的程序中还行,但在VB中工作量太大,并且容易发生“一
般保护行错误”使VB崩溃,不太可取(当然,如果你有足够的信心和不怕崩溃的精神,也
可以试一下 ^_^ )。
3、使用DDE技术。
所谓DDE技术,就是动态数据交换技术。也许你很奇怪,这与本文所讨论的内容有什么相干的?
且听我慢慢讲来。
为了实现拒绝运行并把已经运行的程序激活并实现各种功能,我们可以先用本文开头提到的方
法,检测一下程序有没有被运行过,如果没有,就正常运行,如果已经被运行过,就打通与它的
DDE通道,传给它一个(或一些)数据,然后由已经运行的程序对数据进行处理,再去实现各种
“意想不到”的功能,这时也许就有人对这你的程序喊:“酷、酷……” ^_^
好了,耳听为虚,眼见为实,下面让我们动点真格的。
打开VB,新建一个工程,选择菜单中的“工程->工程1 属性”,把工程名称改为“P1”(我爱
偷懒,能短则短 ^_^ ),把已有的一个窗体的“LinkTopic”属性改为“FormDDE”,把“LinkMode”
属性改为“1 - Source”,添加一个PictureBox控件作为DDE执行控件,命名为picDDE。然后添加一个
TextBox控件,命名为“txtInfo”,并把“MultiLine”属性设置为“True”,以便显示多行文本,作为
消息显示控件。
最后在窗体代码区输入以下代码:
Const COMMANDLINE = "CommandLine=" 注释: 还是为了省事,定义一个常量
Private Sub Form_LinkExecute(CmdStr As String, Cancel As Integer)
Static lngCount As Long
Dim Info As String
Info = txtInfo.Text 注释: 保留原有信息
Select Case CmdStr 注释: CmdStr 是DDE程序传送过来的参数
Case "Max"
Me.WindowState = 2
Info = Info + vbNewLine + "窗体已被最大化"
Case "ShowTime"
Info = Info + vbNewLine + "最后一次运行这个程序的时间是:" + Str(Now)
Case "Count"
lngCount = lngCount + 1
Info = Info + vbNewLine + "你已经第" + Str(lngCount) + "次重复调用这个程序。" _
+ vbNewLine + "但怕您不多给工资,所以只运行了一个 ^_^"
End Select
If Left(CmdStr, Len(COMMANDLINE)) = COMMANDLINE Then
Info = Info + vbNewLine + "新程序曾以命令行形式运行" + vbNewLine + "命令行为:" _
+ vbNewLine + Right(CmdStr, Len(CmdStr) - Len(COMMANDLINE))
End If
txtInfo.Text = Info 注释: 把信息显示出来
Cancel = False
End Sub
Private Sub LinkAndSendMessage(ByVal Msg As String)
Dim t As Long
picDDE.LinkMode = 0 注释:--
picDDE.LinkTopic = "P1|FormDDE" 注释: |______连接DDE程序并发送数据/参数
picDDE.LinkMode = 2 注释: | “|”为管道符,是“退格键”旁边的竖线,
picDDE.LinkExecute Msg 注释:-- 不是字母或数字!
t = picDDE.LinkTimeout 注释:--
picDDE.LinkTimeout = 1 注释: |______终止DDE通道。当然,也可以用别的方法
picDDE.LinkMode = 0 注释: | 这里用的是超时强制终止的方法
picDDE.LinkTimeout = t 注释:--
End Sub
Private Sub Form_Load()
If App.PrevInstance Then 注释: 程序是否已经运行
Me.LinkTopic = "" 注释: 这两行用于清除新运行的程序的DDE服务器属性,
Me.LinkMode = 0 注释: 否则在连接DDE程序时会出乱子的
LinkAndSendMessage "Max" 注释:--
LinkAndSendMessage "Count" 注释: |-----连接DDE接受程序并传送数据/参数
LinkAndSendMessage "ShowTime" 注释:--
If Command <> "" Then 注释: 如果有命令行参数,就传递过去
LinkAndSendMessage COMMANDLINE + Command
End If
End 注释: 结束新程序的运行
End If
End Sub
测试一下:
把工程“P1”编译成EXE文件(设名称为 P1.EXE )
1、打开“我的电脑”,找到 P1.EXE 并执行。可以看到程序正常运行了。
2、再运行一次,这次新程序没有运行成功,而原来运行的程序却被最大化了,而且文本框中有以下
字符:
窗体已被最大化
你已经第 1次重复调用这个程序。
但怕您不多给工资,所以只运行了一个 ^_^
最后一次运行这个程序的时间是:00-2-6 7:11:01
3、打开 MS-DOS方式 ,用命令行方式再次运行程序,如 “P1 How Are You?”
这时原来运行的程序文本框中又多了几行字:
窗体已被最大化
你已经第 2次重复调用这个程序。
但怕您不多给工资,所以只运行了一个 ^_^
最后一次运行这个程序的时间是:00-2-6 7:14:32
新程序曾以命令行形式运行
命令行为:
How Are You?
OK,运行完全正确,然后你就可以把它应用的你的程序中了。
当然,这只是一些个人心得,如有疏漏之出,还请各位大虾指正。
#5
还有没有?
#6
还有没有?
#7
online的方法在一个程序启动多个副本的情况下,只对最后一个副本有效
#8
我写过类似的程序思路如下:
假定你的SERVER工程名为Server,主窗体名为Form1
将窗体Form1的LinkMode属性设为SOURCE,
再放上一个LABEL控件,名为Label_shutdown,CAPTION属性为"",如果不想让人看见可以将它的VISIBLE属性设为FALSE,不影响程序效果。
如果要结束CLINT程序运行,将其CAPTION设为"1"或者其他任何非空值,
如:Label_shutdown.Caption="ShutDown"
在你的CLINT程序中也放一个LABEL控件,假定名为Label1
并在窗体加载时(Form_load()中)作如下设定
Label1.LinkItem = "Label_shutdown"
Label1.LinkTopic = "Server|Form1"
Label1.LinkMode = 2
最后在Label1_Change()中加入
If label1.caption<>"" then end
CLINT程序就会自动关闭功能了。
这样当你在SERVER程序中只要将Label_shutdown的caption属性设为非空,CLINT程序就会自动关闭,无论有几个CLINT程序只要加入上述语句,全部可以关闭。
有一点必须注意,你的SERVER程序必须在CLINT程序之前运行,否则会得到一个"DDE超时"的错误。
最后,请给点分,我的分也不够了,问题也不少。
假定你的SERVER工程名为Server,主窗体名为Form1
将窗体Form1的LinkMode属性设为SOURCE,
再放上一个LABEL控件,名为Label_shutdown,CAPTION属性为"",如果不想让人看见可以将它的VISIBLE属性设为FALSE,不影响程序效果。
如果要结束CLINT程序运行,将其CAPTION设为"1"或者其他任何非空值,
如:Label_shutdown.Caption="ShutDown"
在你的CLINT程序中也放一个LABEL控件,假定名为Label1
并在窗体加载时(Form_load()中)作如下设定
Label1.LinkItem = "Label_shutdown"
Label1.LinkTopic = "Server|Form1"
Label1.LinkMode = 2
最后在Label1_Change()中加入
If label1.caption<>"" then end
CLINT程序就会自动关闭功能了。
这样当你在SERVER程序中只要将Label_shutdown的caption属性设为非空,CLINT程序就会自动关闭,无论有几个CLINT程序只要加入上述语句,全部可以关闭。
有一点必须注意,你的SERVER程序必须在CLINT程序之前运行,否则会得到一个"DDE超时"的错误。
最后,请给点分,我的分也不够了,问题也不少。
#9
不知是否是我理解的有问题,我怎么感觉用sendmessage发送一条wm_close消息就可以了,至于乙程序做的工作,在窗体的unload事件中写一些代码即可
#10
DDE 方法其实很好的。
如果实在不想用,
可以用 SendMessageCallback(HWND_BROADCAST, WM_MYMSG, ................)
这样接收的程序可以有返回数,发送程序的CallBack就可以接收到。
具体使用可以看MSDN,我没法解释的更清楚了。
#11
呵呵,我跟rainstormmaster(暴风雨 v2.0) 有同样的错觉
#12
sendmessage发送一条wm_close消息?怎么做法???
#13
不会吧,肯定是什么地方没说清楚.
kmzs怎么也是一星的人了,不会连这个都不知道吧.
kmzs怎么也是一星的人了,不会连这个都不知道吧.
#14
sendmessage(hwnd,wm_close,0,0)
#15
呵呵,这个帖子的提问者和回答者,除我之外都是CSDN上的重量级人物.是我至今为止,看到的阵容最强大的一帖.
少见!少见!
少见!少见!
#16
hwnd怎么得到?
#17
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
Const SW_SHOWNORMAL = 1
Const WM_CLOSE = &H10
Private Sub Form_Load()
Dim WinWnd As Long, Ret As String, RetVal As Long, lpClassName As String
WinWnd = FindWindow(vbNullString, "Quick Spy")
If WinWnd = 0 Then MsgBox "Couldn't find the window ...": Exit Sub
'PostMessage WinWnd, WM_CLOSE, 0&, 0&
SendMessage WinWnd, WM_CLOSE, 0, 0&
End Sub
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
Const SW_SHOWNORMAL = 1
Const WM_CLOSE = &H10
Private Sub Form_Load()
Dim WinWnd As Long, Ret As String, RetVal As Long, lpClassName As String
WinWnd = FindWindow(vbNullString, "Quick Spy")
If WinWnd = 0 Then MsgBox "Couldn't find the window ...": Exit Sub
'PostMessage WinWnd, WM_CLOSE, 0&, 0&
SendMessage WinWnd, WM_CLOSE, 0, 0&
End Sub
#18
//hwnd怎么得到
手段有很多
一个办法是在乙程序初始话时,将其窗口句柄保存在一个地方(临时文件、内存)中,然后,用甲程序读出数据
也可以先获得乙程序对应的pid,然后由pid获得hwnd
手段有很多
一个办法是在乙程序初始话时,将其窗口句柄保存在一个地方(临时文件、内存)中,然后,用甲程序读出数据
也可以先获得乙程序对应的pid,然后由pid获得hwnd
#19
WinWnd = FindWindow(vbNullString, "Quick Spy")
quick spy是窗口的标题
我就直接写了
看这个qq登陆器
http://community.csdn.net/Expert/topic/3116/3116573.xml?temp=.5579187
quick spy是窗口的标题
我就直接写了
看这个qq登陆器
http://community.csdn.net/Expert/topic/3116/3116573.xml?temp=.5579187
#20
//sendmessage发送一条wm_close消息?怎么做法???
//hwnd怎么得到?
kmzs(.:RNPA:.山水岿濛) 怎么混到一星的?这个连我都知道,虽然我没有做过什么VB程序 :-)
//hwnd怎么得到?
kmzs(.:RNPA:.山水岿濛) 怎么混到一星的?这个连我都知道,虽然我没有做过什么VB程序 :-)
#21
看看这个小例子对你有没有帮助~
仍然是用DDE,是两个程序之间的通讯例子~
'新建工程,窗体上放一个Text1
'Form1的LinkMode设为1,LinkTopic设为FormDDE
Private Sub Form_LinkExecute(CmdStr As String, Cancel As Integer)
If Len(CmdStr) Then Text1.Text = CmdStr
Cancel = 0
End Sub
'生成EXE为Test1.exe
'===========================================
'再新建工程,窗体上放一个Text1
'Form1的LinkMode设为1,添加代码
Private Sub Text1_Change()
With Text1
.LinkTopic = "工程1|FormDDE"
.LinkMode = 2
.LinkExecute Text1.Text
End With
End Sub
'生成EXE为Test2.exe
'===========================================
'分别运行Test1和Test2
'在Test2的文本框中输入内容,Text1的文本框中将出现相同内容
仍然是用DDE,是两个程序之间的通讯例子~
'新建工程,窗体上放一个Text1
'Form1的LinkMode设为1,LinkTopic设为FormDDE
Private Sub Form_LinkExecute(CmdStr As String, Cancel As Integer)
If Len(CmdStr) Then Text1.Text = CmdStr
Cancel = 0
End Sub
'生成EXE为Test1.exe
'===========================================
'再新建工程,窗体上放一个Text1
'Form1的LinkMode设为1,添加代码
Private Sub Text1_Change()
With Text1
.LinkTopic = "工程1|FormDDE"
.LinkMode = 2
.LinkExecute Text1.Text
End With
End Sub
'生成EXE为Test2.exe
'===========================================
'分别运行Test1和Test2
'在Test2的文本框中输入内容,Text1的文本框中将出现相同内容
#22
//kmzs(.:RNPA:.山水岿濛) 怎么混到一星的?这个连我都知道,虽然我没有做过什么VB程序 :-)
直到就说呀,快说。。。。。。
直到就说呀,快说。。。。。。
#23
//一个办法是在乙程序初始话时,将其窗口句柄保存在一个地方(临时文件、内存)中,然后,用甲程序读出数据
我这个倒霉的程序估计只能用这种方法试一试
我这个倒霉的程序估计只能用这种方法试一试
#24
就SendMessage过去好了。
创建一个隐藏的窗口,标题为ucinheviusbovfueobdfvca
然后另一个程序用FindWIndow去找ucinheviusbovfueobdfvca,找到了就发送WM_CLOSE,然后ucinheviusbovfueobdfvca就会有Unload事件。你在Unload里面放上处理代码不就可以了。
这样做最简单了~
创建一个隐藏的窗口,标题为ucinheviusbovfueobdfvca
然后另一个程序用FindWIndow去找ucinheviusbovfueobdfvca,找到了就发送WM_CLOSE,然后ucinheviusbovfueobdfvca就会有Unload事件。你在Unload里面放上处理代码不就可以了。
这样做最简单了~
#25
这么小的通讯量没有必要用DDE
#26
但是按照pigpag的方法,还是这能得到一个副本的窗口,这个程序又不能只让它启动一次。。。
#27
看大不懂了……
#28
如果存在许多ucinheviusbovfueobdfvca都能得到吗?还是只有一个,或者用循环。。。
#29
可以用FindWIndowEx枚举
#30
能用VB自己带的功能作到的事为什么都要用API呢?至少用VB自带的功能更可靠啊。
我自己就是用上面说的那种DDE的方法。代码并不多呀。
我自己就是用上面说的那种DDE的方法。代码并不多呀。
#31
//但是按照pigpag的方法,还是这能得到一个副本的窗口,这个程序又不能只让它启动一次。。。
用我的方法,启动一个副本就追加一次数据
用我的方法,启动一个副本就追加一次数据
#32
//能用VB自己带的功能作到的事为什么都要用API呢?至少用VB自带的功能更可靠啊。
//我自己就是用上面说的那种DDE的方法。代码并不多呀。
VB的DDE和API用的都是Windows的子系统无所谓哪个可靠。
//我自己就是用上面说的那种DDE的方法。代码并不多呀。
VB的DDE和API用的都是Windows的子系统无所谓哪个可靠。
#33
//能用VB自己带的功能作到的事为什么都要用API呢?至少用VB自带的功能更可靠啊。
//我自己就是用上面说的那种DDE的方法。代码并不多呀。
VB的DDE和API用的都是Windows的子系统无所谓哪个可靠。
//我自己就是用上面说的那种DDE的方法。代码并不多呀。
VB的DDE和API用的都是Windows的子系统无所谓哪个可靠。
#34
new.sys不是系统文件,用任务管理器停止此进程,然后删除c:\winnt\system32\的new.sys文件,并用msconfig在启动项内取消此选项前的勾(2000没有msconfig.exe,请从98或XP系统内拷贝此程序到winnt目录下即可使用)!!!
#35
强
#1
谢谢大家帮忙!!!!!!!!!!!!!
#2
up
#3
关注
#4
上网的朋友一定都用过网络蚂蚁(Net Ants)的吧?不知你在使用过程中有没有注意过,
那就是如果你想调动两个“蚂蚁”为您效力是不可能的——它总会把新运行的关闭。
而“蚂蚁”程序的妙处就在于:在重复运行“蚂蚁”时它不仅拒绝运行,而且能把已经运
行的“蚂蚁”激活,这样用上面的程序就无能为力了。但事实上实现拒绝运行并激活已运行的
程序有多种方法:
1、用FindWindow函数得到已经运行窗体的句柄(HWND),然后用SetActiveWindow等API函
数将其激活。其缺点也很明显,那就是没法传递参数。
2、用FindWindow函数得到已运行窗体的句柄后用SendMessage的方法给窗体传送一个自定义
消息(附带参数),然后在窗体中拦截并进行处理,但这样做要修改窗体的标准消息处理
程序,用在VC,BC或DELPHI编写的程序中还行,但在VB中工作量太大,并且容易发生“一
般保护行错误”使VB崩溃,不太可取(当然,如果你有足够的信心和不怕崩溃的精神,也
可以试一下 ^_^ )。
3、使用DDE技术。
所谓DDE技术,就是动态数据交换技术。也许你很奇怪,这与本文所讨论的内容有什么相干的?
且听我慢慢讲来。
为了实现拒绝运行并把已经运行的程序激活并实现各种功能,我们可以先用本文开头提到的方
法,检测一下程序有没有被运行过,如果没有,就正常运行,如果已经被运行过,就打通与它的
DDE通道,传给它一个(或一些)数据,然后由已经运行的程序对数据进行处理,再去实现各种
“意想不到”的功能,这时也许就有人对这你的程序喊:“酷、酷……” ^_^
好了,耳听为虚,眼见为实,下面让我们动点真格的。
打开VB,新建一个工程,选择菜单中的“工程->工程1 属性”,把工程名称改为“P1”(我爱
偷懒,能短则短 ^_^ ),把已有的一个窗体的“LinkTopic”属性改为“FormDDE”,把“LinkMode”
属性改为“1 - Source”,添加一个PictureBox控件作为DDE执行控件,命名为picDDE。然后添加一个
TextBox控件,命名为“txtInfo”,并把“MultiLine”属性设置为“True”,以便显示多行文本,作为
消息显示控件。
最后在窗体代码区输入以下代码:
Const COMMANDLINE = "CommandLine=" 注释: 还是为了省事,定义一个常量
Private Sub Form_LinkExecute(CmdStr As String, Cancel As Integer)
Static lngCount As Long
Dim Info As String
Info = txtInfo.Text 注释: 保留原有信息
Select Case CmdStr 注释: CmdStr 是DDE程序传送过来的参数
Case "Max"
Me.WindowState = 2
Info = Info + vbNewLine + "窗体已被最大化"
Case "ShowTime"
Info = Info + vbNewLine + "最后一次运行这个程序的时间是:" + Str(Now)
Case "Count"
lngCount = lngCount + 1
Info = Info + vbNewLine + "你已经第" + Str(lngCount) + "次重复调用这个程序。" _
+ vbNewLine + "但怕您不多给工资,所以只运行了一个 ^_^"
End Select
If Left(CmdStr, Len(COMMANDLINE)) = COMMANDLINE Then
Info = Info + vbNewLine + "新程序曾以命令行形式运行" + vbNewLine + "命令行为:" _
+ vbNewLine + Right(CmdStr, Len(CmdStr) - Len(COMMANDLINE))
End If
txtInfo.Text = Info 注释: 把信息显示出来
Cancel = False
End Sub
Private Sub LinkAndSendMessage(ByVal Msg As String)
Dim t As Long
picDDE.LinkMode = 0 注释:--
picDDE.LinkTopic = "P1|FormDDE" 注释: |______连接DDE程序并发送数据/参数
picDDE.LinkMode = 2 注释: | “|”为管道符,是“退格键”旁边的竖线,
picDDE.LinkExecute Msg 注释:-- 不是字母或数字!
t = picDDE.LinkTimeout 注释:--
picDDE.LinkTimeout = 1 注释: |______终止DDE通道。当然,也可以用别的方法
picDDE.LinkMode = 0 注释: | 这里用的是超时强制终止的方法
picDDE.LinkTimeout = t 注释:--
End Sub
Private Sub Form_Load()
If App.PrevInstance Then 注释: 程序是否已经运行
Me.LinkTopic = "" 注释: 这两行用于清除新运行的程序的DDE服务器属性,
Me.LinkMode = 0 注释: 否则在连接DDE程序时会出乱子的
LinkAndSendMessage "Max" 注释:--
LinkAndSendMessage "Count" 注释: |-----连接DDE接受程序并传送数据/参数
LinkAndSendMessage "ShowTime" 注释:--
If Command <> "" Then 注释: 如果有命令行参数,就传递过去
LinkAndSendMessage COMMANDLINE + Command
End If
End 注释: 结束新程序的运行
End If
End Sub
测试一下:
把工程“P1”编译成EXE文件(设名称为 P1.EXE )
1、打开“我的电脑”,找到 P1.EXE 并执行。可以看到程序正常运行了。
2、再运行一次,这次新程序没有运行成功,而原来运行的程序却被最大化了,而且文本框中有以下
字符:
窗体已被最大化
你已经第 1次重复调用这个程序。
但怕您不多给工资,所以只运行了一个 ^_^
最后一次运行这个程序的时间是:00-2-6 7:11:01
3、打开 MS-DOS方式 ,用命令行方式再次运行程序,如 “P1 How Are You?”
这时原来运行的程序文本框中又多了几行字:
窗体已被最大化
你已经第 2次重复调用这个程序。
但怕您不多给工资,所以只运行了一个 ^_^
最后一次运行这个程序的时间是:00-2-6 7:14:32
新程序曾以命令行形式运行
命令行为:
How Are You?
OK,运行完全正确,然后你就可以把它应用的你的程序中了。
当然,这只是一些个人心得,如有疏漏之出,还请各位大虾指正。
#5
还有没有?
#6
还有没有?
#7
online的方法在一个程序启动多个副本的情况下,只对最后一个副本有效
#8
我写过类似的程序思路如下:
假定你的SERVER工程名为Server,主窗体名为Form1
将窗体Form1的LinkMode属性设为SOURCE,
再放上一个LABEL控件,名为Label_shutdown,CAPTION属性为"",如果不想让人看见可以将它的VISIBLE属性设为FALSE,不影响程序效果。
如果要结束CLINT程序运行,将其CAPTION设为"1"或者其他任何非空值,
如:Label_shutdown.Caption="ShutDown"
在你的CLINT程序中也放一个LABEL控件,假定名为Label1
并在窗体加载时(Form_load()中)作如下设定
Label1.LinkItem = "Label_shutdown"
Label1.LinkTopic = "Server|Form1"
Label1.LinkMode = 2
最后在Label1_Change()中加入
If label1.caption<>"" then end
CLINT程序就会自动关闭功能了。
这样当你在SERVER程序中只要将Label_shutdown的caption属性设为非空,CLINT程序就会自动关闭,无论有几个CLINT程序只要加入上述语句,全部可以关闭。
有一点必须注意,你的SERVER程序必须在CLINT程序之前运行,否则会得到一个"DDE超时"的错误。
最后,请给点分,我的分也不够了,问题也不少。
假定你的SERVER工程名为Server,主窗体名为Form1
将窗体Form1的LinkMode属性设为SOURCE,
再放上一个LABEL控件,名为Label_shutdown,CAPTION属性为"",如果不想让人看见可以将它的VISIBLE属性设为FALSE,不影响程序效果。
如果要结束CLINT程序运行,将其CAPTION设为"1"或者其他任何非空值,
如:Label_shutdown.Caption="ShutDown"
在你的CLINT程序中也放一个LABEL控件,假定名为Label1
并在窗体加载时(Form_load()中)作如下设定
Label1.LinkItem = "Label_shutdown"
Label1.LinkTopic = "Server|Form1"
Label1.LinkMode = 2
最后在Label1_Change()中加入
If label1.caption<>"" then end
CLINT程序就会自动关闭功能了。
这样当你在SERVER程序中只要将Label_shutdown的caption属性设为非空,CLINT程序就会自动关闭,无论有几个CLINT程序只要加入上述语句,全部可以关闭。
有一点必须注意,你的SERVER程序必须在CLINT程序之前运行,否则会得到一个"DDE超时"的错误。
最后,请给点分,我的分也不够了,问题也不少。
#9
不知是否是我理解的有问题,我怎么感觉用sendmessage发送一条wm_close消息就可以了,至于乙程序做的工作,在窗体的unload事件中写一些代码即可
#10
DDE 方法其实很好的。
如果实在不想用,
可以用 SendMessageCallback(HWND_BROADCAST, WM_MYMSG, ................)
这样接收的程序可以有返回数,发送程序的CallBack就可以接收到。
具体使用可以看MSDN,我没法解释的更清楚了。
#11
呵呵,我跟rainstormmaster(暴风雨 v2.0) 有同样的错觉
#12
sendmessage发送一条wm_close消息?怎么做法???
#13
不会吧,肯定是什么地方没说清楚.
kmzs怎么也是一星的人了,不会连这个都不知道吧.
kmzs怎么也是一星的人了,不会连这个都不知道吧.
#14
sendmessage(hwnd,wm_close,0,0)
#15
呵呵,这个帖子的提问者和回答者,除我之外都是CSDN上的重量级人物.是我至今为止,看到的阵容最强大的一帖.
少见!少见!
少见!少见!
#16
hwnd怎么得到?
#17
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
Const SW_SHOWNORMAL = 1
Const WM_CLOSE = &H10
Private Sub Form_Load()
Dim WinWnd As Long, Ret As String, RetVal As Long, lpClassName As String
WinWnd = FindWindow(vbNullString, "Quick Spy")
If WinWnd = 0 Then MsgBox "Couldn't find the window ...": Exit Sub
'PostMessage WinWnd, WM_CLOSE, 0&, 0&
SendMessage WinWnd, WM_CLOSE, 0, 0&
End Sub
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
Const SW_SHOWNORMAL = 1
Const WM_CLOSE = &H10
Private Sub Form_Load()
Dim WinWnd As Long, Ret As String, RetVal As Long, lpClassName As String
WinWnd = FindWindow(vbNullString, "Quick Spy")
If WinWnd = 0 Then MsgBox "Couldn't find the window ...": Exit Sub
'PostMessage WinWnd, WM_CLOSE, 0&, 0&
SendMessage WinWnd, WM_CLOSE, 0, 0&
End Sub
#18
//hwnd怎么得到
手段有很多
一个办法是在乙程序初始话时,将其窗口句柄保存在一个地方(临时文件、内存)中,然后,用甲程序读出数据
也可以先获得乙程序对应的pid,然后由pid获得hwnd
手段有很多
一个办法是在乙程序初始话时,将其窗口句柄保存在一个地方(临时文件、内存)中,然后,用甲程序读出数据
也可以先获得乙程序对应的pid,然后由pid获得hwnd
#19
WinWnd = FindWindow(vbNullString, "Quick Spy")
quick spy是窗口的标题
我就直接写了
看这个qq登陆器
http://community.csdn.net/Expert/topic/3116/3116573.xml?temp=.5579187
quick spy是窗口的标题
我就直接写了
看这个qq登陆器
http://community.csdn.net/Expert/topic/3116/3116573.xml?temp=.5579187
#20
//sendmessage发送一条wm_close消息?怎么做法???
//hwnd怎么得到?
kmzs(.:RNPA:.山水岿濛) 怎么混到一星的?这个连我都知道,虽然我没有做过什么VB程序 :-)
//hwnd怎么得到?
kmzs(.:RNPA:.山水岿濛) 怎么混到一星的?这个连我都知道,虽然我没有做过什么VB程序 :-)
#21
看看这个小例子对你有没有帮助~
仍然是用DDE,是两个程序之间的通讯例子~
'新建工程,窗体上放一个Text1
'Form1的LinkMode设为1,LinkTopic设为FormDDE
Private Sub Form_LinkExecute(CmdStr As String, Cancel As Integer)
If Len(CmdStr) Then Text1.Text = CmdStr
Cancel = 0
End Sub
'生成EXE为Test1.exe
'===========================================
'再新建工程,窗体上放一个Text1
'Form1的LinkMode设为1,添加代码
Private Sub Text1_Change()
With Text1
.LinkTopic = "工程1|FormDDE"
.LinkMode = 2
.LinkExecute Text1.Text
End With
End Sub
'生成EXE为Test2.exe
'===========================================
'分别运行Test1和Test2
'在Test2的文本框中输入内容,Text1的文本框中将出现相同内容
仍然是用DDE,是两个程序之间的通讯例子~
'新建工程,窗体上放一个Text1
'Form1的LinkMode设为1,LinkTopic设为FormDDE
Private Sub Form_LinkExecute(CmdStr As String, Cancel As Integer)
If Len(CmdStr) Then Text1.Text = CmdStr
Cancel = 0
End Sub
'生成EXE为Test1.exe
'===========================================
'再新建工程,窗体上放一个Text1
'Form1的LinkMode设为1,添加代码
Private Sub Text1_Change()
With Text1
.LinkTopic = "工程1|FormDDE"
.LinkMode = 2
.LinkExecute Text1.Text
End With
End Sub
'生成EXE为Test2.exe
'===========================================
'分别运行Test1和Test2
'在Test2的文本框中输入内容,Text1的文本框中将出现相同内容
#22
//kmzs(.:RNPA:.山水岿濛) 怎么混到一星的?这个连我都知道,虽然我没有做过什么VB程序 :-)
直到就说呀,快说。。。。。。
直到就说呀,快说。。。。。。
#23
//一个办法是在乙程序初始话时,将其窗口句柄保存在一个地方(临时文件、内存)中,然后,用甲程序读出数据
我这个倒霉的程序估计只能用这种方法试一试
我这个倒霉的程序估计只能用这种方法试一试
#24
就SendMessage过去好了。
创建一个隐藏的窗口,标题为ucinheviusbovfueobdfvca
然后另一个程序用FindWIndow去找ucinheviusbovfueobdfvca,找到了就发送WM_CLOSE,然后ucinheviusbovfueobdfvca就会有Unload事件。你在Unload里面放上处理代码不就可以了。
这样做最简单了~
创建一个隐藏的窗口,标题为ucinheviusbovfueobdfvca
然后另一个程序用FindWIndow去找ucinheviusbovfueobdfvca,找到了就发送WM_CLOSE,然后ucinheviusbovfueobdfvca就会有Unload事件。你在Unload里面放上处理代码不就可以了。
这样做最简单了~
#25
这么小的通讯量没有必要用DDE
#26
但是按照pigpag的方法,还是这能得到一个副本的窗口,这个程序又不能只让它启动一次。。。
#27
看大不懂了……
#28
如果存在许多ucinheviusbovfueobdfvca都能得到吗?还是只有一个,或者用循环。。。
#29
可以用FindWIndowEx枚举
#30
能用VB自己带的功能作到的事为什么都要用API呢?至少用VB自带的功能更可靠啊。
我自己就是用上面说的那种DDE的方法。代码并不多呀。
我自己就是用上面说的那种DDE的方法。代码并不多呀。
#31
//但是按照pigpag的方法,还是这能得到一个副本的窗口,这个程序又不能只让它启动一次。。。
用我的方法,启动一个副本就追加一次数据
用我的方法,启动一个副本就追加一次数据
#32
//能用VB自己带的功能作到的事为什么都要用API呢?至少用VB自带的功能更可靠啊。
//我自己就是用上面说的那种DDE的方法。代码并不多呀。
VB的DDE和API用的都是Windows的子系统无所谓哪个可靠。
//我自己就是用上面说的那种DDE的方法。代码并不多呀。
VB的DDE和API用的都是Windows的子系统无所谓哪个可靠。
#33
//能用VB自己带的功能作到的事为什么都要用API呢?至少用VB自带的功能更可靠啊。
//我自己就是用上面说的那种DDE的方法。代码并不多呀。
VB的DDE和API用的都是Windows的子系统无所谓哪个可靠。
//我自己就是用上面说的那种DDE的方法。代码并不多呀。
VB的DDE和API用的都是Windows的子系统无所谓哪个可靠。
#34
new.sys不是系统文件,用任务管理器停止此进程,然后删除c:\winnt\system32\的new.sys文件,并用msconfig在启动项内取消此选项前的勾(2000没有msconfig.exe,请从98或XP系统内拷贝此程序到winnt目录下即可使用)!!!
#35
强