我写了一个splitter,关键部分的代码:
case WM_MOUSEMOVE:
if(nBeginPos >= 0)//刚按下的位置
{
SetCursor(hResizeCursor);
}
else
{
MousePos.x = LOWORD(lParam);
MousePos.y = HIWORD(lParam);
GetClientRect(hwnd, &splitRect);
if(PtInRect(&splitRect, MousePos))
{
SetCursor(hResizeCursor);
}
else
{
SetCursor(hNormalCursor);
}
}
return 0; case WM_LBUTTONDOWN:
assert(nCapture == 0);
SetCursor(hResizeCursor);
SetCapture(hwnd);
++ nCapture;
if (bHSplitter)
{
nBeginPos = HIWORD(lParam); //y
}
else
{
nBeginPos = LOWORD(lParam); //x
}
return 0; case WM_LBUTTONUP:
if(nBeginPos >= 0)
{
POINT point;
int offset;
short x = LOWORD(lParam);
short y = HIWORD(lParam);
GetWindowRect(hwnd, &splitRect);
point.x = splitRect.left;
point.y = splitRect.top;
ScreenToClient(GetParent(hwnd), &point); if (bHSplitter)
{
offset = y - nBeginPos;
SendMessage (GetParent (hwnd), WM_COMMAND,
GetWindowLong (hwnd, GWL_ID), 
(LPARAM) offset);
MoveWindow(hwnd, point.x, splitRect.top + offset, splitRect.right - splitRect.left, splitRect.bottom - splitRect.top, TRUE);
}
else
{
offset = x - nBeginPos;
SendMessage (GetParent (hwnd), WM_COMMAND,
GetWindowLong (hwnd, GWL_ID), 
(LPARAM) offset);
MoveWindow(hwnd, point.x + offset, point.y, splitRect.right - splitRect.left, splitRect.bottom - splitRect.top, TRUE);
} nBeginPos = -1;
assert(nCapture == 1);
-- nCapture;
ReleaseCapture();
}
return 0;
如果在splitter的clientrect里释放鼠标,则没问题(当然就是不拖动);如果拖动了,即在splitter的clientrect外释放鼠标之后,splitter就无法再响应任何鼠标事件了,何解?

解决方案 »

  1.   

    你在窗体外WM_LBUTTONUP,这个窗体没有办法接收到这个消息,所以不会ReleaseCapture();
    建议加判断鼠标是否在离开窗体.
    或者采用别的方法,把WM_LBUTTONUP发送到该窗体.
      

  2.   

    ls我窗体外是能收到WM_LBUTTONUP的,因为我在窗体内收到WM_LBUTTONDOWN时SetCapture了
      

  3.   

    楼主什么意思呀?
    在Spliter的WM_LBUTTONDOWN处SetCapture(以后所有的鼠标消息都发往Spliter
    窗口)
    Spliter的WM_LBUTTONUP处ReleaseCapture就行了呀.
      

  4.   

    没错啊,我就是这个干的,不过ReleaseCapture后splitter就不再响应任何鼠标事件了,就是这个splitter只能拖动一次,很奇怪啊
      

  5.   

    你看下ReleaseCapture的返回值是否为零.
      

  6.   

    你下一次Spliter的WM_LBUTTONDOWN处不又SetCapture吗,怎么会只能拖动一次呢。
      

  7.   

    你的ReleaseCapture()放到你的if(nBeginPos >= 0)外边去。
      

  8.   

    ReleaseCapture(); 置外面!试试
      

  9.   

    回WindAndSnow(清风和明月游戏) ,返回值不是0,ReleaseCapture调用是成功了的;回lyg_zy(学无止境,宁静致远) ReleaseCapture放到if(nBeginPos >= 0)外边去也不行啊,另外你说的“下一次Spliter的WM_LBUTTONDOWN处不又SetCapture”,就是因为下一次splitter收不到WM_LBUTTONDOWN所以就只能拖动一次啊
      

  10.   

    真实怪了,我先拖到原client area外后不释放鼠标再拖回原处释放鼠标,就能继续拖动了
      

  11.   

    还有一个问题,我在splitter的父窗口的WM_SIZE里用MoveWindow把splitter重置在窗口中间。现在先拖动splitter,splitter就不能再拖动了,这时改变窗口大小引发WM_SIZE将splitter重置,这时竟然能再次拖动了splitter了!不过拖动后仍然是老问题 -- 失去鼠标响应。