⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sinstance.cpp

📁 一款密码保险箱源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
void CInstanceChecker::ReleaseLock()
{
  if (m_pExecuteLock)
  {
    delete m_pExecuteLock;
    m_pExecuteLock = NULL;
  }  
}

// Track the first instance of our App.
// return TRUE on success, else FALSE
BOOL CInstanceChecker::TrackFirstInstanceRunning()
{
  //If a previous instance is running, just return prematurely
  if (PreviousInstanceRunning())
    return FALSE;

  //If this is the first instance then copy in our info into the shared memory

  //First create the MMF
  int nMMFSize = sizeof(CWindowInstance);
  instanceData.hInstanceData = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nMMFSize, GetMMFFilename());
  if (instanceData.hInstanceData == NULL)
  {
    TRACE(_T("Failed to create the MMF even though this is the first instance, you might want to consider overriding GetMMFFilename()\n"));
    return FALSE;
  }

  //Open the MMF
  CWindowInstance* pInstanceData = static_cast<CWindowInstance*>(::MapViewOfFile(instanceData.hInstanceData, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize));
  ASSERT(pInstanceData != NULL);   //Opening the MMF should work

  // Lock the data prior to updating it
  CSingleLock dataLock(&m_instanceDataMutex, TRUE);
  pInstanceData->hMainWnd = GetWindowToTrack();
  ::UnmapViewOfFile(pInstanceData);

  //Since this will be the last function that will be called 
  //when this is the first instance we can release the lock
  ReleaseLock();

  return TRUE;
}

// Returns TRUE if a previous instance of the App is running.
BOOL CInstanceChecker::PreviousInstanceRunning()
{
  //Try to open the MMF first to see if we are the second instance
  HANDLE hPrevInstance = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, GetMMFFilename());
  BOOL bPreviousInstance = (hPrevInstance != NULL);
  if (hPrevInstance)
    CloseHandle(hPrevInstance);

  return bPreviousInstance;
}

CString CInstanceChecker::GetMMFFilename()
{
  CString sMMF(_T("CInstanceChecker_MMF_"));
  sMMF += m_sName;
  return sMMF;
}

HWND CInstanceChecker::GetWindowToTrack()
{
  //By default the window tracked will be the standard AfxGetMainWnd()
  ASSERT(AfxGetMainWnd() != NULL); //Did you forget to set up the mainfrm in InitInstance ?
  return AfxGetMainWnd()->GetSafeHwnd();
}

// Activate the Previous Instance of our Application.
HWND CInstanceChecker::ActivatePreviousInstance(LPCTSTR lpCmdLine, DWORD dwCopyDataItemData)
{
  //Try to open the previous instances MMF
  HANDLE hPrevInstance = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, GetMMFFilename());
  if (hPrevInstance)
  {
    // Open up the MMF
    int nMMFSize = sizeof(CWindowInstance);
    CWindowInstance* pInstanceData = static_cast<CWindowInstance*>(::MapViewOfFile(hPrevInstance, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize));
    if (pInstanceData != NULL) //Opening the MMF should work
    {
      //Lock the data prior to reading from it
      CSingleLock dataLock(&m_instanceDataMutex, TRUE);

      //activate the old window
      ASSERT(pInstanceData->hMainWnd); //Something gone wrong with the MMF
      HWND hWindow = pInstanceData->hMainWnd;

      if (hWindow)
      {
        CWnd wndPrev;
        wndPrev.Attach(hWindow);
        CWnd* pWndChild = wndPrev.GetLastActivePopup();

        //Restore the focus to the previous instance and bring it to the foreground
        if (wndPrev.IsIconic())
          wndPrev.ShowWindow(SW_RESTORE);

        if (pWndChild)
          pWndChild->SetForegroundWindow();

        if (lpCmdLine)
        {  
          //Send the current apps command line to the previous instance using WM_COPYDATA
          COPYDATASTRUCT cds;
          cds.dwData = dwCopyDataItemData;
          DWORD dwCmdLength = static_cast<DWORD>(_tcslen(lpCmdLine) + 1);
          cds.cbData = dwCmdLength * sizeof(TCHAR); 
          TCHAR* pszLocalCmdLine = new TCHAR[dwCmdLength]; //We use a local buffer so that we can specify a constant parameter
                                                           //to this function
        #if (_MSC_VER >= 1400)
          _tcscpy_s(pszLocalCmdLine, dwCmdLength, lpCmdLine);
        #else                                                 
          _tcscpy(pszLocalCmdLine, lpCmdLine);
        #endif
          cds.lpData = pszLocalCmdLine;
          CWnd* pMainWindow = AfxGetMainWnd();
          HWND hSender = NULL;
          if (pMainWindow)
            hSender = pMainWindow->GetSafeHwnd();

          //Send the message to the previous instance
          wndPrev.SendMessage(WM_COPYDATA, reinterpret_cast<WPARAM>(hSender), reinterpret_cast<LPARAM>(&cds));

          //Tidy up the heap memory we have used
          delete [] pszLocalCmdLine;
        }

        //Detach the CWnd we were using
        wndPrev.Detach();
      }

      //Unmap the MMF we were using
      ::UnmapViewOfFile(pInstanceData);

      //Close the file handle now that we 
      ::CloseHandle(hPrevInstance);

      //When we have activate the previous instance, we can release the lock
      ReleaseLock();

      //return the Window handle of the previous instance
      return hWindow;
    }

    //Close the file handle now that we 
    ::CloseHandle(hPrevInstance);

    //When we have activate the previous instance, we can release the lock
    ReleaseLock();
  }

  return NULL;
}

void CInstanceChecker::QuitPreviousInstance(int nExitCode)
{
  //Try to open the previous instances MMF
  HANDLE hPrevInstance = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, GetMMFFilename());
	if (hPrevInstance)
	{
		// Open up the MMF
		int nMMFSize = sizeof(CWindowInstance);
		CWindowInstance* pInstanceData = static_cast<CWindowInstance*>(::MapViewOfFile(hPrevInstance, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize));
		if (pInstanceData != NULL) //Opening the MMF should work
		{
		  // Lock the data prior to reading from it
		  CSingleLock dataLock(&m_instanceDataMutex, TRUE);

		  //activate the old window
		  ASSERT(pInstanceData->hMainWnd); //Something gone wrong with the MMF
		  HWND hWindow = pInstanceData->hMainWnd;

      //Ask it to exit
		  if (hWindow)
			  PostMessage(hWindow, WM_QUIT, nExitCode, 0);
	  }

    //Close the file handle now that we 
    ::CloseHandle(hPrevInstance);
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -