如何與資源管理器互動剪切、拷貝、粘貼文件_第1頁
如何與資源管理器互動剪切、拷貝、粘貼文件_第2頁
如何與資源管理器互動剪切、拷貝、粘貼文件_第3頁
如何與資源管理器互動剪切、拷貝、粘貼文件_第4頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、如何與資源管理器互動剪切/拷貝/粘貼文件 作者:blueelf 下載源代碼 一.本文將向讀者介紹下面兩個問題的解決方案: 1,用戶在資源管理器(Windows Explorer)中剪切/拷貝(Cut/Copy)文件,然后在自己的應(yīng)用程序中進行粘貼(Paste)操作; 2.用戶在自己的應(yīng)用程序中剪切/拷貝文件,在資源管理其中粘貼操作。 二.本文中的代碼編寫工具及測試環(huán)境: 1,VC6.0, Platform SDK(無須MFC); 2.Windows 2000。 三.概述 我們知道,在Windows中可以通過剪貼板(Clipboard)來共享和傳遞數(shù)據(jù),比如在資源管理器(Windows Expl

2、orer)中可以剪切/拷貝/粘貼文件。同樣我們也可以在自己的應(yīng)用程序中通過剪貼板來完成這些工作,從而提高我們自己的應(yīng)用程序與Windows操作系統(tǒng)之間的互操作性。但我們?nèi)绾尾拍芘c資源管理器之類的應(yīng)用程序共享和傳遞數(shù)據(jù)呢?本文提供的方法是:使用Windows本身提供的一些數(shù)據(jù)結(jié)構(gòu)和API,通過剪貼板來實現(xiàn)數(shù)據(jù)共享和傳遞。 四.實現(xiàn)方法 首先,Windows在剪切/拷貝文件時并不是把文件名稱寫入剪貼板,而是在剪貼板中放入了一個DragAndDrop文件對象,并寫入了一個狀態(tài)值來標(biāo)識操作類型(移動/拷貝,剪切其實就是移動,如果你剪切之后并沒有粘貼,那么該文件依然存在而不會被刪除)。依據(jù)這個知識,我們

3、首先來看看在應(yīng)用程序中如何識別出Windows 資源管理器的剪切/拷貝動作。 在使用剪貼板前,我們首先要打開它:BOOL OpenClipboard(HWND hWnd); 參數(shù) hWnd 是打開剪貼板的窗口句柄,成功返回TRUE,失敗返回FALSE。 之后,可以用GetClipboardData來得到剪貼板中的數(shù)據(jù): HANDLE GetClipboardData(UINT uFormat); uFormat是所需要數(shù)據(jù)的格式,例如本文拖放對象的格式為CF_HDROP。而表明該拖放對象類型(Move/Copy)的數(shù)據(jù)格式并不是Windows標(biāo)準(zhǔn)的剪貼板數(shù)據(jù)結(jié)構(gòu),而是一個簡單的DWORD指針。

4、我們可以通過下面的語句來注冊一下數(shù)據(jù)類型 : UINT uDropEffect=RegisterClipboardFormat("Preferred DropEffect"); 這里返回的uDropEffect就是我們將要代入GetClipboardData函數(shù)的該數(shù)據(jù)結(jié)構(gòu)的代碼, GetClipboardData函數(shù)返回是一個句柄,這只是Windows為了統(tǒng)一性而做的工作,我們可以根據(jù)需要來轉(zhuǎn)換成相應(yīng)的數(shù)據(jù)形式,比如我們的uDropEffect就 是一個DWORD指針。 前面我已經(jīng)說過在剪貼板中放的是一個拖放對象,因此我們可以通過如下語句得到該對象: HDROP hDro

5、p = HDROP( GetClipboardData( CF_HDROP); 如果確實存在一個hDrop對象,我們應(yīng)該取得uDropEffect的數(shù)據(jù),以便我們處理后面的文件: DWORD dwEffect=*(DWORD*)(GetClipboardData( uDropEffcet); 關(guān)于這個值的含義,我們只要包含一下"OLEIDL.H"頭文件即可, 在該頭文件中5種狀態(tài)的定義而本文只關(guān)注: #define DROPEFFECT_COPY ( 1 ) #define DROPEFFECT_MOVE ( 2 ) 因此,我們可以通過 if(dwEffect &

6、DROPEFFECT_COPY) CopyFile(.); else (dwEffect & DROPEFFECT_MOVE) MoveFile(.); 來完成剪切/拷貝操作。 在我們?nèi)〉胾DropEffect狀態(tài)之后,我們需要得到文件列表,得到拖放對象中的文件列表可以通過DragQueryFile來實現(xiàn): UINT DragQueryFile(HDROP hDrop, UINT iFile,LPTSTR lpszFile,UINT cch); 第二個參數(shù)是文件序列號,可以通過將iFile置為-1的方法來得到文件數(shù)量。 最后我們給出完整的例子: #include <Shellap

7、i.h> #include <oleidl.h> . UINT uDropEffect=RegisterClipboardFormat("Preferred DropEffect"); if( OpenClipboard( hWnd) HDROP hDrop = HDROP( GetClipboardData( CF_HDROP); if( hDrop) DWORD dwEffect,*dw; dw=(DWORD*)(GetClipboardData( uDropEffect); if(dw=NULL) dwEffect=DROPEFFECT_COPY;

8、else dwEffect=*dw; char Buf4096; Buf0 = 0; UINT cFiles = DragQueryFile( hDrop, (UINT) -1, NULL, 0); POINT Point; char szFile MAX_PATH; for( UINT count = 0; count < cFiles; count+ ) DragQueryFile( hDrop, count, szFile, sizeof( szFile); lstrcat(Buf,szFile); lstrcat(Buf,"n"); if(dwEffect &

9、amp; DROPEFFECT_MOVE) MessageBox(NULL,Buf,"Move Files",MB_OK); else if(dwEffect & DROPEFFECT_COPY) MessageBox(NULL,Buf,"Copy Files",MB_OK); CloseClipboard(); 在這個例子中,我并沒有進行文件操作,只是簡單的顯示一個消息框,實際應(yīng)用時,需要使用MoveFile和CopyFile函數(shù)來完成,本文不做討論。 知道如何識別其他程序的剪切/拷貝 文件的動作后,我們對該操作的數(shù)據(jù)結(jié)構(gòu)已經(jīng)很了解了,要想讓其

10、他程序能識別我們的剪切/拷貝 文件動作其實就是將以上數(shù)據(jù)結(jié)構(gòu)放入剪貼板的過程。 在我們這個例子中,往剪貼板中放的數(shù)據(jù)必須是內(nèi)存對象:HGLOBAL。這個對象可以通過GlobalAlloc來生成。然后使用GlobalLock就可以得到該對象的內(nèi)存地址,繼而往里面寫 數(shù)據(jù)。實際上在Win32中由于進程擁有獨立的內(nèi)存空間,因而常規(guī)的內(nèi)存分配已經(jīng)不需要GlobalLock了,看看MSDN就知道該函數(shù)主要就是為DDE和剪貼板服務(wù)的。 根據(jù)前面的知識,要想讓其他程序識別出我們的剪切/拷貝動作我們必須往剪貼板中放兩項數(shù)據(jù),現(xiàn)在就讓我們來為DropEffect準(zhǔn)備數(shù)據(jù)吧,同樣我們需要先注冊該數(shù)據(jù)格式: uDr

11、opEffect=RegisterClipboardFormat("Preferred DropEffect"); 然后分配內(nèi)存對象并得到指針: hGblEffect=GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE,sizeof(DWORD); dwDropEffect=(DWORD*)GlobalLock(hGblEffect); 注意往剪貼板中放的數(shù)據(jù)必須使用GMEM_MOVEABLE標(biāo)志,最后我們設(shè)置數(shù) 據(jù)并解除鎖定: if(COPY) *dwDropEffect=DROPEFFECT_COPY; else

12、*dwDropEffect=DROPEFFECT_MOVE; GlobalUnlock(hGblEffect); 這樣我就為DropEffect準(zhǔn)備還數(shù)據(jù)了,等一會兒我們連同文件拖放對象一起放入剪貼板。建立文件拖放對象的方法與DropEffect基本相同,只是文件拖放對象有特殊的數(shù)據(jù)結(jié)構(gòu) 而不象DropEffect那樣簡單,該對象數(shù)據(jù)結(jié)構(gòu)如下: +-+ | DROPFILES | Files List | +-+ DROPFILES是拖放對象的頭數(shù)據(jù),該結(jié)構(gòu)在shlobj.h中定義: typedef struct _DROPFILES DWORD pFiles; POINT pt; BOOL

13、fNC; BOOL fWide; DROPFILES, FAR * LPDROPFILES; pFiles指針是以對象首地址為參照的文件列表(上圖中的Files List項)的offset量。通常該值等于DROPFILES結(jié)構(gòu)的長度(我還沒見過例外);pt表明文件拖放的位置坐標(biāo),在這個例子里我們忽略為0; fNC表明pt值是否為客戶區(qū)坐標(biāo)(FALSE表明是屏幕坐標(biāo));fWide表明Files List是否包含unicode,作為中國人,我們當(dāng)然要設(shè)其為TRUE。DROPFILES結(jié)構(gòu)之后緊跟Files List,F(xiàn)iles List是一組寬字符串,之間以0相隔,比如:"文件10文件2

14、0." 我們可以通過MultiByteToWideChar函數(shù)將常規(guī)的字符串轉(zhuǎn)換成寬字符串。下面就是生成拖放對象的代碼: uDropFilesLen=sizeof(DROPFILES); dropFiles.pFiles =uDropFilesLen; dropFiles.pt.x=0; dropFiles.pt.y=0; dropFiles.fNC =FALSE; dropFiles.fWide =TRUE; uGblLen=uDropFilesLen+uBufLen<<1+8; /uBufLen是文件名字符傳組的長度,由于要轉(zhuǎn)換成寬字符,因此長度要乘2 hGblFil

15、es= GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE, uGblLen); szData=(char*)GlobalLock(hGblFiles); memcpy(szData,(LPVOID)(&dropFiles),uDropFilesLen); /將DROPFILES copy到頭部 szFileList=szData+uDropFilesLen; /得到存放文件列表的首地址 MultiByteToWideChar(CP_ACP,MB_COMPOSITE, lpBuffer,uBufLen,(WCHAR *)szFil

16、eList,uBufLen); GlobalUnlock(hGblFiles); 現(xiàn)在我們就可以將上面兩組數(shù)據(jù)放入剪貼板中了,注意在寫數(shù)據(jù)前應(yīng)先清空剪貼板。為了方便大家使用,下面我給出實現(xiàn)此功能的獨立的函數(shù): VOID CutOrCopyFiles(char * lpBuffer,UINT uBufLen,BOOL bCopy) lpBuffer是包括所有準(zhǔn)備剪切/拷貝的文件名稱的緩沖區(qū);uBufLen是lpBuffer的長度;bCopy決定該操作是Copy還是Cut,TRUE為Copy,FALSE為Cut。例如我們可以這樣調(diào)用該函數(shù): char szFiles="c:1.txt0c

17、:2.txt0" CutOrCopyFiles(szFiles,sizeof(szFiles),FALSE); 來剪切文件,或者使用: CutOrCopyFiles(szFiles,sizeof(szFiles),TRUE); 來拷貝文件。 #include <Shellapi.h> #include <Shlobj.h> #include <oleidl.h> . VOID CutOrCopyFiles(char *lpBuffer,UINT uBufLen,BOOL bCopy) UINT uDropEffect; DROPFILES drop

18、Files; UINT uGblLen,uDropFilesLen; HGLOBA L hGblFiles,hGblEffect; char *szData,*szFileList; DWORD *dwDropEffect; uDropEffect=RegisterClipboardFormat("Preferred DropEffect"); hGblEffect=GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE,sizeof(DWORD); dwDropEffect=(DWORD*)GlobalLock(hGbl

19、Effect); if(bCopy) *dwDropEffect=DROPEFFECT_COPY; else *dwDropEffect=DROPEFFECT_MOVE; GlobalUnlock(hGblEffect); uDropFilesLen=sizeof(DROPFILES); dropFiles.pFiles =uDropFilesLen; dropFiles.pt.x=0; dropFiles.pt.y=0; dropFiles.fNC =FALSE; dropFiles.fWide =TRUE; uGblLen=uDropFilesLen+uBufLen*2+8; hGblFiles= GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE, uGblLen); szData=(char*)GlobalLock(hGblFiles); memcpy(szData,(LPVOID)(&dropFiles),uDro

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論