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 TextTransferBlockHeaderTextTransferBlockHeader 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----------