@@ -41,42 +41,12 @@ public static class DataFormats
4141 /// <summary>
4242 /// Gets the data format with the Windows Clipboard numeric ID and name for the specified ID.
4343 /// </summary>
44- public static DataFormat GetDataFormat ( int id ) => InternalGetDataFormat ( id ) ;
44+ public static DataFormat GetDataFormat ( int id ) => DataFormatsImpl . GetDataFormat ( id ) ;
4545
4646 /// <summary>
4747 /// Gets the data format with the Windows Clipboard numeric ID and name for the specified data format.
4848 /// </summary>
49- public static DataFormat GetDataFormat ( string format )
50- {
51- ArgumentNullException . ThrowIfNull ( format ) ;
52-
53- if ( format == string . Empty )
54- throw new ArgumentException ( SR . DataObject_EmptyFormatNotAllowed ) ;
55-
56- // Lock the data format list to obtain the mutual-exclusion.
57- lock ( _formatListlock )
58- {
59- for ( int i = 0 ; i < _formatList . Count ; i ++ )
60- {
61- DataFormat formatItem = _formatList [ i ] ;
62-
63- if ( formatItem . Name . Equals ( format , StringComparison . OrdinalIgnoreCase ) )
64- return formatItem ;
65- }
66-
67- // Register this format string
68- int formatId = UnsafeNativeMethods . RegisterClipboardFormat ( format ) ;
69-
70- if ( formatId == 0 )
71- throw new System . ComponentModel . Win32Exception ( ) ;
72-
73- // Create a new format and store it
74- DataFormat newFormat = new ( format , formatId ) ;
75- _formatList . Add ( newFormat ) ;
76-
77- return newFormat ;
78- }
79- }
49+ public static DataFormat GetDataFormat ( string format ) => DataFormatsImpl . GetDataFormat ( format ) ;
8050
8151 #endregion Public Methods
8252
@@ -286,113 +256,174 @@ public static DataFormat GetDataFormat(string format)
286256
287257 //------------------------------------------------------
288258 //
289- // Private Methods
259+ // Data Formats Implementation
290260 //
291261 //------------------------------------------------------
292262
293- #region Private Methods
263+ #region Data Formats Implementation Class
294264
295265 /// <summary>
296- /// Allows a the new format name to be specified if the requested format is not
297- /// in the list
266+ /// Static class containing the internal format list and associated lookup methods.
298267 /// </summary>
299- private static DataFormat InternalGetDataFormat ( int id )
268+ private static class DataFormatsImpl
300269 {
301- // Lock the data format list to obtain the mutual-exclusion.
302- lock ( _formatListlock )
270+ //------------------------------------------------------
271+ //
272+ // Static constructor
273+ //
274+ //------------------------------------------------------
275+
276+ #region Static constructor
277+
278+ /// <summary>
279+ /// Ensures that the Win32 predefined formats are setup in our format list.
280+ /// This is called anytime we need to search the list.
281+ /// </summary>
282+ static DataFormatsImpl ( )
303283 {
304- DataFormat formatItem ;
305- StringBuilder sb ;
306-
307- for ( int i = 0 ; i < _formatList . Count ; i ++ )
284+ // Create format list for the default formats.
285+ formatList = new List < DataFormat > ( 19 )
308286 {
309- formatItem = _formatList [ i ] ;
287+ new ( DataFormats . UnicodeText , NativeMethods . CF_UNICODETEXT ) ,
288+ new ( DataFormats . Text , NativeMethods . CF_TEXT ) ,
289+ new ( DataFormats . Bitmap , NativeMethods . CF_BITMAP ) ,
290+ new ( DataFormats . MetafilePicture , NativeMethods . CF_METAFILEPICT ) ,
291+ new ( DataFormats . EnhancedMetafile , NativeMethods . CF_ENHMETAFILE ) ,
292+ new ( DataFormats . Dif , NativeMethods . CF_DIF ) ,
293+ new ( DataFormats . Tiff , NativeMethods . CF_TIFF ) ,
294+ new ( DataFormats . OemText , NativeMethods . CF_OEMTEXT ) ,
295+ new ( DataFormats . Dib , NativeMethods . CF_DIB ) ,
296+ new ( DataFormats . Palette , NativeMethods . CF_PALETTE ) ,
297+ new ( DataFormats . PenData , NativeMethods . CF_PENDATA ) ,
298+ new ( DataFormats . Riff , NativeMethods . CF_RIFF ) ,
299+ new ( DataFormats . WaveAudio , NativeMethods . CF_WAVE ) ,
300+ new ( DataFormats . SymbolicLink , NativeMethods . CF_SYLK ) ,
301+ new ( DataFormats . FileDrop , NativeMethods . CF_HDROP ) ,
302+ new ( DataFormats . Locale , NativeMethods . CF_LOCALE )
303+ } ;
304+
305+ int xamlFormatId = UnsafeNativeMethods . RegisterClipboardFormat ( DataFormats . Xaml ) ;
306+ if ( xamlFormatId != 0 )
307+ formatList . Add ( new ( DataFormats . Xaml , xamlFormatId ) ) ;
308+
309+ // This is the format to store trust boundary information. Essentially this is accompalished by storing
310+ // the permission set of the source application where the content comes from. During paste we compare this to
311+ // the permission set of the target application.
312+ int applicationTrustFormatId = UnsafeNativeMethods . RegisterClipboardFormat ( DataFormats . ApplicationTrust ) ;
313+ if ( applicationTrustFormatId != 0 )
314+ formatList . Add ( new ( DataFormats . ApplicationTrust , applicationTrustFormatId ) ) ;
315+
316+ // RegisterClipboardFormat returns 0 on failure
317+ int inkServicesFrameworkFormatId = UnsafeNativeMethods . RegisterClipboardFormat ( StrokeCollection . InkSerializedFormat ) ;
318+ if ( inkServicesFrameworkFormatId != 0 )
319+ formatList . Add ( new ( StrokeCollection . InkSerializedFormat , inkServicesFrameworkFormatId ) ) ;
320+ }
310321
311- // OLE FORMATETC defined CLIPFORMAT as the unsigned short, so we should ignore
312- // high 2bytes to find the matched CLIPFORMAT ID.
313- if ( ( formatItem . Id & 0x0000ffff ) == ( id & 0x0000ffff ) )
314- return formatItem ;
315- }
322+ #endregion Static Constructor
323+
324+ //------------------------------------------------------
325+ //
326+ // Private Methods
327+ //
328+ //------------------------------------------------------
316329
317- sb = new StringBuilder ( NativeMethods . MAX_PATH ) ;
330+ #region Private Methods
318331
319- // This can happen if windows adds a standard format that we don't know about,
320- // so we should play it safe.
321- if ( UnsafeNativeMethods . GetClipboardFormatName ( id , sb , sb . Capacity ) == 0 )
332+ /// <summary>
333+ /// Allows a new format name to be specified if the requested format is not in the list.
334+ /// </summary>
335+ public static DataFormat GetDataFormat ( int id )
336+ {
337+ // Lock the data format list to obtain the mutual-exclusion.
338+ lock ( _formatListlock )
322339 {
323- sb . Length = 0 ; // Same as Clear()
324- sb . Append ( "Format" ) . Append ( id ) ;
340+ DataFormat formatItem ;
341+ StringBuilder sb ;
342+
343+ for ( int i = 0 ; i < formatList . Count ; i ++ )
344+ {
345+ formatItem = formatList [ i ] ;
346+
347+ // OLE FORMATETC defined CLIPFORMAT as the unsigned short, so we should ignore
348+ // high 2bytes to find the matched CLIPFORMAT ID.
349+ if ( ( formatItem . Id & 0x0000ffff ) == ( id & 0x0000ffff ) )
350+ return formatItem ;
351+ }
352+
353+ sb = new StringBuilder ( NativeMethods . MAX_PATH ) ;
354+
355+ // This can happen if windows adds a standard format that we don't know about,
356+ // so we should play it safe.
357+ if ( UnsafeNativeMethods . GetClipboardFormatName ( id , sb , sb . Capacity ) == 0 )
358+ {
359+ sb . Length = 0 ; // Same as Clear()
360+ sb . Append ( "Format" ) . Append ( id ) ;
361+ }
362+
363+ // Create a new format and store it
364+ formatItem = new ( sb . ToString ( ) , id ) ;
365+ formatList . Add ( formatItem ) ;
366+
367+ return formatItem ;
325368 }
369+ }
370+
371+ /// <summary>
372+ /// Retrieves a data format using its name or attempts to register a new one if it doesn't exist.
373+ /// </summary>
374+ public static DataFormat GetDataFormat ( string format )
375+ {
376+ ArgumentNullException . ThrowIfNull ( format ) ;
377+
378+ if ( format == string . Empty )
379+ throw new ArgumentException ( SR . DataObject_EmptyFormatNotAllowed ) ;
380+
381+ // Lock the data format list to obtain the mutual-exclusion.
382+ lock ( _formatListlock )
383+ {
384+ for ( int i = 0 ; i < formatList . Count ; i ++ )
385+ {
386+ DataFormat formatItem = formatList [ i ] ;
387+
388+ if ( formatItem . Name . Equals ( format , StringComparison . OrdinalIgnoreCase ) )
389+ return formatItem ;
390+ }
326391
327- // Create a new format and store it
328- formatItem = new ( sb . ToString ( ) , id ) ;
329- _formatList . Add ( formatItem ) ;
392+ // Register this format string
393+ int formatId = UnsafeNativeMethods . RegisterClipboardFormat ( format ) ;
330394
331- return formatItem ;
395+ if ( formatId == 0 )
396+ throw new System . ComponentModel . Win32Exception ( ) ;
397+
398+ // Create a new format and store it
399+ DataFormat newFormat = new ( format , formatId ) ;
400+ formatList . Add ( newFormat ) ;
401+
402+ return newFormat ;
403+ }
332404 }
333- }
334405
335- /// <summary>
336- /// Ensures that the Win32 predefined formats are setup in our format list. This
337- /// is called anytime we need to search the list
338- /// </summary>
339- static DataFormats ( )
340- {
341- // Create format list for the default formats.
342- _formatList = new List < DataFormat > ( 19 )
343- {
344- new ( DataFormats . UnicodeText , NativeMethods . CF_UNICODETEXT ) ,
345- new ( DataFormats . Text , NativeMethods . CF_TEXT ) ,
346- new ( DataFormats . Bitmap , NativeMethods . CF_BITMAP ) ,
347- new ( DataFormats . MetafilePicture , NativeMethods . CF_METAFILEPICT ) ,
348- new ( DataFormats . EnhancedMetafile , NativeMethods . CF_ENHMETAFILE ) ,
349- new ( DataFormats . Dif , NativeMethods . CF_DIF ) ,
350- new ( DataFormats . Tiff , NativeMethods . CF_TIFF ) ,
351- new ( DataFormats . OemText , NativeMethods . CF_OEMTEXT ) ,
352- new ( DataFormats . Dib , NativeMethods . CF_DIB ) ,
353- new ( DataFormats . Palette , NativeMethods . CF_PALETTE ) ,
354- new ( DataFormats . PenData , NativeMethods . CF_PENDATA ) ,
355- new ( DataFormats . Riff , NativeMethods . CF_RIFF ) ,
356- new ( DataFormats . WaveAudio , NativeMethods . CF_WAVE ) ,
357- new ( DataFormats . SymbolicLink , NativeMethods . CF_SYLK ) ,
358- new ( DataFormats . FileDrop , NativeMethods . CF_HDROP ) ,
359- new ( DataFormats . Locale , NativeMethods . CF_LOCALE )
360- } ;
361-
362- int xamlFormatId = UnsafeNativeMethods . RegisterClipboardFormat ( DataFormats . Xaml ) ;
363- if ( xamlFormatId != 0 )
364- _formatList . Add ( new ( DataFormats . Xaml , xamlFormatId ) ) ;
365-
366- // This is the format to store trust boundary information. Essentially this is accompalished by storing
367- // the permission set of the source application where the content comes from. During paste we compare this to
368- // the permission set of the target application.
369- int applicationTrustFormatId = UnsafeNativeMethods . RegisterClipboardFormat ( DataFormats . ApplicationTrust ) ;
370- if ( applicationTrustFormatId != 0 )
371- _formatList . Add ( new ( DataFormats . ApplicationTrust , applicationTrustFormatId ) ) ;
372-
373- // RegisterClipboardFormat returns 0 on failure
374- int inkServicesFrameworkFormatId = UnsafeNativeMethods . RegisterClipboardFormat ( StrokeCollection . InkSerializedFormat ) ;
375- if ( inkServicesFrameworkFormatId != 0 )
376- _formatList . Add ( new ( StrokeCollection . InkSerializedFormat , inkServicesFrameworkFormatId ) ) ;
377- }
406+ #endregion Private Methods
378407
379- #endregion Private Methods
408+ //------------------------------------------------------
409+ //
410+ // Private Fields
411+ //
412+ //------------------------------------------------------
380413
381- //------------------------------------------------------
382- //
383- // Private Fields
384- //
385- //------------------------------------------------------
414+ #region Private Fields
386415
387- #region Private Fields
416+ // The registered data format list.
417+ private static readonly List < DataFormat > formatList ;
418+ // This object is for locking the _formatList to access safe in the multi-thread.
419+ private static readonly object _formatListlock = new ( ) ;
388420
389- // The registered data format list.
390- private static readonly List < DataFormat > _formatList ;
421+ #endregion Private Fields
422+
423+ }
391424
392- // This object is for locking the _formatList to access safe in the multi-thread.
393- private static readonly object _formatListlock = new ( ) ;
425+ #endregion Data Formats Implementation Class
394426
395- #endregion Private Fields
396427 }
397428
398429 #endregion DataFormats class
0 commit comments