熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

delphi中,讓程序只運行一次的方法[1]

2013-11-23 17:39:18  來源: Delphi編程 

  公司開發的軟件需要對串口進行操作每次打開軟件後程序自動去打開串口尋找連接到串口上的設備但是如果用戶不知道打開了兩次那麼第二次打開的程序是不能正常使用的因為對串口的操作時獨占的第一個程序獨占了串口的使用權其他程序無法再使用那一個串口當然如果PC機器上有兩個串口那第二個程序也是可以用的為了解決這個問題必須限制對串口操作的軟件只能打開一個打開軟件後用戶如果誤操作再次想打開該軟件需要提示用戶軟件已經打開並讓已打開的軟件顯示在窗口最頂層

  下面是Delphi版的解決方法

  (方法一)
  利用互斥對象
  開發過多線程軟件的可能都使用過互斥對象它常被用做線程間同步的技術手段簡要的提一下互斥對象互斥對象把第一次建立它的程序作為主程序這樣只用檢測互斥對象是否已經有主程序就判斷程序是否已經運行過這裡需要涉及到一個api函數WaitForSingleObject該函數的第一個參數為用以檢測的互斥對象個參數的表示函數返回結果前的滯留時間如果改函數返回wait_TimeOut就表明互斥對象已經有了一個主程序

  注意以下的代碼都出現在工程文件中而不是單元文件中
  var
   myMutex:HWND;
  begin
    //CreateMutex建立互斥對象並且給互斥對象起一個唯一的名字
    myMutex:=CreateMutex(nilfalsehkOneCopy);
    //程序沒有被運行過
    if WaitForSingleObject(myMutex)<>wait_TimeOut then
    begin
     ApplicationInitialize;
     ApplicationCreateForm(TForm Form);
     ApplicationRun;
    End;
  End;
  [注釋]

  當應用程序第一次運行的時候在應用程序中會建立一個互斥對象名稱為hkOneCopy然後判斷系統中有沒有這個互斥對象如果沒有則初始化應用程序

  下面再完善一下這個程序

  我們不希望程序被多次運行而是希望如果程序運行過後再運行這個程序的時候將已運行的程序做出一些響應比如說讓它變為最上層的活動窗口來提示用戶該程序正在運行為達到這個目的必須要獲得正在運行程序的句柄然後用一個APISetForeGroundWindow(handle)來使程序的窗口最前並激活為了得到程序的句柄要使用windows枚舉函數EnumWindows來遍歷windows窗口列表該函數需要一個回調函數作參數用這個回調函數來對每一個系統中的窗口進行調用直到最後一個窗口或回調函數返回false為止[注關於EnumWindows函數的介紹在篇尾]只要編寫這個回調函數並在其中不斷的比較當前遍歷到的窗口類名和我們的程序的主窗口類名以及比較窗口可執行文件的名稱和我們程序的名稱直到找到相同的為止將這時的窗口句柄保存下來就行了為獲得窗口的類名和句柄需要一個APIGetClassName為獲得可執行文件的名稱需要APIGetModuleFileName

  下面是詳細代碼

  注意下面代碼在delphi下運行通過但是如果窗口最小化後再次運行程序時原先已經運行的程序能夠被置前並激活但是標題欄的最小化按鈕卻不能用了當嘗試了N中方法後估計是delphi自身TForm類的問題下面給出一個解決方案在窗口上放一個ApplicationEvents控件它管理著應用程序所有的消息我們在它的OnMessage事件裡寫上下面的代碼
    if Msghwnd=FormHandle then
   begin
  // 是在標題欄按下鼠標
  // 是在標題欄的最小化按鈕上按下鼠標
     if (Msgmessage= ) and (msgwParam= ) then
     begin
       FormWindowState:=  wsMinimized;
     end;
   end;
  

[]  []  []  


From:http://tw.wingwit.com/Article/program/Delphi/201311/24832.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.