关于让程序窗口弹出的有关问题,欢迎深入细致的分析和讨论
关于让程序窗口弹出的问题,欢迎深入细致的分析和讨论
情境如下:有一个计时用的小程序,要求就是当时间达到后不论是否获得焦点都弹出到所有窗口最前面,以提示用户到时间了。
问题在于用户可能是最小化了这个程序,也可能是没有最小化但程序被其它窗口遮挡了,怎样才能最高效的让窗口肯定能弹出呢?
以下是我试验的几个方法,都有点问题,希望大神能解释一下这些现象
一、使用BringToTop(),不论是被遮挡还是最小化都不会有任何反应,程序的窗口都不会弹出。
二、使用ShowWindow(SW_RESTORE),只有在最小化的时候才会弹出,如果是被遮挡就无效了
三、连续执行SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE)和SetWindowPos(&wndNoTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);被遮挡的时候可以弹出,但是如果是最小化就无效了。
四、使用SetForegroundWindow(),被遮挡时不会弹出,但是任务栏上的图标会闪,最小化时无效。
我现在是把二和三同时使用,问题虽然可以解决,但是我更想知道的是背后的原理。比如最小化后窗口是不是已经不在Z序中了?怎样才是最专业最高效的写法?欢迎大家一起来讨论
------解决方案--------------------
------解决方案--------------------
...OnTimer.....
{
CPoint pt;
GetCursorPos(&pt);
CWnd *pWinAny=WindowFromPoint(pt);
DWORD tidOrig=GetWindowThreadProcessId(pWinAny->m_hWnd,0);
DWORD tid=GetCurrentThreadId();
if( tid != tidOrig)
{
afxDump << "Active My Window!\n";
if(AttachThreadInput(tid,tidOrig,TRUE))
{
SetActiveWindow();
// we have to detach it !
AttachThreadInput(tid,tidOrig,FALSE);
}
}
// 最小化后,要加入:
if (IsIconic())
{
ShowWindow(SW_RESTORE);
}
....
}
情境如下:有一个计时用的小程序,要求就是当时间达到后不论是否获得焦点都弹出到所有窗口最前面,以提示用户到时间了。
问题在于用户可能是最小化了这个程序,也可能是没有最小化但程序被其它窗口遮挡了,怎样才能最高效的让窗口肯定能弹出呢?
以下是我试验的几个方法,都有点问题,希望大神能解释一下这些现象
void CContTenMinDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(0==m_sec)
{
m_sec=59;
if(0==m_min)
{
m_min=9;
PlaySound("SystemStart",NULL,SND_ALIAS|SND_ASYNC);
BringWindowToTop();
//ShowWindow(SW_RESTORE);
//SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
//SetWindowPos(&wndNoTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
//SetForegroundWindow();
}
else
m_min--;
}
else
m_sec--;
一、使用BringToTop(),不论是被遮挡还是最小化都不会有任何反应,程序的窗口都不会弹出。
二、使用ShowWindow(SW_RESTORE),只有在最小化的时候才会弹出,如果是被遮挡就无效了
三、连续执行SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE)和SetWindowPos(&wndNoTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);被遮挡的时候可以弹出,但是如果是最小化就无效了。
四、使用SetForegroundWindow(),被遮挡时不会弹出,但是任务栏上的图标会闪,最小化时无效。
我现在是把二和三同时使用,问题虽然可以解决,但是我更想知道的是背后的原理。比如最小化后窗口是不是已经不在Z序中了?怎样才是最专业最高效的写法?欢迎大家一起来讨论
------解决方案--------------------
SetWindowPos(&CWnd::wndTopMost,0,0,800,600,SWP_SHOWWINDOW);
------解决方案--------------------
...OnTimer.....
{
CPoint pt;
GetCursorPos(&pt);
CWnd *pWinAny=WindowFromPoint(pt);
DWORD tidOrig=GetWindowThreadProcessId(pWinAny->m_hWnd,0);
DWORD tid=GetCurrentThreadId();
if( tid != tidOrig)
{
afxDump << "Active My Window!\n";
if(AttachThreadInput(tid,tidOrig,TRUE))
{
SetActiveWindow();
// we have to detach it !
AttachThreadInput(tid,tidOrig,FALSE);
}
}
// 最小化后,要加入:
if (IsIconic())
{
ShowWindow(SW_RESTORE);
}
....
}