|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionRecently I had some free time and I was thinking about an area of Windows programming that I didn't know much about, but wanted to learn more about, namely the clipboard. I had written a utility for myself that dealt with HDROP data on the clipboard to simulate Explorer's Copy and Paste commands, but using just one format wasn't enough. I wanted to see deeper into the contents of the clipboard, and in the process maybe uncover some neat factoids about apps that use the clipboard. (For example, what's a "Woozle"? - See Figure 2 above.) Well, the free time turned into a free weekend (lucky for me I had all my Christmas shopping done!), and the result of my self-teaching is ClipSpy, a souped-up clipboard viewer. It can also view the data in a drag-and-drop operation (since MFC uses the same class to handle drag-and-drop and the clipboard), but I chose the name ClipSpy since ClipboardAndDragAndDropSpy is a bit harder to type. If you're just itching to learn more about the clipboard yourself, check out the "Implementation details" section of the article, where I point out interesting points in the code. What ClipSpy doesClipSpy registers itself as a clipboard viewer. Nothing magical there. But when the contents of the clipboard change, ClipSpy enumerates all the data formats on the clipboard (there may be many) and displays them all in the left-hand pane. Clicking on a format in the list shows the data that was placed on the clipboard in the right-hand pane. The right pane shows the raw data as well as the ASCII representation, similar to the memory debug window in MSVC. The left-hand pane also registers as a drop target, so you can drag any data from a program that supports drag-and-drop, drop it over the list, and ClipSpy will show all the data that the drag source provided. Again, the formats are listed in the left-hand pane, and clicking a format shows the corresponding data in the right-hand pane. The File menu also has a few commands. The Implementation detailsClipSpy does most of its work via the MFC class BOOL CLeftView::ReadDataAndFillList ( COleDataObject* pDO )
{
FORMATETC etc;
UINT uNumFormats = 0;
// Determine how many formats are available on the clipboard.
pDO->BeginEnumFormats();
while ( pDO->GetNextFormat ( &etc ))
{
if ( pDO->IsDataAvailable ( etc.cfFormat ))
{
uNumFormats++;
}
}
For each format, ClipSpy checks to see if it is a built-in type. If not, it gets the descriptive string for the format by calling TCHAR szFormat [256]; GetClipboardFormatName ( etc.cfFormat, szFormat, 256 ); ClipSpy has a list of strings used for the built-in types (since HGLOBAL hgData;
UINT uDataSize;
CClipSpyDoc* pDoc = GetDocument();
// Get an HGLOBAL of the data.
hgData = pDO->GetGlobalData ( etc.cfFormat );
if ( NULL != hgData )
{
uDataSize = GlobalSize ( hgData );
pDoc->AddDataBlock ( hgData, uDataSize );
}
else
{
pDoc->AddEmptyBlock();
}
The functions This same code is used when data is dropped on the list control - the function The other interesting pieces of code are Quirks in the programThe right-hand pane is a rich edit control, which supports copying to the clipboard. However, you should not copy from it, since doing so can lead to crashes inside OLE. Again, this is probably due to something I'm doing wrong, but in the meantime, just don't do it. :) Since clipboard data is originally allocated with Something to keep in mind if you debug the program - if you are stepping through the code, do not try to use the clipboard. Since ClipSpy isn't running, the entire clipboard operation hangs and brings down ClipSpy, MSVC, and whatever program you did the clipboard operation in. Ouch! On Windows 9x, you might as well hit the reset button at that point. Revision HistoryDecember 20, 1999: Version 1.0, first release. October 28, 2001: Version 1.2, added ability to save any block of data; added IDropTargetHelper support to CLeftView.
|
||||||||||||||||||||||