资讯专栏INFORMATION COLUMN

win32拖拽编程

idisfkj / 3459人阅读

摘要:同时,由于锁定导致了我们在拖拽时对窗口的绘制无法生效的问题亦可解决。免费领取验证码内容安全短信发送直播点播体验包及云服务器等套餐更多网易技术产品运营经验分享请访问网易云社区。文章来源网易云社区

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

在邮箱大师PC版中,我们需要实现一个功能:账号和邮件夹拖拽排序。
准备
封装win32 API。我们使用到的API有,
ImageList_Create、ImageList_Destroy、
ImageList_Add、ImageList_AddMasked、ImageList_Remove、
ImageList_BeginDrag、ImageList_DragEnter、ImageList_EndDrag、ImageList_DragLeave、
ImageList_DragMove、ImageList_SetDragCursorImage、ImageList_DragShowNoLock。
For more information,see Using Image Lists

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

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));

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

问题

Ⅰ、如何使拖拽图像背景透明?
使用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,可在一定程度上减小抖动出现拖拽图像的情况。

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

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

文章来源: 网易云社区

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/25341.html

相关文章

  • 基于electron制作一个node压缩图片的桌面应用

    摘要:压缩图片桌面应用基于制作一个压缩图片的桌面应用下载地址项目源码准备工作我们来整理一下我们需要做什么压缩图片模块获取文件路径桌面应用生成压缩图片我们需要使用这个库来压缩图片,这里我们把这个库封装成压缩模块。 压缩图片桌面应用imagemin-electron 基于electron制作一个node压缩图片的桌面应用 下载地址:https://github.com/zenoslin/imag...

    bigdevil_s 评论0 收藏0
  • node-webkit实践-一键安装

    摘要:博客原文地址实践一键安装前言很久以前我简单的写过关于的使用但是我在更换博客的时候丢弃了,我在下面的文章把它引用一遍。 博客原文地址node-webkit实践-一键安装 前言 很久以前我简单的写过关于node-webkit的使用,但是我在更换博客的时候丢弃了,我在下面的文章把它引用一遍。 node-webkit其实在很多地方用处很大,请自行发散。 本文的相关代码:点击查...

    yy736044583 评论0 收藏0
  • Electron折腾笔记

    摘要:读取文件路径写入配置文件调用服务调用服务部分,主要用到的子进程。最后,上一张初步完成之后的运行图博客原文 背景 部门的项目每次开发都需要手动开启三个服务:server、webpack、grunt,每个服务都要输入一些东西(端口号,项目命,项目类型,启动器名)。而且,在推送调试的时候,这三项服务非常容易被终止掉,然后又得一个个开起来,总之每天都要来上那么10几遍吧。看图:showImg(...

    DataPipeline 评论0 收藏0
  • 不要迷恋我,我只是利用Python修改了游戏内存

    摘要:上篇文章我许了一个愿,就是想让大家多多关注我,然后我的粉丝就蹭蹭的涨了好几百,谢谢大家的厚爱。可是我发现粉丝是涨了,三连变少了,谢谢大家这次给我三连,我一定再接再厉。地址的寻找阳光总值,种植一个豌豆需要,非常不够用。 目录 前言 游戏的安装 思路       一句话总结       大概的思...

    ermaoL 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<