程序只运行一个实例
2012-11-17 22:05
183 查看
这个问题应该是大多数程序员很熟知的问题,记录再此仅仅是作为备忘录,同时对于一些小的细节问题跟大家作一些探讨。这里仅仅针对window ce 6.0系统,其它平台未做过测试,这里不做讨论。
在开发手机应用程序时,如果应用程序已经在运行,再次运行该应用程序时,我们需要把该应用程序的窗口提到前面来,把新的命令行参数传递给第一个运行实例,而第二个实例退出。从问题可以看出,需要解决的问题有三个:
保证应用程序单实例运行。最简单办法就是创建一个命名的mutex,第二个实例运行时创建同名的mutex会失败,便认为当前运行实例不是第一个了。
将新的参数传递给第一个运行实例。这可以通过WM_COPYDATA消息来实现。
将正在运行的应用程序的窗口提到前面来。这个问题在网上看到的办法都是采用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。
在开发手机应用程序时,如果应用程序已经在运行,再次运行该应用程序时,我们需要把该应用程序的窗口提到前面来,把新的命令行参数传递给第一个运行实例,而第二个实例退出。从问题可以看出,需要解决的问题有三个:
保证应用程序单实例运行。最简单办法就是创建一个命名的mutex,第二个实例运行时创建同名的mutex会失败,便认为当前运行实例不是第一个了。
将新的参数传递给第一个运行实例。这可以通过WM_COPYDATA消息来实现。
将正在运行的应用程序的窗口提到前面来。这个问题在网上看到的办法都是采用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。
相关文章推荐
- 确保一个程序只运行一个实例(BCB,Delphi)
- vc 防止程序重复运行(即只运行一个实例)并激活已运行进程和枚举进程及窗口
- C# WINFORM判断程序是否运行,且只能运行一个实例
- WINCE中只允许程序运行一个实例
- .net中如何只允许运行一个程序实例
- 点击程序只运行一个实例
- qt编写一个只能运行单个实例的程序,不用Windows API
- 程序只运行一个实例
- C# 让程序只能运行一个实例
- 用C#给程序加启动画面并只允许一个应用程序实例运行
- 用C#给程序加启动画面并只允许一个应用程序实例运行
- Qt中让程序只运行一个实例
- 使Qt 程序只能运行一个实例的3种方法
- 在VC++中实现让程序只运行一个实例的方法
- 让程序只运行一个实例的5种方法
- 让程序只运行一个实例的四种方法
- 使程序只能运行一个实例
- MFC 程序只能运行一个实例 互斥对象
- 让程序只运行一个实例的四种方法(转)
- 程序只运行一个实例(四)