|
//------------------------------------------------------------------------------
// <copyright file="Brush.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Drawing
{
using System.Runtime.InteropServices;
using System.Diagnostics;
using System;
using System.ComponentModel;
using Microsoft.Win32;
using System.Drawing;
using System.Drawing.Internal;
using System.Globalization;
/**
* Represent a Brush object
*/
/// <include file='doc\Brush.uex' path='docs/doc[@for="Brush"]/*' />
/// <devdoc>
/// <para>
/// Classes derrived from this abstract base class define objects used to fill the
/// interiors of graphical shapes such as rectangles, ellipses, pies, polygons, and paths.
/// </para>
/// </devdoc>
public abstract class Brush : MarshalByRefObject, ICloneable, IDisposable
{
#if FINALIZATION_WATCH
private string allocationSite = Graphics.GetAllocationStack();
#endif
// handle to native GDI+ brush object to be used on demand.
/// <include file='doc\Brush.uex' path='docs/doc[@for="Brush.nativeBrush;"]/*' />
private IntPtr nativeBrush;
/// <include file='doc\Brush.uex' path='docs/doc[@for="Brush.Clone"]/*' />
/// <devdoc>
/// When overriden in a derived class, creates
/// an exact copy of this <see cref='System.Drawing.Brush'/>.
/// </devdoc>
public abstract object Clone();
/// <devdoc>
/// Sets the native GDI+ brush reference.
/// Note: This method is intended to be used by derived classes only! (internal protected doesn't work as in C++).
/// </devdoc>
protected internal void SetNativeBrush(IntPtr brush)
{
IntSecurity.UnmanagedCode.Demand();
SetNativeBrushInternal(brush);
}
internal void SetNativeBrushInternal(IntPtr brush)
{
Debug.Assert( brush != IntPtr.Zero, "WARNING: Assigning null to the GDI+ native brush object.");
Debug.Assert( this.nativeBrush == IntPtr.Zero, "WARNING: Initialized GDI+ native brush object being assigned a new value.");
this.nativeBrush = brush;
}
/// <devdoc>
/// Gets the GDI+ native object reference. Triggers GDI+ obect initialization.
/// </devdoc>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
internal IntPtr NativeBrush
{
get
{
//Need to comment this line out to allow for checking this.NativePen == IntPtr.Zero.
//Debug.Assert(this.nativeBrush != IntPtr.Zero, "this.nativeBrush == null." );
return this.nativeBrush;
}
}
/// <include file='doc\Brush.uex' path='docs/doc[@for="Brush.Dispose"]/*' />
/// <devdoc>
/// <para>
/// Deletes this <see cref='System.Drawing.Brush'/>.
/// </para>
/// </devdoc>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <include file='doc\Brush.uex' path='docs/doc[@for="Brush.Dispose1"]/*' />
protected virtual void Dispose(bool disposing)
{
#if FINALIZATION_WATCH
if (!disposing && nativeBrush != IntPtr.Zero )
Debug.WriteLine("**********************\nDisposed through finalization:\n" + allocationSite);
#endif
if (this.nativeBrush != IntPtr.Zero) {
try{
#if DEBUG
int status =
#endif
SafeNativeMethods.Gdip.GdipDeleteBrush(new HandleRef(this, this.nativeBrush));
#if DEBUG
Debug.Assert(status == SafeNativeMethods.Gdip.Ok, "GDI+ returned an error status: " + status.ToString(CultureInfo.InvariantCulture));
#endif
}
catch( Exception ex ){
if( ClientUtils.IsSecurityOrCriticalException( ex ) ) {
throw;
}
Debug.Fail( "Exception thrown during Dispose: " + ex.ToString() );
}
finally{
this.nativeBrush = IntPtr.Zero;
}
}
}
/**
* Object cleanup
*/
/// <include file='doc\Brush.uex' path='docs/doc[@for="Brush.Finalize"]/*' />
/// <devdoc>
/// <para>
/// Releases memory allocated for this <see cref='System.Drawing.Brush'/>.
/// </para>
/// </devdoc>
~Brush()
{
Dispose(false);
}
}
}
|