Format in the clipboard

Post Reply
Natter
Posts: 1402
Joined: Mon May 14, 2007 9:49 am

Format in the clipboard

Post by Natter »

An Excel sheet fragment has been copied to the clipboard. Is it possible to find out the name of the data format in the clipboard?

User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Format in the clipboard

Post by Antonio Linares »

Finding the Clipboard Data Format Name in FWH

The short answer is: partially. You can obtain the numeric format ID, but not the name string of the format directly through FWH's existing API.

--- What FWH Can Do: Get the Numeric Format ID

FWH provides the GetClipContentFormat() Harbour function, which internally calls GETPRIORITYCLIPBOARDFORMAT (a wrapper around the Windows API GetPriorityClipboardFormat). This returns the numeric format ID of the highest-priority available clipboard format. 0-cite-0

The underlying C implementation in GETPRIORITYCLIPBOARDFORMAT uses a default priority list of formats (1–15 + CF_UNICODETEXT) and calls the Win32 GetPriorityClipboardFormat(), returning the matched format's integer ID: 0-cite-1

--- The Excel-Specific Situation

The codebase itself already acknowledges the problem in a comment inside TClipBoard:GetUnicodeText():

"Clipboard from Excel, Word, etc are format no. 49161. This is object. WE should know how to handle this." 0-cite-2

This means when Excel copies a sheet fragment, it places data in a registered (custom) format with a dynamically assigned numeric ID (e.g., 49161), which is above the standard CF_* range (1–15). FWH's current approach is to fall back to reading CF_UNICODETEXT (format 13) for the text part: 0-cite-3

--- What FWH Cannot Do: Get the Format Name String

To translate a numeric format ID like 49161 into its human-readable name (e.g., "Biff12" or "XML Spreadsheet"), the Windows API GetClipboardFormatName() would be needed. Likewise, EnumClipboardFormats() would be needed to iterate all formats currently on the clipboard. Neither of these functions is wrapped anywhere in the FWH codebase.

The only mention of EnumClipboardFormats in the entire codebase is in a commented-out line inside GETCLPDATA: 0-cite-4

The only registered (named) custom formats in FWH are "Get Text Format" (GTF) and "Rich Text Format" (RTF), registered via RegisterClipboardFormat in fgetclip.c: 0-cite-5

--- Notes
  • You can call GetClipContentFormat() to get the number of the Excel clipboard format (likely 49161 or similar), but this number alone does not tell you the name.
  • You cannot currently get the format's name string through FWH, because neither GetClipboardFormatName nor EnumClipboardFormats is wrapped as an HB_FUNC in the library. To add this capability, a new HB_FUNC wrapper would need to be added to source/winapi/clpbrd.c.
  • FWH's recommended workaround is to read Excel clipboard content as CF_UNICODETEXT (format 13), ignoring Excel's native proprietary format.
Citations

File: source/classes/clipbrd.prg (L197-199)

Code: Select all | Expand

// Notes: Clipboard from Excel,Word,etc are format no. 49161
// This is object. WE should know how to handle this
// We can get text part of it as CF_UNICODETEXT

File: source/classes/clipbrd.prg (L201-209)

Code: Select all | Expand

   if ::Open()
      cText = GetClpData( CF_UNICODETEXT )
      if IsText8Bit( cText )
         cText = GetClpData( CF_TEXT )
      else
         cText = UTF16TOUTF8( cText )
      endif
      ::Close()
   endif

File: source/classes/clipbrd.prg (L248-265)

Code: Select all | Expand

function GetClipContentFormat(...)

   local aParams  := HB_AParams()

   if Len( aParams ) == 1 .and. ValType( aParams[ 1 ] ) == 'A'
      aParams  := aParams[ 1 ]
   endif
   if Empty( aParams ) .or. Empty( aParams[ 1 ] )
      aParams  := nil
   else
      if AScan( aParams,  1 ) > 0 .and. ;
         AScan( aParams, 13 ) == 0

         AAdd( aParams, 13 )
      endif
   endif

return GETPRIORITYCLIPBOARDFORMAT( aParams )

File: source/winapi/clpbrd.c (L146-147)

Code: Select all | Expand

   // if( ( wType == CF_TEXT ) && ( EnumClipboardFormats( 0 ) == CF_UNICODETEXT ) )
   //    wType = CF_UNICODETEXT;

File: source/winapi/clpbrd.c (L198-217)

Code: Select all | Expand

HB_FUNC (GETPRIORITYCLIPBOARDFORMAT)
{
   int uFormat;
   UINT auPriorityList[] = { CF_UNICODETEXT, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15 };
   int iFormats = 15;
   int i;

   if ( HB_ISARRAY( 1 ) )
   {
      iFormats = ( int ) hb_parinfa( 1, 0 );
      for ( i = 0; i < iFormats; i++ )
      {
         auPriorityList[ i ] = hb_parvni( 1, i + 1 );
      }
   }

   uFormat = GetPriorityClipboardFormat( auPriorityList, iFormats );
//   if ( uFormat == NULL ) { uFormat = 0; }
   hb_retni( uFormat );
}

File: source/function/fgetclip.c (L11-12)

Code: Select all | Expand

static far char GTF[] = "Get Text Format";
static far char RTF[] = "Rich Text Format";
regards, saludos

Antonio Linares
www.fivetechsoft.com
Natter
Posts: 1402
Joined: Mon May 14, 2007 9:49 am

Re: Format in the clipboard

Post by Natter »

Thanks !!!

Post Reply