如何确定桌面上任何两个窗口的Z-Order关系

本文介绍了一个算法用于在具有父子窗口关系的应用程序中找到两个指定窗口的Z顺序,通过构建窗口链来解决不同顶级窗口和同一顶级窗口内的窗口比较问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://topic.csdn.net/t/20050612/18/4077073.html

 

struct   CWndNode 
{ 
HWND               m_hWnd; 
CWndNode   *   m_pPrev; 
CWndNode   *   m_pNext; 

CWndNode   (HWND   hWnd)   {   m_hWnd   =   hWnd;   m_pPrev   =   m_pNext   =   NULL;   }
}; 

void   DeleteWndLine   (CWndNode   *   pNode) 
{ 
ASSERT   (pNode   !=   NULL); 

CWndNode   *   pCur   =   pNode; 
while   (pCur-> m_pPrev) 
pCur   =   pCur-> m_pPrev; 

while   (pCur) 
{ 
CWndNode   *   pTemp   =   pCur; 
pCur   =   pCur-> m_pNext; 
delete   pTemp; 
} 
} 

 

 

BOOL CComputerOper::FindZOrder(HWND   hWndA,   HWND   hWndB) 
{ 
    ASSERT   (IsWindow(hWndA)); 
    ASSERT   (IsWindow(hWndB)); 
    ASSERT   (hWndA   !=   hWndB); 

    //   取两个窗口的顶级窗口 
    HWND     hTopA   =   hWndA; 
    HWND     hTopB   =   hWndB; 
    while   (GetParent(hTopA)   !=   NULL) 
        hTopA   =   GetParent(hTopA); 
    while   (GetParent(hTopB)   !=   NULL) 
        hTopB   =   GetParent(hTopB); 

    //   第一种情况:两个窗口分别属于不同的顶级窗口 
    if   (hTopA   !=   hTopB) 
    { 
        HWND   hCur     =   GetTopWindow(NULL); 
        while   (hCur   !=   NULL) 
        { 
            if   (hTopA   ==   hCur) 
                return   TRUE; 
            else   if   (hTopB   ==   hCur) 
                return   FALSE; 
            hCur   =   GetWindow(hCur,   GW_HWNDNEXT); 
        } 
    } 
    //   第二种情况:两个窗口属于同一个顶级窗口 
    else 
    { 
        //   建立   父-子窗口链   > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > 
        CWndNode   *   pWndLineA   =   new   CWndNode(hWndA); 
        CWndNode   *   pWndLineB   =   new   CWndNode(hWndB); 

        HWND   hTemp   =   hWndA; 
        while   (hTemp   !=   hTopA) 
        { 
            hTemp   =   GetParent(hTemp); 
            CWndNode   *   pTempNode   =   new   CWndNode(hTemp); 
            pTempNode-> m_pNext   =   pWndLineA; 
            pWndLineA-> m_pPrev   =   pTempNode; 
            pWndLineA   =   pTempNode; 
        } 

        hTemp   =   hWndB; 
        while   (hTemp   !=   hTopB) 
        { 
            hTemp   =   GetParent(hTemp); 
            CWndNode   *   pTempNode   =   new   CWndNode(hTemp); 
            pTempNode-> m_pNext   =   pWndLineB; 
            pWndLineB-> m_pPrev   =   pTempNode; 
            pWndLineB   =   pTempNode; 
        } 
        //   建立   父-子窗口链   < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < 

        //   查询同层窗口 
        while   (pWndLineA-> m_hWnd   ==   pWndLineB-> m_hWnd) 
        { 
            if   (pWndLineA-> m_pNext   ==   NULL   ||   pWndLineB-> m_pNext   ==   NULL) 
            //   此时出现特殊情况:其中一个窗口是另外一个窗口的父窗口 
            { 
                BOOL   res; 
                if   (pWndLineA-> m_pNext   ==   NULL)   //   A   是   B   的父窗口,即   B   在   A   的前面(子窗口总在父窗口前面) 
                res   =   FALSE; 
                else 
                res   =   TRUE; 
                DeleteWndLine   (pWndLineA); 
                DeleteWndLine   (pWndLineB); 
                return   res; 
            } 
            pWndLineA   =   pWndLineA-> m_pNext; 
            pWndLineB   =   pWndLineB-> m_pNext; 
        } 

        //   此时   pWndLineA-> m_hWnd   和   pWndLineB-> m_hWnd   位于同一层,可以比较他们的   Z   序了。 
        //   需要注意,此时   pWndLineA-> m_hWnd   不一定等于   hWndA 
        //                                 pWndLineB-> m_hWnd   不一定等于   hWndB 
        HWND   hA   =   pWndLineA-> m_hWnd; 
        HWND   hB   =   pWndLineB-> m_hWnd; 
        DeleteWndLine   (pWndLineA); 
        DeleteWndLine   (pWndLineB); 

        HWND   hCur     =   GetTopWindow   (GetParent(hA)); 
        while   (hCur   !=   NULL) 
        { 
            if   (hA   ==   hCur) 
            return   TRUE; 
            else   if   (hB   ==   hCur) 
            return   FALSE; 
            hCur   =   GetWindow   (hCur,   GW_HWNDNEXT); 
        } 
    } 

    TRACE0   ( "函数错误,FindZOrder   出现意外情况。 "); 
    ASSERT   (FALSE); 

    return   FALSE; 
} 

 

 

转载于:https://www.cnblogs.com/carl2380/archive/2012/08/21/2648543.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值