如何复制文件到剪贴板

来源:互联网 发布:淘宝一个差评都没有 编辑:程序博客网 时间:2024/06/08 16:41

闲话少说,直接上代码。


BOOL CopyFilesToClipboard( std::vector<CString> const & vecFiles ){    RETURN_IF_FALSE_EX( FALSE, vecFiles.size() );    UINT  uDropEffect     = RegisterClipboardFormat(_T("Preferred DropEffect"));    HGLOBAL hGblEffect    = GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE, sizeof(DWORD));    DWORD *pDWDropEffect  = (DWORD*)GlobalLock(hGblEffect);    *pDWDropEffect        = DROPEFFECT_COPY;    GlobalUnlock(hGblEffect);    DROPFILES dropFiles;    dropFiles.pFiles = sizeof(DROPFILES);    dropFiles.pt.x   = 0;    dropFiles.pt.y   = 0;    dropFiles.fNC    = FALSE;    dropFiles.fWide  = TRUE;    UINT uFileListLen = 0;    for (std::vector<CString>::const_iterator it = vecFiles.begin(); it != vecFiles.end(); ++it)    {        uFileListLen += (it->GetLength() + 1);//尾部一个\0结束符    }    UINT uGblLen      = sizeof(DROPFILES) + sizeof(TCHAR)* (uFileListLen + 1);    HGLOBAL hGblFiles = GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE, uGblLen);    BYTE *  pData     = (BYTE*)GlobalLock(hGblFiles);    memcpy(pData, (LPVOID)(&dropFiles), sizeof(DROPFILES));        BYTE *pFileList = pData + sizeof(DROPFILES);    for (std::vector<CString>::const_iterator it = vecFiles.begin(); it != vecFiles.end(); ++it)    {        UINT uLen = (it->GetLength() + 1) * sizeof(TCHAR);        memcpy(pFileList, (BYTE*)(LPCTSTR)(*it),  uLen);        pFileList += uLen;    }    GlobalUnlock(hGblFiles);    if( OpenClipboard(NULL) )    {        EmptyClipboard();        SetClipboardData( CF_HDROP, hGblFiles );        SetClipboardData(uDropEffect,hGblEffect);        CloseClipboard();        return TRUE;    }    else    {        ::GlobalFree(hGblEffect);        ::GlobalFree(hGblFiles);    }    return FALSE;}

关键点解释

1.复制、剪切文件到剪贴板的操作是类似的。

由两个地方控制:一个是CF_HDROP格式的数据,一个是"Preferred DropEffect"格式的数据。

Preferred DropEffect数据控制了是复制还是剪切。CF_HDROP控制了文件列表。

2.对CF_HDROP格式的解释

这个数据的格式在内存中是这样的:

前面是   DROPFILES数据,后面是文件列表;

DROPFILES格式如下:


typedef struct _DROPFILES {    DWORD pFiles;//固定的,就不说了    POINT pt;//拖放点的坐标,它的解释依赖于fNC。我不需要这个值,设为0    BOOL fNC;//如果为TRUE,则上面的pt为非客户区的屏幕坐标;如果为FALSE,则为客户区坐标。这个值我也不需要,随便填的。    BOOL fWide;//是否UNICODE,我的代码是UNICODE环境,为TRUE} DROPFILES, *LPDROPFILES;


文件列表它的格式如下:

c:\a.txt \0 c:\b.txt \0 \0

请注意后面有两个\0

很多Windows API都是这么做的,当传递多个字符串的时候,最后的结尾有两个\0


3. “Preferred DropEffect”格式的数据

其实就是一个DWORD,

可以赋值为DROPEFFECT_COPY;

或者DROPEFFECT_MOVE;


其他东西都是很老套的,不说了。有问题QQ联系:3_5_9_3_2_4_1_0


原创粉丝点击