Article # 266, added by Geoworks, historical record
| first | previous | index | next | last |

Directly accessing CIF_TEXT on the Clipboard.



Direct clipboard manipulation of text is possible. As a
proof-of-concept, some sample code which grabs info from the
clipboard's text vmchain is at the end of this article.

Here is some information about the VMChains in the 
TextTransferBlockHeader


TextTransferBlockHeader
    TTBH_text		  huge array of chars
    TTBH_charAttrRuns	  huge array TextRunArrayElement
    TTBH_paraAttrRuns	  huge array TextRunArrayElement
    TTBH_typeRuns	  huge array TextRunArrayElement
    TTBH_graphicRuns	  huge array TextRunArrayElement
    TTBH_charAttrElements element array of VisTextCharAttr
    TTBH_paraAttrElements element array of VisTextParaAttr (variable sized)
    TTBH_typeElements	  (element array?) of VisTextType
    TTBH_graphicElements  (element array?) of VisTextGraphic
    TTBH_styles		  vm block handle
    TTBH_names		  vm block handle
    TTBH_pageSetup	  VMChain of PageSetupInfo

TTBH_pageSetup really is a VMChain, so you can hop from block to
block using PSI_meta.VMCL_next. (The structure in each VMBlock is a
PageSetupInfo struct.);


Here's the code snippet for dealing with CIF_TEXT:

----------Start Code Sample----------
/***********************************************************************
 *		PasteCommonText
 ***********************************************************************
 * SYNOPSIS:	 Go through and grab bits of data from the clipboard
 *		 text vmchain tree.
 *
 * CALLED BY:	 (INTERNAL) PasteCommon
 * RETURN:	 ClipboardQuickNotifyFlags for ClipboardEndQuickTransfer
 * SIDE EFFECTS: none
 *
 * STRATEGY:
 *
 * REVISION HISTORY:
 *	Name	Date		Description
 *	----	----		-----------
 *	eb	7/95		Initial Revision
 *
 ***********************************************************************/
static ClipboardQuickNotifyFlags
PasteCommonText(ClipboardQueryArgs *query, ClipboardRequestArgs *request)
{
    ClipboardQuickNotifyFlags retVal;

    MemHandle		     handleTTBH;
    TextTransferBlockHeader *ptrTTBH;

    char                    *clpbdText;

    /* need these for messing with the element array chunk */
    LMemBlockHeader         *ptrLMemBH;   
    ChunkHandle              elmntChnkH;  

    /* need these for the CharAttr runs and elements */
    TextRunArrayElement     *clpbdCAR;  
    MemHandle                handleCAE;   
    VisTextCharAttr         *clpbdCAE; 
    word                     elemSize;
    dword                    elemCount;

    /*
     * Fetch the file/block handle of transfer format 
     * TEXT_FORMAT is MANUFACTURER_ID_GEOWORKS::CIF_TEXT
     */
    ClipboardRequestItemFormat(TEXT_FORMAT, query->CQA_header, request);


    /*
     * Get the TextTransferBlockHeader struct, which is a VMChainTree.
     * (It is defined in vTextC.goh.). This will point to the various
     * vmchains that make up the elements of text and formatting info.
     */
    ptrTTBH = VMLock(request->CRA_file,
		     VMCHAIN_GET_VM_BLOCK(request->CRA_data),
		     &handleTTBH);

    /*
     * ****GET TEXT****
     * First we grab the plain text from the clipboard. The text vmchain
     * is a HugeArray.
     */

    /*
     * Get the total size of the text that is stored.
     */
     elemCount = HugeArrayGetCount(request->CRA_file,
		  VMCHAIN_GET_VM_BLOCK(ptrTTBH->TTBH_text));


    /*
     * Now get a pointer to the text pointer (*clpbdText). elemSize also
     * tells the size of the block of text.
     */
    HugeArrayLock(request->CRA_file,
		  VMCHAIN_GET_VM_BLOCK(ptrTTBH->TTBH_text),
		  0, &clpbdText, &elemSize);

    HugeArrayUnlock(clpbdText);


    /*
     * ****GET CHARACTER ATTRIBUTES****
     * The character attribute information is stored in two arrays.
     * One array, TTBH_charAttrElements, stores an array of
     * VisTextCharAttr elements. It is stored in an ElementArray,
     * so we will use ChunkArray routines to access the info.
     *
     * The other array, TTBH_charAttrRuns, stores an array of
     * TextRunArrayElement elements. These are in a HugeArray.
     */
    if(VMCHAIN_GET_VM_BLOCK(ptrTTBH->TTBH_charAttrRuns))
    {
	/*
	 * Enum thru the runs. There are two ways we could enum thru these
	 * runs. One is to start at the beginning (element 0) and go thru
	 * until we reach an element that has TRAE_position =
	 * TEXT_ADDRESS_PAST_END and and TRAE_token = CA_NULL_ELEMENT.
	 * The other way is to get the element count and use a for loop to
	 * enumerate thru the list. (We will use the latter approach in
	 * this example.) Be careful because the last element in the list
	 * has TRAE_token = CA_NULL_ELEMENT, which is not a valid token
	 * into the element array.
	 */

	/*
	 * Get element the first (0) element from character attribute run.
	 */
	HugeArrayLock(request->CRA_file,
		      VMCHAIN_GET_VM_BLOCK(ptrTTBH->TTBH_charAttrRuns),
		      0, &clpbdCAR, &elemSize);
	do {
	    /*
	     * Now get the character attributes for the specified run.
	     * To get the optr to the chunk array, we need the block
	     * handle, which we get with VMLock.  Putting VMLock inside
	     * of a loop like this is really a bad idea, but it was done
	     * in this case to keep all the necessary functionality close
	     * together. (otherwise you would have to page up and down
	     * looking for where handleCAE was set.)
	     *
	     * Since this block contains an element array, it is an LMem
	     * type block. Therefore, it contains an LMemBlockHeader at
	     * the beginning and the header contains the chunk to the
	     * element array. So we use this to get the handle and chunk
	     * to the element array.
	     */
	    ptrLMemBH = VMLock(request->CRA_file,
		  VMCHAIN_GET_VM_BLOCK(ptrTTBH->TTBH_charAttrElements),
		  &handleCAE);
	    /* If you do "phandle handleCAE", you see that the block contains
	     * lmem. Thus you can use "print LMemBlockHeader *ptrLMemBH"
	     * to see the structure. */
	    elmntChnkH = ptrLMemBH->LMBH_offset;

	    clpbdCAE = ChunkArrayElementToPtr(
				ConstructOptr(handleCAE, elmntChnkH),
				clpbdCAR->TRAE_token,
				&elemSize);
	    /* here is a good place in swat to do a "print *clpbdCAE" */
	    VMUnlock(handleCAE);

	    /*
	     * Now get next run.
	     */
	    HugeArrayNext(&clpbdCAR, &elemSize);

	    /*
	     * Fall thru when we reach the end-of-runs marker, otherwise,
	     * loop back up and get the info.
	     */
	} while (clpbdCAR->TRAE_token != CA_NULL_ELEMENT);

	HugeArrayUnlock(clpbdCAR);
    }


    /*
     * ****GET PARAGRAPH ATTRIBUTES****
     * This is almost exactly the same as the character attributes
     * except that the VisTextParaAttr is variable sized due to
     * VTMPA_tabList, which is tacked on to the end of the structure
     * if the text has special tabs set up for the paragraph. See
     * the Tab structure.
     *
     * We leave the coding as an excercise for you.
     */


    VMUnlock(handleTTBH);

    retVal = CQNF_COPY;

    return(retVal);
}
----------End Code Sample----------