本文由作者邹启文授权网易云社区发布。

在邮箱大师PC版中,我们需要实现一个功能:账号和邮件夹拖拽排序。

  1. 准备 
    封装win32 API。我们使用到的API有, 
    ImageList_CreateImageList_Destroy、 
    ImageList_AddImageList_AddMaskedImageList_Remove、 
    ImageList_BeginDragImageList_DragEnterImageList_EndDragImageList_DragLeave、 
    ImageList_DragMoveImageList_SetDragCursorImageImageList_DragShowNoLock。 
    For more information,see Using Image Lists

  2. Drag开始 
    拦截鼠标的LButtonDown消息,判断point所在的控件是否符合拖拽要求,如果符合,记住状态(这里使用bool will_drag_和MailFolderNode* drag_from_标识可以拖拽,使用bool is_draging_标识正在拖拽中,使用MailFolderNode* drag_to_标识接受控件)

  3. Drag进行中 
    拦截鼠标的MouseMove消息,判断will_drag_,如果是,那么需要做如下操作: 
    ->ImageList_Create创建ImageList对象 
    ->ImageList_AddMasked加入拖拽时将要显示的图像 
    ->ImageList_BeginDrag即将开始拖拽,并设置鼠标在拖拽图像中的位置 
    ->ImageList_DragEnter进入拖拽,并设置拖拽图像的位置 
    ->修改will_drag_为false,is_draging_为true,保证上面几步只做一次 
    ->判断point是否在拖拽接受范围内,以及point对应控件是否接受拖拽(及时更新drag_to_) 
    ->如果是,那么执行ImageList_DragMove、ImageList_DragShowNoLock(TRUE)、SetCursor(LoadCursor(NULL, IDC_ARROW)); 
    ->如果不是,那么执行ImageList_DragShowNoLock(FALSE)、SetCursor(LoadCursor(NULL, IDC_NO));

  4. Drag结束 
    拦截鼠标的LButtonUp消息,如果is_draging_,那么执行ImageList_EndDrag、ImageList_DragLeave、ImageList_Destroy,然后根据drag_from_和drag_to_处理本次拖拽操作。

  5. 问题

    Ⅰ、如何使拖拽图像背景透明? 
    使用CreateCompatibleBitmap创建位图,调用FillRect将位图背景刷成白色RGB(255,255,255); 
    在ImageList_Create时指定ILC_COLOR32 | ILC_MASK; 
    调用ImageList_AddMasked(bitmap, RGB(255,255,255)); 
    至此,拖拽图像中的白色会与mask'中和'

    Ⅱ、在拖拽时出现窗口绘制被'破坏',并且残留痕迹? 
    这是由于在调用ImageList_DragEnter时锁定了窗口导致,我们使用NULL代替HWND即可解决此问题。同时,由于锁定导致了我们在拖拽时对窗口的绘制无法生效的问题亦可解决。另,记得在拖拽结束时ImageList_DragLeave(NULL);

    Ⅲ、ImageList_BeginDrag和ImageList_DragEnter中的位置是何含义? 
    在ImageList_BeginDrag中,此处位置为鼠标图标相对于拖拽图像的位置。 
    在mageList_DragEnter中,此处位置为鼠标相对于HWND的位置,如果HWND为NULL,那么便是相对于屏幕的位置。

    Ⅳ、ImageList_DragShowNoLock含义是什么? 
    参数BOOL表示是否显示拖拽图像。当拖拽move在可接受控件时,显示拖拽鼠标,更改鼠标样式(或使用ImageList_SetDragCursorImage设置自定义鼠标样式,注意此时需隐藏ShowCursor(FALSE));否则,不显示拖拽图像,并显示IDC_NO不可操作样式。

    Ⅴ、will_drag_的标识是否多余? 
    为何要等到MouseMove再去真正开始drag?因为正常的单击操作,我们不希望看到拖拽图像,因此设置此标记。实际应用中发现,有时候单击时发生'抖动',此时也出现拖拽图像,因此我们加入了延时,在按下100ms后才将will_drag_设置成true,可在一定程度上减小抖动出现拖拽图像的情况。

免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

更多网易技术、产品、运营经验分享请访问网易云社区

相关文章:
【推荐】 从用户端到后台系统,严选分销教会我这些事
【推荐】 MySQL多线程备份工具mydumper 之 RDS外部实例迁移平台
【推荐】 微服务化之服务拆分与服务发现

win32拖拽编程的更多相关文章

  1. jsDOM编程-拖拽层

    页面样式代码: <!doctype html><html><head><meta http-equiv="content-type" co ...

  2. Win32 文件拖拽

    1.响应系统消息  WM_DROPFILES 2.在响应函数里面获取拖拽文件路径 LRESULT OnDropFiles(UINT uMsg, WPARAM wParam, LPARAM lParam ...

  3. 高德地图 Android编程中 如何设置使 标记 marker 能够被拖拽

    由于本人对智能手机真心的不太会用,我本人大概是不到3年前才买的智能手机,用以前的索尼爱立信手机比较方便小巧,平时学习工作打个电话发个短信也就够了,出去吃饭一般都是朋友拿手机去弄什么美团团购啥的,然后我 ...

  4. dropzonejs中文翻译手册 DropzoneJS是一个提供文件拖拽上传并且提供图片预览的开源类库.

    http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/ 由于项目需要,完成一个web的图片拖拽上传,也就顺便学习和了解了一下前端的比较新的技术 ...

  5. wpf图片查看器,支持鼠标滚动缩放拖拽

    最近项目需要,要用到一个图片查看器,类似于windows自带的图片查看器那样,鼠标滚动可以缩放,可以拖拽图片,于是就写了这个简单的图片查看器. 前台代码: <Window x:Class=&qu ...

  6. C# 图片盖章功能实现,支持拖拽-旋转-放缩-保存

    实现图片盖章功能,在图片上点击,增加“图章”小图片,可以拖拽“图章”到任意位置,也可以点击图章右下角园框,令图片跟着鼠标旋转和放缩. 操作方法:1.点击增加“图章”2.选中移动图标3.点中右下角放缩旋 ...

  7. 移动端拖拽(模块化开发,触摸事件,webpack)

    通过jquery可以很容易实现CP端的拖拽.但是在移动端却不好用了.于是我自己写了一个在移动端的拖拽demo,主要用到的事件是触摸事件(touchstart,touchmove和touchend). ...

  8. WPF.UIShell UIFramework之自定义窗口的深度技术 - 模态闪动(Blink)、窗口四边拖拽支持(WmNCHitTest)、自定义最大化位置和大小(WmGetMinMaxInfo)

    无论是在工作和学习中使用WPF时,我们通常都会接触到CustomControl,今天我们就CustomWindow之后的一些边角技术进行探讨和剖析. 窗口(对话框)模态闪动(Blink) 自定义窗口的 ...

  9. 纯JS Web在线可拖拽的流程设计器

    F2工作流引擎之-纯JS Web在线可拖拽的流程设计器 Web纯JS流程设计器无需编程,完全是通过鼠标拖.拉.拽的方式来完成,支持串行.并行.分支.异或分支.M取N路分支.会签.聚合.多重聚合.退回. ...

随机推荐

  1. 常见的linux服务器构建

    Linux常用服务器构建-ftp服务器 ftp服务器 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”. 用于Internet上的控制文件的双 ...

  2. 关于hibernate4.3版本之后org.hibernate.service.ServiceRegistryBuilder被弃用

    之前一直都是使用hibernate4.2.21的我,有一天突然没有使用本地的jar包而是让IDEA自动下载最新版本的hibernate5.2.2之后,发现有几个经常使用的方法报错了. -这真是让我惊了 ...

  3. vb.net 与 c# 运算符区别

    vb.net vs c# 详细的Operators运算符区别 vb.net ===================== Comparison = < > <= >= <& ...

  4. Nginx rewrite使用

    转自: https://www.cnblogs.com/czlun/articles/7010604.html

  5. NotePad++替换行前、行后空格,替换空行

    用 Notepad++ 打开,把每一个将要放在表中单元格的内容放一行(注: ^ 代表行首 $ 代表行尾) 去除行尾空格和空白行:按CTRL+H 选择正则表达式– 查找目标:\s+$ 替换为空 去除行首 ...

  6. hive 建表导入数据

    1. hive> create table wyp > (id int, name string, > age int, tel string) > ROW FORMAT DE ...

  7. 简单API练手:(1)复制自身程序到windows目录和系统目录下;(2)获得系统的相关信息。

    1.复制自身程序到windows目录和系统目录下: #include <windows.h> #include <stdio.h> #include <string.h& ...

  8. C#开发微信公众化平台

     C#开发微信公众化平台 写在前面 服务号和订阅号 URL配置 创建菜单 查询.删除菜单 接受消息 发送消息(图文.菜单事件响应) 示例Demo下载 后记 最近公司在做微信开发,其实就是接口开发,网上 ...

  9. 基于 Web 的远程 Terminal 模拟器安装使用详解

    http://lzw.me/a/shellinabox.html 一.Shellinabox 简介 Shellinabox 是一个基于 web 的终端模拟器,采用 C 语言编写,使用 Ajax 与后端 ...

  10. 我读《从Paxos到zookeeper分布式一致性原理与实践》

    从年后拿到这本书开始阅读,到准备系统分析师考试之前,终于读完了一遍,对Zookeeper有了一个全面的认识,整本书从理论到应用再到细节的阐述,内容安排从逻辑性和实用性上都是很优秀的,对全面认识Zook ...