用VC++實現程式運行唯一執行個體

來源:互聯網
上載者:User

用VC++實現程式運行唯一執行個體

方法一:

一、 實現方法

  對於具有視窗的應用程式,可以用靜態函數CWnd::FindWindow()尋找固定視窗,來判斷程式是否已經運行。函數原型為:

CWnd* PASCAL FindWindow( LPCTSTR lpszClassName, LPCTSTR lpszWindowName );

  這個函數有兩個參數,第一個是要找的視窗的類,第二個是要找的視窗的標題。在搜尋的時候不一定兩者都知道,但至少要知道其中的一個。有的視窗的標題是比較容易得到的,如"計算機",所以搜尋時應使用標題進行搜尋。但有的軟體的標題不是固定的,如"記事本",如果開啟的檔案不同,視窗標題也不同,這時使用視窗類別搜尋就比較方便。如果找到了滿足條件的視窗,這個函數返回該視窗的指標,否則傳回值為NULL。

  考慮到程式的健壯性,我們還需要判斷視窗是否處於最小化狀態、是否有彈出式子視窗,這就需要使用CWnd:: GetLastActivePopup()、CWnd::IsIconic()函數,它們的原型分別為:

CWnd* GetLastActivePopup( )

  該函數返回一個指定父視窗中最近啟用過的彈出式視窗的指標。如果視窗本身是剛剛啟用的,或視窗不包含任何快顯視窗,那麼該函數返回指向父視窗自身的指標。

BOOL IsIconic( )

  該函數用來判斷當前視窗是否處於最小化狀態,如果視窗處於最小化狀態,函數傳回值為True,否則返回Flase。

  對於處於最小化狀態的視窗,可以調用CWnd::ShowWindow( int nCmdShow )恢複視窗的正常狀態,該函數的原型為:

BOOL ShowWindow( int nCmdShow )

  如視窗之前是可見的,函數調用後返回True,否則返回False。參數nCmdShow的值可以為以下任意個常數:

  SW_HIDE:隱藏視窗,活動狀態給令一個視窗;

  SW_MINIMIZE:已最小化的視窗,活動狀態給另一個視窗;

  SW_RESTORE:用原來的大小和位置顯示一個視窗,同時令其進入活動狀態;

  SW_SHOW:用當前的大小和位置顯示一個視窗,同時令其進入活動狀態;

  SW_SHOWMAXIMIZED:已最大化的視窗,並將其啟用;

  SW_SHOWMINIMIZED:已最小化的視窗,並將其啟用;

  SW_SHOWMINNOACTIVE:最小化一個視窗,同時不改變使用中視窗;

  SW_SHOWNA:用當前的大小和位置顯示一個視窗,不改變使用中視窗;

  SW_SHOWNOACTIVATE:用最近的大小和位置顯示一個視窗,不改變使用中視窗;

  SW_SHOWNORMAL:與SW_RESTORE相同;

  最後不要忘記了用CWnd:: SetForegroundWindow()函數將快顯視窗設定為案頭的最前端。

  有了上面的知識,我們就可以修改程式中應用程式類的InitInstance()函數,如果程式已經運行,也即是可以發現相應的程式視窗,那麼就顯示該視窗,InitInstance()函數就返回False,程式提前退出,否則就正常運行。

      上述方法雖然實現起來很簡單,但是他對於無視窗的應用程式卻無能為力。

  二、 編程步驟

  1、 啟動Visual C++6.0,產生一個基於對話方塊的應用程式,程式命名為"Instance";

  2、 修改程式的InitInstance()函數;

  3、 添加代碼,編譯運行程式;

     代碼如下:
     BOOL CTestApp::InitInstance()
    {//------------添加--------------
       if (!FirstInitInstance())
       return false;
      //--------------end--------------

       AfxEnableControlContainer();

     //SetDialogBkColor(RGB(160,180,220),RGB(0,0,0));//設定背景顏色
     #ifdef _AFXDLL
        Enable3dControls();   
     #else
     Enable3dControlsStatic(); 
     #endif

     CTestrDlg dlg;
     m_pMainWnd = &dlg;
     int nResponse = dlg.DoModal();
     if (nResponse == IDOK)
     {
 
     }
     else if (nResponse == IDCANCEL)
     {
  
     }
     return FALSE;
 }
  //-----------添加的成員函數FirstInitInstance()---------------
  BOOL CTestApp::FirstInitInstance()
  {
     CWnd *p;
     if(p = CWnd::FindWindow(NULL, "ocr"))
     {
        p->GetLastActivePopup();
        if (p->IsIconic())

       {
           p->ShowWindow(SW_RESTORE);

       }
       p->SetForegroundWindow();
       return false;
   }
   else
      return true;
 }
  //成員函數的型別宣告是:
  public:
    CTestApp();

   //{{AFX_VIRTUAL(COcrApp)
   public:
   virtual BOOL InitInstance();
   virtual BOOL FirstInitInstance();
   //}}AFX_VIRTUAL

方法二:

1.聲明控制代碼HANDLE hApp

2.在InitInstance()函數中寫入以下代碼:

  //只運行一個執行個體
   hApp = CreateMutex(NULL,FALSE,"OnlyOneInstanceExample");
  if(GetLastError() == ERROR_ALREADY_EXISTS)
  {
    AfxMessageBox("Already Exist An Instance!");
    return FALSE;
   }

 3. 在ExitInstance() 函數中寫入以下代碼:
  {
    CloseHandle(hApp);
    return CWinApp::ExitInstance();
   }

方法三:

      通過動態串連庫DLL實現更通用的控製程式啟動並執行方法。在DLL中使用#pragma data_seg指令實現共用資料區段,在該資料區段中定義一個變數long m_nRun,並配置其初始值為-1,同時還要在DLL的進入點函數DllMain返回成功值的語句前添加語句m_nRun++,意思是在應用程式啟動串連DLL成功時對已啟動並執行執行個體進行計數,然後在DLL中匯出一個函數來返回該變數的值。最後將應用程式的工程配置為依賴於該DLL的工程,在應用程式根據DLL中的m_nRun變數的值來判斷是否程式已運行了。

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.