窗口消息:
当一个非激活的顶级窗口或非激活的顶级窗口的子窗口被单击,首先会产生 WM_MOUSEACTIVATE 消息并传递给顶级窗口。窗口接到消息后交由 DefWindowProc 处理。
WM_MOUSEACTIVATE 消息可以使用如下方式响应:
MA_ACTIVATE 激活窗口,并接收鼠标消息
MA_NOACTIVATE 不激活窗口,接收鼠标消息
MA_ACTIVATENDEAT 激活窗口,忽略鼠标消息
MA_NOACTIVATEANDEAT 不激活窗口,忽略鼠标消息
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
const int MA_NOACTIVATE = 3;
const int WM_MOUSEACTIVATE = 0x21;
if (m.Msg == WM_MOUSEACTIVATE)
m.Result = (IntPtr)MA_NOACTIVATE;
}
若窗口被鼠标点击激活,而且 WM_MOUSEACTIVATE 返回 MA_ACTIVATE,此时会收到系统消息 WM_ACTIVATEAPP (wParam 标识为激活),然后收到 WM_ACTIVATE 消息(wParam 标识为激活),再有 WM_SETFOCUS 消息。但是在这个过程之前原先拥有焦点的窗口会先发生如下事件: WM_ACTIVATE (wParam 标识为失活)-> WM_ACTIVATEAPP (wPARAM 标识为失活) -> WM_KILLFOCUS。
若窗被鼠标激活,返回的是 WM_NOACTIVATEANDEAT 窗口就不会收到 WM_SETFOCUS,这将会使到当前没有窗口拥有焦点,而且窗口上的对象也无法获得鼠标的消息,包括点击。要使原窗口不失去焦点,可以在原窗口上捕获 WM_NCACTIVATE 消息,当 wParam = 0 时,把它设置回 1,即 wParam =1。那么原窗口的焦点还被保留着。
protected override void WndProc(ref Message m)
{
const int WM_NCACTIVATE = 0x86;
if (m.Msg == WM_NCACTIVATE && m.WParam == IntPtr.Zero)
m.WParam = (IntPtr)1;
base.WndProc(ref m);
}
获取 wParam 的高位和低位的值:
取 DWORD 无符号整数低位:
(IntPtr) loword = (IntPtr) wParam & 0xffff;
取 DWORD 无符号整数高位:
(IntPtr) hiword = (IntPtr) wParam >> 16 & 0xffff;
WM_MOUSEACTIVATE = &H21 '当用鼠标激活窗口时
WM_ACTIVATEAPP = &H1C '窗口准备被激活前或准备失去激活状态后的消息
WM_NCACTIVATE = &H86 '窗口非客户区准备被激活时或准备失去激活状态时的消息
WM_ACTIVATE = &H6 '窗口准备被激活时或准备失去激活状态时的消息
WM_SETFOCUS = &H7 '窗口得到焦点时(比如窗口由最小化还原时)的消息
WM_KILLFOCUS = &H8 '窗口失去焦点时的消息