Clipboard (Clipboard)

Source: Internet
Author: User

I. This article will introduce the solution to the following two problems:
1. Cut/copy files in the Resource Manager (Windows Explorer) and paste them in your own applications;
2. You can cut or copy files in your own applications and paste the files in resource management.

Ii. coding tools and testing environment in this article:
1, vc6.0, platform SDK (no need for MFC );
2. Windows 2000.

Iii. Overview
We know that in windows, we can share and transmit data through the clipboard (Clipboard). For example, in Windows Explorer, we can cut, copy, and paste files. Similarly, we can use clipboard in our own applications to improve the interoperability between our own applications and Windows operating systems. But how can we share and transmit data with applications such as resource manager? The method provided in this article is to use some data structures and APIs provided by windows to share and transmit data through the clipboard.

IV. Implementation Method
First, Windows does not write the file name to the clipboard when cutting/copying a file, but adds a draganddrop file object to the clipboard, A status value is written to identify the operation type (moving/copying, cutting is actually moving. If you do not paste it after cutting, the file will still exist and will not be deleted ). Based on this knowledge, we will first look at how the application recognizes the cut/copy actions of Windows Resource Manager.

Before using the clipboard, open it first:

Bool openclipboard (hwnd); The hwnd parameter is the window handle for opening the clipboard. True is returned for success, and false is returned for failure.

Then, you can use getclipboarddata to obtain the data in the clipboard:

HANDLE GetClipboardData(UINT uFormat);      

Uformat is the format of the required data. For example, the format of the drag-and-drop object in this document is cf_hddrop. It indicates that the data format of this drag-and-drop object type (move/copy) is not a Windows Standard Clipboard data structure, but a simple DWORD pointer. We can use the following statement to register the Data Type:

UINT uDropEffect=RegisterClipboardFormat("Preferred DropEffect");      

The returned udropeffect is the code that will be substituted into the data structure of the getclipboarddata function,
The getclipboarddata function returns a handle, which is only a work of windows for uniformity. We can convert it into a corresponding data form as needed. For example, our udropeffect is a DWORD pointer.
As I have mentioned before, a drag-and-drop object is placed in the clipboard, so we can get this object through the following statement:

HDROP hDrop = HDROP( GetClipboardData( CF_HDROP));      

If an hdrop object exists, we should obtain the udropeffect data so that we can process the following files:

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

For the meaning of this value, we only need to include the "oleidl. H" header file. In this header file, five States are defined. This article only focuses on:

#defineDROPEFFECT_COPY( 1 )#defineDROPEFFECT_MOVE( 2 )      

Therefore, we can

if(dwEffect & DROPEFFECT_COPY)  CopyFile(....);else (dwEffect & DROPEFFECT_MOVE)  MoveFile(...);      

To complete the cut/copy operation.
After obtaining the udropeffect state, we need to get the file list. To get the list of files in the drag-and-drop object, we can use dragqueryfile to achieve this:

UINT DragQueryFile(HDROP hDrop, UINT iFile,LPTSTR lpszFile,UINT cch);      

The second parameter is the file serial number. You can set ifile to-1 to get the number of files.
Finally, we provide a complete example:

#include <Shellapi.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;elsedwEffect=*dw;    char Buf[4096];Buf[0] = 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 & DROPEFFECT_MOVE) {MessageBox(NULL,Buf,"Move Files",MB_OK);} elseif(dwEffect & DROPEFFECT_COPY) {MessageBox(NULL,Buf,"Copy Files",MB_OK);}CloseClipboard();}}      

In this example, I did not perform file operations, but simply displayed a message box. In actual use, the movefile and copyfile functions are required. This article will not discuss them.
After we know how to identify the cut/copy actions of other programs, we know the data structure of this operation very well, to enable other programs to recognize our cut/copy operations is actually the process of putting the above data structure into the clipboard.
In our example, the data placed in the clipboard must be a memory object: hglobal. This object can be generated through globalalloc. Then, use globallock to get the memory address of the object and write data into it. In fact, in Win32, because the process has independent memory space, globallock is no longer required for regular memory allocation. In msdn, we can see that this function is mainly used for DDE and clipboard services.
Based on the previous knowledge, to let other programs identify our cut/copy actions, we must put two pieces of data in the clipboard. Now let's prepare data for dropeffect, we also need to register the data format first:

uDropEffect=RegisterClipboardFormat("Preferred DropEffect");      

Then allocate the memory object and get the pointer:

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

Note that the gmem_moveable flag must be used for the data to be placed in the clipboard. Finally, we can set the data and unlock it:

if(COPY)  *dwDropEffect=DROPEFFECT_COPY;else  *dwDropEffect=DROPEFFECT_MOVE;GlobalUnlock(hGblEffect);      

In this way, I have prepared the data for dropeffect. After a while, we will put the data to the clipboard together with the drag-and-drop object of the file. The method for creating a file drag-and-drop object is basically the same as that of dropeffect, but the file drag-and-drop object has a special data structure, which is not as simple as dropeffect. The data structure of this object is as follows:

+----------------------------+|  DROPFILES  |  Files List  |+----------------------------+      

Dropfiles is the header data of the drag-and-drop object. This structure is defined in shlobj. h:

typedef struct _DROPFILES {    DWORD pFiles;     POINT pt;     BOOL fNC;     BOOL fWide; } DROPFILES, FAR * LPDROPFILES;       

The pfiles pointer is the offset of the file list (the files list item in) referenced by the object's first address. Generally, this value is equal to the length of the dropfiles structure (I have not seen any exceptions). PT indicates the coordinate of the drag and drop position of the file. In this example, we ignore it as 0; FNC indicates whether the PT value is the client zone coordinate (false indicates the screen coordinate); fwide indicates whether the files list contains Unicode. as Chinese, we must set it to true. The dropfiles structure is followed by the files list. The files list is a set of wide strings separated by 0. For example, "file 1/0 file 2/0 ..."
We can use the multibytetowidechar function to convert a regular string to a wide string. The following code generates a drag-and-drop object:

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 is the length of the character Transfer Group of the file name. to convert it to a wide character, therefore, the length must be 2 hgblfiles = globalalloc (gmem_zeroinit | gmem_moveable | gmem_ddeshare, ugbllen); szdata = (char *) globallock (hgblfiles); memcpy (szdata, (lpvoid) (& dropfiles), udropfileslen); // copy dropfiles to the header szfilelist = szdata + udropfileslen; // obtain the first address of the List of stored files (cp_acp, mb_composite, lpbuffer, ubuflen, (wchar *) szfilelist, ubuflen); globalunlock (hgblfiles );

Now we can put the above two groups of data into the clipboard. Note that the clipboard should be cleared before writing data. For ease of use, the following is an independent function that implements this function:

VOID CutOrCopyFiles(char * lpBuffer,UINT uBufLen,BOOL bCopy)      

Lpbuffer is a buffer that includes the names of all files to be cut/copied; ubuflen is the length of lpbuffer; bcopy determines whether the operation is copy or cut, true indicates copy, and false indicates cut. For example, we can call this function as follows:

char szFiles[]="c://1.txt/0c://2.txt/0";CutOrCopyFiles(szFiles,sizeof(szFiles),FALSE);      

To cut the file, or use:

CutOrCopyFiles(szFiles,sizeof(szFiles),TRUE);      

To copy files.

#include <Shellapi.h>#include <Shlobj.h>#include <oleidl.h>      
......VOID CutOrCopyFiles(char *lpBuffer,UINT uBufLen,BOOL bCopy){UINT uDropEffect;DROPFILES dropFiles;UINT uGblLen,uDropFilesLen;HGLOBAL hGblFiles,hGblEffect;char *szData,*szFileList;DWORD *dwDropEffect;uDropEffect=RegisterClipboardFormat("Preferred DropEffect");hGblEffect=GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE,sizeof(DWORD));dwDropEffect=(DWORD*)GlobalLock(hGblEffect);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),uDropFilesLen);szFileList=szData+uDropFilesLen;MultiByteToWideChar(CP_ACP,MB_COMPOSITE,lpBuffer,uBufLen,(WCHAR *)szFileList,uBufLen);GlobalUnlock(hGblFiles);if( OpenClipboard(NULL) ){EmptyClipboard();SetClipboardData( CF_HDROP, hGblFiles );SetClipboardData(uDropEffect,hGblEffect);CloseClipboard();}}      

I hope the above content will help you.
The following describes how to use the cutcopy.exe program after compiling a demo project:
After the program is started, you can use Windows resource manager and other programs to cut/copy files, and then click [checkclipboard] In the program. The demo program will analyze the content in the clipboard, in the displayed dialog box, copy files or cut files are displayed, and a file list is displayed. after you click [OK] to close the message box, the file list will be placed in the text box. You can click [CUT]/[copy] to change the attributes of the clipboard.
At the same time, you can use [browser] to select several files to the text box, and then click [CUT]/[copy] to perform the operation. Then, you can use [checkclipboard] to check the content in the clipboard or paste (paste) in programs such as Windows Resource Manager to check whether the clipboard is correct.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.