程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> Visual Basic語言 >> VB6 >> 用DDE實現窗體防止運行多個實例並傳遞命令

用DDE實現窗體防止運行多個實例並傳遞命令

編輯:VB6

上網的朋友一定都用過網絡螞蟻(Net Ants)的吧?不知你在使用過程中有沒有注意過,那就是如果你想調動兩個“螞蟻”為您效力是不可能的——它總會把新運行的關閉。這點在VB 中很容易實現:

Private Sub Form_Load()

If App.PrevInstance Then

MsgBox "你已經運行這個應用程序了"

End   注釋: 退出新運行的程序

End If

End Sub

這樣如果你運行這個程序後在運行它,它會彈出一個消息框並拒絕再次運行。這非常容易。

而“螞蟻”程序的妙處就在於:在重復運行“螞蟻”時它不僅拒絕運行,而且能把已經運行的“螞蟻”激活,這樣用上面的程序就無能為力了。但事實上實現拒絕運行並激活已運行的 程序有多種方法:

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,運行完全正確,然後你就可以把它應用的你的程序中了。

當然,這只是一些個人心得,如有疏漏之出,還請各位大蝦指正。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved