拖放选中对象
来源:互联网 发布:网络招商是怎么回事 编辑:程序博客网 时间:2024/04/27 20:47
简单就是:在图形范围内判断鼠标点击,捕获鼠标,随着鼠标的移动,不断地擦除原有位置上的图形,在新位置上绘图。
要保存好:图形位置(左上角坐标)、图形尺寸、鼠标点于图形位置的偏移、是否选中图形的标记。
注意:逻辑坐标和设备坐标的转换。
保存的图形坐标、尺寸为逻辑坐标;
用DC来画图用的是逻辑坐标;
创建的可选中区域和判断鼠标点再区域内用设备坐标;
得到鼠标点相对图形的偏移是设备坐标;
擦除矩形用设备坐标。
新建一个单文档应用程序,View类继承自CScrollView带滚动条。
一、在工程View类中添加数据成员:
protected:
const CSize m_sizeEllipse; // 所绘制图形的尺寸
CPoint m_pointTopLeft; // 所绘制图形左上角点的坐标
CSize m_sizeOffset; // 鼠标的位置相对于图形左上角的偏移
BOOL m_bCaptured; // 图形是否被选中的标记
二、在工程View类的构造函数中初始化这些数据成员:
CMoveSelObView:: CMoveSelObView () : m_sizeEllipse(100, -100),
m_pointTopLeft(0, 0),
m_sizeOffset(0, 0)
{
m_bCaptured = FALSE;
}
三、在View类的OnInitialUpdate函数中设置滚动条的属性:(如果不用带滚动条的窗口,这些不是必需的,但必需设定映射模式)
void CMoveSelObView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
//设置滚动范围
CSize sizeTotal(800, 1050); // 8-by-10.5 inches
CSize sizePage(sizeTotal.cx / 2, sizeTotal.cy / 2);
CSize sizeLine(sizeTotal.cx / 50, sizeTotal.cy / 50);
SetScrollSizes(MM_LOENGLISH, sizeTotal, sizePage, sizeLine);
}
四、在View的OnDraw函数中绘制一个用于拖动的图形:
void CMoveSelObView::OnDraw(CDC* pDC)
{
CMoveSelObDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//创建红色画刷
CBrush brushHatch(HS_DIAGCROSS , RGB(255, 0, 0));
CPoint point(0, 0);
//转换逻辑坐标到设备坐标
pDC->LPtoDP(&point);
pDC->SetBrushOrg(point); // 以设备坐标为参数
CBrush* pOldBrush = pDC->SelectObject(&brushHatch);
//画红色圆圈
pDC->Ellipse(CRect(m_pointTopLeft, m_sizeEllipse));
pDC->SelectObject(pOldBrush);
}
五、在View类中添加WM_LBUTTONDOWN的消息响应,在其中创建可选中区域、启动鼠标捕捉、更新选中图形标记、计算鼠标相对图形的偏移、改变光标形状:
void CMoveSelObView::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rectEllipse(m_pointTopLeft, m_sizeEllipse);
CRgn circle;
CClientDC dc(this);
OnPrepareDC(&dc); // 准备好设备上下文,通知设备的映射模式(由SetScrollSizes指定)
dc.LPtoDP(rectEllipse); // 逻辑坐标转换为设备坐标
circle.CreateEllipticRgnIndirect(rectEllipse); // 创建用于选中的区域(参数要求逻辑坐标)
if (circle.PtInRegion(point)) // 点在区域内
{
//捕捉鼠标
SetCapture(); //将鼠标捕获设置到窗口
m_bCaptured = TRUE;
CPoint pointTopLeft(m_pointTopLeft);
dc.LPtoDP(&pointTopLeft);
m_sizeOffset = point - pointTopLeft; // 得到鼠标位置相对于图形左上角的偏移,设备坐标
//设置光标形状为十字状
::SetCursor(::LoadCursor(NULL, IDC_CROSS));
}
CScrollView::OnLButtonDown(nFlags, point);
}
六、在View中添加WM_MOUSEMOVE消息的响应函数。如果图形被选中,在鼠标移动时调用2个InvalidateRect函数,前一个用来擦除旧图形,后一个用来显示新图形。
void CMoveSelObView::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bCaptured)
{//如果有图形被选中,并且鼠标被捕捉则更新图形位置
CClientDC dc(this);
OnPrepareDC(&dc);
CRect rectOld(m_pointTopLeft, m_sizeEllipse);
dc.LPtoDP(rectOld);
//擦除老位置的图形
InvalidateRect(rectOld, TRUE);
m_pointTopLeft = point - m_sizeOffset; // 更新图形左上角位置
dc.DPtoLP(&m_pointTopLeft);
//在新位置画图形
CRect rectNew(m_pointTopLeft, m_sizeEllipse);
dc.LPtoDP(rectNew);
InvalidateRect(rectNew, TRUE);
}
CScrollView::OnMouseMove(nFlags, point);
}
七、在View中添加WM_LBUTTONUP消息的响应函数。释放鼠标左键,释放鼠标捕捉,清除图形选中标记:
void CMoveSelObView::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bCaptured) {
//释放鼠标捕捉
::ReleaseCapture();
m_bCaptured = FALSE;
}
CScrollView::OnLButtonUp(nFlags, point);
}
- 拖放选中对象
- 利用MFC实现对象拖放
- 利用MFC实现对象拖放
- 自定义拖放数据对象--54
- MFC实现对象的拖放
- 拖放
- 拖放
- 拖放
- 拖放
- 拖放
- 拖放
- 拖放
- 拖拽功能--拖放桌面上的对象
- 创建可拖放的显示对象
- SCCM / SMS 中拖放集合对象
- 用拖放和剪贴板传输Shell对象
- 利用MFC实现对象的拖放
- 用拖放和剪贴板传输Shell对象
- media service开发备忘
- 登陆到域的情况下连接Oracle数据库
- Oracle数据库配置错误信息解决方法
- 一段获得网卡地址的代码
- java简单的获取windows系统网卡mac地址
- 拖放选中对象
- 在Oracle上构建 .NET 应用程序
- Oracle灾难防护的关键技术
- 网站流量统计与网站访问分析
- alexa作弊大全经典收藏版
- 调用约定(Calling convention)
- 各种软件常用端口
- MovieClipLoader
- WebWork+Spring+Hibernate的烦恼