• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大龍的博客

            常用鏈接

            統(tǒng)計(jì)

            最新評論

            如何做到像《金山詞霸》一樣只運(yùn)行一個(gè)實(shí)例 --------- zt

            如何做到像《金山詞霸》一樣只運(yùn)行一個(gè)實(shí)例

            作者:孫鑫           日期:2002-7-30

            我們在使用《金山詞霸》時(shí)發(fā)現(xiàn),在《金山詞霸》已經(jīng)運(yùn)行了的情況下,再次點(diǎn)擊《金山詞霸》的圖標(biāo),那么它不會再運(yùn)行另外一個(gè)《金山詞霸》,而是將已有的《金山詞霸》給激活,始終只能運(yùn)行一個(gè)《金山詞霸》的實(shí)例。

            在我們的程序當(dāng)中如果要實(shí)現(xiàn)類似《金山詞霸》的功能,就要解決兩個(gè)問題,首先是要判斷該程序已有一個(gè)實(shí)例在運(yùn)行,其次是要將已運(yùn)行的應(yīng)用程序?qū)嵗せ睿瑫r(shí)退出第二個(gè)應(yīng)用程序?qū)嵗?/span>

            對于第一個(gè)問題,我們可以通過設(shè)置命名互斥對象或命名信標(biāo)對象,在程序啟動的時(shí)候檢測互斥對象或信標(biāo)對象,如互斥對象或信標(biāo)對象已存在,則可以判斷此程序已有一個(gè)實(shí)例正在運(yùn)行。

            第二個(gè)問題是如何找到已經(jīng)運(yùn)行的應(yīng)用程序?qū)嵗绻覀兡軌蛘业揭堰\(yùn)行實(shí)例主窗口的指針,即可調(diào)用SetForegroundWindow來激活該實(shí)例。我們可以通過兩種形式找到已運(yùn)行實(shí)例的主窗口,一種形式是通過調(diào)用FindWindowEx去查找正在運(yùn)行的窗口的句柄,這種方式用得比較多一些,而本文通過另一種形式去查找正在運(yùn)行的窗口的句柄。通過調(diào)用SetProp給應(yīng)用程序主窗口設(shè)置一個(gè)標(biāo)記,用GetDesktopWindow 可以獲取Windows環(huán)境下的桌面窗口的句柄,所有應(yīng)用程序的主窗口都可以看成該窗口的子窗口,接著我們就可以用GetWindow函數(shù)來獲得這些窗口的句柄。然后再用Win32 SDK函數(shù)GetProp查找每一個(gè)應(yīng)用程序的主窗口是否包含有我們設(shè)置的標(biāo)記,這樣就可以找到我們要找的第一個(gè)實(shí)例主窗口。

            下面演示代碼是以一個(gè)單文檔應(yīng)用程序?yàn)槔?,工程名字?/span>Mutex。

            1、在應(yīng)用程序類InitInstance()函數(shù)中判斷是否已有一個(gè)應(yīng)用程序?qū)嵗谶\(yùn)行。

            BOOL CMutexApp::InitInstance()

            {

                   //創(chuàng)建命名信標(biāo)對象。

                   HANDLE hSem=CreateSemaphore(NULL,1,1,"維新");

                   if(hSem) //信標(biāo)對象創(chuàng)建成功。

                   {

                          //信標(biāo)對象已經(jīng)存在,則程序已有一個(gè)實(shí)例在運(yùn)行。

                          if(ERROR_ALREADY_EXISTS==GetLastError())

                          {                  

                                 CloseHandle(hSem);      //關(guān)閉信號量句柄。

             

            //獲取桌面窗口的一個(gè)子窗口。

                                 HWND hWndPrev=::GetWindow(::GetDesktopWindow(),GW_CHILD);   

             

                                 while(::IsWindow(hWndPrev))

                                 {

                                 //判斷窗口是否有我們預(yù)先設(shè)置的標(biāo)記,如有,則是我們尋找的窗口,并將它激活。

                                        if(::GetProp(hWndPrev,"維新"))   

                                        {

                                        //如果主窗口已最小化,則恢復(fù)其大小。

                                               if (::IsIconic(hWndPrev))     

                                                      ::ShowWindow(hWndPrev,SW_RESTORE);

             

                                               //將應(yīng)用程序的主窗口激活。

                                               ::SetForegroundWindow(hWndPrev);

                                               return FALSE;                      //退出實(shí)例。

                                        }

                                        //繼續(xù)尋找下一個(gè)窗口。

                                        hWndPrev = ::GetWindow(hWndPrev,GW_HWNDNEXT);

                                 }

                                

                                 AfxMessageBox("已有一個(gè)實(shí)例在運(yùn)行,但找不到它的主窗口!");

                          }

                   }

                   else

                   {

                          AfxMessageBox("創(chuàng)建信標(biāo)對象失敗,程序退出!");

                          return FALSE;

                   }

             

                   AfxEnableControlContainer();

             

                   // Standard initialization

                   // If you are not using these features and wish to reduce the size

                   // of your final executable, you should remove from the following

                   // the specific initialization routines you do not need.

                  

            #ifdef _AFXDLL

                   Enable3dControls();                     // Call this when using MFC in a shared DLL

            #else

                   Enable3dControlsStatic();      // Call this when linking to MFC statically

            #endif

             

                   // Change the registry key under which our settings are stored.

                   // TODO: You should modify this string to be something appropriate

                   // such as the name of your company or organization.

                   SetRegistryKey(_T("Local AppWizard-Generated Applications"));

             

                   LoadStdProfileSettings(); // Load standard INI file options (including MRU)

             

                   // Register the application's document templates. Document templates

                   // serve as the connection between documents, frame windows and views.

             

                   CSingleDocTemplate* pDocTemplate;

                   pDocTemplate = new CSingleDocTemplate(

                          IDR_MAINFRAME,

                          RUNTIME_CLASS(CMutexDoc),

                          RUNTIME_CLASS(CMainFrame),       // main SDI frame window

                          RUNTIME_CLASS(CMutexView));

                   AddDocTemplate(pDocTemplate);

             

                   // Parse command line for standard shell commands, DDE, file open

                   CCommandLineInfo cmdInfo;

                   ParseCommandLine(cmdInfo);

             

                   // Dispatch commands specified on the command line

                   if (!ProcessShellCommand(cmdInfo))

                          return FALSE;

             

                   // The one and only window has been initialized, so show and update it.

                   m_pMainWnd->ShowWindow(SW_SHOW);

                   m_pMainWnd->UpdateWindow();

             

                   return TRUE;

            }

            2、在框架類的OnCreate()函數(shù)中設(shè)置查找標(biāo)記。

            int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

            {

                   if (CFrameWnd::OnCreate(lpCreateStruct) == -1)

                          return -1;

                  

                   if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP

                          | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||

                          !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

                   {

                          TRACE0("Failed to create toolbar\n");

                          return -1;      // fail to create

                   }

             

                   if (!m_wndStatusBar.Create(this) ||

                          !m_wndStatusBar.SetIndicators(indicators,

                           sizeof(indicators)/sizeof(UINT)))

                   {

                          TRACE0("Failed to create status bar\n");

                          return -1;      // fail to create

                   }

             

                   // TODO: Delete these three lines if you don't want the toolbar to

                   // be dockable

             

                   m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

                   EnableDocking(CBRS_ALIGN_ANY);

                   DockControlBar(&m_wndToolBar);

             

                  

                   //設(shè)置查找標(biāo)記。

                   ::SetProp(m_hWnd,"維新",(HANDLE)1);

             

                   return 0;

            }

            3、在程序退出是刪除設(shè)置的標(biāo)記,在框架類中響應(yīng)WM_DESTROY消息,進(jìn)行處理。

            void CMainFrame::OnDestroy()

            {

                   CFrameWnd::OnDestroy();

                  

                   // TODO: Add your message handler code here

                   //刪除所設(shè)置的標(biāo)記。

                   ::RemoveProp(m_hWnd,"維新");

            }

            至此,使應(yīng)用程序只運(yùn)行一個(gè)實(shí)例的功能就完成了。

            posted on 2007-08-29 11:32 大龍 閱讀(181) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            国产精品午夜久久| 久久久久久极精品久久久| 久久精品无码av| 亚洲国产精品久久久久久| 精品国产乱码久久久久久1区2区| 久久99久久99精品免视看动漫| 亚洲乱码日产精品a级毛片久久| 国产福利电影一区二区三区久久久久成人精品综合 | 99久久夜色精品国产网站| 亚洲国产一成久久精品国产成人综合 | 久久久久久精品成人免费图片| 热综合一本伊人久久精品| 久久99精品国产99久久6| 久久91这里精品国产2020| 久久五月精品中文字幕| 无码国内精品久久人妻麻豆按摩| 亚洲欧美久久久久9999| 亚洲AV成人无码久久精品老人| 久久99亚洲网美利坚合众国| 日韩亚洲欧美久久久www综合网| 国产精品欧美久久久天天影视| 嫩草影院久久国产精品| 欧美大战日韩91综合一区婷婷久久青草 | 亚洲中文字幕久久精品无码喷水| 久久久久成人精品无码中文字幕| 国内精品九九久久久精品| 精品久久久无码中文字幕| 久久亚洲精品成人无码网站 | 久久久噜噜噜久久中文福利| 18岁日韩内射颜射午夜久久成人| 国产精品久久波多野结衣| 无码人妻久久一区二区三区蜜桃 | 久久人人爽人人爽人人片AV麻豆 | 青青草国产精品久久久久| 久久青青色综合| 久久久综合九色合综国产| 色婷婷噜噜久久国产精品12p| 久久久国产精品亚洲一区| 久久精品国产亚洲一区二区三区| 久久精品人妻中文系列| 99精品久久久久久久婷婷|