拖拽实现的基本思路
l 首先在WM_LBUTTONDOWN消息进行拖拽测试,看当前用户是否要进行拖拽操作。进行检测的API函数是:BOOL DragDetect(HWND hwnd, POINT pt );该函数捕获鼠标并且跟踪鼠标的移动直到用户释放鼠标左键、点击ESE或者把鼠标移到拖拽区域之外。拖拽区域的宽和高是通过SM_CXDRAG和SM_CYDRAG进行指定的。这些值可以通过GetSystemMetric函数获得。如果该函数返回真,则代表用户启动了一个拖拽动作。相关代码如下:
case WM_LBUTTONDOWN:
POINT pt;
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
if(::DragDetect(hWnd,pt))
{
::SetCapture(hWnd);
isDrag = true;
}
POINT pt;
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
if(::DragDetect(hWnd,pt))
{
::SetCapture(hWnd);
isDrag = true;
}
l 其次在WM_MOUSEMOVE消息进行一些拖拽的处理或者显示拖拽的动作。通常显示拖拽的动作是通过重设鼠标图标的来实现的。
Code
l 再次在WM_LBUTTONUP消息里进行拖拽数据的处理并且完成整个拖拽任务。
if(::GetCapture() == _hSelf)
::ReleaseCapture();
isDrag = false;
::ReleaseCapture();
isDrag = false;
其实,isDrag=false还可以在WM_CAPTURECHANGED消息里进行设置。WM_CAPTURECHANGED消息是当用户失去鼠标捕获时激发的。例如:
case WM_CAPTURECHANGED :
{
if (_isDragging)
{
_isDragging = false;
return TRUE;
}
break;
}
{
if (_isDragging)
{
_isDragging = false;
return TRUE;
}
break;
}
对于TabControl,常见的命中测试消息如下:
Code