www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 芯聞號(hào) > 充電吧
[導(dǎo)讀]如何與資源管理器互動(dòng)剪切/拷貝/粘貼文件 2016-06-06一.本文將向讀者介紹下面兩個(gè)問題的解決方案:1,用戶在資源管理器(Windows Explorer)中剪切/拷貝(Cut/Copy)文件,

如何與資源管理器互動(dòng)剪切/拷貝/粘貼文件 2016-06-06

一.本文將向讀者介紹下面兩個(gè)問題的解決方案:

1,用戶在資源管理器(Windows Explorer)中剪切/拷貝(Cut/Copy)文件,然后在自己的應(yīng)用程序中進(jìn)行粘貼(Paste)操作;

2.用戶在自己的應(yīng)用程序中剪切/拷貝文件,在資源管理其中粘貼操作。

二.本文中的代碼編寫工具及測(cè)試環(huán)境:

1,VC6.0, Platform SDK(無須MFC);

2.Windows 2000。

三.概述

我們知道,在Windows中可以通過剪貼板(Clipboard)來共享和傳遞數(shù)據(jù),比如在資源管理器(Windows Explorer)中可以剪切/拷貝/粘貼文件。同樣我們也可以在自己的應(yīng)用程序中通過剪貼板來完成這些工作,從而提高我們自己的應(yīng)用程序與Windows操作系統(tǒng)之間的互操作性。但我們?nèi)绾尾拍芘c資源管理器之類的應(yīng)用程序共享和傳遞數(shù)據(jù)呢?本文提供的方法是:使用Windows本身提供的一些數(shù)據(jù)結(jié)構(gòu)和API,通過剪貼板來實(shí)現(xiàn)數(shù)據(jù)共享和傳遞。

四.實(shí)現(xiàn)方法

首先,Windows在剪切/拷貝文件時(shí)并不是把文件名稱寫入剪貼板,而是在剪貼板中放入了一個(gè)DragAndDrop文件對(duì)象,并寫入了一個(gè)狀態(tài)值來標(biāo)識(shí)操作類型(移動(dòng)/拷貝,剪切其實(shí)就是移動(dòng),如果你剪切之后并沒有粘貼,那么該文件依然存在而不會(huì)被刪除)。依據(jù)這個(gè)知識(shí),我們首先來看看在應(yīng)用程序中如何識(shí)別出Windows 資源管理器的剪切/拷貝動(dòng)作。

在使用剪貼板前,我們首先要打開它:

1 2BOOL OpenClipboard(HWND hWnd);參數(shù) hWnd 是打開剪貼板的窗口句柄,成功返回TRUE,失敗返回FALSE。

之后,可以用GetClipboardData來得到剪貼板中的數(shù)據(jù):

1HANDLEGetClipboardData(UINTuFormat);

uFormat是所需要數(shù)據(jù)的格式,例如本文拖放對(duì)象的格式為CF_HDROP。而表明該拖放對(duì)象類型(Move/Copy)的數(shù)據(jù)格式并不是Windows標(biāo)準(zhǔn)的剪貼板數(shù)據(jù)結(jié)構(gòu),而是一個(gè)簡(jiǎn)單的DWORD指針。我們可以通過下面的語句來注冊(cè)一下數(shù)據(jù)類型 :

1UINT uDropEffect=RegisterClipboardFormat("Preferred DropEffect");

這里返回的uDropEffect就是我們將要代入GetClipboardData函數(shù)的該數(shù)據(jù)結(jié)構(gòu)的代碼,GetClipboardData函數(shù)返回是一個(gè)句柄,這只是Windows為了統(tǒng)一性而做的工作,我們可以根據(jù)需要來轉(zhuǎn)換成相應(yīng)的數(shù)據(jù)形式,比如我們的uDropEffect就是一個(gè)DWORD指針。

前面我已經(jīng)說過在剪貼板中放的是一個(gè)拖放對(duì)象,因此我們可以通過如下語句得到該對(duì)象:

1HDROP hDrop = HDROP( GetClipboardData( CF_HDROP));

如果確實(shí)存在一個(gè)hDrop對(duì)象,我們應(yīng)該取得uDropEffect的數(shù)據(jù),以便我們處理后面的文件:

1DWORD dwEffect=*((DWORD*)(GetClipboardData( uDropEffcet)));

關(guān)于這個(gè)值的含義,我們只要包含一下"OLEIDL.H"頭文件即可,在該頭文件中5種狀態(tài)的定義而本文只關(guān)注:

1 2#define DROPEFFECT_COPY ( 1 )#define DROPEFFECT_MOVE ( 2 )

因此,我們可以通過

1 2 3 4if(dwEffect & DROPEFFECT_COPY)??CopyFile(....);else (dwEffect & DROPEFFECT_MOVE)??MoveFile(...);

來完成剪切/拷貝操作。

在我們?nèi)〉胾DropEffect狀態(tài)之后,我們需要得到文件列表,得到拖放對(duì)象中的文件列表可以通過DragQueryFile來實(shí)現(xiàn):

1UINT DragQueryFile(HDROP hDrop, UINT iFile,LPTSTRlpszFile,UINTcch);

第二個(gè)參數(shù)是文件序列號(hào),可以通過將iFile置為-1的方法來得到文件數(shù)量。

最后我們給出完整的例子:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37#include < Shellapi.h >#include < oleidl.h >?....???UINTuDropEffect=RegisterClipboardFormat("Preferred DropEffect");?????if( OpenClipboard( hWnd)) {????????HDROPhDrop = HDROP( GetClipboardData( CF_HDROP));????????if( hDrop) {????????????DWORDdwEffect,*dw;????????????dw=(DWORD*)(GetClipboardData( uDropEffect));????????????if(dw==NULL)????????????????dwEffect=DROPEFFECT_COPY;????????????else????????????????dwEffect=*dw;?????????????????????charBuf[4096];????????????Buf[0] = 0;????????????UINTcFiles = DragQueryFile( hDrop, (UINT) -1, NULL, 0);????????????POINT Point;????????????charszFile[ MAX_PATH];????????????for(UINT count = 0; count < cFiles; count++ ) {????????????????DragQueryFile( hDrop, count, szFile,sizeof( szFile));????????????????lstrcat(Buf,szFile);????????????????lstrcat(Buf,"n");????????????}?????????????????if(dwEffect & DROPEFFECT_MOVE) {????????????????MessageBox(NULL,Buf,"Move Files",MB_OK);????????????}else? if(dwEffect & DROPEFFECT_COPY) {????????????????????MessageBox(NULL,Buf,"Copy Files",MB_OK);????????????}?????????????CloseClipboard();????????}????}

在這個(gè)例子中,我并沒有進(jìn)行文件操作,只是簡(jiǎn)單的顯示一個(gè)消息框,實(shí)際應(yīng)用時(shí),需要使用MoveFile和CopyFile函數(shù)來完成,本文不做討論。?

知道如何識(shí)別其他程序的剪切/拷貝 文件的動(dòng)作后,我們對(duì)該操作的數(shù)據(jù)結(jié)構(gòu)已經(jīng)很了解了,要想讓其他程序能識(shí)別我們的剪切/拷貝 文件動(dòng)作其實(shí)就是將以上數(shù)據(jù)結(jié)構(gòu)放入剪貼板的過程。

在我們這個(gè)例子中,往剪貼板中放的數(shù)據(jù)必須是內(nèi)存對(duì)象:HGLOBAL。這個(gè)對(duì)象可以通過GlobalAlloc來生成。然后使用GlobalLock就可以得到該對(duì)象的內(nèi)存地址,繼而往里面寫 數(shù)據(jù)。實(shí)際上在Win32中由于進(jìn)程擁有獨(dú)立的內(nèi)存空間,因而常規(guī)的內(nèi)存分配已經(jīng)不需要GlobalLock了,看看MSDN就知道該函數(shù)主要就是為DDE和剪貼板服務(wù)的。?

根據(jù)前面的知識(shí),要想讓其他程序識(shí)別出我們的剪切/拷貝動(dòng)作我們必須往剪貼板中放兩項(xiàng)數(shù)據(jù),現(xiàn)在就讓我們來為DropEffect準(zhǔn)備數(shù)據(jù)吧,同樣我們需要先注冊(cè)該數(shù)據(jù)格式:

1uDropEffect=RegisterClipboardFormat("Preferred DropEffect");

然后分配內(nèi)存對(duì)象并得到指針:

1 2hGblEffect=GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE,sizeof(DWORD));dwDropEffect=(DWORD*)GlobalLock(hGblEffect);

注意往剪貼板中放的數(shù)據(jù)必須使用GMEM_MOVEABLE標(biāo)志,最后我們?cè)O(shè)置數(shù)據(jù)并解除鎖定:

1 2 3 4 5if(COPY)??*dwDropEffect=DROPEFFECT_COPY;else?*dwDropEffect=DROPEFFECT_MOVE;GlobalUnlock(hGblEffect);

這樣我就為DropEffect準(zhǔn)備還數(shù)據(jù)了,等一會(huì)兒我們連同文件拖放對(duì)象一起放入剪貼板。建立文件拖放對(duì)象的方法與DropEffect基本相同,只是文件拖放對(duì)象有特殊的數(shù)據(jù)結(jié)構(gòu) 而不象DropEffect那樣簡(jiǎn)單,該對(duì)象數(shù)據(jù)結(jié)構(gòu)如下:

1 2 3+----------------------------+|? DROPFILES? |? Files List? |+----------------------------+

DROPFILES是拖放對(duì)象的頭數(shù)據(jù),該結(jié)構(gòu)在shlobj.h中定義:

1 2 3 4 5 6typedefstruct _DROPFILES {????DWORDpFiles; ????POINT pt;????BOOLfNC; ????BOOLfWide; } DROPFILES, FAR * LPDROPFILES;

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