• win32拖拽编程


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


    在邮箱大师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,可在一定程度上减小抖动出现拖拽图像的情况。


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

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


    相关文章:
    【推荐】 为何要在网站上设置的验证码

  • 相关阅读:
    win7游戏窗口设置
    怎么在 html 中 动态的加载一个 script
    nodejs+express +jade模板引擎 新建项目
    将大数据利用 BCP 导出SqlServer数据到CSV
    产品经理如何赢得开发人员的尊重和支持?-摘自infoq
    Microsoft TFS 如何显示在Windows 的上下文菜单中
    使用PowerDesigner 设计SQL Server 数据库
    sqlserver 删掉日志文件ldf以后 救命语句
    SqlServer修改数据库文件及日志文件存放位置
    快速备份sqlserver2005以上版本数据库的方法-摘自网络
  • 原文地址:https://www.cnblogs.com/zyfd/p/10113253.html
Copyright © 2020-2023  润新知