呵呵,如果被遮住了,用IsWindowVisible判断。这个一定准确:)

解决方案 »

  1.   


    可以在窗口的WM_ACTIVATE消息或OnActivate中判断窗口显示状态的改变。
      

  2.   

    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) 
        {
           
    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;
      

  3.   

    ::GetWindow(::GetTopWindow(NULL),GW_HWNDNEXT))GetForegroundWindow不是取Z-order第一个。
      

  4.   

    重点看对 WM_LBUTTONUP 的处理部分我用这段函数的结果就是,永远执行不到
    下面那句    else //在最上面
                    ::ShowWindow(m_tnd.hWnd,SW_HIDE);我也试过getforegroundwindow/getactivewindow....不行,原因我标题里已经给出我还试过。GetWindow(m_tnd.hWnd,GW_HWNDNEXT);
                注:m_tnd为一个结构,m_tnd.hWnd这个句柄就是主界面的背景。。
    如果各位有kingsoft词霸,可以点着看看,我要的就是那种效果。(它如果被遮住[不是隐藏],点击图标会提前)
            
      

  5.   

    好的,我试试,我用::GetWindow(::GetTopWindow(NULL),GW_HWNDNEXT))是不行的
      

  6.   

    ::GetTopWindow(NULL)也不行。本来getwindow挺好的,它第一个参数如果是topmost  则只枚举topmost窗体。
                                   如果是top       则只枚举top窗体。
    而taskbar应该属于topmost窗体吧,所以我认为 GetWindow(m_tnd.hWnd,GW_HWNDNEXT);
    应该可以,可惜~~~~~~~~~~
      

  7.   


    IsWindowVisible 不是这样用的,它只是说明这个窗口是否可见,只要这个窗口及其父窗口,父窗口的父窗口等都有 WS_VISIBLE 属性,它就返回TRUE,而不管这个窗口当前是否可见。
      

  8.   


    你可以用GetForegroundWindow是否与当m_tnd.hWnd相等来判断。
      

  9.   

    to xxxbird:
        是呀,我现在的难度就是要判断这两种情况,
    1。主窗体为最前(其实这么说不科学,应该是获得输入。)
    2。主窗体被某个窗体遮住,并不是被topmost窗体遮住。按道理用getactivewindow不就行了,可是当用户点了system tray后,taskbar将剥夺当前active window的焦点
      

  10.   

    上面两种情况用iswindowvisble判断都是true!
      

  11.   

    to xxxbird:    看前面我的说明,你的建议我已经试过了。 :(
      

  12.   

    1。本程序主窗体在最前面,则隐藏,
    2。如果主窗体隐藏了,则显示,并setforegroundwindow
    3。如果主窗体被别的窗体遮住了,则setforegroundwindow等价于1。本程序主窗体在激活状态,则隐藏,
    2。如果主窗体未激活,则显示,并setforegroundwindow
    3。如果主窗体未激活,则显示,并setforegroundwindow隐藏或被别的窗体遮住不都是在未激活状态.
      

  13.   

    to zcpro:  如果有如此简单那就好了。
    能再把我的说明看清楚一点吗。再次感谢
      

  14.   

    响应WM_ACTIVATE,记个标志行不行?
      

  15.   

    不行,在点击system tray的那一瞬间,不论是主窗体在最前还是被遮住,都是处于失去焦点的状态
      

  16.   

    所以我感觉只能判断主窗体是否是notopmost窗体们中最前的一个。topmost窗体太多了(如QQ,taskbar都是),可是判断总也无效呀,烦呀~~~~
      

  17.   

    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. 
      

  18.   

    这个函数我看过多次了。
    它并不区分topmost和nontopmost窗体,topmost的zorder当然要比nontopmost的高了。
      

  19.   

    getwindowplacement好象和这没有关系哦~~
      

  20.   

    ::GetForegroundWindow() ;
    然后:::GetWindow(hwndCurr,GW_HWNDFIRST);试试
      

  21.   

    ahphone(阿丰) 这个我试过的哦。看说明
      

  22.   

    我明天替你看看吧,我新写了一个SmartDummy,可以探索鼠标指向的任何一个窗口的一些参数,我改改试试看
      

  23.   

    没关系,请帮忙想想办法,谢谢
    winamp是总也setforegroundwindow,很容易实现金山词霸,金山毒霸,flashget等等实现了这种。
      

  24.   

    好的,我做过一个delphi程序,可以获得鼠标指向的窗口句柄(有了句柄就好说),但手头现在没delphi,也就不好改。
      

  25.   

    有一个变通的方法,就是在OnActivateApp()中记录是那个THREAD夺取了焦点,然后在消息函数中判断一下是否是被TRAY WINDOW夺取了焦点,这样就可以实现。void CMainFrame::OnActivateApp(BOOL bActive, HTASK hTask) 
    {
    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窗口
    }
    }
      

  26.   

    我的程序是基于Dialog的,CDialog的onActivate参数并非这几个,
    我试试看是否可以用
      

  27.   

    注意,不是WM_ACTIVE,而是WM_ACTIVEAPP
      

  28.   

    用WindowFromPoint(参数为自己窗口的位置)得到窗口句柄,判断GetWindowThreadProcessId是否和当前的process id一样,可以了吧?
      

  29.   

    如果processid一样,说明窗口是看得到的(不管是Activate还是非Actiate的)。
      

  30.   

    对于CDialog类,你在Add Window Message Handler中,“Filter for messages available to”中选“Window”,就可以添加这个消息了。因为它是CWND消息,所以都支持的。
      

  31.   

    windowfrompoint...
    恩,好主意!!!
    不过不知道被topmost窗体盖住的话会是怎样。。真不知道金山词霸2000 (.net版本是狗屎!!!不能实现)是怎么处理的,flashget的处理方式有别于金山词霸2000 ,flashget只要露出一点点就点一下就hide,而词霸2000只要是被人家遮住一点都会提前的。
      

  32.   

    哦,nustchen(壁虎) ,我看见了。
    我这个CDialog原来就已被改为window了,只是我以为只有一个WM_ACTIVE呢,原来还有一个WM_ACTIVEAPP,呵呵,试试
      

  33.   

    to  nustchen:    好象不能实现,是不是窗体搞错了,“Shell_TrayWnd”只是个子窗体吧
      

  34.   

    to nustchen:    现在我发现究竟是怎么回事了!    我认为金山词霸的做法就是向任务栏的它自己对应的那个按钮发送点击信息或等效的其他做法。因为当窗体显示的时候,如果窗体是最前,点了那个按钮后就最小化,如果被别的程序遮住了,则提前效果完全一致。    可是我这个基于Dialog的程序没有要标题栏,因此即使点了任务栏里的按钮也不会有反应。
    所以也不能简单的向任务栏按钮发送点击信息(并且我现在用了WS_EXTOOLWINDOW属性,隐藏了任务栏的按钮)