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

在邮箱大师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. 并发服务器和HTTP协议

    单进程服务器 1. 完成一个简单的TCP服务器 from socket import * serSocket = socket(AF_INET, SOCK_STREAM) # 重复使用绑定的信息 se ...

  2. Linux下的终端快捷键

    今天才发现Linux下的终端有这么多好用的快捷键. Shift+Ctrl+T:新建标签页 Shift+Ctrl+W:关闭标签页 Ctrl+PageUp:前一标签页 Ctrl+PageDown:后一标签 ...

  3. 若p是与10互质的质数,则p-1个9能被p整除

    [若p是与10互质的质数,则k(p-1)个9能被p整除] 因为(p,10)=1,所以(p,10^k)=1.根据费马定理,10^(k*(p-1))-1|p. 而10^k*(p-1)-1是一个位数为(p- ...

  4. 使用java代码编辑oracle数据库

    package com.hanqi; import java.io.IOException; import java.sql.Connection; import java.sql.DriverMan ...

  5. maven下拉项目不能同步

    maven下拉项目不能同步,如下图: 解决方法: 对项目右键,team, 选择这里 我选择第一项,有的需要根据情况选择第二项,如果点击完成后,还是不能同步代码,对项目右键,team,disconnec ...

  6. oralce 知识

    原文链接 附录:1.SQL 简介2.SQL 操作符3.Oracle 常用数据类型4.Oracle 函数5.[转] Oracle 常用SQL语法 字符串函数LENGTH()    字符长度LENTTHB ...

  7. unity animation readonly 无法加事件?

    目前找到的解决方案是用代码加Event: using System.Collections; using System.Collections.Generic; using UnityEngine; ...

  8. OPENSSL 生成https 客户端证书

    下面说下拿服务器证书.(前提是服务器是https,客户端认证用的时候),服务端不给的时候,我们自己去拿(不给怼他!,哈哈,开个玩笑,都会给的) openssl s_client -connect 域名 ...

  9. 区块链相关在线加解密工具(非对称加密/hash)

    https://cse.buffalo.edu/blockchain/tools.html https://cse.buffalo.edu/blockchain/encryption.html 由纽约 ...

  10. [Jmeter]让报告在邮件中以链接进行显示,通过IIS