百科问答小站 logo
百科问答小站 font logo



剪切板、文件拖拽这些功能桌面环境是怎么实现的? 第1页

  

user avatar   s.invalid 网友的相关建议: 
      

这玩意儿原理挺简单的;但真的实现起来细节特别多、特别麻烦也特别容易出错。


参与这玩意儿的角色大概分为四类:

1、用户,计算机的操作者

2、内容提供者,如资源管理器、word、记事本、画图以及截屏软件等

3、剪贴板实现者,一般是操作系统(或其提供的桌面环境管理器)

4、内容接收者,如另一个资源管理器、记事本、word/excel、图像编辑软件等


其中,剪贴板实现者主要提供一组接口,允许其它角色通过这个接口把资源上传给剪贴板、或者从剪贴板获取资源——至于剪贴板,那只是一块任何人都可以访问的内存而已。


内容提供者则需要响应CTRL+C/CTRL+X等快捷键,把资源上传到系统剪贴板——当然,它也完全可以不理睬CTRL+C快捷键,而是通过自带的菜单或其它快捷键触发“资源上传系统剪贴板”功能。


类似的,内容接收者要响应CTRL+V快捷键,把剪贴板内容取下来、插入自己的编辑环境。

同样的,它也可以不理CTRL+V快捷键,而是用上下文菜单获取剪贴板内容。比如,通过菜单选择“只粘贴文本”还是“粘贴文本以及格式”。

当然,同时响应CTRL+V和菜单也是可行的;有的软件也允许你配置它,使得它响应CTRL+V的行为从“粘贴文本及格式”改为“默认接受无格式文本”。


类似的,当鼠标选中一些对象、开始拖曳时,就会触发“drag start”事件;停止拖曳并松开左/右键,则触发“drag end”事件。你只需像响应CTRL+C/CTRL+V一样写一个事件响应程序、然后在里面调用系统剪贴板接口就好了。


这里面真正的困难在于:需要拷贝的东西是千变万化的。可能是记事本里面的一段话、也可能是word里面一段图文混排的富文本;可能是excel的一整个sheet页面,也可能是文件系统里面一个40G的大文件——甚至是隔一个选一个、一共8000个400G的媒体文件。


懂得编程的话,就知道文本只是一串数字,这串数字是ascii或者Unicode编码的;而富文本则不光有数字编码的文本,还有一些格式标签;图片呢,又是数字编码的一个个像素点的组合(还可能有很多种格式);excel的sheet页面是一个复杂的运行时对象;视频文件……那么大怎么可能放到区区8G内存里!


这下麻烦大了,对吧……


因此,Windows提供了一组标准格式识别标记,允许你往剪贴板上传纯文本、位图数据等信息;如果你需要借助剪贴板传递的对象过于复杂,它还有三个DSP开头的格式(CF_DSPTEXT、CF_DSPBITMAP和CF_DSPMETAFILEPICT),允许你通过剪贴板在自己写的程序之间交换数据。或者,你也可以注册新的数据格式并上传数据——比如,注册一个file path/URI格式,然后把需要拷贝的文件路径上传到剪贴板,自然就能通过剪贴板“复制文件”或者往网上上传文件了。

说白了,在复制文件的场景里,这里传的仅仅是源文件路径,文件本身没动;选定了目标后,才把源文件路径、目标路径作为参数开始执行复制/移动操作。

类似的,在网络上传这个场景里,也是把源文件路径当成参数,丢给了upload相关函数……


不仅如此。每次剪贴板操作都还可以上传不同类型的多个数据。比如,可以同时上传一个富文本数据、一个纯文本数据、一个选择区域的截图数据;那么接受剪贴板内容的应用程序就可以根据自身需要,选择读取其中一个。这就是我前面提到的“粘贴文本及格式”和“仅粘贴文本”的实现原理(当然,程序员的事,极少限死一条道的。比如你完全可以写个算法剔除富文本里面的格式标签、内链对象,仅仅保留纯文本,从而实现“把剪贴板里面的富文本当纯文本粘贴”功能)。


知道了原理,那么,写一个剪贴板管理器,完成“给用户展示最近提交到剪贴板的若干项内容、并允许用户选择自历史粘贴”、“把剪贴板内容存入硬盘,系统重启后仍然可以粘贴”、“在家里电脑上按CTRL+C,在办公室电脑按CTRL+V”、“在虚拟机里面的Linux桌面按CTRL+C,到外部宿主机的Windows桌面按CTRL+V”之类花里胡哨的功能,你心里已经有方案了吧。




  

相关话题

  如何用一句(段)代码表现孤独? 
  程序员用机械键盘是为了识别敲击声还是为了宏编程所带来的方便? 
  如何评价 Windows 11 抄袭 mac OS 的声音就没断过? 
  仅仅从好玩程度考虑,做编译器或操作系统哪个更有趣味? 
  你在 GitHub 上看到过哪些有意思的 Issue? 
  为什么 .NET 平台在技术上远强过 Java,而多数大公司却仍采用后者? 
  微软 2021 年 6 月 24 日发布的 Windows11 体验如何?在哪些方面做了改进? 
  Windows NT 内核与 Linux 内核相比哪个更安全? 
  如何看待「大部分程序员只会写三年代码」的说法? 
  为什么系统调用时要把一些寄存器保存到内核栈又从内核栈恢复? 

前一个讨论
为什么冷酸灵牙膏用完口腔内脱皮?
下一个讨论
如何看待Windows 11中仍然有Windows 3.1的组件,是否说明前者是后者的套壳?





© 2024-05-20 - tinynew.org. All Rights Reserved.
© 2024-05-20 - tinynew.org. 保留所有权利