【400分求助】如何确定桌面上任何两个窗口的Z-Order关系???

Genghiskhan 2005-06-12 06:30:22
请大家帮帮忙,如果可以解决问题,下面两个帖子的分数立马送出
这个问题困扰了我很久,希望大家可以帮帮我,谢谢!

http://community.csdn.net/Expert/TopicView3.asp?id=4077066
http://community.csdn.net/Expert/TopicView3.asp?id=4077068

给定桌面上的任意两个窗口,比如A和B,A和B可能是同一个父窗口的
子窗口,也可能不是同一父窗口的子窗口,还有可能是两个顶层窗口,
总之,A和B代表桌面上任意两个用户可见的窗口。现在我想知道A和B
的前后次序(Z-Order),即哪个窗口在前哪个窗口在后,我试了
GetTopWindow、GetNextWindow、FindWindowEx等好像都不行,
请问用什么方法可以得到这两个窗口的Z-Order关系???

我期待的功能是类似下面的一个函数:

BOOL FindZOrder(HWND hWndA, HWND hWndB)
{
if (hWndA 在 hWndB前面)
return TRUE;
else
return FALSE;

}
...全文
377 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
he_sl 2005-06-14
  • 打赏
  • 举报
回复
mark
lsvine 2005-06-14
  • 打赏
  • 举报
回复
mark
tatu 2005-06-14
  • 打赏
  • 举报
回复
mark
cdeee 2005-06-13
  • 打赏
  • 举报
回复
非顶级窗口未测试,估计没问题。
cdeee 2005-06-13
  • 打赏
  • 举报
回复

以上代码在 Visual Studio .net 2003 中调试通过,测试桌面上的两个顶级窗口通过,非顶级窗口为测试,估计没什么问题。
cdeee 2005-06-13
  • 打赏
  • 举报
回复

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 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;
}

allenhiman 2005-06-13
  • 打赏
  • 举报
回复
我也想和高手们讨论问题
想飞的菜鸟 嘿嘿
allenhiman 2005-06-13
  • 打赏
  • 举报
回复
我想这可能需要比较很多情况,我的思路是得到要比较两个窗口的窗口风格和是否为活动窗口,然后分
很多种情况处理,这样会很麻烦的...不知道楼主的思路是什么?
下面这个函数 也许能比较两个窗口有其一是活动窗口的情况
我只是给你提供了一个思路 不好意思 我是菜鸟~~!
BOOL IsTop(HWND top, HWND bottom)
{

ASSERT( top != NULL );
ASSERT( bottom != NULL );
ASSERT( top != bottom );
//Get the style of top
DWORD stTop = GetWindowLong( top, GWL_STYLE );
//Get the style of bottom
DWORD stBottom = GetWindowLong( bottom, GWL_STYLE );
//Get the active window
CWnd *pWnd = GetActiveWindow();
ASSERT( pWnd != NULL );
// HWND hWndActive = ( top == pWnd ) ? top : bottom;
//If the top has topmost stytle
if( stTop & WS_EX_TOPMOST )
{
if( stBottom & WS_EX_TOPMOST )
{
if( pWnd->m_hWnd == top )
return TRUE;
else
return FALSE;
}
else
{
return TRUE;
}
}
else
{
if( stBottom & WS_EX_TOPMOST )
{
return FALSE;
}
else
{
if( pWnd->m_hWnd == top )
return TRUE;
else
return FALSE;
}
}
}
cdeee 2005-06-13
  • 打赏
  • 举报
回复

不用谢,助人为快乐之本!

我的代码没有测试非顶级窗口,不知道有没有漏洞,你自己测试一下。
Genghiskhan 2005-06-13
  • 打赏
  • 举报
回复
非常感谢大家的帮助,尤其是cdeee(亦难)的代码,确实很好用,辛苦了,谢谢啦!:)

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧