如何从剪贴板中清除指定格式的数据

How to clear specified format data from clipboard?

本文关键字:定格 格式 数据 清除 剪贴板      更新时间:2023-10-16

我将一些数据放入剪贴板,在我从剪贴板复制数据后,我想在不清除整个剪贴板的情况下清除数据。

像这样:

wchar_t* buf=NULL;
if( OpenClipboard(NULL)!=0)
{
HANDLE hData = GetClipboardData( CF_UNICODETEXT );
buf = (wchar_t*)GlobalLock( hData );
GlobalUnlock( hData );
CloseClipboard();
return buf;
} 
//job is done, and now I want to clear only hData!

据我所知,EmptyClipboard()将清空所有内容!

提前感谢!

剪贴板一次只能保存一个IDataObject;这个数据对象可以表示多种数据格式,但它只是一个COM对象。唯一的方法是复制现有的数据对象(减去要删除的格式),并将其设置为剪贴板中原始数据的位置。

我想知道你为什么要这样做。我不是Windows编程方面的专家,但无论如何我都会试着回答这个问题,因为对我来说,这个问题似乎是一个"孤儿",我可能会提供一些见解(希望我没有大错特错)。

据我所知,剪贴板意味着保存一个实体的几个替代表示(以不同的格式)。

只删除一个这样的表示的用例是什么?我想说,有意义的是要么删除所有的表示(通过EmptyClipboard()),要么不删除。

可能你认为剪贴板是为了容纳几个不同类型的实体,这就是为什么你正在寻找一个选择性的删除。这恐怕是一种误解,并没有反映出剪贴板的真正用途。

我需要它,所以我对它进行了编码,"清空然后重新填充减去我想要删除的内容",有时会崩溃,真正的InsideClipboard.exe不会崩溃,所以我一定是出错了

https://github.com/FuPeiJiang/InsideClipboard.ah2
Gui,而不是库/函数
Ahkv2,足够接近C

编辑:CF_BITMAP,CF_ENHMETAFILE,CF_PALETTE是HANDLE,而不是内存地址,(导致崩溃的原因)
我需要一个gui,但也许有人需要C代码,所以:

#include <string.h>
#include <windows.h>
#include <winuser.h>
#pragma comment(lib, "User32.lib")
typedef struct FORMAT_AND_DATA {
    UINT format;
    HGLOBAL data;
} FORMAT_AND_DATA;
void deleteClipboardFormat(UINT format) {
    OpenClipboard(GetClipboardOwner());
    FORMAT_AND_DATA *format_and_data = malloc(sizeof(FORMAT_AND_DATA)*(CountClipboardFormats()));
    size_t i=0;
    UINT clip_format = 0;
    while ((clip_format=EnumClipboardFormats(clip_format))) {
        if (clip_format==format) {
            continue;
        }
        HANDLE src = GetClipboardData(clip_format);
        if (GetLastError()) {
            continue;
        }
        size_t size;
        HGLOBAL copy = src;
        if (src==0) {
            //delayed rendering
        } else {
            switch (clip_format) {
                case CF_BITMAP:
                case CF_ENHMETAFILE:
                case CF_PALETTE:
                    //handle
                    break;
                default:
                    //memory
                    size = GlobalSize(src);
                    copy = GlobalAlloc(0x2, size);
                    void *dst=GlobalLock(copy);
                    memcpy(dst, src, size);
                    GlobalUnlock(copy);
                    break;
            }
        }
        format_and_data[i].format = clip_format;
        format_and_data[i].data = copy;
        ++i;
    }
    EmptyClipboard();
    for (size_t j = 0; j < i; ++j) {
        SetClipboardData(format_and_data[j].format, format_and_data[j].data);
    }
    CloseClipboard();
    free(format_and_data);
}
int main() {
    // I don't know if these numbers change so replace with your numbers
    deleteClipboardFormat(49338); // HTML FORMAT
    deleteClipboardFormat(49562); // text/html
    deleteClipboardFormat(49459); // image/svg+xml
    //-really inefficient, code your own to take an array of formats as input
}