理解SetCapture、ReleaseCapture、GetCapture(控制了消息发往哪个窗口,是理解消息的关键)

//----http://www.cnblogs.com/findumars/p/3907635.html

正常情况下,鼠标指针位于哪个窗口区域内,鼠标消息就自动发给哪个窗口。如果调用了SetCapture,之后无论鼠标的位置在哪,鼠标消息都发给指定的这个窗口,直到调用ReleaseCapture或者调用SetCapture设置另一个窗口为止。
很多时候,窗口或控件在鼠标按下后,需要知道鼠标移动和放开的情况,例如按钮在鼠标按下后会变为“按下”状态,鼠标移出按钮区域时“弹起”,所以按钮控件需要在鼠标按下时SetCapture,鼠标放开后ReleaseCapture。
GetCapture只是检查一下当前是哪个窗口捕获了鼠标,通常不需要调用。
用微软的话来说:
Retrieves a handle to the window (if any) that has captured the mouse. Only one window at a time can capture the mouse; this window receives mouse input whether or not the cursor is within its borders.
Return value 

Type: HWND

The return value is a handle to the capture window associated with the current thread. If no window in the thread has captured the mouse, the return value is NULL.

Remarks 

NULL return value means the current thread has not captured the mouse. However, it is possible that another thread or process has captured the mouse.

尤其要注意,如果返回值为NULL并不一定就是说当前线程没有捕捉到鼠标,完全有可能是另一个线程或进程捕捉到了鼠标。

 
对于SetCapture/ReleaseCapture 
作用:改变 MOUSEMOVE 消息默认发送方式.
一般移动 鼠标时,鼠标在哪个窗口 MOUSEMOVE 消息就发给哪个窗口(会触发OnIdle),
不管这个窗口是不是当前窗口,也不管是不是拥有焦点,或者有没有激活
而SetCapture 则会改变这种行为.当某个窗口被设置了SetCapture 后
鼠标在全屏范围内移动时MouseMove 消息都会发送给该窗口.
直到 ReleaseCapture,或者在其他窗口点击 才结束

参考:

http://hi.baidu.com/iaskall/item/15e52cf8ebfc72d742c36a63

 

函数功能:该函数在属于当前线程的指定窗口里设置鼠标捕获。一旦窗口捕获了鼠标,所有鼠标输入都针对该窗口,无论光标是否在窗口的边界内。同一时刻只能有一个窗口捕获鼠标。如果鼠标光标在另一个线程创建的窗口上,只有当鼠标键按下时系统才将鼠标输入指向指定的窗口。

下面我举一个例子,能简单地理解SetCapture和ReleaseCapture的作用:
当你在浏览本日志的时候,你会拉动右手边的滑动条来调整内容上下位置,那么当你按下左键的时候,移动鼠标到非滚动条处,你会发现上下移动鼠标滚动条仍然后控制,对,这就是俘获鼠标函数SetCapture的作用。

参考:

http://blog.csdn.net/haussuden/article/details/5853365

 
//-------- http://blog.csdn.net/lanyzh0909/article/details/5543399

查MSND,对SetCapture()函数的说明为:“该函数在属于当前线程的指定窗口里设置鼠标捕获。一旦窗口捕获了鼠标,所有鼠标输入都针对该窗口,无论光标是否在窗口的边界内。同一时刻只能有一个窗口捕获鼠标。如果鼠标光标在另一个线程创建的窗口上,只有当鼠标键按下时系统才将鼠标输入指向指定的窗口。”一开始我看这个解释误认为了只要在属于窗口里的一个线程调用了SetCapture(hWnd)把hWnd设为当前的窗口句柄,那么以后的所有窗口消息都会发到我们指定的那个窗口消息队列中。这样的理解是错误的!!!在你调用SetCapture(hWnd)函数后,只是能够捕获onmousedown、onmouseup、onmousemove、onclick、ondblclick、onmouseover和onmouseout鼠标消息,但是一般我们是捕获onmousemove和onmouseup两个消息。需要只注意最后一句“如果鼠标光标在另一个线程创建的窗口上,只有当鼠标键按下时系统才将鼠标输入指向指定的窗口”的解释,就是即使你在一个窗口线程里对了了SetCapture(),但你在别的窗口的上点击了同样会把鼠标消息发个这个窗口而是我们通过调用SetCapture()设定那个窗口。因为当鼠标在窗口外面点击的时候,被点击的窗口获得焦点,原来的SetCapture()也就失效了。

    当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉,否则别的线程想调用就会失败。记住:SetCapture()和ReleaseCapture()必须成对呈现。

posted @ 2016-08-19 10:45  海蓝7  阅读(555)  评论(0编辑  收藏  举报