系统托盘的问题

时间:2022-06-27 03:35:17
程序作了个系统托盘,现在我要在再次运行程序的时候把原来的程序界面显示出来,类似于金山词霸,最小化到系统菜单,再点击的图标的时候就显示原来隐藏的界面。我现在用CreateMutex判断程序是否已经运行,在它已经运行的时候我想调用已经运行程序的函数使界面显示出来(程序中有个OnAppShow函数来显示程序),应该怎么做??

12 个解决方案

#1


得到窗体的句柄,给她发送消息呀,就可以,给分吧!

#2


SetForegroundWindow

#3


标准方法:
1。程序一开始创建一个有名事件,并且有一个线程,执行WaitForSing.....,即等待该有名事件有信号;
2。同一个程序第二次运行时通过CreateEvent,可以知道之前是否有一个实例在运行了;
3。如果已有一个实例运行,则SetEvent,可使第一个实例的WaitForSing..收到事件信号;
4。第一个实例的线程收到信号后,可PostMessage消息到程序的主窗口里,然后执行OnAppShow


#4


symonds(就) :怎么得到窗口的句柄??
huangbeyond(校园人渣):可以给个范例吗??

#5


比較標准﹗

#6


BOOL CWinAppEx::FindAnotherInstance(LPCTSTR lpszUID)
{
ASSERT(lpszUID != NULL);
BOOL   bFound = FALSE;

// If two different applications register the same message string, 
// the applications return the same message value. The message 
// remains registered until the session ends. No need to use statics.

m_uMsgCheckInst = ::RegisterWindowMessage(lpszUID);

// If the message is successfully registered, the return value is a 
// message identifier in the range 0xC000 through 0xFFFF.

ASSERT(m_uMsgCheckInst >= 0xC000 && m_uMsgCheckInst <= 0xFFFF);

// Create a new mutex. If fails means that process already exists.

HANDLE hMutex  = ::CreateMutex(NULL, FALSE, lpszUID);
DWORD  dwError = ::GetLastError();

if(hMutex  != NULL &&
   dwError == ERROR_ALREADY_EXISTS || 
   dwError == ERROR_ACCESS_DENIED)
{
// Another instance of application is running

bFound = TRUE;

// One process can terminate the other process by broadcasting the private message 
// using the BroadcastSystemMessage function as follows:

if(::GetVersion() < 0x80000000) // WinNT
{
// TODO: Enable the SE_TCB_NAME  privilege 
// in the process token for BSM_ALLDESKTOPS.
}

DWORD dwReceipents = BSM_APPLICATIONS | BSM_ALLDESKTOPS; // BSM_ALLCOMPONENTS
::BroadcastSystemMessage( BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE,
&dwReceipents, m_uMsgCheckInst, NULL, NULL);
}
 
// Don't forget to close handles...

if (hMutex != NULL)
{
::ReleaseMutex(hMutex);
hMutex = NULL;   
}

return bFound;
}

#7


要那么复杂吗?
第二个进程用FindWindow找到窗口,然后再用ShowWindow显示就好了

#8


tabris17(四不象) :你有做过吗??能否给个例子?
f26511314(今天) :不太明白呢,我还要显示原来的程序界面

#9


CreateMutex()出错以后用
FindWindowEx()查找已经运行的窗口句柄
然后ShowWindow();

#10


HANDLE hMutex=CreateMutex(NULL,TRUE,"MemNerv\n\t");
  if (GetLastError()==ERROR_ALREADY_EXISTS)
  {
  ShowWindow(FindWindow(NULL,"windows caption"/*你的程序窗口的标题*/),SW_MAXIMIZE);
  SetForegroundWindow(FindWindow(NULL,"windows caption"));
  goto rtn;
  }

#11


goto rtn;
不好,最好别用goto

你要是在OnCreate()里面的话直接
return -1就行了

#12


thanx!!
一会给分!!

#1


得到窗体的句柄,给她发送消息呀,就可以,给分吧!

#2


SetForegroundWindow

#3


标准方法:
1。程序一开始创建一个有名事件,并且有一个线程,执行WaitForSing.....,即等待该有名事件有信号;
2。同一个程序第二次运行时通过CreateEvent,可以知道之前是否有一个实例在运行了;
3。如果已有一个实例运行,则SetEvent,可使第一个实例的WaitForSing..收到事件信号;
4。第一个实例的线程收到信号后,可PostMessage消息到程序的主窗口里,然后执行OnAppShow


#4


symonds(就) :怎么得到窗口的句柄??
huangbeyond(校园人渣):可以给个范例吗??

#5


比較標准﹗

#6


BOOL CWinAppEx::FindAnotherInstance(LPCTSTR lpszUID)
{
ASSERT(lpszUID != NULL);
BOOL   bFound = FALSE;

// If two different applications register the same message string, 
// the applications return the same message value. The message 
// remains registered until the session ends. No need to use statics.

m_uMsgCheckInst = ::RegisterWindowMessage(lpszUID);

// If the message is successfully registered, the return value is a 
// message identifier in the range 0xC000 through 0xFFFF.

ASSERT(m_uMsgCheckInst >= 0xC000 && m_uMsgCheckInst <= 0xFFFF);

// Create a new mutex. If fails means that process already exists.

HANDLE hMutex  = ::CreateMutex(NULL, FALSE, lpszUID);
DWORD  dwError = ::GetLastError();

if(hMutex  != NULL &&
   dwError == ERROR_ALREADY_EXISTS || 
   dwError == ERROR_ACCESS_DENIED)
{
// Another instance of application is running

bFound = TRUE;

// One process can terminate the other process by broadcasting the private message 
// using the BroadcastSystemMessage function as follows:

if(::GetVersion() < 0x80000000) // WinNT
{
// TODO: Enable the SE_TCB_NAME  privilege 
// in the process token for BSM_ALLDESKTOPS.
}

DWORD dwReceipents = BSM_APPLICATIONS | BSM_ALLDESKTOPS; // BSM_ALLCOMPONENTS
::BroadcastSystemMessage( BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE,
&dwReceipents, m_uMsgCheckInst, NULL, NULL);
}
 
// Don't forget to close handles...

if (hMutex != NULL)
{
::ReleaseMutex(hMutex);
hMutex = NULL;   
}

return bFound;
}

#7


要那么复杂吗?
第二个进程用FindWindow找到窗口,然后再用ShowWindow显示就好了

#8


tabris17(四不象) :你有做过吗??能否给个例子?
f26511314(今天) :不太明白呢,我还要显示原来的程序界面

#9


CreateMutex()出错以后用
FindWindowEx()查找已经运行的窗口句柄
然后ShowWindow();

#10


HANDLE hMutex=CreateMutex(NULL,TRUE,"MemNerv\n\t");
  if (GetLastError()==ERROR_ALREADY_EXISTS)
  {
  ShowWindow(FindWindow(NULL,"windows caption"/*你的程序窗口的标题*/),SW_MAXIMIZE);
  SetForegroundWindow(FindWindow(NULL,"windows caption"));
  goto rtn;
  }

#11


goto rtn;
不好,最好别用goto

你要是在OnCreate()里面的话直接
return -1就行了

#12


thanx!!
一会给分!!