以下代码放在BOOL CxxxApp::InitInstance()中
BOOL bAlreadyRunning;
HANDLE hMutexOneInstance = CreateMutex(NULL,FALSE,_T("706238C88F98"));
bAlreadyRunning = (GetLastError() == ERROR_ALREADY_EXISTS);
if(hMutexOneInstance)
ReleaseMutex(hMutexOneInstance);
if(bAlreadyRunning)
{
DWORD Pid = 0;
Pid = GetProcessidFromName("are.exe");//根据进程名获得进程ID
HWND hwnd = NULL;
hwnd = GetWindowHandleByPID(Pid);//根据进程ID获得窗口句柄
if (NULL! = hwnd)
{
::ShowWindow(hwnd,SW_SHOWMAXIMIZED); //窗口最大化
}
exit(NULL); //退出程序
return FALSE;
}
当打开第二次时,可以将前面打开的程序最大化,但是问题出来了,最大化的程序窗口不再响应鼠标消息,鼠标点上去没有任何反应,但是能响应键盘消息。
请问是什么原因呢?
有没有其他成熟的代码实现该功能,即防止软件重复打开,如果判断已经打开,那把第一个转到前台,最大化。
14 个解决方案
#1
HANDLE m_hMutex=CreateMutex(NULL,TRUE,"s1231254353535dd");
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
//AfxMessageBox("该程序已经运行",MB_ICONEXCLAMATION);
ExitProcess(0);
// return FALSE;
}
防止重复打开为什么还要让打开呢?
在BOOL CXXXXApp::InitInstance()加上上面这句好不?直接关闭。。
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
//AfxMessageBox("该程序已经运行",MB_ICONEXCLAMATION);
ExitProcess(0);
// return FALSE;
}
防止重复打开为什么还要让打开呢?
在BOOL CXXXXApp::InitInstance()加上上面这句好不?直接关闭。。
#2
用线程让前一个程序等待消息,再次打开可以用上段程序判断到,向前一个程序发送消息。。
#3
把
换成这样试下。
::ShowWindow(hwnd,SW_SHOWMAXIMIZED);
换成这样试下。
PostMessage(hWnd, WM_SHOWWINDOW,(WPARAM)TRUE, (LPARAM)SW_OTHERZOOM)
#4
谢谢回答,不过消息好像没有传递给hwnd。没有反应。如何让前一个程序响应本程序的消息呢?
#5
谢谢!请问如何让前一个程序等待消息?
#6
是把已经打开的那个程序最大化,你上面的给的代码是判断已经打开了程序,直接退出,我是想增加个功能,退出前把已经打开的程序最大化,再退出
#7
把他激活到置顶窗口就行了。
#8
Pid = GetProcessidFromName("are.exe");//根据进程名获得进程ID
HWND hwnd = NULL;
hwnd = GetWindowHandleByPID(Pid);//根据进程ID获得窗口句柄
--------------------------
你的这两个得到的HWND句柄对吗?
HWND hwnd = NULL;
hwnd = GetWindowHandleByPID(Pid);//根据进程ID获得窗口句柄
--------------------------
你的这两个得到的HWND句柄对吗?
#9
HANDLE hMutex = CreateMutex(NULL, FALSE, _T("XXXXXXXXX"));
if((NULL != hMutex) && (ERROR_ALREADY_EXISTS == GetLastError()))
{
HWND hWnd = ::FindWindow(NULL, _T("XXXXX"));
if(NULL != hWnd)
{
ShowWindow(hWnd, SW_MAXIMIZE);
}
CloseHandle(hMutex);
return FALSE;
}
#10
也可以查找前一个窗口,然后向该窗口发送你的自定义消息。你的程序截获这个自定义消息中实现最大化
#11
版主出来果然不一样。用::FindWindow 函数可以。
#12
我发现用上面的方法得到的窗口句柄hwnd 与 用::FindWindow函数得到的窗口句柄不一样,值不一样。是不是存在问题?
我的两个函数代码如下:
//根据进程名获得进程ID
DWORD Casfr::GetProcessidFromName(LPCTSTR name)
{
PROCESSENTRY32 pe;
DWORD id=0;
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe.dwSize=sizeof(PROCESSENTRY32);
if(!Process32First(hSnapshot,&pe))
return 0;
while(1)
{
pe.dwSize=sizeof(PROCESSENTRY32);
if(Process32Next(hSnapshot,&pe)==FALSE)
break;
if(strcmp(pe.szExeFile,name)==0)
{
id=pe.th32ProcessID;
break;
}
}
CloseHandle(hSnapshot);
return id;
}
//通过进程ID获取窗口句柄
HWND Casfr ::GetWindowHandleByPID(DWORD dwProcessID)
{
HWND h = GetTopWindow(0);
while ( h )
{
DWORD pid = 0;
DWORD dwTheardId = GetWindowThreadProcessId( h,&pid);
if (dwTheardId != 0)
{
if ( pid == dwProcessID/*your process id*/ )
{
// here h is the handle to the window
return h;
}
}
h = GetNextWindow( h , GW_HWNDNEXT);
}
return NULL;
}
请版主及高人帮我看看是不是有问题。
#13
获取进程ID的以后,利用EnumWindows枚举窗口,在枚举窗口的毁掉函数中GetWindowThreadProcessId()比对ID,匹配则找到HWND,返回该HWND窗口句柄即可。
#14
为什么不用互斥量?
#1
HANDLE m_hMutex=CreateMutex(NULL,TRUE,"s1231254353535dd");
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
//AfxMessageBox("该程序已经运行",MB_ICONEXCLAMATION);
ExitProcess(0);
// return FALSE;
}
防止重复打开为什么还要让打开呢?
在BOOL CXXXXApp::InitInstance()加上上面这句好不?直接关闭。。
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
//AfxMessageBox("该程序已经运行",MB_ICONEXCLAMATION);
ExitProcess(0);
// return FALSE;
}
防止重复打开为什么还要让打开呢?
在BOOL CXXXXApp::InitInstance()加上上面这句好不?直接关闭。。
#2
用线程让前一个程序等待消息,再次打开可以用上段程序判断到,向前一个程序发送消息。。
#3
把
换成这样试下。
::ShowWindow(hwnd,SW_SHOWMAXIMIZED);
换成这样试下。
PostMessage(hWnd, WM_SHOWWINDOW,(WPARAM)TRUE, (LPARAM)SW_OTHERZOOM)
#4
谢谢回答,不过消息好像没有传递给hwnd。没有反应。如何让前一个程序响应本程序的消息呢?
#5
谢谢!请问如何让前一个程序等待消息?
#6
是把已经打开的那个程序最大化,你上面的给的代码是判断已经打开了程序,直接退出,我是想增加个功能,退出前把已经打开的程序最大化,再退出
#7
把他激活到置顶窗口就行了。
#8
Pid = GetProcessidFromName("are.exe");//根据进程名获得进程ID
HWND hwnd = NULL;
hwnd = GetWindowHandleByPID(Pid);//根据进程ID获得窗口句柄
--------------------------
你的这两个得到的HWND句柄对吗?
HWND hwnd = NULL;
hwnd = GetWindowHandleByPID(Pid);//根据进程ID获得窗口句柄
--------------------------
你的这两个得到的HWND句柄对吗?
#9
HANDLE hMutex = CreateMutex(NULL, FALSE, _T("XXXXXXXXX"));
if((NULL != hMutex) && (ERROR_ALREADY_EXISTS == GetLastError()))
{
HWND hWnd = ::FindWindow(NULL, _T("XXXXX"));
if(NULL != hWnd)
{
ShowWindow(hWnd, SW_MAXIMIZE);
}
CloseHandle(hMutex);
return FALSE;
}
#10
也可以查找前一个窗口,然后向该窗口发送你的自定义消息。你的程序截获这个自定义消息中实现最大化
#11
版主出来果然不一样。用::FindWindow 函数可以。
#12
我发现用上面的方法得到的窗口句柄hwnd 与 用::FindWindow函数得到的窗口句柄不一样,值不一样。是不是存在问题?
我的两个函数代码如下:
//根据进程名获得进程ID
DWORD Casfr::GetProcessidFromName(LPCTSTR name)
{
PROCESSENTRY32 pe;
DWORD id=0;
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe.dwSize=sizeof(PROCESSENTRY32);
if(!Process32First(hSnapshot,&pe))
return 0;
while(1)
{
pe.dwSize=sizeof(PROCESSENTRY32);
if(Process32Next(hSnapshot,&pe)==FALSE)
break;
if(strcmp(pe.szExeFile,name)==0)
{
id=pe.th32ProcessID;
break;
}
}
CloseHandle(hSnapshot);
return id;
}
//通过进程ID获取窗口句柄
HWND Casfr ::GetWindowHandleByPID(DWORD dwProcessID)
{
HWND h = GetTopWindow(0);
while ( h )
{
DWORD pid = 0;
DWORD dwTheardId = GetWindowThreadProcessId( h,&pid);
if (dwTheardId != 0)
{
if ( pid == dwProcessID/*your process id*/ )
{
// here h is the handle to the window
return h;
}
}
h = GetNextWindow( h , GW_HWNDNEXT);
}
return NULL;
}
请版主及高人帮我看看是不是有问题。
#13
获取进程ID的以后,利用EnumWindows枚举窗口,在枚举窗口的毁掉函数中GetWindowThreadProcessId()比对ID,匹配则找到HWND,返回该HWND窗口句柄即可。
#14
为什么不用互斥量?