窗口激活-无焦点窗口禁止激活

Posted 陈晓猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了窗口激活-无焦点窗口禁止激活相关的知识,希望对你有一定的参考价值。

窗口激活
当用户单击一个非激活的顶级窗体,或非激活的顶级窗体的子窗体时,系统就会发送WM_MOUSEACTIVATE消息(还包括其他消息)给顶级窗体或子窗体,该消息在WM_NCHITTEST消息之后,但在button-down消息之前。当把WM_MOUSEACTIVATE消息交给DefWindowProc函数处理时,系统激活该顶级窗口并投递button-down消息。
  通过处理WM_MOUSEACTIVATE,一个窗体可以就像鼠标单击一样控制激活顶级窗口,并确定该窗体是否接收后续的button-down消息。处理WM_MOUSEACTIVATE后,通过返回以下值实现该目的:
值 含义 
MA_ACTIVATE 激活窗体,但不删除鼠标消息。 
MA_NOACTIVATE 不激活窗体,也不删除鼠标消息。 
MA_ACTIVATEANDEAT 激活窗体,删除鼠标消息。 
MA_NOACTIVATEANDEAT 不激活窗体,但删除鼠标消息。
 
‘相关资料链接
‘http://topic.csdn.net/t/20020314/11/575275.html
我用钩子拦截了WH_CALLWNDPROC,发现在鼠标点击切换窗口的过程中,是原窗口先收到WM_ACTIVATE消息(wParam指示失活),再收到WM_ACTIVATEAPP消息(wParam指示失活),再收到WM_KILLFOCUS消息,然后才是新窗口收到WM_MOUSEACTIVATE消息,如果新窗口对这个消息返回MA_NOACTIVATE或MA_NOACTIVATEANDEAT,则不再有其它消息;如果新窗口对WM_MOUSEACTIVATE消息的处理返回MA_ACTIVATE,则接下来新窗口还收到WM_ACTIVATEAPP消息(wParam指示激活),然后是WM_ACTIVATE消息(wParam指示鼠标激活),然后是WM_SETFOCUS消息。 
由此看来,在新窗口处理WM_MOUSEACTIVATE消息之前,旧窗口已经处理了WM_KILLFOCUS消息将焦点丢弃,所以对WM_MOUSEACTIVATE返回MA_NOACTIVATEANDEAT,新窗口就不会收到WM_SETFOCUS因而就将使没有窗口拥有焦点了。
‘相关资料链接  2
在windows的窗口系统中,popup窗口的焦点是与它的活动状态密切相关的。只要使 
popup窗口不获得活动状态,popup窗口就不会自动获得焦点。具体方法如下: 
1. 在创建popup窗口时不要有WS_VISIBLE风格,然后调用SetWindowPos函数显示 
创建的窗口,参数uFlag取值SWP_SHOWWINDOW and SWP_NOACTIVATE,这样就可以保证 
窗口在创建是不会得到活动状态,也就不会获得焦点。 
2. 响应WM_MOUSEACTIVATE消息,返回MA_NOACTIVATE表示窗口在鼠标点击时不需要 
获得活动状态,这样就可以保证在鼠标点击时窗口不会自动获得焦点。 
至于鼠标输入的响应,本就与窗口是否获得焦点无关,不会受到影响。  
‘相关资料链接 3
   一个窗口我在WM_MOUSEACTIVATE消息中这么处理
int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
return MA_NOACTIVATE;
}
这样是正常的,点击到它的client区域没问题,它不会获得焦点。
如果它包含一个按钮,那么点击按钮,这个窗口还是获得焦点了。
用spy++看,它走了WM_MOUSEACTIVATE消息并返回MA_NOACTIVATE以后紧接着就WM_ACTIVE了。
用spy++跟踪那个按钮,也走了WM_MOUSEACTIVATE并且返回MA_NOACTIVATE。
1.按钮如何响应WM_MOUSEACTIVATE的?
2.点了按钮以后这个窗口为什么还会获得焦点?
3.它获得焦点的整个过程(消息的收发)是怎样的? 
 
 MA_NOACTIVATEANDEAT以后,是不会获得焦点了,但是按钮也不响应点击了。
如果我希望按钮既可以响应点击事件而且窗口也不会获得焦点要如何做? 
 
‘个人总结
在原来窗口使用WM_NCACTIVATE消息当 wParam = 0 时  ,返回wParam = 1 ,那么原窗口就不会失去焦点,然后新窗口使用子类来处理消息也是可以的

以上是关于窗口激活-无焦点窗口禁止激活的主要内容,如果未能解决你的问题,请参考以下文章

WPF 打开新窗口 如何设置 焦点还在原来的窗口 谢谢

WPF 让窗口激活作为前台最上层窗口的方法

WM消息大全

WM消息大全

WPF 让窗口激活作为前台最上层窗口的方法

win7系统 当前窗口总是失去焦点