说明1 ::SetCapture(GetDlgItem(IDC_XX)->m_hWnd); or GetDlgItem(IDC_XX)->SetCapture(); 要与ReleaseCapture()成对使用
说明2 SetCapture 一般只在鼠标点击时(WM_LBUTTONDOWN)调用; ReleaseCapture在鼠标抬起时(WM_LBUTTONUP)调用
使用场景1 自绘控件调用,比如拖动条/滑块之类,鼠标出窗体,还能响应鼠标位置。
使用场景2 需要拖拽的静态控件(CStatic)调用。如果不用捕获, 常见Bug是:鼠标出窗体后,控件停留在边界处,不再随鼠标移动。 因为控件无法再接收到 mousemove消息
SetCapture/ReleaseCapture 大致意思就是一根绳子(指定捕获的窗体),拴住羊(鼠标),无论羊跑哪里,绳子都能把它拽回来。 不会因为羊跑出羊圈(鼠标出窗体)而走失。
道理很简单。但具体使用还分情况。比如 通过消息处理PreTranslateMessage 实现拖拽按钮,就不需要使用捕获。但是拖拽图片控件,就需要捕获。 为什么呢?
这涉及控件本身,按钮是响应输入输出消息的。 图片等控件是静态控件,本身不响应输入输出。 只能通过设置notify属性,从而接收父窗体的消息。
按钮在窗体外,PreTranslateMessage为什么还能接到move消息? 因为按钮响应 点击/悬浮/移动/抬起 消息,未抬起鼠标,就不会结束响应。属于正常的窗体响应。
静态控件在窗体外,PreTranslateMessage为什么无法接到move消息? 静态控件设置notify=true后,是通过其父窗体响应。此时,鼠标在父窗体外,父窗体当然不接收move消息。然后也就无法更新 静态控件位置。