to sundayboys: 我本来就可以判断的。 to xxxbird: 你可能误解了我的意思了。给你门看看我的代码吧 CMenu menu, *pSubMenu; // Clicking with right button brings up a context menu if (LOWORD(lParam) == WM_RBUTTONUP) { if (!menu.LoadMenu(m_tnd.uID)) return 0; if (!(pSubMenu = menu.GetSubMenu(0))) return 0; // Make first menu item the default (bold font) ::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE); //Display and track the popup menu CPoint pos; GetCursorPos(&pos); ::SetForegroundWindow(m_tnd.hWnd); ::TrackPopupMenu(pSubMenu->m_hMenu, 0, pos.x, pos.y, 0, m_tnd.hWnd, NULL); // BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly" ::PostMessage(m_tnd.hWnd, WM_NULL, 0, 0); menu.DestroyMenu(); } else if (LOWORD(lParam) == WM_LBUTTONUP) {
HWND GetTopWindow( HWND hWnd // handle to parent window ); Parameters hWnd [in] Handle to the parent window whose child windows are to be examined. If this parameter is NULL, the function returns a handle to the window at the top of the Z order.
可以在窗口的WM_ACTIVATE消息或OnActivate中判断窗口显示状态的改变。
我本来就可以判断的。
to xxxbird:
你可能误解了我的意思了。给你门看看我的代码吧
CMenu menu, *pSubMenu; // Clicking with right button brings up a context menu
if (LOWORD(lParam) == WM_RBUTTONUP)
{
if (!menu.LoadMenu(m_tnd.uID)) return 0;
if (!(pSubMenu = menu.GetSubMenu(0))) return 0; // Make first menu item the default (bold font)
::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE); //Display and track the popup menu
CPoint pos;
GetCursorPos(&pos); ::SetForegroundWindow(m_tnd.hWnd);
::TrackPopupMenu(pSubMenu->m_hMenu, 0, pos.x, pos.y, 0, m_tnd.hWnd, NULL); // BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly"
::PostMessage(m_tnd.hWnd, WM_NULL, 0, 0); menu.DestroyMenu();
}
else if (LOWORD(lParam) == WM_LBUTTONUP)
{
if(!IsWindowVisible(m_tnd.hWnd))
{
::ShowWindow(m_tnd.hWnd, SW_SHOW);
::SetForegroundWindow(m_tnd.hWnd);
//::ShowWindow(m_tnd.hWnd,SW_RESTORE);
}
else
{
HWND topWin=GetWindow(GetForegroundWindow(),GW_HWNDNEXT);
if(topWin!=m_tnd.hWnd)
{//被别的窗体挡住了,提前
::SetForegroundWindow(m_tnd.hWnd);
}
else //在最上面
::ShowWindow(m_tnd.hWnd,SW_HIDE);
}
menu.DestroyMenu();
} return 1;
下面那句 else //在最上面
::ShowWindow(m_tnd.hWnd,SW_HIDE);我也试过getforegroundwindow/getactivewindow....不行,原因我标题里已经给出我还试过。GetWindow(m_tnd.hWnd,GW_HWNDNEXT);
注:m_tnd为一个结构,m_tnd.hWnd这个句柄就是主界面的背景。。
如果各位有kingsoft词霸,可以点着看看,我要的就是那种效果。(它如果被遮住[不是隐藏],点击图标会提前)
如果是top 则只枚举top窗体。
而taskbar应该属于topmost窗体吧,所以我认为 GetWindow(m_tnd.hWnd,GW_HWNDNEXT);
应该可以,可惜~~~~~~~~~~
IsWindowVisible 不是这样用的,它只是说明这个窗口是否可见,只要这个窗口及其父窗口,父窗口的父窗口等都有 WS_VISIBLE 属性,它就返回TRUE,而不管这个窗口当前是否可见。
你可以用GetForegroundWindow是否与当m_tnd.hWnd相等来判断。
是呀,我现在的难度就是要判断这两种情况,
1。主窗体为最前(其实这么说不科学,应该是获得输入。)
2。主窗体被某个窗体遮住,并不是被topmost窗体遮住。按道理用getactivewindow不就行了,可是当用户点了system tray后,taskbar将剥夺当前active window的焦点
2。如果主窗体隐藏了,则显示,并setforegroundwindow
3。如果主窗体被别的窗体遮住了,则setforegroundwindow等价于1。本程序主窗体在激活状态,则隐藏,
2。如果主窗体未激活,则显示,并setforegroundwindow
3。如果主窗体未激活,则显示,并setforegroundwindow隐藏或被别的窗体遮住不都是在未激活状态.
能再把我的说明看清楚一点吗。再次感谢
HWND hWnd // handle to parent window
);
Parameters
hWnd
[in] Handle to the parent window whose child windows are to be examined. If this parameter is NULL, the function returns a handle to the window at the top of the Z order.
它并不区分topmost和nontopmost窗体,topmost的zorder当然要比nontopmost的高了。
然后:::GetWindow(hwndCurr,GW_HWNDFIRST);试试
winamp是总也setforegroundwindow,很容易实现金山词霸,金山毒霸,flashget等等实现了这种。
{
CFrameWnd::OnActivateApp(bActive, hTask);
// TODO: Add your message handler code here
if( !bActive )
{
m_hTask = (DWORD)hTask;
}
}void CMainFrame::OnTrayNotify(WPARAM wParam,LPARAM lParam)
{
switch( (UINT)lParam )
{
case WM_LBUTTONDBLCLK:
CWnd* pWnd = FindWindow("Shell_TrayWnd", NULL);
DWORD hThread;
hThread = GetWindowThreadProcessId( pWnd->GetSafeHwnd(), NULL );
if( hThread == m_hTask )
{
// 主窗口为TOPMOST窗口
}
}
我试试看是否可以用
恩,好主意!!!
不过不知道被topmost窗体盖住的话会是怎样。。真不知道金山词霸2000 (.net版本是狗屎!!!不能实现)是怎么处理的,flashget的处理方式有别于金山词霸2000 ,flashget只要露出一点点就点一下就hide,而词霸2000只要是被人家遮住一点都会提前的。
我这个CDialog原来就已被改为window了,只是我以为只有一个WM_ACTIVE呢,原来还有一个WM_ACTIVEAPP,呵呵,试试
所以也不能简单的向任务栏按钮发送点击信息(并且我现在用了WS_EXTOOLWINDOW属性,隐藏了任务栏的按钮)