要实现的效果:

鼠标点击控件(自绘控件,可继承任意控件类,下文将给出示例),并且进行拖拽,会有一个半透明黑色阴影来表示当前拖动的位置。当松开鼠标,控件重新绘制在鼠标松开的位置。拖拽功能的实现代码主要在DoEvent函数和DoPostPaint函数中完成的。

实现步骤:

1、继承需要的控件并重写DoEvent函数,在UIEVENT_BUTTONDOWN、UIEVENT_BUTTONUP、UIEVENT_MOUSEMOVE三个事件

2、在UIEVENT_BUTTONDOWN事件里调用AddPostPaint函数注册本控件

3、在UIEVENT_MOUSEMOVE事件里计算新的控件位置,并且将新旧位置组合起来调用Invalidate函数刷新位置(否则会有残影)

4、在UIEVENT_BUTTONUP事件里调用RemovePostPaint反注册自己,并且刷新控件。

5、重写DoPostPaint函数完成阴影的绘制

自定义控件类的实现如下(类名可自行定义):

CNetDevice类头文件.h实现如下:

#pragma once
#include "../duilib/UIlib.h"
using namespace DuiLib;class CNetDevice : public CContainerUI      //这里继承了CContainerUI,你也可以继承任意控件类如CButtonUI等,实现自定义控件
{
public:CNetDevice();~CNetDevice();LPVOID GetInterface(LPCTSTR pstrName);void DoEvent(TEventUI& event);void DoPostPaint(HDC hDC, const RECT& rcPaint);//CControlUI* CreateControl(LPCTSTR pstrClass);private:UINT m_uButtonState;POINT m_ptLastMouse;RECT m_rcNewPos;//CPaintManagerUI m_PaintManager;
};

CNetDevice类.cpp实现代码如下:

#include "stdafx.h"
#include "NetDevice.h"CNetDevice::CNetDevice()
{
}CNetDevice::~CNetDevice()
{
}LPVOID CNetDevice::GetInterface(LPCTSTR pstrName)
{if (_tcscmp(pstrName, _T("NetDeviceInfo")) == 0){return static_cast<CNetDevice*>(this);}else{return CContainerUI::GetInterface(pstrName);}
}void CNetDevice::DoEvent(TEventUI& event)
{if (event.Type == UIEVENT_BUTTONDOWN && IsEnabled()){if (::PtInRect(&m_rcItem, event.ptMouse)){m_uButtonState |= UISTATE_CAPTURED;m_ptLastMouse = event.ptMouse;m_rcNewPos = m_rcItem;if (m_pManager)m_pManager->AddPostPaint(this);return;}}else if (event.Type == UIEVENT_BUTTONUP){if ((m_uButtonState & UISTATE_CAPTURED) != 0){m_uButtonState &= ~UISTATE_CAPTURED;this->SetPos(m_rcNewPos);                   //这句是拖拽到目的地的关机,否则无法拖动到目的位置if (m_pManager){m_pManager->RemovePostPaint(this);m_pManager->Invalidate(m_rcNewPos);}NeedParentUpdate();return;}}else if (event.Type == UIEVENT_MOUSEMOVE){if ((m_uButtonState & UISTATE_CAPTURED) != 0){LONG cx = event.ptMouse.x - m_ptLastMouse.x;LONG cy = event.ptMouse.y - m_ptLastMouse.y;m_ptLastMouse = event.ptMouse;RECT rcCurPos = m_rcNewPos;rcCurPos.left += cx;rcCurPos.right += cx;rcCurPos.top += cy;rcCurPos.bottom += cy;//将当前拖拽块的位置 和 当前拖拽块的前一时刻的位置,刷新  CDuiRect rcInvalidate = m_rcNewPos;m_rcNewPos = rcCurPos;rcInvalidate.Join(m_rcNewPos);if (m_pManager) m_pManager->Invalidate(rcInvalidate);return;}}if (event.Type == UIEVENT_SETCURSOR){if (IsEnabled()){::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND)));return;}}CContainerUI::DoEvent(event);
}void CNetDevice::DoPostPaint(HDC hDC, const RECT& rcPaint)
{if ((m_uButtonState & UISTATE_CAPTURED) != 0) {CDuiRect rcParent = m_pParent->GetPos();RECT rcUpdate = { 0 };rcUpdate.left = m_rcNewPos.left < rcParent.left ? rcParent.left : m_rcNewPos.left;rcUpdate.top = m_rcNewPos.top < rcParent.top ? rcParent.top : m_rcNewPos.top;rcUpdate.right = m_rcNewPos.right > rcParent.right ? rcParent.right : m_rcNewPos.right;rcUpdate.bottom = m_rcNewPos.bottom > rcParent.bottom ? rcParent.bottom : m_rcNewPos.bottom;CRenderEngine::DrawColor(hDC, rcUpdate, 0xAA000000);}
}

在主对话框DuiFrameWnd.cpp中的InitWindow()函数中加入动态创建的自定义控件代码如下:

CVerticalLayoutUI* pVLNet = static_cast<CVerticalLayoutUI*>(m_PaintManager.FindControl(_T("vlSchoolNet")));//需要绘制的背景布局
if (NULL != pVLNet)
{int _left = 205;int _top = 47;CNetDevice *pCNetDevice = new CNetDevice();//创建自定义控件if (NULL != pCNetDevice){pCNetDevice->SetFloat();                     //一定要设置为绝对定位,否则不能拖动SIZE leftTop = { _left,_top };pCNetDevice->SetFixedXY(leftTop);           // 自定义控件在背景布局的起始位置pCNetDevice->SetFixedWidth(80);pCNetDevice->SetFixedHeight(80);pCNetDevice->SetAttribute(_T("bkimage"), _T("file='SchoolNet/logo2.png' dest='16,0,64,57'"));CLabelUI *pUserNameLabel = new CLabelUI;     //自定义控件增加一个标签if (pUserNameLabel != NULL){pUserNameLabel->SetAttribute(_T("float"), _T("true"));pUserNameLabel->SetAttribute(_T("pos"), _T("8,60,46,80"));//pUserNameLabel->SetAttribute(_T("bkimage"), _T("SchoolNet/123.png"));pUserNameLabel->SetText(_T("大灰狼"));pUserNameLabel->SetAttribute(_T("textcolor"), _T("#FF9FFF99"));//pUserNameLabel->SetMouseEnabled(false);pCNetDevice->Add(pUserNameLabel);}pVLNet->Add(pCNetDevice);}
}

可拖动控件完成了,我们看下效果吧:

拖动过程的黑色透明阴影

松开鼠标后,重新绘制位置

至此,可拖动自定义控件完成了,这是项目功能所需写的代码,希望能帮助到需要的人,欢迎大家提意见!

教你如何用duilib实现控件可拖动,可拖拽相关推荐

  1. 教你如何用VB做控件*.ocx

    教你如何用VB做控件*.ocx 一个控件有很多事件如:Click.MouseDown.MouseUp.MouseMove等.要触发这些事件都需要你加入代码.在控件的声明处加入Public Event ...

  2. jquery 磁铁模式控件_利用JQuery拖拽插件实现拖拽效果

    asp教程x.cs" inherits="jquerydrag._default" %> $(document).ready(function() { //拖拽方法 ...

  3. 关于duilib CComboUI控件下拉框 字体显示 与xml 设置不相符的问题

    duilib的下拉列表框的字体无法通过itemfont自定义 关于duilib CComboUI控件下拉框 字体显示 与xml 设置不相符的问题 解决办法: 添加链接描述 在设置全局字体属性时,设置字 ...

  4. 拆轮子系列之教你一步步写验证码控件

    拆轮子系列之教你一步步写验证码控件 前言 先看看效果 怎么样不错吧?别急下面我就一步一步的教你实现. 用到的知识点总结: 1.Canvas和pint的使用,我们用它画点,线,字 2.View的基本用法 ...

  5. Android 简单实现控件的拖动

    控件的拖动,使用到一个监听事件 setOnTouchListener:XML代码: 1 <?xml version="1.0" encoding="utf-8&qu ...

  6. FullCalendarDemo5 控件的实例讲解—拖拽实现值班排班(五)

    FullCalendarDemo5 控件的实例讲解-拖拽实现值班排班(五) (五)c# asp.net 操作FullCalendarDemo5 导出排班记录 目的:点击导出按钮,弹出参数指定对话框,选 ...

  7. Qt实现类似Designer中的拖拽效果:从左侧树控件中拖动图标到右侧布局窗口

    大家在Qt开发中都用过这样的拖动操作,从左边拖动一个控件到右侧的窗口.或是在其它很多软件使用中,都有把图标通过拖动布置到主画面的操作. 如何实现呢? 先看看Qt帮助中的一个实例: 这个例子自定义了一个 ...

  8. VB6.0 控件自由拖动

    VB6.0 控件自由拖动 有时,在编写代码的时候,可能需要一个浮动的界面(根据用户需求,实时拖动),下面将介绍如何实现 1.首先要修改控件的DragMode模式为0.如下图所示: '注意,以下代码可以 ...

  9. duilib list控件扩展

    对于简单的list控件已经有前辈分析了自带demo的ListRes全过程,duilib DirectUI库里面的一个简单的例子ListDemo, 他分析了listdemo的来龙去脉,这里我只是将个人理 ...

最新文章

  1. 5、Makefile基础知识汇总(转自陈皓总述)
  2. Android Spinner值不显示,选择列表正常
  3. android .a文件报毒,游戏开始文件,小A报毒!
  4. iOS开发之权限判断(这里只说相册的权限判断status一直是PHAuthorizationStatusNotDetermined问题)
  5. shell 脚本执行报错/bin/bash^M: bad interpreter: No such file or directory
  6. vs2017 安装Qt VS Tools ,新建项目没有Qt GUI Application选项 ,解决方法
  7. 2018年——不平凡的一年
  8. c语言中大于号什么意思和作用,程序员必须要使用的大于号,小于号你知道几个?教你轻松入门C语言...
  9. linux美学设计,扁平化设计美学探讨
  10. 人工智能阿发狗技术都包含哪些内容
  11. python直角坐标转极坐标_Python在OpenCV里实现极坐标变换功能
  12. 香港云服务器网站打开缓慢,香港云服务器搭建的网站卡慢怎么办?火星直播
  13. 华为Meta30 Pro怎么禁用系统更新
  14. 多彩M618XSD垂直立式人体工学鼠标拆解
  15. 超融合和服务器关系_分析超融合与传统服务器部署的区别
  16. 技术、产业、人才三管齐下,数字人民币渐行渐近 | 产业区块链发展周报
  17. MessageBox 按钮显示英文或其他语言
  18. 使用 SciPy探索标准正态分布
  19. 输入网络密码来进入共享计算机,Win7共享文件时提示输入网络密码怎么办?
  20. 【附源码】计算机毕业设计JAVA校园一卡通管理系统

热门文章

  1. taglib指令作用以及属性
  2. SSL证书不会安装配置?手把手教会你,3步搞定
  3. AI实战:推荐系统之影视领域用户画像——数据采集内容
  4. 发现了更好的 MSIL编辑器,看来我的MSIL STUDIO来晚了~~
  5. ThinkPHP框架漏洞总结
  6. 计算机主机报警是什么原因,不同的电脑故障声音分别是什么意思【详解】
  7. 华为OD机试题:小朋友高矮排列
  8. 【分享】国内著名互联网企业PHP笔试题
  9. python爬取mblock的图片素材
  10. 什么是正态分布?为何如此重要?终于有人讲明白了