程序只运行一个实例

来源:互联网 发布:淘宝退货卖家说损坏了 编辑:程序博客网 时间:2024/06/09 18:55

  这个问题应该是大多数程序员很熟知的问题,记录再此仅仅是作为备忘录,同时对于一些小的细节问题跟大家作一些探讨。这里仅仅针对window ce 6.0系统,其它平台未做过测试,这里不做讨论。

        在开发手机应用程序时,如果应用程序已经在运行,再次运行该应用程序时,我们需要把该应用程序的窗口提到前面来,把新的命令行参数传递给第一个运行实例,而第二个实例退出。从问题可以看出,需要解决的问题有三个:

  1. 保证应用程序单实例运行。最简单办法就是创建一个命名的mutex,第二个实例运行时创建同名的mutex会失败,便认为当前运行实例不是第一个了。
  2. 将新的参数传递给第一个运行实例。这可以通过WM_COPYDATA消息来实现。
  3. 将正在运行的应用程序的窗口提到前面来。这个问题在网上看到的办法都是采用API BringWindowToTop,只是我在测试过程中发现该api并没起到作用,所以只得使用了另一个函数SetWindowPos。

        下面是实例代码:

/**初始化代码**/
 HANDLE h = CreateMutex( NULL,TRUE,L"PhoneAppMutex");

 LPWSTR pstr = ::GetCommandLine();

 if (h)
 {
  int err = GetLastError();
  if (ERROR_ALREADY_EXISTS == err)
  {
   
   HWND     hWnd   =   ::FindWindow(L"CPhoneMainWnd",NULL);   


   COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/

   cpd.dwData = 0;

   cpd.cbData = wcslen(pstr) + 1;

   cpd.lpData = (void*)pstr;

   ::SendMessage(hWnd,WM_COPYDATA,NULL,(LPARAM)&cpd);//发送!   

   PostQuitMessage(0);

   return FALSE;
  }
 }
 else
 {
  return FALSE;
 }

 m_hPhoneMutex = h;    //保留句柄

--------------------------------------------------------------------------------------------

/**WM_COPYDATA消息处理**/

std::wstring str = (LPCWCHAR)pCopyDataStruct->lpData;
 str.substr(0,pCopyDataStruct->cbData);
 //MessageBox(NULL, str.c_str(), L"Phone", MB_OK);

//加入处理运行参数代码

 //::BringWindowToTop( m_hWnd );  奇怪的是该api无效,

//将窗口提到最前

 ::SetWindowPos(m_hWnd,HWND_TOPMOST,0,0,480,720,SWP_SHOWWINDOW);


总结:

步骤:
1、保证应用程序单实例运行。
最简单办法就是创建一个命名的mutex,第二个实例运行时创建同名的mutex会失败,便认为当前运行实例不是第一个了。
还可通过使用SetProp设置实例属性,在启动实例前查找是否存在该属性的程序,若存在则表示已运行。
2、将新的参数传递给第一个运行实例。
这可以通过WM_COPYDATA消息来实现。第二个实例在退出之前通过SendMessage发送消息,并在第一个实例中接收消息并处理。
3、将正在运行的应用程序的窗口提到前面来。
这个问题在网上看到的办法都是采用API BringWindowToTop,只是我在测试过程中发现该api并没起到作用,所以只得使用了另一个函数SetWindowPos。

原创粉丝点击