精华内容
下载资源
问答
  • 但是,有些时候这样做确实能够带来方便,比如“一键复制”功能,用户点击一下按钮,指定的内容就自动进入剪贴板。 目前,一共有三种方法可以实现剪贴板操作。 Document.execCommand()方法 异步的 Clipboard API ...

    简介

    浏览器允许 JavaScript 脚本读写剪贴板,自动复制或粘贴内容。

    一般来说,脚本不应该改动用户的剪贴板,以免不符合用户的预期。但是,有些时候这样做确实能够带来方便,比如“一键复制”功能,用户点击一下按钮,指定的内容就自动进入剪贴板。

    目前,一共有三种方法可以实现剪贴板操作。

    • Document.execCommand()方法
    • 异步的 Clipboard API
    • copy事件和paste事件

    本文逐一介绍这三种方法。

    Document.execCommand() 方法

    Document.execCommand()是操作剪贴板的传统方法,各种浏览器都支持。

    它支持复制、剪切和粘贴这三个操作。

    • document.execCommand('copy')(复制)
    • document.execCommand('cut')(剪切)
    • document.execCommand('paste')(粘贴)

    (1)复制操作

    复制时,先选中文本,然后调用document.execCommand('copy'),选中的文本就会进入剪贴板。

    const inputElement = document.querySelector('#input');
    inputElement.select();
    document.execCommand('copy');
    

    上面示例中,脚本先选中输入框inputElement里面的文字(inputElement.select()),然后document.execCommand('copy')将其复制到剪贴板。

    注意,复制操作最好放在事件监听函数里面,由用户触发(比如用户点击按钮)。如果脚本自主执行,某些浏览器可能会报错。

    (2)粘贴操作

    粘贴时,调用document.execCommand('paste'),就会将剪贴板里面的内容,输出到当前的焦点元素中。

    const pasteText = document.querySelector('#output');
    pasteText.focus();
    document.execCommand('paste');
    

    (3)缺点

    Document.execCommand()方法虽然方便,但是有一些缺点。

    首先,它只能将选中的内容复制到剪贴板,无法向剪贴板任意写入内容。

    其次,它是同步操作,如果复制/粘贴大量数据,页面会出现卡顿。有些浏览器还会跳出提示框,要求用户许可,这时在用户做出选择前,页面会失去响应。

    为了解决这些问题,浏览器厂商提出了异步的 Clipboard API。

    异步 Clipboard API

    Clipboard API 是下一代的剪贴板操作方法,比传统的document.execCommand()方法更强大、更合理。

    它的所有操作都是异步的,返回 Promise 对象,不会造成页面卡顿。而且,它可以将任意内容(比如图片)放入剪贴板。

    navigator.clipboard属性返回 Clipboard 对象,所有操作都通过这个对象进行。

    const clipboardObj = navigator.clipboard;
    

    如果navigator.clipboard属性返回undefined,就说明当前浏览器不支持这个 API。

    由于用户可能把敏感数据(比如密码)放在剪贴板,允许脚本任意读取会产生安全风险,所以这个 API 的安全限制比较多。

    首先,Chrome 浏览器规定,只有 HTTPS 协议的页面才能使用这个 API。不过,开发环境(localhost)允许使用非加密协议。

    其次,调用时需要明确获得用户的许可。权限的具体实现使用了 Permissions API,跟剪贴板相关的有两个权限:clipboard-write(写权限)和clipboard-read(读权限)。“写权限”自动授予脚本,而“读权限”必须用户明确同意给予。也就是说,写入剪贴板,脚本可以自动完成,但是读取剪贴板时,浏览器会弹出一个对话框,询问用户是否同意读取。

    另外,需要注意的是,脚本读取的总是当前页面的剪贴板。这带来的一个问题是,如果把相关的代码粘贴到开发者工具中直接运行,可能会报错,因为这时的当前页面是开发者工具的窗口,而不是网页页面。

    (async () => {
      const text = await navigator.clipboard.readText();
      console.log(text);
    })();
    

    如果你把上面的代码,粘贴到开发者工具里面运行,就会报错。因为代码运行的时候,开发者工具窗口是当前页,这个页面不存在 Clipboard API 依赖的 DOM 接口。一个解决方法就是,相关代码放到setTimeout()里面延迟运行,在调用函数之前快速点击浏览器的页面窗口,将其变成当前页。

    setTimeout(async () => {
      const text = await navigator.clipboard.readText();
      console.log(text);
    }, 2000);
    

    上面代码粘贴到开发者工具运行后,快速点击一下网页的页面窗口,使其变为当前页,这样就不会报错了。

    Clipboard 对象

    Clipboard 对象提供了四个方法,用来读写剪贴板。它们都是异步方法,返回 Promise 对象。

    Clipboard.readText()

    Clipboard.readText()方法用于复制剪贴板里面的文本数据。

    document.body.addEventListener(
      'click',
      async (e) => {
        const text = await navigator.clipboard.readText();
        console.log(text);
      }
    )
    

    上面示例中,用户点击页面后,就会输出剪贴板里面的文本。注意,浏览器这时会跳出一个对话框,询问用户是否同意脚本读取剪贴板。

    如果用户不同意,脚本就会报错。这时,可以使用try...catch结构,处理报错。

    async function getClipboardContents() {
      try {
        const text = await navigator.clipboard.readText();
        console.log('Pasted content: ', text);
      } catch (err) {
        console.error('Failed to read clipboard contents: ', err);
      }
    }
    

    Clipboard.read()

    Clipboard.read()方法用于复制剪贴板里面的数据,可以是文本数据,也可以是二进制数据(比如图片)。该方法需要用户明确给予许可。

    该方法返回一个 Promise 对象。一旦该对象的状态变为 resolved,就可以获得一个数组,每个数组成员都是 ClipboardItem 对象的实例。

    async function getClipboardContents() {
      try {
        const clipboardItems = await navigator.clipboard.read();
        for (const clipboardItem of clipboardItems) {
          for (const type of clipboardItem.types) {
            const blob = await clipboardItem.getType(type);
            console.log(URL.createObjectURL(blob));
          }
        }
      } catch (err) {
        console.error(err.name, err.message);
      }
    }
    

    ClipboardItem 对象表示一个单独的剪贴项,每个剪贴项都拥有ClipboardItem.types属性和ClipboardItem.getType()方法。

    ClipboardItem.types属性返回一个数组,里面的成员是该剪贴项可用的 MIME 类型,比如某个剪贴项可以用 HTML 格式粘贴,也可以用纯文本格式粘贴,那么它就有两个 MIME 类型(text/htmltext/plain)。

    ClipboardItem.getType(type)方法用于读取剪贴项的数据,返回一个 Promise 对象。该方法接受剪贴项的 MIME 类型作为参数,返回该类型的数据,该参数是必需的,否则会报错。

    Clipboard.writeText()

    Clipboard.writeText()方法用于将文本内容写入剪贴板。

    document.body.addEventListener(
      'click',
      async (e) => {
        await navigator.clipboard.writeText('Yo')
      }
    )
    

    上面示例是用户在网页点击后,脚本向剪贴板写入文本数据。

    该方法不需要用户许可,但是最好也放在try...catch里面防止报错。

    async function copyPageUrl() {
      try {
        await navigator.clipboard.writeText(location.href);
        console.log('Page URL copied to clipboard');
      } catch (err) {
        console.error('Failed to copy: ', err);
      }
    }
    

    Clipboard.write()

    Clipboard.write()方法用于将任意数据写入剪贴板,可以是文本数据,也可以是二进制数据。

    该方法接受一个 ClipboardItem 实例作为参数,表示写入剪贴板的数据。

    try {
      const imgURL = 'https://dummyimage.com/300.png';
      const data = await fetch(imgURL);
      const blob = await data.blob();
      await navigator.clipboard.write([
        new ClipboardItem({
          [blob.type]: blob
        })
      ]);
      console.log('Image copied.');
    } catch (err) {
      console.error(err.name, err.message);
    }
    

    上面示例中,脚本向剪贴板写入了一张图片。注意,Chrome 浏览器目前只支持写入 PNG 格式的图片。

    ClipboardItem()是浏览器原生提供的构造函数,用来生成ClipboardItem实例,它接受一个对象作为参数,该对象的键名是数据的 MIME 类型,键值就是数据本身。

    下面的例子是将同一个剪贴项的多种格式的值,写入剪贴板,一种是文本数据,另一种是二进制数据,供不同的场合粘贴使用。

    function copy() {
      const image = await fetch('kitten.png');
      const text = new Blob(['Cute sleeping kitten'], {type: 'text/plain'});
      const item = new ClipboardItem({
        'text/plain': text,
        'image/png': image
      });
      await navigator.clipboard.write([item]);
    }
    

    copy 事件,cut 事件

    用户向剪贴板放入数据时,将触发copy事件。

    下面的示例是将用户放入剪贴板的文本,转为大写。

    const source = document.querySelector('.source');
    source.addEventListener('copy', (event) => {
      const selection = document.getSelection();
      event.clipboardData.setData('text/plain', selection.toString().toUpperCase());
      event.preventDefault();
    });
    

    上面示例中,事件对象的clipboardData属性包含了剪贴板数据。它是一个对象,有以下属性和方法。

    • Event.clipboardData.setData(type, data):修改剪贴板数据,需要指定数据类型。
    • Event.clipboardData.getData(type):获取剪贴板数据,需要指定数据类型。
    • Event.clipboardData.clearData([type]):清除剪贴板数据,可以指定数据类型。如果不指定类型,将清除所有类型的数据。
    • Event.clipboardData.items:一个类似数组的对象,包含了所有剪贴项,不过通常只有一个剪贴项。

    下面的示例是拦截用户的复制操作,将指定内容放入剪贴板。

    const clipboardItems = [];
    document.addEventListener('copy', async (e) => {
      e.preventDefault();
      try {
        let clipboardItems = [];
        for (const item of e.clipboardData.items) {
          if (!item.type.startsWith('image/')) {
            continue;
          }
          clipboardItems.push(
            new ClipboardItem({
              [item.type]: item,
            })
          );
          await navigator.clipboard.write(clipboardItems);
          console.log('Image copied.');
        }
      } catch (err) {
        console.error(err.name, err.message);
      }
    });
    

    上面示例中,先使用e.preventDefault()取消了剪贴板的默认操作,然后由脚本接管复制操作。

    cut事件则是在用户进行剪切操作时触发,它的处理跟copy事件完全一样,也是从Event.clipboardData属性拿到剪切的数据。

    paste 事件

    用户使用剪贴板数据,进行粘贴操作时,会触发paste事件。

    下面的示例是拦截粘贴操作,由脚本将剪贴板里面的数据取出来。

    document.addEventListener('paste', async (e) => {
      e.preventDefault();
      const text = await navigator.clipboard.readText();
      console.log('Pasted text: ', text);
    });
    
    展开全文
  • windows 剪贴板If you have Clipboard history enabled in Windows 10, the feature keeps a record of items you have recently copied to the Clipboard while using copy and paste. Here’s how to clear your ...
    windows 剪贴板

    windows 剪贴板

    Windows 10 Hero Image Version 2

    If you have Clipboard history enabled in Windows 10, the feature keeps a record of items you have recently copied to the Clipboard while using copy and paste. Here’s how to clear your Clipboard history—or disable it if you prefer.

    如果您在Windows 10中启用了剪贴板历史记录,则该功能将保留您最近在使用复制和粘贴时复制到剪贴板的项目的记录。 以下是清除剪贴板历史记录或根据需要将其禁用的方法。

    剪贴板历史记录中存储了什么? (What Gets Stored in Clipboard History?)

    Clipboard history, first introduced in Windows 10’s October 2018 Update, stores a list of the 25 most recent items that you’ve copied to the Clipboard. These items can include text, HTML, and images smaller than 4 MB in size. Unless an item is pinned to the Clipboard, the Clipboard history list gets erased every time you restart your device.

    剪贴板历史记录最早在Windows 10的2018年10月更新中引入,它存储了已复制到剪贴板的25个最新项的列表。 这些项目可以包括文本,HTML和大小小于4 MB的图像。 除非将项目固定在剪贴板上,否则每次重新启动设备时剪贴板历史记录列表都会被删除。

    如何在Windows 10中清除剪贴板历史记录 (How to Clear Clipboard History in Windows 10)

    Unlike other potentially privacy-invasive features in Windows 10, the Clipboard history feature only works if it has been enabled from Settings > System > Clipboard.

    Windows 10中其他可能会侵犯隐私的功能不同,剪贴板历史记录功能仅在已从“设置”>“系统”>“剪贴板”中启用后才可用。

    When Clipboard history is enabled, pressing Windows+V will bring up a small window that lists the most recent items you have copied to the Clipboard.

    启用剪贴板历史记录后,按Windows + V将弹出一个小窗口,其中列出了您已复制到剪贴板的最新项目。

    The Clipboard history pop-up window on Windows 10

    To remove individual items from Clipboard history, call up the list with Windows+V and then click the three dots (ellipses) beside the item you’d like to delete.

    要从剪贴板历史记录中删除单个项目,请使用Windows + V调出列表,然后单击要删除的项目旁边的三个点(椭圆)。

    Click the ellipses in Clipboard history on Windows 10

    A small menu will pop up. Click “Delete” and the item will be removed from the list.

    将会弹出一个小菜单。 单击“删除”,该项目将从列表中删除。

    Click Delete in Clipboard history on Windows 10

    To clear the entire Clipboard history, click any set of three dots (ellipses) in the list and a menu will pop up. Select “Clear All.”

    要清除剪贴板的整个历史记录,请在列表中单击任意一组三个点(椭圆),然后会弹出一个菜单。 选择“全部清除”。

    Click clear all in Clipboard history on Windows 10

    Any remaining items on the list after you click “Clear All” are pinned in place. If you’d like to remove a pinned item, click the ellipses beside it and select “Unpin.” Then you can either delete it or try “Clear All” from the ellipses menu again.

    单击“全部清除”后,列表上的所有剩余项目都固定在适当的位置。 如果您想删除固定的项目,请点击其旁边的省略号,然后选择“取消固定”。 然后,您可以将其删除,或再次从椭圆菜单中尝试“全部清除”。

    If you’re running a version of Windows 10 from before build 1909, then the steps are nearly identical, but the interface has changed slightly.

    如果您运行的是版本1909之前的Windows 10版本,则步骤几乎相同,但是界面略有更改。

    When enabled, if you press Windows+V, you will see a small pop-up window that contains a list of the most recent items you have copied.

    启用后,如果按Windows + V,您将看到一个小的弹出窗口,其中包含您已复制的最新项目的列表。

    The Clipboard history window in Windows 10

    To remove individual items from Clipboard history, call up the list with Windows+V, then click the small “X” beside any item on the list.

    要从剪贴板历史记录中删除单个项目,请使用Windows + V调用列表,然后单击列表中任何项目旁边的小“ X”。

    Click the X to remove items from your Clipboard history

    To remove the entire contents of the Clipboard history list, click “Clear All” in the upper-right corner of the Clipboard history window.

    要删除剪贴板历史记录列表的全部内容,请单击剪贴板历史记录窗口右上角的“全部清除”。

    Click Clear all to remove items from your Clipboard history

    If any items remain on the list after you click “Clear All,” then they are likely pinned in place. Click the small pushpin icon beside the remaining items on the list and click “Clear All” again.

    如果单击“全部清除”后列表中仍有任何项目,则可能已将其固定在适当的位置。 单击列表中其余项目旁边的小图钉图标,然后再次单击“全部清除”。

    Note that with Clipboard history enabled, new items will continue to appear in the Clipboard history list every time you copy something to the Clipboard. If you would like to prevent Windows from storing your Clipboard history, you will need to disable the feature in Windows Settings.

    请注意,启用剪贴板历史记录后,每次将某些内容复制到剪贴板时,新项目将继续出现在剪贴板历史记录列表中。 如果要阻止Windows存储剪贴板历史记录,则需要在Windows设置中禁用该功能。

    清除所有剪贴板数据的另一种方法 (Another Way to Clear All Clipboard Data)

    You can also clear your clipboard data in Windows Settings. Navigate to Settings > System > Clipboard and locate the “Clear Clipboard Data” section. Click on the “Clear” button, and the clipboard will be erased.

    您也可以在Windows设置中清除剪贴板数据。 导航到“设置”>“系统”>“剪贴板”,然后找到“清除剪贴板数据”部分。 单击“清除”按钮,剪贴板将被删除。

    Click Clear to clear clipboard data in Windows 10

    This is equivalent to pushing the “Clear All” button in the Clipboard history window, but it also works with Clipboard history turned off.

    这等效于在剪贴板历史记录窗口中按下“全部清除”按钮,但是在剪贴板历史记录已关闭的情况下也可以使用。

    如何在Windows 10中禁用剪贴板历史记录 (How to Disable Clipboard History in Windows 10)

    First, click the “Start” button, and then click the “gear” icon on the left side of the Start menu to open the “Windows Settings” menu. You can also press Windows+i to get there.

    首先,单击“开始”按钮,然后单击“开始”菜单左侧的“齿轮”图标以打开“ Windows设置”菜单。 您也可以按Windows + i到达那里。

    In Windows Settings, click on “System.”

    在Windows设置中,单击“系统”。

    Click System in Settings on Windows 10

    On the Settings sidebar, click on “Clipboard.” In Clipboard settings, locate the section called “Clipboard history” and toggle the switch to “Off.”

    在“设置”侧边栏上,单击“剪贴板”。 在“剪贴板设置”中,找到“剪贴板历史记录”部分,然后将开关切换到“关闭”。

    Click on the Clipboard History Switch in Windows 10 System Settings to turn it off

    Once disabled, if you press Windows+V, you will see a small window alerting you that Windows 10 cannot show your Clipboard history because the feature is turned off.

    禁用后,如果按Windows + V,您将看到一个小窗口,警告您Windows 10无法显示剪贴板历史记录,因为该功能已关闭。

    Can't show Clipboard history message in Windows 10

    Now you’re free to copy and paste in privacy once again.

    现在,您可以自由地再次复制并粘贴到隐私中。

    翻译自: https://www.howtogeek.com/672429/how-to-clear-your-clipboard-history-on-windows-10/

    windows 剪贴板

    展开全文
  • Windows进程通信之剪贴板

    千次阅读 2014-08-01 14:03:40
    本文从剪贴板概念、剪贴板内容监听,普通数据类型,打开剪贴板,读剪贴板,写剪贴板、API汇总、他山之石、通过剪贴板实现进程间通信和总结共11个方面来较为深入地探讨Windows剪贴板的机制和使用。   说明:建议先...

    本文由danny发表于http://blog.csdn.net/danny_share

     

    前面两篇废话了这么多,本文开始上干货。

    本文从剪贴板概念、剪贴板内容监听,普通数据类型,打开剪贴板,读剪贴板,写剪贴板、API汇总、他山之石、通过剪贴板实现进程间通信和总结共10个方面来较为深入地探讨Windows剪贴板的机制和使用。

     

    说明:建议先下载本文配套工程,其中

    (1)      ClipBoardDemo工程主要演示剪贴板相关API使用

    (2)      MainProcess工程、ASubProcess工程、BSubProcess工程分别用于演示本文第九部分进程间通信的主进程和两个子进程

    下载地址:http://download.csdn.net/detail/danny_share/7703279

     

    一.剪贴板概念

    剪贴板是系统级的堆空间,且任何一个应用程序都具备访问权,主要涉及复制(Ctrl+C),剪切(Ctrl+X)、粘贴(Ctrl+V)、清空和监听五个操作。

     

    二.剪贴板内容监听

    1.开始监听

    【a】SetClipboardViewer将窗口加入监听链

    【b】一旦剪贴板内容变化,系统会向监听链中的第一个注册监听的窗口发送WM_DRAWCLIPBOARD消息。为什么说是第一个呢?参见“消息链顺序”

    【c】通过实验发现,如果新拷贝的内容和原来一样,系统还是会出发消息,说明普通的复制操作不管内容相不相同,都是直接覆盖原来剪贴板中的数据的

     

    2.处理消息

    (1)WM_CHANGECBCHAIN

    【a】除自己以外,其他进程加入了监听链,或者退出了监听链,系统就会发出这个消息

    【b】这里只说明监听者发生了变化,并不表示剪贴板中内容发生变化。

    【c】如果存在下一个监听进程,那么需要将该消息发送给下一个监听者

         否则下一个监听者将收不到该消息

    【d】对于MFC,可通过重载OnChangeCbChain函数实现

     

    (2)WM_DRAWCLIPBOARD

    【a】进程首次运行时或者是剪贴板内容发生变化时,进程都会收到这个消息

    【b】如果存在下一个监听进程,那么需要将该消息发送给下一个监听者

    否则下一个监听者将收不到该消息

    【c】对于MFC,可通过重载OnDrawClipboard函数实现

     

    3.停止监听

    【a】使用ChangeClipboardChain()函数停止监听

    【b】本质是发送WM_CHANGECBCHAIN消息,且将自己从监听链中去除

    【c】其他监听进程将会收到WM_CHANGECBCHAIN消息

     

    4.消息链顺序

    【a】刚才一直在说当剪贴板内容变化时,进程将会收到WM_DRAWCLIPBOARD消息,然后该进程处理完以后,需向下个监听者发送该消息,那下个监听者是谁呢?

    【b】我们在WM_DRAWCLIPBOARD消息处理函数OnDrawClipboard中closeClipboard后sleepl两秒后弹窗

    【c】然后拷贝ClipBoardOne.exe三份,依次启动,我们分别取名A、B和C

    【d】当剪贴板内容变化时,进程弹出剪贴板变化的顺序也是A、B、C,说明加入监听的顺序和收到消息的顺序是一致的。

     

    三.数据类型

    分类

    ID

    格式

    说明

    标准

    1

    CF_BITMAP

    位图句柄

    2

    CF_DIB

     

    3

    CF_DIBV5

    包含BITMAPV5HEADER结构且跟着位图颜色空间和位图数据

    4

    CF_DIF

     

    5

    CF_DSPBITMAP

     

    6

    CF_DSPENHMETAFILE

     

    7

    CF_DSPMETAFILEPICT

     

    8

    CF_DSPTEXT

     

    9

    CF_ENHMETAFILE

     

    10

    CF_GDIOBJFIRST

     

    11

    CF_GDIOBJLAST

     

    12

    CF_HDROP

    拖放服务,文件拷贝也是这个类型

    13

    CF_LOCALE

     

    14

    CF_METAFILEPICT

     

    15

    CF_OEMTEXT

    在窗口中执行DOS一起使用剪贴板

    16

    CF_OWNERDISPLAY

     

    17

    CF_PALETTE

    调色板句柄,通常和CF_DIB配合

    18

    CF_PENDATA

     

    19

    CF_PRIVATEFIRST

     

    20

    CF_PRIIVATELAST

     

    21

    CF_RIFF

    资源交换文件格式的多媒体数据

    22

    CF_SYLK

     

    23

    CF_TEXT

    ANSI文本

    24

    CF_TIFF

    TIFF格式图片数据内存块

    25

    CF_UNICODETEXT

    Unicode格式字符

    26

    CF_WAVE

    wave文件

    注册

    27

    自定义数值

    RegisterClipboardFormat自定义格式

    私有

    28

    值范围

    CF_PRIVATEFIRST

    CF_PRIVATELAST

    (1)     不需要向系统注册

    (2)     WM_DESTROYCLIPBOARD消息释放资源

    多重

    29

     

     

    实质没有新定义格式

    (1)     CoutClipboardFormats查询格式总数

    (2)     要返回具体格式,EnumClipboardFormats

    转换

    30

    (1)     当剪贴板中为格式A,而Windows需格式B,假如A转成B在左侧表格中,则系统默认转换

    (2)     例如拷贝BMP文件时,由于BMP文件和系统调色板相关,所以最好格式为CF_DIB或CF_DIBVS,这样系统请求CF_BITMAP时,会自动使用调色板



    四.打开剪贴板

    (1)打开剪贴板之前,我们首先需要查看是否有其他应用正在使用剪贴板

    (2)Windows提供了两个和查看拥有者相关的函数,分别是

    GetClipboardOwner和GetOpenClipboardWindow

    (3)GetClipboardOwner函数一般指上次存放数据的进程

    (4)GetOpenClipboardWindow才是真正指当前获得剪贴板操作权的进程

    (5)因此OpenClipboard前需调用GetOpenClipboardWindow函数,当返回句柄为空才行。

    HWND myHwnd=GetSafeHwnd();//当前窗口进程
    CWnd* ownerCHwnd=GetClipboardOwner();//一般指上次使用读写剪贴板的进程
    CWnd* wndUserCHwnd=GetOpenClipboardWindow();//这才是真正的当前取得剪贴板使用权的进程
    


    (6)根据前面的分析,进程打开剪贴板使用完毕以后,一定要调用CloseClipboard交出使用权,否则其他进程将无法取得剪贴板使用权

     

    五.读剪贴板

    (1)读剪贴板之前,首先还是打开剪贴板,读完以后关闭剪贴板

    (2)假如想读取特定格式的数据,则可先用IsClipboardFormatAvailable来判断该格式是否存在。

    (3)读文本CF_TEXT

    <pre name="code" class="cpp">void*tempData=NULL;
        if(this->myClip->readData(CBType_Text,&tempData))
        {
           char* test=(char*)tempData;
           CStringinfo="Read Success , the content is:\r\n";
           info+=test;
           MessageBox(info,MB_OK);
        }
        else
        {
           MessageBox("Read Failed",MB_OK);
        }
    


     
    

    (1)读图片CF_BITMAP

    这里复制时不是复制图片文件,而是类似于在浏览器里右击复制图片

    这里我复制了百度首页的logo。原理跟读取CF_TEXT一样,先读出一个HBITMAP句柄,再保存成图片即可

       

    (2)读文件CF_HDROP

    【a】本质上是得到文件路径

    【b】打开剪贴板前需

    UINTuDropEffect=RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);

    注意,Windows系统在ShlObj.h文件中

    <pre name="code" class="cpp">#define CFSTR_PREFERREDDROPEFFECT           TEXT("Preferred DropEffect")
    


     
    

    【c】通过DragQueryFile函数可遍历剪贴板中文件,先传入0得到一个UNIT指,而后将该值迭代传参即可

     

    (3)枚举剪切板中所有格式

    存在两个枚举格式相关函数。分别是

    <pre name="code" class="cpp">CountClipboardFormats()   //此函数是获取格式总数
    EnumClipboardFormats()    //首次传0,以后用返回值迭代,即可遍历
    


     
    

    六.写剪贴板

    都比较简单,详见ClipBoardDemo工程

    1.写文本CF_TEXT

    2.写图片CF_BITMAP

    3.写文件CF_HDROP

    (1)对于拷贝,标志位是DROPEFFECT_COPY

    (2)对于剪切,标志位是DROPEFFECT_MOVE

    4.写多种格式

    原理一样,只要写数据的时候不清空,多种格式写完以后再关闭剪贴板即可。

     

    七.API汇总

    (1)MFC提供了两组本质是一样的API,一组属于全局函数,一组属于窗口的成员函数(全局函数中需传窗口句柄的函数都被MFC封装了一层)。

    (2)我们在窗口button里调用this-> OpenClipboard(),然后debug F11进入观察一下

    <pre name="code" class="cpp">_AFXWIN_INLINE BOOLCWnd::OpenClipboard()
        {ASSERT(::IsWindow(m_hWnd)); return::OpenClipboard(m_hWnd); }
    


     
    

    所以窗口成员剪贴板函数实质上调用的仍是全局函数,不过在内部多传了个句柄

    (3)所以我们自己封装时,也可借此思路,内部多传个句柄封装。

    ID

    函数

    功能

    1

    SetClipboardViewer

    监听剪贴板

    2

    ChangeClipboardChain

    取消监听剪贴板

    3

    OnChangeCbChain

    剪贴板监听对象变化事件

    4

    OnDrawClipboard

    剪贴板内容变化事件

    5

    AddClipboardFormatListener

    添加某种格式的监听

    6

    RemoveClipboardFormatListener

    去除某种格式的监听

    7

    GetClipboardSequenceNumber

    获取在监听链中的顺序

    8

    EnumClipboardFormats

    枚举格式

    9

    CountClipboardFormats

    获取格式数量

    10

    GetPriorityClipboardFormat

    获取最符合的格式

    11

    GetClipboardFormatName

    获取非预定义的格式名称

    12

    IsClipboardFormatAvailable

    判断剪贴板中是否含有目标格式

    13

    RegisterClipboardFormat

    注册格式

    14

    GetUpdatedClipboardFormats

    获取当前支持的格式

    15

    OpenClickborder

    打开剪贴板,取得使用权

    16

    CloseClipboard

    关闭剪贴板,释放使用权

    17

    GetClipboardViewer

    获取剪贴板监听链的第一个窗口句柄

    18

    GetOpenClipboardWindow

    获取当前正在使用剪贴板的窗口句柄

    19

    GetClipboardOwner

    一般指上次向剪贴板写数据的对象

    20

    EmptyClipboard

    清空剪贴板

    21

    SetClipboardData

    写数据,第二个参数NULL表示延迟写入

    22

    GetClipboardData

    读数据

    八.他山之石

    1.迅雷

    当我们复制文本时,如果剪贴板中包含链接地址,且是迅雷支持的下载格式,则迅雷会弹出下载对话框,这其实就是使用了剪贴板的监听原理

     

    2.QQ

    我们在QQ聊天界面里粘贴时,如果之前复制的是文字,则文字内容复制到了输入框中,如果之前复制的是文件,则文件直接发给对方好友了。其原理就是在粘贴的时候判断当前剪贴板中到底是什么内容,然后做出不同的处理

    九.通过剪贴板实现进程间通信

    (1)需求设计

    好,原理说了这么多,现在来实现我们在“Windows进程间通信之目录”中所说的需求,我们下面简化需求,形成下面的模型:

    【a】  一个主进程启动两个子进程

    【b】  主进程可随时发送不同的命令给不同的子进程

    【c】  子进程收到命令以后去做相应的操作,完成后发送响应给主进程

    【d】  主进程收到子进程的响应后,再做相应处理

    使用剪贴板的思维来实现上述需求:

    【a】  三个进程都监听剪贴板

    【b】  设计协议格式,使得进程读取剪贴板中数据即可区分相关参数

    我们简化,在剪贴板中放置纯文本数据来传输数据,协议格式如下:

    (2)实现

    贴上主进程关键代码,其他详见工程

    voidCMainProcessDlg::analysisClipboard()
    {
        CBProtocolStructtempData;
        m_protocol->getProtocolData(tempData);
     
        if(tempData.receiver=='M')
        {
           if(tempData.sender='A')
           {
               if(tempData.command=='0')
               {
                  CStringinfo="A Sub Process send Work response to MainProcess\r\nthe Data is ";
                  info+=tempData.data;
                  MessageBox(info,"Info",MB_OK);
               }
               else
               {
                  if(tempData.command=='1')
                  {
                      CStringinfo="A Sub Process send Close response toMain Process\r\nthe Data is ";
                      info+=tempData.data;
                      MessageBox(info,"Info",MB_OK);
                  }
               }
           }
           else
           {
               if(tempData.sender='B')
               {
                  if(tempData.command=='0')
                  {
                      CStringinfo="B Sub Process send Work response to MainProcess\r\nthe Data is ";
                      info+=tempData.data;
                      MessageBox(info,"Info",MB_OK);
                  }
                  else
                  {
                      if(tempData.command=='1')
                      {
                         CStringinfo="B Sub Process send Close response toMain Process\r\nthe Data is ";
                         info+=tempData.data;
                         MessageBox(info,"Info",MB_OK);
                      }
                  }
               }
           }
        }
    }
    voidCMainProcessDlg::OnDrawClipboard()
    {
        CDialog::OnDrawClipboard();
     
        if(NULL!=this->nextWindow)
        {
           ::SendMessage(nextWindow,WM_DRAWCLIPBOARD, 0, 0);
        }
        analysisClipboard();
    }
    

    另外贴上子进程A的关键函数

     

    void CASubProcessDlg::analysisClipboard()
    {
    	CBProtocolStruct tempData;
    	m_protocol->getProtocolData(tempData);
    
    	if(tempData.receiver=='A')
    	{
    		if(tempData.sender='M')
    		{
    			if(tempData.command=='0')
    			{	
    				CBProtocolStruct responseData;
    				responseData.sender='A';
    				responseData.receiver='M';
    				responseData.command='0';
    				m_protocol->setProtocolData(responseData);
    				MessageBox("A receive Work command","Info",MB_OK);
    			}
    			else
    			{
    				if(tempData.command=='1')
    				{
    					CBProtocolStruct responseData;
    					responseData.sender='A';
    					responseData.receiver='M';
    					responseData.command='1';
    					responseData.data='Z';
    					m_protocol->setProtocolData(responseData);
    					MessageBox("A receive Close command","Info",MB_OK);
    
    					SendMessage(WM_CLOSE,0,0);
    				}
    			}
    		}
    	}
    }
    void CASubProcessDlg::OnDrawClipboard()
    {
    	CDialog::OnDrawClipboard();
    
    	if(NULL!=this->nextWindow)
    	{
    		::SendMessage(nextWindow, WM_DRAWCLIPBOARD, 0, 0);
    	}
    	analysisClipboard();
    
    }
    

    (1)  时序

    我们以主进程向A发送MA00为例,来解析整个命令时序

    【a】  第2步中A感知变化后第3步是B感知变化,而不是A处理变化的是因为,在OnDrawClipboard中是先SendMessage,然后再处理的。

    void CASubProcessDlg::OnDrawClipboard()
    {
        CDialog::OnDrawClipboard();
     
        if(NULL!=this->nextWindow)
        {
           ::SendMessage(nextWindow,WM_DRAWCLIPBOARD, 0, 0);
        }
        analysisClipboard();
    }

    【b】剪贴板内容变化后,感知顺序都是先A再B再M,是因为,我们启动程序的顺序就是A、B和M(参见本文第二部分监听剪贴板内容消息链顺序一节)

     

    十.总结

    优点:

    (1)  原理简单,上手很快

    (2)  支持不同的数据格式

     

    缺点:

    (1)后台虽有两个子进程,但由于剪贴板权限只有一个,无法实现两个子进程同时操作;

    (2)剪贴板更适合传输数据,虽提供剪贴板监听机制达到传输命令和时序的目的,但需自己额外设计数据格式,比较繁琐,不像Windows多线程拥有众多基础设施。所以适合主子进程间命令交互不频繁、数据交互较多的应用。


    Danny

    2014年8月1号

    于天津河西


    展开全文
  • JavaScript操作剪贴板

    千次阅读 2013-11-06 23:31:43
    IE是第一个支持与剪贴板相关的事件,以及通过JavaScript访问剪贴板数据的浏览器。IE的实现成为了某种标准,不仅Safari 2、Chrome和Firefox 3也都支持类似的事件和剪贴板(Oprea不支持通过JavaScript访问剪贴板),就...

    IE是第一个支持与剪贴板相关的事件,以及通过JavaScript访问剪贴板数据的浏览器。IE的实现成为了某种标准,不仅Safari 2、Chrome和Firefox 3也都支持类似的事件和剪贴板(Oprea不支持通过JavaScript访问剪贴板),就连后来的HTML 5也引入了剪贴板事件。下列就是6个剪贴板事件:

    • beforecopy:在发生复制操作前触发;
    • copy:在发生复制操作时触发
    • cut:在发生剪切操作时触发
    • beforeecut:在发生剪切操作前触发,
    • paste:在发生粘贴操作时触发

    由于没有针对剪贴板操作的标准,这些事件及相关对象会因为浏览器而已。在Safari、Chrome和Firefox中,beforecopy、beforecut和beforepaste事件只会在针对文本框的上下文菜单的情况下触发。但是IE则会在触发copy、cut和paste事件之前先行触发这些事件。至于copy、cut和paste事件,只要在上下文菜单中选择了相应的选项,或者使用了相应的键盘组合键,所有浏览器都会触发它们。

    在实际的事件发生之前,通过beforecpy、beforecut和beforepaste事件可以在向剪贴板发送数据,或者从剪贴板取得数据之前修改数据。不过,取消这些事件并不会取消对剪切板的操作——只有取消copy、cut和paste事件,才能阻止相应操作发生。

    要访问剪贴板中的数据,可以使用clipboardDate对象:在IE中,这个对象是window对象的属性;而在Safari和Chrome中,这个对象是相应event对象的属性。但是,Firefox不支持clipboardDate对象。而且,在Safari和Chrom中,只有在处理剪贴板事件期间clipboardDate对象才有效,这是为了防止对剪贴板的未授权访问;在IE中,则可以随时访问clopboardDate对象。为了确保跨浏览器兼容性,最好只发生剪贴板事件期间使用这个对象。

    这个clipboardDate对象有3个方法:getDate()、setDate()和clearDate()。其中,getDate()用于从剪贴板中取得数据,它接受一个参数,即要取得的数据的格式。在IE中,有两种数据格式:“text”和“URL”。在Safari和Chrome中,这个参数是一种MIME类型;不过,可以使用“text”代表“text/plain”。

    类似地,setDate()方法的第一个参数也是数据类型,第二个参数是要放在剪贴板中的文本。对于第一个参数,IE照样支持“text”和“URL”,而Safari和Chrome仍然只支持MIME类型。但是,与getDate()方法不同的是,Sarai和Chrome的setData()方法不能识别“text”类型。这两个浏览器在成功将文本放到剪贴板中后,都会返回true;否则,返回false。为了弥合这些差异,我们可以向EventUtil中添加下列方法:

    var EventUtil = {
        addHandler: function (element, type, handler) {
            if (element.addEventListener) {
                element.addEventListener(type, handler, false);
            } else if (element.attachEvent) {
                element.attachEvent("on" + type, handler);
            } else {
                element["on" + type] = handler;
            }
        },
        getEvent: function (event) {
            return event ? event : window.event;
        },
        getClipboardText: function (event) {
            var clipboardData = (event.clipboardData || window.clipboardData);
            return clipboardData.getData("text");
        },
        setClipboardText: function (event, value) {
            if (event.clipboardData) {
                return event.clipboardData.setData("text/plain", value);
            } else if (window.clipboardData) {
                return window.clipboardData.setData("text", value);
            }
        },
        preventDefault: function (event) {
            if (event.preventDefault) {
                event.preventDefault();
            } else {
                event.returnValue = false;
            }
        }
    };

    这里的getClipboardText()方法相对简单;它只要确定clipboardData对象的位置,然后再以“text”类型调用getDate()方法即可。相应地,setClipboardText()方法则要稍微复杂一些。在取得clipboardDate对象之后,需要根据不同的浏览器实现为setDate()传入不同的类型(对于Safari和Chrome,是“text/plain”;对于IE是”text”)。

    在需要确保粘贴到文本框中的文本中包含某些字符,或者符合某种格式要求时,能够访问剪贴板是非常有用的。例如,如果有一个文本框值接受数值,那么就必须检测粘贴过来的值,以确保有效。在paste事件中,可以确定剪贴板中的值是否有效,如果无效,就可以像下面示例中那样,取消默认的行为。

    var textbox = document.forms[0].elements["textbox1"]
    EventUtil.addHandler(textbox, "paste", function (event) {
        event = EventUtil.getEvent(event);
        var text = EventUtil.getClipboardText(event);
    
        if (!/^\d*$/.test(text)) {
            EventUtil.preventDefault(event);
        }
    });

    在这里,onpaste事件处理程序可以确保只有数值才会被粘贴到文本框中,如果剪贴板的值与正则表达式不匹配,则会取消粘贴操作。Safari和Chrome值允许在onpaste事件处理程序中访问getDate()方法。
    同样,也可以将数据设置到剪贴板中,这样就可以覆盖基于元素的默认剪切或复制功能。来看下面的例子:

    var textbox = document.forms[0].elements["textbox1"]
    EventUtil.addHandler(textbox, "copy", function (event) {
        event = EventUtil.getEvent(event);
        EventUtil.preventDefault(event);
        EventUtil.setClipboardText(event, "Hello world!");
    });

    在这个例子中,我们覆盖了文本框的copy事件,将字符串“Hello world!”放到了剪贴板中。结果,就不会将文本框中的文本赋值到剪贴板中了。

    由于并非所有浏览器都支持访问剪贴板,所以更简单的做法是屏蔽一或多个剪贴板操作。在支持copy、cut和paste事件的浏览器中(IE、Safari、Chrome和Firefox3及更高版本),很容易阻止这些事件的默认性。在Opera中,则需要阻止那些会触发这些事件的按键操作,同时还要阻止在文本框中显示上下文菜单。

    展开全文
  • 剪贴板云同步网页Windows 10’s October 2018 Updatehas a new Clipboard experience. You can now access a history of items you’ve copied to your clipboard, pin frequently used items, and sync your ...
  • windows 剪贴板监控

    万次阅读 2009-04-19 18:53:00
    迅雷下载或者旋风下载都有一个很有意思的剪贴板监控功能,当你打开剪贴板监控时,如果你复制了一个下载的URL,这两个程序都会弹出来下载框来让你去下载,显得很智能,昨天发现灵格斯词霸也有个剪贴板取词功能。...
  • js复制文本到剪贴板Windows 10 makes copy and paste more convenient with a feature called Clipboard history. It allows you to pin items you frequently copy and paste to a list for quick access. Here’s ...
  • 操作剪贴板相关的事件

    千次阅读 2014-03-08 00:36:51
    E是第一个支持与剪贴板相关的事件,以及通过JavaScript访问剪贴板数据的浏览器。IE的实现成为了某种标准,不仅Safari 2、Chrome和Firefox 3也都支持类似的事件和剪贴板(Oprea不支持通过JavaScript访问剪贴板),就...
  • // 取消选中   window.addEventListener('copy', function(clipBoardEvent) { var text = window.getSelection().toString(); console.log(clipBoardEvent); clipBoardEvent.clipboardData.setData...
  • 有没有办法在VI编辑器中将所有行从打开文件复制到剪贴板。 我试图ÿg,但它不使用剪贴板来存储这些行。 那有可能吗?
  • 管理远程 Windows 剪贴板

    千次阅读 2008-07-30 17:29:00
    (转) 安装远程组件 .NET 剪贴板 API 构建远程剪贴板处理程序 远程剪贴板客户端 小结 当 DCOM 在若干年前登上历史舞台时,用于演示其功能的最常用示例之一就是远程剪贴板管理器。通过使用 DCOM 编程模型,一个...
  • IE是第一个支持与剪贴板相关的事件,以及通过JavaScript访问剪贴板数据的浏览器。IE的实现成为了某种标准,不仅Safari 2、Chrome和Firefox 3也都支持类似的事件和剪贴板(Oprea不支持通过JavaScript访问剪贴板),就...
  • Z]:撤消上一个选择[Ctrl + Shift + Z]:取消突出显示整个页面[Ctrl + /]:启用/禁用页面[Ctrl +左/右箭头]:更改突出显示颜色按住Ctrl并单击一个句子将突出显示该句子并将其放置在剪贴板中。 选择文本并将其复制也...
  •  打开和关闭Office剪贴板方法 首先,我们可以单击Word的“开始”功能区“剪贴板”旁边的小按钮来启动“Office剪贴板”;如图 单击一次便是启动,再次单击此按钮便是关闭剪贴板。 清空或删除Office剪贴板内容 若...
  • 如何在Vim中复制到剪贴板

    千次阅读 2019-12-26 13:48:42
    是否可以直接从Vim复制到剪贴板? yy只复制东西给Vim的内部缓冲区。 我想复制到操作系统的剪贴板。 在Vim中有没有这样的命令,或者你只能在Vim中猛拉东西?
  • javascript 复制到剪贴板

    千次阅读 2019-01-28 22:21:35
    取消所有的选择只 留下anchorNode 和focusNode属性并将其设置为null */ //先看下面的 if else 代码 function otherEle(element) { if (document.selection) {//如果已经选中内容 var range = document.body....
  • 使用计算机的日常中,我们经常会使用两个组合键 --> Ctrl + C、Ctrl + V,这两个键...剪贴板通信思路: 在服务端窗口中,我们将数据放进剪贴板中 在客户端窗口中,我们取出剪贴板中的数据 案例效果演示: ...
  • Win10 Cloud Clipboard功能允许您拥有多个复制文本的列表,以便您可以重复使用它。 也就是说,我们知道每次...在Win10中打开/关闭和清除剪贴板历史记录早些时候,没有功能可以关闭剪贴板的历史记录。 您必须使用其...
  • JS实现将图片复制到剪贴板

    千次阅读 2018-06-13 00:52:09
    前言 最近项目新增需求:用户能够拖拽页面上的图片...在现有的拖拽事件所提供api无法满足需求的情况下,换一个思路走:尝试将图片复制到剪贴板。 对于原生js的复制操作,已有封装好的库clipboard.js,但是封装得太...
  • C#中利用剪贴板进行进程间通信

    千次阅读 2011-07-11 19:48:53
    这篇文章中主要讲了大致实现过程,详细原理可以参照我的下一篇博客。一,这里首先介绍C#中的剪贴板操作:Clipboard....,//将字符串存入剪贴板,//将信息存入剪贴板后,再在其他地方使用IDataObject iData = Clipb
  • Clipper Plus是一个功能强大的Android剪贴板增强工具,它能有效地增强安卓系统中剪贴、复制等功能的应用。同时,它还可以让你保存剪贴内容并共享,再也不用担心丢失您剪贴板上的内容,能给我们提供很大的方便,可以...
  • 在IE中,JS可以直接访问剪贴板,但是firefox,chrome等其它"高级"浏览器,就没这么幸运了。网上流传的所谓兼容firefox/IE的剪贴板访问javascript代码,都是N年前的往事了。 根据...
  • 原因:用户开启了监视剪贴板功能的软件,这些软件比如:迅雷,flashget,灵格斯翻译家等。(有时候灵格斯又不会出错解决办法:关闭监视剪贴板功能,或者退出这类软件 
  • VB6监视/操作剪贴板示例(VB6.0代码)

    千次阅读 2012-01-11 09:01:17
    剪贴板的监视,需要先使用SetClipboardViewer设置某个句柄为剪贴板查看器的一员.然后当剪贴板发生改变时,系统就会向这个句柄发送WM_DRAWCLIPBOARD消息.只要使用子类化拦截到这个消息即可. 界面:   ...
  • 1,把有道词典更新到最新版本就能解决。是旧版本的划词功能导致的,更新软件就好了。    2,补充:也有可能是金山词霸等翻译软件的“划词翻译”功能。再补充:也有可能是迅雷的“监视剪贴板”选项。
  • 此“功能”称为通用剪贴板或“切换”。 并且默认情况下在每台Mac上启用该功能。 For your privacy, I recommend you turn this feature off immediately. It only takes a few seconds. Here's how to do this. ...
  • Windows剪贴板增强小工具---ditto

    千次阅读 2015-05-22 09:19:20
    和大多数免费剪贴板软件一样,Ditto也缺乏“顺序粘贴” 或 “强力粘贴”功能。有需求者,可参照 Hamsin Clipboard 顺序粘贴功能  进行试用。支持此功能的免费软件,目前只发现 Hamsin Clipboard 一款。” 四...
  • 2018年12月18日,发明复制粘贴这一伟大功能的女工程师Evelyn Berezin于数月前被确诊患上淋巴癌,由于选择放弃治疗,于本月初离世,享年93岁。 在此表示隆重哀悼。本人作为一个重度电脑工作者,不敢想像如果没有复制...
  • Windows 10使用称为剪贴板历史记录的功能将复制和粘贴到另一个级别,该功能使您可以查看最近复制到剪贴板的项目的列表。 只需按Windows + V。 这是打开和查看剪贴板历史记录的方法。 剪贴板历史记录中存储了什么? ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,801
精华内容 7,120
关键字:

如何取消剪贴板功能