教你如何用duilib实现控件可拖动,可拖拽
要实现的效果:
鼠标点击控件(自绘控件,可继承任意控件类,下文将给出示例),并且进行拖拽,会有一个半透明黑色阴影来表示当前拖动的位置。当松开鼠标,控件重新绘制在鼠标松开的位置。拖拽功能的实现代码主要在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实现控件可拖动,可拖拽相关推荐
- 教你如何用VB做控件*.ocx
教你如何用VB做控件*.ocx 一个控件有很多事件如:Click.MouseDown.MouseUp.MouseMove等.要触发这些事件都需要你加入代码.在控件的声明处加入Public Event ...
- jquery 磁铁模式控件_利用JQuery拖拽插件实现拖拽效果
asp教程x.cs" inherits="jquerydrag._default" %> $(document).ready(function() { //拖拽方法 ...
- 关于duilib CComboUI控件下拉框 字体显示 与xml 设置不相符的问题
duilib的下拉列表框的字体无法通过itemfont自定义 关于duilib CComboUI控件下拉框 字体显示 与xml 设置不相符的问题 解决办法: 添加链接描述 在设置全局字体属性时,设置字 ...
- 拆轮子系列之教你一步步写验证码控件
拆轮子系列之教你一步步写验证码控件 前言 先看看效果 怎么样不错吧?别急下面我就一步一步的教你实现. 用到的知识点总结: 1.Canvas和pint的使用,我们用它画点,线,字 2.View的基本用法 ...
- Android 简单实现控件的拖动
控件的拖动,使用到一个监听事件 setOnTouchListener:XML代码: 1 <?xml version="1.0" encoding="utf-8&qu ...
- FullCalendarDemo5 控件的实例讲解—拖拽实现值班排班(五)
FullCalendarDemo5 控件的实例讲解-拖拽实现值班排班(五) (五)c# asp.net 操作FullCalendarDemo5 导出排班记录 目的:点击导出按钮,弹出参数指定对话框,选 ...
- Qt实现类似Designer中的拖拽效果:从左侧树控件中拖动图标到右侧布局窗口
大家在Qt开发中都用过这样的拖动操作,从左边拖动一个控件到右侧的窗口.或是在其它很多软件使用中,都有把图标通过拖动布置到主画面的操作. 如何实现呢? 先看看Qt帮助中的一个实例: 这个例子自定义了一个 ...
- VB6.0 控件自由拖动
VB6.0 控件自由拖动 有时,在编写代码的时候,可能需要一个浮动的界面(根据用户需求,实时拖动),下面将介绍如何实现 1.首先要修改控件的DragMode模式为0.如下图所示: '注意,以下代码可以 ...
- duilib list控件扩展
对于简单的list控件已经有前辈分析了自带demo的ListRes全过程,duilib DirectUI库里面的一个简单的例子ListDemo, 他分析了listdemo的来龙去脉,这里我只是将个人理 ...
最新文章
- 5、Makefile基础知识汇总(转自陈皓总述)
- Android Spinner值不显示,选择列表正常
- android .a文件报毒,游戏开始文件,小A报毒!
- iOS开发之权限判断(这里只说相册的权限判断status一直是PHAuthorizationStatusNotDetermined问题)
- shell 脚本执行报错/bin/bash^M: bad interpreter: No such file or directory
- vs2017 安装Qt VS Tools ,新建项目没有Qt GUI Application选项 ,解决方法
- 2018年——不平凡的一年
- c语言中大于号什么意思和作用,程序员必须要使用的大于号,小于号你知道几个?教你轻松入门C语言...
- linux美学设计,扁平化设计美学探讨
- 人工智能阿发狗技术都包含哪些内容
- python直角坐标转极坐标_Python在OpenCV里实现极坐标变换功能
- 香港云服务器网站打开缓慢,香港云服务器搭建的网站卡慢怎么办?火星直播
- 华为Meta30 Pro怎么禁用系统更新
- 多彩M618XSD垂直立式人体工学鼠标拆解
- 超融合和服务器关系_分析超融合与传统服务器部署的区别
- 技术、产业、人才三管齐下,数字人民币渐行渐近 | 产业区块链发展周报
- MessageBox 按钮显示英文或其他语言
- 使用 SciPy探索标准正态分布
- 输入网络密码来进入共享计算机,Win7共享文件时提示输入网络密码怎么办?
- 【附源码】计算机毕业设计JAVA校园一卡通管理系统