The Clipboard: 3.4 Using The Clipboard: Handling Cut and Copy

Up: GEOS SDK TechDocs | Up | Prev: 3.3 The GenEditControl | Next: 3.5 Handling Paste
MSG_META_CLIPBOARD_CUT, MSG_META_CLIPBOARD_COPY

Cut and Copy are very similar in function; both put data onto the Clipboard. However, Cut causes the data to subsequently be deleted from the document, and Copy does not.

When the user starts either of these operations, the object that handles them must go through a series of specific steps to load the data into the Clipboard's VM file. (For simplicity of example, this chapter will assume that the Process object will handle all Clipboard operations; this may not be the case in complex programs.)

The steps are simple; each is enumerated below, and edited examples from the sample application ClipSamp are provided in MSG_META_CLIPBOARD_CUT and MSG_META_CLIPBOARD_COPY . Note that these examples do not use the default text object handlers for copy and paste; they treat the entire text flow as the current selection.

  1. Duplicate and attach the data
    You must create a duplicate of whatever data is being loaded into the Clipboard. This step includes allocating new VM blocks in the Transfer VM File with VMAlloc() . As an alternative, you may pre-duplicate the item in memory with MemAlloc() and then simply attach them to the Transfer VM File with VMAttach() .
  2. Complete the transfer item's header
    Fill in all information fields in the transfer item's header block including formats, owner, and flags.
  3. Register the transfer item
    Once the data has been attached and the header completed, you must register the transfer with the Clipboard. The UI will then delete any old data in the Clipboard and replace it with your new transfer item. To register the transfer item, use ClipboardRegisterItem() .

Code Display 7-7 MSG_META_CLIPBOARD_CUT

/* This is the same as MSG_META_CLIPBOARD_COPY except that after copying the
 * data to the Clipboard, it deletes the data from the document.
 *
 * MSG_META_CLIPBOARD_CUT has no parameters and no return value. The strategy
 * is as follows: First, copy the subject data into the Clipboard with
 * MSG_META_CLIPBOARD_COPY. Then, delete the data (which, in this case, is a single
 * memory block containing all the subject text). */
@method ClipSampProcessClass, MSG_META_CLIPBOARD_CUT {
	/* Use MSG_META_CLIPBOARD_COPY to copy the data to the clipboard. */
    @call self::MSG_META_CLIPBOARD_COPY();
	/* Delete the data. The data is contained entirely within a single memory
	 * block and is just text. The block is referenced by the memory handle
	 * textHandle. If textHandle is not null, then the block may be freed. */
    if (textHandle) {					/* If textHandle is valid, */
	MemFree(textHandle);				/* free the memory block */
	textHandle = 0;				/* and zero the handle. */
    }
	/* Redraw the view area to reflect the deleted text. */
    ResetViewArea();			/* Custom routine to redraw the view. */
}

Code Display 7-8 MSG_META_CLIPBOARD_COPY

/* This message handler goes through all the steps necessary for a Copy operation
 * that works with text data only.
 * MSG_META_CLIPBOARD_COPY has no parameters and requires no return.
 * 
 * The strategy employed by this handler is as follows:
 * First, allocate memory for and create the duplicate data block, filling in all
 * the appropriate fields.
 * Next, retrieve the Transfer VM File and attach the data block to the file.
 * Next, allocate and construct the transfer item header VM block.
 * Finally, register and lock in the transfer item to the Clipboard.
 *
 * A single global variable named textHandle refers to the block of text owned and
 * used by the sample application. All other data structures are defined within the
 * message handler. */
@method ClipSampProcessClass, MSG_META_CLIPBOARD_COPY {
    char			*textText;		/* temporary string for the text */
    int			textLength;		/* length of string including null */
    MemHandle			headerMemHandle;		/* handle of ClipboardItemHeader block */
    VMFileHandle 			transferVMFile;		/* VM file handle of Transfer VM File */
    VMBlockHandle 			dataVMBlock;		/* VM handle of attached data block */
    VMBlockHandle 			headerVMBlock;		/* VM handle of attached header block */
    ClipboardItemHeader 			*headerMem;		/* ClipboardItemHeader for the VM file */
    optr			textObj;		/* temporary text object for transfer */
    /* First, lock the text string into memory and get its length, adding one for
     * the null character at the end. Then unlock the text string's block. */
    textText = (char *) MemLock(textHandle);
    textLength = (strlen(textText) + 1);
    MemUnlock(textHandle);
    /* Next, build the transfer item block by creating a temporary text object and
     * copying our text into it. Other formats may simply copy the text directly
     * into a VM block. */
    textObj = TextAllocClipboardObject(ClipboardGetClipboardFile(), 0, 0);
    @call textObj::MSG_VIS_TEXT_REPLACE_ALL_PTR((char *)MemLock(textHandle), 0);
    MemUnlock(textHandle);
    dataVMBlock = TextFinishedWithClipboardObject(
					textObj, TCO_RETURN_TRANSFER_FORMAT);
    /* Now get the transfer VM file. */
    transferVMFile = ClipboardGetClipboardFile();
    /* Now, allocate and fill in the transfer item header block. */
    headerVMBlock = VMAlloc(				transferVMFile, 
				sizeof(ClipboardItemHeader), 
				MY_TRANSFER_ID);
    headerMem = (ClipboardItemHeader *)VMLock(transferVMFile, headerVMBlock,
							&headerMemHandle);
    headerMem->CIH_owner = (optr) (((dword)GeodeGetProcessHandle()<<16) | 0);
    headerMem->CIH_flags = 0;					/* Normal transfer; no flags. */
    (void) strcpy(headerMem->CIH_name, "Sample Text");
    headerMem->CIH_formatCount = 1;
    headerMem->CIH_sourceID = 0;
    headerMem->CIH_formats[0].CIFI_format =
		FormatIDFromManufacturerAndType(MANUFACTURER_ID_ME, CIF_TEXT);
    headerMem->CIH_formats[0].CIFI_vmChain =
				VMCHAIN_MAKE_FROM_VM_BLOCK(dataVMBlock);
    headerMem->CIH_formats[0].CIFI_extra1 = 0;
    headerMem->CIH_formats[0].CIFI_extra2 = 0;
    VMUnlock(headerMemHandle);
    /* Now register the transfer item with the Clipboard. This will actually put
     * the transfer item and its header into the Clipboard. */
    ClipboardRegisterItem(BlockIDFromFileAndBlock(
					transferVMFile, headerVMBlock),
			0);
}  

Up: GEOS SDK TechDocs | Up | Prev: 3.3 The GenEditControl | Next: 3.5 Handling Paste