RegisterClipboardFormat (user32)
Last changed: -77.11.107.197

.
Summary

C# Signature:

[DllImport("user32.dll", SetLastError=true)]
static extern uint RegisterClipboardFormat(string lpszFormat);

User-Defined Types:

None.

Notes:

None.

Tips & Tricks:

Please add some!

Translation from chinese sample code (using bing translator, no hand edits):

In this example, I did not do the file operation, just simply display a message box, practical application, the use of MoveFile and CopyFile functions to complete, this article is not discussed.

Knowing how to recognize the action of other programs to cut/copy files, we already know the data structure of the operation, so that other programs can recognize our cut/copy file action is actually the above data structure into the clipboard process.

In our example, the data placed in the clipboard must be a memory object: HGLOBAL. This object can be generated through GlobalAlloc. GlobalLock can then be used to get the object's memory address and then write data inside. In fact, in Win32 because the process has a separate memory space, so the regular memory allocation no longer need GlobalLock, look at MSDN to know that the function is mainly for The DDE and clipboard services.

Based on the previous knowledge, in order for other programs to recognize our cut/copy actions we have to put two items of data into the clipboard, now let's prepare the data for DropEffect, and 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 data placed in the clipboard must use the GMEM_MOVEABLE flag, and finally we set the data and unlock it:

if(COPY)

 *dwDropEffect=DROPEFFECT_COPY;

else

*dwDropEffect=DROPEFFECT_MOVE;

GlobalUnlock(hGblEffect);

So I'm ready to pay back the data for DropEffect, and then we put it on the clipboard with the file drag-and-drop object. The method of creating a file drag-and-drop object is basically the same as DropEffect, except that the file drag-and-drop object has a special data structure rather than the same as DropEffect, which is the same data structure as follows:

----------------------------

| DROPFILES | Files List |

----------------------------

DROPFILES IS THE HEAD DATA OF THE DRAG-AND-DROP OBJECT, WHICH 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 amount of the list of files referenced by the object's first address (the Files List item in the figure above). Usually the value is equal to the length of the DROPFILES structure (I haven't seen an exception) ;pt indicates the location coordinates of file drag-and-drop, in this case we ignore it as 0; fNC indicates whether the pt value is the customer area coordinates (FALSE indicates that the screen coordinates); and fWide indicates that files are Whether list contains unicode, as a Chinese, of course, we have to set it as TRUE. DROPFILES STRUCTURE IS FOLLOWED BY FILES LIST, FILES LIST IS A SET OF WIDE STRINGS, SEPARATED BY 0, SUCH AS: "FILE 1 S0 FILE 2 S.0."

We can convert regular strings into wide strings through the MultiByteToWideChar function. Here's the code to build the 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 file name character pass group, and because it is converted to a wide character, the length is multiplied by 2

hGblFiles= GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE, uGblLen);

szData=(char*)GlobalLock(hGblFiles);

memcpy(szData,(LPVOID)(&dropFiles),uDropFilesLen);

//DROPFILES copy to head

szFileList=szData+uDropFilesLen;

//Get the first address of the list of files stored

MultiByteToWideChar(CP_ACP,MB_COMPOSITE,

  lpBuffer,uBufLen,(WCHAR *)szFileList,uBufLen);

GlobalUnlock(hGblFiles);

This article is available from programming getting started: http://www.bianceng.cn/programming/vc/201007/18403-3.htm

Sample Code:

在这个例子中,我并没有进行文件操作,只是简单的显示一个消息框,实际应用时,需要使用MoveFile和CopyFile函数来完成,本文不做讨论。

知道如何识别其他程序的剪切/拷贝 文件的动作后,我们对该操作的数据结构已经很了解了,要想让其他程序能识别我们的剪切/拷贝 文件动作其实就是将以上数据结构放入剪贴板的过程。

在我们这个例子中,往剪贴板中放的数据必须是内存对象:HGLOBAL。这个对象可以通过GlobalAlloc来生成。然后使用GlobalLock就可以得到该对象的内存地址,继而往里面写 数据。实际上在Win32中由于进程拥有独立的内存空间,因而常规的内存分配已经不需要GlobalLock了,看看MSDN就知道该函数主要就是为DDE和剪贴板服务的。

根据前面的知识,要想让其他程序识别出我们的剪切/拷贝动作我们必须往剪贴板中放两项数据,现在就让我们来为DropEffect准备数据吧,同样我们需要先注册该数据格式:

uDropEffect=RegisterClipboardFormat("Preferred DropEffect");

然后分配内存对象并得到指针:

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

dwDropEffect=(DWORD*)GlobalLock(hGblEffect);

注意往剪贴板中放的数据必须使用GMEM_MOVEABLE标志,最后我们设置数据并解除锁定:

if(COPY)

 *dwDropEffect=DROPEFFECT_COPY;

else

*dwDropEffect=DROPEFFECT_MOVE;

GlobalUnlock(hGblEffect);

这样我就为DropEffect准备还数据了,等一会儿我们连同文件拖放对象一起放入剪贴板。建立文件拖放对象的方法与DropEffect基本相同,只是文件拖放对象有特殊的数据结构 而不象DropEffect那样简单,该对象数据结构如下:

----------------------------

| DROPFILES | Files List |

----------------------------

DROPFILES是拖放对象的头数据,该结构在shlobj.h中定义:

typedef struct _DROPFILES {

  DWORD pFiles;

  POINT pt;

  BOOL fNC;

  BOOL fWide;

} DROPFILES, FAR * LPDROPFILES;

pFiles指针是以对象首地址为参照的文件列表(上图中的Files List项)的offset量。通常该值等于DROPFILES结构的长度(我还没见过例外);pt表明文件拖放的位置坐标,在这个例子里我们忽略为0; fNC表明pt值是否为客户区坐标(FALSE表明是屏幕坐标);fWide表明Files List是否包含unicode,作为中国人,我们当然要设其为TRUE。DROPFILES结构之后紧跟Files List,Files List是一组宽字符串,之间以0相隔,比如:"文件1\0文件2\0..."

我们可以通过MultiByteToWideChar函数将常规的字符串转换成宽字符串。下面就是生成拖放对象的代码:

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是文件名字符传组的长度,由于要转换成宽字符,因此长度要乘2

hGblFiles= 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 *)szFileList,uBufLen);

GlobalUnlock(hGblFiles);

本文来自编程入门网:http://www.bianceng.cn/Programming/vc/201007/18403_3.htm

Alternative Managed API:

Do you know one? Please contribute it!

Documentation