1. 程式人生 > >如何複製檔案到剪貼簿

如何複製檔案到剪貼簿

閒話少說,直接上程式碼。

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