如何把指定窗口置于顶层?特急!!!!

lionpb 2003-01-07 02:42:55
我现在做一个应用,所有内容都是动态创建的。在同一个位置有可能需要先后创建两个甚至多个窗口(也就是说存在互相覆盖的问题),创建后一切正常,焦点的切换,窗口层次等都正常,但是当我用ALT+TAB将焦点切换到其他应用,然后再切换会来之后,原来的顶层窗口被位于其下的窗口覆盖(经常发生,但不是必然),我通过单击将原来的窗口重新置于顶层,但是窗口上的控件如按钮、编辑框等原来的3D边框都变成了平面视图了。请问各位有没有什么好办法?

另外有一个窗口,生成之后一直需要置于顶层,我在创建时用了WS_EX_TOPMOST,或者在创建后用SetWindowPos( &wndTopMost, ... ), SetWindowPos( &wndTop, ... )以及::SetWindowPos( hwnd, HWND_TOPMOST, ... )等方法,都无法将该窗口保持在顶层,经常是该窗口被其他窗口遮盖。各位大侠是否有什么指示?
...全文
1825 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
lionpb 2003-01-13
  • 打赏
  • 举报
回复
各位大侠请帮忙,现在集成测试就这个问题卡住我了,简直没脸面对观众!!!
lionpb 2003-01-13
  • 打赏
  • 举报
回复
而且我现在特别不明白的是,为什么是HWND_BOTTOM,而不是HWND_TOP?为什么HWND_TOPMOST在用MoveWindow移动过窗口或者直接用鼠标拖拉过窗口以后就失效了?
lionpb 2003-01-13
  • 打赏
  • 举报
回复
zswzwy(←圣骑士!帕迪拉斯!) :
实际上我调用了SetForegroundWindow,也没有什么作用。经过这两天的测试,我发现如下规律:
1.在SetWindowPos之后,如果调用SetFocus( HWND )将焦点设置到该窗口,那么该窗口的Z-Order会改变,也就是说SetWindowPos失去作用( TOPMOST除外),
2.调用MoveWindow后,窗口的位置被设置到其他激活窗口之后。
3.改变了窗口的位置或者是Z-Order,必须将父窗口重新绘制,才能刷新新的位置。
4.即便用SetWindowPos改变了窗口的位置,用SetFocus改变了焦点,但是鼠标的“焦点”还是没有被设置到该窗口上。
5.如果用MoveWindow移动了窗口或者改变其大小,鼠标的焦点也同时被设置到该窗口上。

因此也就有一个问题:我设置将窗口置前了,但是鼠标焦点却不在该窗口上,如果我用MoveWindow假装移动该窗口,鼠标焦点倒是获得了,但是窗口却被其他窗口覆盖了。如果用SetCapture将鼠标强制设置到该窗口上,则实际效果是鼠标在其他控件或者窗口上也就没用了。
我感觉这简直就是一个悖论,大侠有没有什么高见?
zswzwy 2003-01-13
  • 打赏
  • 举报
回复
这是个老问题,下面的代码将会对你有所启示

#include "Windows.h"

#pragma data_seg("shared")

HHOOK g_hHook = NULL;
HINSTANCE g_DllInst = NULL;

#pragma data_seg()

BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_DllInst = hInst;
return TRUE;
}

LRESULT CALLBACK GetMsgProc( int code,WPARAM wParam,LPARAM lParam)
{
UINT nMsg = RegisterWindowMessage("Set foreground window");
MSG * pMsg;
HWND hWnd;

pMsg = (MSG *)lParam;
if(pMsg->message==nMsg)
{
hWnd = (HWND)pMsg->wParam;
OpenIcon(hWnd);
if(IsIconic(hWnd))
OpenIcon(hWnd);
else
SetForegroundWindow(hWnd);
}
return CallNextHookEx(g_hHook, code, wParam,lParam);
}
BOOL __declspec(dllexport) ReallySetForegroundWindow(HWND hWnd)
{
int nMsg;
HWND fhWnd = GetForegroundWindow();

if(IsIconic(hWnd))
OpenIcon(hWnd);
else
SetForegroundWindow(hWnd);

if(fhWnd == GetForegroundWindow())
{
if (g_hHook)
UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
g_hHook = SetWindowsHookEx(WH_GETMESSAGE , GetMsgProc,
g_DllInst,GetWindowThreadProcessId(fhWnd, NULL));
nMsg = RegisterWindowMessage("Set foreground window");
PostMessage(fhWnd,nMsg, (WPARAM)hWnd, 0);
}
return TRUE;
}

sinhighly 2003-01-13
  • 打赏
  • 举报
回复
up
lionpb 2003-01-13
  • 打赏
  • 举报
回复
yu_wlof(yukun) :
我没有一个窗口是TOPMOST的。
商海连横 2003-01-11
  • 打赏
  • 举报
回复
路过!
lionpb 2003-01-11
  • 打赏
  • 举报
回复
想不到必须将所有的分都散完才能结贴!那就顺便请各位就此问题进行一番讨论,以解我的疑惑。谢谢。
主要是:
SwitchToThisWindow具体怎么用?我在调用之前应该声明一下吧?可以我在MSDN中找不到该函数的说明(我用的是VC++6.0)。请 In355Hz(好象一条狗) 大侠解释一下。
另外我发现ModifyStyle,ModifyStyleEx好像没有什么效果。我的部分控件如编辑框,静态标签,按钮等需要在运行时改变其外观,但是用ModifyStyle和ModifySytleEx根本就没有变化。这是为什么?
为什么要用HWND_BOTTOM,而不是HWND_TOP或者HWND_TOPMOST?我需要一个窗口保持在顶层,但是HWND_TOPMOST或者WS_EX_TOPMOST都不能达到这个效果(仅仅这个窗口需要这样,不存在多个窗口都是TOPMOST的情况),这是为什么?
为什么在修改窗口的位置之后,需要将父窗口重新绘制才能将修改效果体现出来,为什么?
lionpb 2003-01-11
  • 打赏
  • 举报
回复
感谢各位的支持!虽然各位都没有解决我的问题,但我愿意将这些分散给大家。不过要留下20分,给能够解释为什么是BOTTOM而不是TOP或者TOPMOST的人。
lionpb 2003-01-11
  • 打赏
  • 举报
回复
我们都错了.我估计谁也想不到最后的解决办法是这样的:
::SetWindowPos( m_pwnd1->m_hWnd,
HWND_BOTTOM,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE );
::SetFocus( m_pwnd1->m_hWnd );//这一句不是必须的

ShowWindow( SW_HIDE ); //隐藏父窗口
ShowWindow( SW_SHOW ); //显示父窗口

大家都以为是TOP或者TOPMOST,谁也没有想到是BOTTOM吧?
differ1 2003-01-11
  • 打赏
  • 举报
回复
学习收藏!
yu_wlof 2003-01-11
  • 打赏
  • 举报
回复
是不是你有多窗口都是TOPMOST,多个顶层窗口之间是可以变化他们的Z轴的,而BOTTOM一定是在TOPMOST下的.在窗口重新得到焦点时,线程将从其内部结构中把第一个检索到的ActiveWindow置于前面.
在OnActiveWindow消息中BringWindowToTop应该可以
qrlvls 2003-01-07
  • 打赏
  • 举报
回复
SetWindowPos
BringWindowToTop
fontyliu 2003-01-07
  • 打赏
  • 举报
回复
修改窗口的属性
ModifyStyle(0,GetStyle()|WS_EX_TOPMOST);
In355Hz 2003-01-07
  • 打赏
  • 举报
回复
Undocument API SwitchToThisWindow,Win 95/98/ME/NT/2000/XP

void WINAPI SwitchToThisWindow (
HWND hWnd, // Handle to the window that should be activated
BOOL bRestore // Restore the window if it is minimized
);

该函数只能通过 GetProcAddress 获取:
typedef void (WINAPI *LPSWITCHTOTHISWINDOW)(HWND, BOOL);

LPSWITCHTOTHISWINDOW lpfnSwitchToThisWindow;

lpfnSwitchToThisWindow = (LPSWITCHTOTHISWINDOW) GetProcAddress( GetModuleHandle(_T("user32")), _T("SwitchToThisWindow") );
hailong0108 2003-01-07
  • 打赏
  • 举报
回复
如何使窗口始终在最前方?


BringWindowToTop(Handle)
SetWindowPos函数,指定窗口的 最顶风格,用WS_EX_TOPMOST扩展窗口的风格

Example:
void ToggleTopMost(
CWnd *pWnd)
{
ASSERT_VALID(pWnd)

pWnd ->SetWindowPos(pWnd-> GetStyle( ) &WS_EX_TOPMOST)?

&wndNoTopMOST: &wndTopMost,0,0,0,0,SSP_NOSIZE|WSP_NOMOVE)
}



lionpb 2003-01-07
  • 打赏
  • 举报
回复
试过了!
用户 昵称 2003-01-07
  • 打赏
  • 举报
回复
setforegroundwindow
lionpb 2003-01-07
  • 打赏
  • 举报
回复
我创建了很多个窗口,都是用同样的代码。
SetWindowPos是在窗口获得焦点时调用的。我是在应用里自己控制焦点的。在窗口接到WM_SETFOCUS消息之后,在OnSetFocus中调用的SetWindowPos。
wltsui 2003-01-07
  • 打赏
  • 举报
回复
用这个不成吗?
SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);


你把这个放在那了?
加载更多回复(6)

15,979

社区成员

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

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