鼠标拖动控件边缘,改变其大小的问题!~~ 当鼠标到达控件边缘的时候,1.改变鼠标形状,2.然后当鼠标点下左键的时候,3.开始实现拖拽,接着控件的边缘会随着鼠标的移动而改变边缘的位置,当鼠标左键放开,动作完成。由于我是个新手,所以不知道有什么函数,改如何实现,请大侠们 逐一给于解答!谢谢! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 1、响应控件的WM_MOUSEMOVE在OnMouseMove时候,判断一下当前鼠标位置,这个边缘可以自己定义以下,如离边5个像素;如 果在这之内就改变鼠标形状SetCursor(AfxGetApp->LoadCursor(IDC_CURSOR_LINK));2、响应控件的WM_LBUTTONDOWN,可以设个标志位,默认为FALSE,按下左键之后置为TRUE。然后再在Dialog的OnMouseMove中改变控件的大小3、响应空间的WM_LBUTTONUP,将第二步中标志位置回来。 OnMouseMoveOnLButtonDownOnLButtonUpSetCursor 1.改变鼠标形状,SetCursor2.然后当鼠标点下左键的时候,OnLButtonDown3.开始实现拖拽,接着控件的边缘会随着鼠标的移动而改变边缘的位置,OnMouseMove 判断来设置SetCursor当鼠标左键放开OnLButtonUp 这一切请交给Windows帮你完成,响应WM_NCHITTEST,WM_SETCURSOR,WM_NCLBUTTONDOWN这三个消息即可 void CMyCtrl::OnNcLButtonDown( UINT nHitTest, CPoint point ){ if(nHitTest == HTTOP) SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_TOP, MAKELPARAM(point.x, point.y)); else if(nHitTest == HTBOTTOM) SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOM, MAKELPARAM(point.x, point.y)); else if(nHitTest == HTLEFT) SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_LEFT, MAKELPARAM(point.x, point.y)); else if(nHitTest == HTRIGHT) SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_RIGHT, MAKELPARAM(point.x, point.y)); else if(nHitTest == HTTOPLEFT) SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPLEFT, MAKELPARAM(point.x, point.y)); else if(nHitTest == HTTOPRIGHT) SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPRIGHT, MAKELPARAM(point.x, point.y)); else if(nHitTest == HTBOTTOMLEFT) SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMLEFT, MAKELPARAM(point.x, point.y)); else if(nHitTest == HTBOTTOMRIGHT) SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMRIGHT, MAKELPARAM(point.x, point.y)); else if (nHitTest == HTSYSMENU) SendMessage(m_hWnd,WM_SYSCOMMAND, SC_MOUSEMENU,MAKELPARAM(point.x, point.y));}BOOL CMyCtrl::OnSetCursor(CWindow Wnd, UINT nHitTest, UINT message){ switch (nHitTest) { case HTTOPLEFT: case HTBOTTOMRIGHT: { SetCursor(::LoadCursor(NULL, IDC_SIZENWSE)); } break; case HTTOPRIGHT: case HTBOTTOMLEFT: { SetCursor(::LoadCursor(NULL, IDC_SIZENESW)); } break; case HTLEFT: case HTRIGHT: { SetCursor(::LoadCursor(NULL, IDC_SIZEWE)); } break; case HTTOP: case HTBOTTOM: { SetCursor(::LoadCursor(NULL, IDC_SIZENS)); } break; default: { SetCursor(::LoadCursor(NULL, IDC_ARROW)); } break; } return TRUE;}LRESULT CMyCtrl::OnNcHitTest(CPoint point, BOOL& bHandled){ bHandled=FALSE; if (IsZoomed(m_hWnd)) { return 0; } CRect rect; GetClientRect(m_hWnd,&rect); CPoint pt = point; ScreenToClient(m_hWnd,&pt); static int nFrame=4; // 窗口边框的宽度 rect.DeflateRect(nFrame,nFrame); bHandled =TRUE; if (!rect.PtInRect(pt)) { if (pt.x<=nFrame && pt.y>=rect.bottom-nFrame) { return HTBOTTOMLEFT; } else if (pt.x<=nFrame && pt.y<=nFrame) { return HTTOPLEFT; } else if (pt.x>=rect.right-nFrame && pt.y<=nFrame) { return HTTOPRIGHT; } else if (pt.x>=rect.right-nFrame && pt.y>=rect.bottom-nFrame) { return HTBOTTOMRIGHT; } else if (pt.x<=nFrame) { return HTLEFT; } else if (pt.y<=nFrame) { return HTTOP; } else if (pt.y>=rect.bottom-nFrame) { return HTBOTTOM; } else if (pt.x>=rect.right-nFrame) { return HTRIGHT; } } else { return HTCLIENT; } bHandled = FALSE; return 0;} 真晕,难道控件就不可以了么?都一样是窗口的嘛,你这种行为交给windows,windows对这种默认行为最拿手,没必要去自己实现一套 上面我给的这段代码是告诉你怎么实现缩放无边框窗口的,对控件同样适用的,控件本身就是一个无边框的子窗口代码你复制过去转换下,我这是WTL下的。 其实只是一个问题,自己派生一个控件类,响应WM_NCHITTEST消息即可。//#include <math.h> RECT rc; GetWindowRect(&rc); if (abs(point.x-rc.left) < 2) { if (abs(point.y-rc.top) < 2) return HTTOPLEFT; if (abs(point.y-rc.bottom+1) < 2) return HTBOTTOMLEFT; return HTLEFT; } if (abs(point.x-rc.right+1) < 2) { if (abs(point.y-rc.top) < 2) return HTTOPRIGHT; if (abs(point.y-rc.bottom+1) < 2) return HTBOTTOMRIGHT; return HTRIGHT; } if (abs(point.y-rc.top) < 2) return HTTOP; if (abs(point.y-rc.bottom+1) < 2) return HTBOTTOM; return CWnd::OnNcHitTest(point); 1.一下为 movemouse 判断 到达边缘的时候CWnd* pWnd = GetDlgItem(IDC_LIST2); CRect rect,rect2; pWnd->GetWindowRect(&rect2);//相对与窗体的坐标 ScreenToClient(&rect2); //p1->GetWindowRect(&rect); //int y=rect.left; int x,x1,y,y1; x=rect2.left; y=rect2.top; x1=rect2.right; y1=rect2.bottom; int a,b; a=point.x; b=point.y; if((a>x&&a<x1)) { if(abs(y-b)<4) { SetCursor(::LoadCursor(NULL, IDC_SIZENS)); } else { } }2 SetCursor(::LoadCursor(NULL, IDC_SIZENS)); 再返回到 movemouse 改变大小!CRect r; m_l1.GetWindowRect(&r); r.top=point.y; ScreenToClient(r); m_l1.MoveWindow(&r,true);帮忙看下,我控制的控件 改变大小不正常! 2 SetCursor(::LoadCursor(NULL, IDC_SIZENS)); 再返回到 movemouse 改变大小!C/C++ codeCRect r; m_l1.GetWindowRect(&r); r.top=point.y; ScreenToClient(r); m_l1.MoveWindow(&r,true);帮忙看下,我控制的控件 改变大小不正常! 去掉红色的 m_Resize = FALSE;if(m_Resize == TRUE) { CRect r; m_l1.GetWindowRect(&r); ScreenToClient(&r); //ClientToScreen(&point); r.top=point.y; // ScreenToClient(r); m_l1.MoveWindow(r.left,r.top,r.Width(),r.Height(),true); pu=0; }你要在PreTranslateMessage里处理WM_LBUTTONUP与 WM_LBUTTONDOWN消息而不是直接用DLG里自动添加生成的WM_LBUTTONUP与 WM_LBUTTONDOWN处理事件 不会API 木马编程可以用 vc++.net2008吗?还是vc++6.0更好? 系统钩子可以用于软键盘编写? 读二进制文件 如何接管CHtmlView的脚本引擎接口? 如何在BUTTON上随时绘制图形? 请求帮助!!如何获取局域网内其他机子屏幕?? ACCESS数据库问题, 怎样得到IE的鼠标拖放时存储地数据? wtl中建立如下的进度条为什么不相应 WM_TIMER vs2010无法打开包括文件:“d3dx9.h” 如何自定义给VC++ CTreeCtrl控件节点排序
OnLButtonDown
OnLButtonUp
SetCursor
2.然后当鼠标点下左键的时候,OnLButtonDown
3.开始实现拖拽,接着控件的边缘会随着鼠标的移动而改变边缘的位置,OnMouseMove 判断来设置SetCursor
当鼠标左键放开OnLButtonUp
void CMyCtrl::OnNcLButtonDown( UINT nHitTest, CPoint point )
{
if(nHitTest == HTTOP)
SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_TOP, MAKELPARAM(point.x, point.y));
else if(nHitTest == HTBOTTOM)
SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOM, MAKELPARAM(point.x, point.y));
else if(nHitTest == HTLEFT)
SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_LEFT, MAKELPARAM(point.x, point.y));
else if(nHitTest == HTRIGHT)
SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_RIGHT, MAKELPARAM(point.x, point.y));
else if(nHitTest == HTTOPLEFT)
SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPLEFT, MAKELPARAM(point.x, point.y));
else if(nHitTest == HTTOPRIGHT)
SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPRIGHT, MAKELPARAM(point.x, point.y));
else if(nHitTest == HTBOTTOMLEFT)
SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMLEFT, MAKELPARAM(point.x, point.y));
else if(nHitTest == HTBOTTOMRIGHT)
SendMessage(m_hWnd,WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMRIGHT, MAKELPARAM(point.x, point.y));
else if (nHitTest == HTSYSMENU)
SendMessage(m_hWnd,WM_SYSCOMMAND, SC_MOUSEMENU,MAKELPARAM(point.x, point.y));}BOOL CMyCtrl::OnSetCursor(CWindow Wnd, UINT nHitTest, UINT message)
{ switch (nHitTest)
{
case HTTOPLEFT:
case HTBOTTOMRIGHT:
{
SetCursor(::LoadCursor(NULL, IDC_SIZENWSE));
}
break;
case HTTOPRIGHT:
case HTBOTTOMLEFT:
{
SetCursor(::LoadCursor(NULL, IDC_SIZENESW));
}
break;
case HTLEFT:
case HTRIGHT:
{
SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
}
break;
case HTTOP:
case HTBOTTOM:
{
SetCursor(::LoadCursor(NULL, IDC_SIZENS));
}
break;
default:
{
SetCursor(::LoadCursor(NULL, IDC_ARROW));
}
break;
}
return TRUE;
}LRESULT CMyCtrl::OnNcHitTest(CPoint point, BOOL& bHandled)
{
bHandled=FALSE; if (IsZoomed(m_hWnd))
{
return 0;
} CRect rect;
GetClientRect(m_hWnd,&rect); CPoint pt = point;
ScreenToClient(m_hWnd,&pt); static int nFrame=4; // 窗口边框的宽度 rect.DeflateRect(nFrame,nFrame); bHandled =TRUE;
if (!rect.PtInRect(pt))
{
if (pt.x<=nFrame && pt.y>=rect.bottom-nFrame)
{
return HTBOTTOMLEFT;
}
else if (pt.x<=nFrame && pt.y<=nFrame)
{
return HTTOPLEFT;
}
else if (pt.x>=rect.right-nFrame && pt.y<=nFrame)
{
return HTTOPRIGHT;
}
else if (pt.x>=rect.right-nFrame && pt.y>=rect.bottom-nFrame)
{
return HTBOTTOMRIGHT;
}
else if (pt.x<=nFrame)
{
return HTLEFT;
}
else if (pt.y<=nFrame)
{ return HTTOP;
}
else if (pt.y>=rect.bottom-nFrame)
{
return HTBOTTOM;
}
else if (pt.x>=rect.right-nFrame)
{
return HTRIGHT;
}
}
else
{
return HTCLIENT;
} bHandled = FALSE; return 0;
}
真晕,难道控件就不可以了么?都一样是窗口的嘛,你这种行为交给windows,windows对这种默认行为最拿手,没必要去自己实现一套
代码你复制过去转换下,我这是WTL下的。
//#include <math.h>
RECT rc;
GetWindowRect(&rc);
if (abs(point.x-rc.left) < 2)
{
if (abs(point.y-rc.top) < 2)
return HTTOPLEFT;
if (abs(point.y-rc.bottom+1) < 2)
return HTBOTTOMLEFT;
return HTLEFT;
}
if (abs(point.x-rc.right+1) < 2)
{
if (abs(point.y-rc.top) < 2)
return HTTOPRIGHT;
if (abs(point.y-rc.bottom+1) < 2)
return HTBOTTOMRIGHT;
return HTRIGHT;
}
if (abs(point.y-rc.top) < 2)
return HTTOP;
if (abs(point.y-rc.bottom+1) < 2)
return HTBOTTOM; return CWnd::OnNcHitTest(point);
CRect rect,rect2;
pWnd->GetWindowRect(&rect2);//相对与窗体的坐标
ScreenToClient(&rect2);
//p1->GetWindowRect(&rect);
//int y=rect.left;
int x,x1,y,y1;
x=rect2.left;
y=rect2.top;
x1=rect2.right;
y1=rect2.bottom;
int a,b;
a=point.x;
b=point.y; if((a>x&&a<x1))
{
if(abs(y-b)<4)
{
SetCursor(::LoadCursor(NULL, IDC_SIZENS));
}
else
{
}
}
2 SetCursor(::LoadCursor(NULL, IDC_SIZENS)); 再返回到 movemouse
改变大小!CRect r;
m_l1.GetWindowRect(&r);
r.top=point.y;
ScreenToClient(r);
m_l1.MoveWindow(&r,true);
帮忙看下,我控制的控件 改变大小不正常!
改变大小!
C/C++ codeCRect r;
m_l1.GetWindowRect(&r);
r.top=point.y;
ScreenToClient(r);
m_l1.MoveWindow(&r,true);
帮忙看下,我控制的控件 改变大小不正常!
去掉红色的
if(m_Resize == TRUE)
{
CRect r;
m_l1.GetWindowRect(&r);
ScreenToClient(&r);
//ClientToScreen(&point);
r.top=point.y;
// ScreenToClient(r);
m_l1.MoveWindow(r.left,r.top,r.Width(),r.Height(),true);
pu=0;
}
你要在PreTranslateMessage里处理WM_LBUTTONUP与 WM_LBUTTONDOWN消息而不是直接用DLG里自动添加生成的WM_LBUTTONUP与 WM_LBUTTONDOWN处理事件