Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Misc / GDI / WindowsGraphics.cs / 1305376 / WindowsGraphics.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- //#define GDI_FINALIZATION_WATCH // THIS PARTIAL CLASS CONTAINS THE BASE METHODS FOR CREATING AND DISPOSING A WINDOWSGRAPHICS AS WELL // GETTING, DISPOSING AND WORKING WITH A DC. #if [....]_NAMESPACE namespace System.Windows.Forms.Internal #elif DRAWING_NAMESPACE namespace System.Drawing.Internal #else namespace System.Experimental.Gdi #endif { using System; using System.Internal; using System.Runtime.InteropServices; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Drawing.Drawing2D; using System.Runtime.Versioning; ////// /// WindowsGraphics is a library for rendering text and drawing using GDI; it was /// created to address performance and compatibility issues found in GDI+ Graphics /// class. /// /// Note: WindowsGraphics is a stateful component, DC properties are persisted from /// method calls, as opposed to Graphics (GDI+) which performs attomic operations and /// always restores the hdc. /// The underlying hdc is always saved and restored on dispose so external HDCs won't /// be modified by WindowsGraphics. So we don't need to restore previous objects into /// the dc in method calls. /// See VSWhidbey 300692 & 445469 for some background. /// #if [....]_PUBLIC_GRAPHICS_LIBRARY public #else internal #endif sealed partial class WindowsGraphics : MarshalByRefObject, IDisposable, IDeviceContext { // Wrapper around the window dc this object refers to. // Note: this dc is only disposed when owned (created) by the WindowsGraphics. DeviceContext dc; bool disposeDc; Graphics graphics; // cached when initialized FromGraphics to be able to call g.ReleaseHdc from Dispose. #if GDI_FINALIZATION_WATCH private string AllocationSite = DbgUtil.StackTrace; #endif // Construction/destruction API ///public WindowsGraphics( DeviceContext dc ) { Debug.Assert( dc != null, "null dc!"); this.dc = dc; this.dc.SaveHdc(); //this.disposeDc = false; // the dc is not owned by this object. } /// /// Creates a WindowsGraphics from a memory DeviceContext object compatible with the primary screen device. /// This object is suitable for performing text measuring but not for drawing into it because it does /// not have a backup bitmap. /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public static WindowsGraphics CreateMeasurementWindowsGraphics() { DeviceContext dc = DeviceContext.FromCompatibleDC(IntPtr.Zero); WindowsGraphics wg = new WindowsGraphics(dc); wg.disposeDc = true; // we create it, we dispose it. return wg; } ///public static WindowsGraphics FromHwnd(IntPtr hWnd) { DeviceContext dc = DeviceContext.FromHwnd( hWnd ); WindowsGraphics wg = new WindowsGraphics( dc ); wg.disposeDc = true; // we create it, we dispose it. return wg; } /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public static WindowsGraphics FromHdc(IntPtr hDc) { Debug.Assert( hDc != IntPtr.Zero, "null hDc" ); DeviceContext dc = DeviceContext.FromHdc(hDc); WindowsGraphics wg = new WindowsGraphics( dc ); wg.disposeDc = true; // we create it, we dispose it. return wg; } /// /// Creates a WindowsGraphics object from a Graphics object. Clipping and coordinate transforms /// are preserved. /// /// Notes: /// - The passed Graphics object cannot be used until the WindowsGraphics is disposed /// since it borrows the hdc from the Graphics object locking it. /// - Changes to the hdc using the WindowsGraphics object are not preserved into the Graphics object; /// the hdc is returned to the Graphics object intact. /// /// Some background about how Graphics uses the internal hdc when created from an existing one /// (mail from GillesK from GDI+ team): /// User has an HDC with a particular state: /// Graphics object gets created based on that HDC. We query the HDC for its state and apply it to the Graphics. /// At this stage, we do a SaveHDC and clear everything out of it. /// User calls GetHdc. We restore the HDC to the state it was in and give it to the user. /// User calls ReleaseHdc, we save the current state of the HDC and clear everything /// (so that the graphics state gets applied next time we use it). /// Next time the user calls GetHdc we give him back the state after the second ReleaseHdc. /// (But the state changes between the GetHdc and ReleaseHdc are not applied to the Graphics). /// Please note that this only applies the HDC created graphics, for Bitmap derived graphics, GetHdc creates a new DIBSection and /// things get a lot more complicated. /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public static WindowsGraphics FromGraphics(Graphics g) { ApplyGraphicsProperties properties = ApplyGraphicsProperties.All; return WindowsGraphics.FromGraphics(g, properties); } [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public static WindowsGraphics FromGraphics(Graphics g, ApplyGraphicsProperties properties) { Debug.Assert( g != null, "null Graphics object." ); //Debug.Assert( properties != ApplyGraphicsProperties.None, "Consider using other WindowsGraphics constructor if not preserving Graphics properties." ); WindowsRegion wr = null; float[] elements = null; Region clipRgn = null; Matrix worldTransf = null; if ((properties & ApplyGraphicsProperties.TranslateTransform) != 0 || (properties & ApplyGraphicsProperties.Clipping) != 0) { object[] data = g.GetContextInfo() as object[]; if( data != null && data.Length == 2 ) { clipRgn = data[0] as Region; worldTransf = data[1] as Matrix; } if( worldTransf != null ) { if ((properties & ApplyGraphicsProperties.TranslateTransform) != 0) { elements = worldTransf.Elements; } worldTransf.Dispose(); } if( clipRgn != null ) { if ((properties & ApplyGraphicsProperties.Clipping) != 0) { // We have to create the WindowsRegion and dipose the Region object before locking the Graphics object, // in case of an unlikely exception before releasing the WindowsRegion, the finalizer will do it for us. // (no try-finally block since this method is used frequently - perf). // See VSWhidbey#383762 // If the Graphics.Clip has not been set (Region.IsInfinite) we don't need to apply it to the DC. if (!clipRgn.IsInfinite(g)) { wr = WindowsRegion.FromRegion(clipRgn, g); // WindowsRegion will take ownership of the hRegion. } } clipRgn.Dispose(); // Disposing the Region object doesn't destroy the hRegion. } } WindowsGraphics wg = WindowsGraphics.FromHdc( g.GetHdc() ); // This locks the Graphics object. wg.graphics = g; // Apply transform and clip if (wr != null) { using (wr) { // If the Graphics object was created from a native DC the actual clipping region is the intersection // beteween the original DC clip region and the GDI+ one - for display Graphics it is the same as // Graphics.VisibleClipBounds. See VSW#490404. wg.DeviceContext.IntersectClip(wr); } } if (elements != null) { // elements (XFORM) = [eM11, eM12, eM21, eM22, eDx, eDy], eDx/eDy specify the translation offset. wg.DeviceContext.TranslateTransform((int)elements[4], (int)elements[5]); } return wg; } ///~WindowsGraphics() { Dispose(false); } public DeviceContext DeviceContext { [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")] get { return this.dc; } } /// // Okay to suppress. From [....]: //"WindowsGraphics object does not own the Graphics object. For instance in a control’s Paint event we pass the //GraphicsContainer object to TextRenderer, which uses WindowsGraphics; //if the Graphics object is disposed then further painting will be broken." [SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed")] public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } [SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed")] [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] internal void Dispose(bool disposing) { if (this.dc != null ) { DbgUtil.AssertFinalization(this, disposing); try { // Restore original dc. this.dc.RestoreHdc(); if( this.disposeDc) { this.dc.Dispose(disposing); } if( this.graphics != null ) // if created from a Graphics object... { this.graphics.ReleaseHdcInternal(this.dc.Hdc); this.graphics = null; } } catch(Exception ex ) { if( ClientUtils.IsSecurityOrCriticalException( ex ) ) { throw; // rethrow the original exception. } Debug.Fail("Exception thrown during disposing: \r\n" + ex.ToString()); } finally { this.dc = null; } } } /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public IntPtr GetHdc() { return this.dc.Hdc; } /// public void ReleaseHdc() { this.dc.Dispose(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- //#define GDI_FINALIZATION_WATCH // THIS PARTIAL CLASS CONTAINS THE BASE METHODS FOR CREATING AND DISPOSING A WINDOWSGRAPHICS AS WELL // GETTING, DISPOSING AND WORKING WITH A DC. #if [....]_NAMESPACE namespace System.Windows.Forms.Internal #elif DRAWING_NAMESPACE namespace System.Drawing.Internal #else namespace System.Experimental.Gdi #endif { using System; using System.Internal; using System.Runtime.InteropServices; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Drawing.Drawing2D; using System.Runtime.Versioning; ////// /// WindowsGraphics is a library for rendering text and drawing using GDI; it was /// created to address performance and compatibility issues found in GDI+ Graphics /// class. /// /// Note: WindowsGraphics is a stateful component, DC properties are persisted from /// method calls, as opposed to Graphics (GDI+) which performs attomic operations and /// always restores the hdc. /// The underlying hdc is always saved and restored on dispose so external HDCs won't /// be modified by WindowsGraphics. So we don't need to restore previous objects into /// the dc in method calls. /// See VSWhidbey 300692 & 445469 for some background. /// #if [....]_PUBLIC_GRAPHICS_LIBRARY public #else internal #endif sealed partial class WindowsGraphics : MarshalByRefObject, IDisposable, IDeviceContext { // Wrapper around the window dc this object refers to. // Note: this dc is only disposed when owned (created) by the WindowsGraphics. DeviceContext dc; bool disposeDc; Graphics graphics; // cached when initialized FromGraphics to be able to call g.ReleaseHdc from Dispose. #if GDI_FINALIZATION_WATCH private string AllocationSite = DbgUtil.StackTrace; #endif // Construction/destruction API ///public WindowsGraphics( DeviceContext dc ) { Debug.Assert( dc != null, "null dc!"); this.dc = dc; this.dc.SaveHdc(); //this.disposeDc = false; // the dc is not owned by this object. } /// /// Creates a WindowsGraphics from a memory DeviceContext object compatible with the primary screen device. /// This object is suitable for performing text measuring but not for drawing into it because it does /// not have a backup bitmap. /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public static WindowsGraphics CreateMeasurementWindowsGraphics() { DeviceContext dc = DeviceContext.FromCompatibleDC(IntPtr.Zero); WindowsGraphics wg = new WindowsGraphics(dc); wg.disposeDc = true; // we create it, we dispose it. return wg; } ///public static WindowsGraphics FromHwnd(IntPtr hWnd) { DeviceContext dc = DeviceContext.FromHwnd( hWnd ); WindowsGraphics wg = new WindowsGraphics( dc ); wg.disposeDc = true; // we create it, we dispose it. return wg; } /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public static WindowsGraphics FromHdc(IntPtr hDc) { Debug.Assert( hDc != IntPtr.Zero, "null hDc" ); DeviceContext dc = DeviceContext.FromHdc(hDc); WindowsGraphics wg = new WindowsGraphics( dc ); wg.disposeDc = true; // we create it, we dispose it. return wg; } /// /// Creates a WindowsGraphics object from a Graphics object. Clipping and coordinate transforms /// are preserved. /// /// Notes: /// - The passed Graphics object cannot be used until the WindowsGraphics is disposed /// since it borrows the hdc from the Graphics object locking it. /// - Changes to the hdc using the WindowsGraphics object are not preserved into the Graphics object; /// the hdc is returned to the Graphics object intact. /// /// Some background about how Graphics uses the internal hdc when created from an existing one /// (mail from GillesK from GDI+ team): /// User has an HDC with a particular state: /// Graphics object gets created based on that HDC. We query the HDC for its state and apply it to the Graphics. /// At this stage, we do a SaveHDC and clear everything out of it. /// User calls GetHdc. We restore the HDC to the state it was in and give it to the user. /// User calls ReleaseHdc, we save the current state of the HDC and clear everything /// (so that the graphics state gets applied next time we use it). /// Next time the user calls GetHdc we give him back the state after the second ReleaseHdc. /// (But the state changes between the GetHdc and ReleaseHdc are not applied to the Graphics). /// Please note that this only applies the HDC created graphics, for Bitmap derived graphics, GetHdc creates a new DIBSection and /// things get a lot more complicated. /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public static WindowsGraphics FromGraphics(Graphics g) { ApplyGraphicsProperties properties = ApplyGraphicsProperties.All; return WindowsGraphics.FromGraphics(g, properties); } [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public static WindowsGraphics FromGraphics(Graphics g, ApplyGraphicsProperties properties) { Debug.Assert( g != null, "null Graphics object." ); //Debug.Assert( properties != ApplyGraphicsProperties.None, "Consider using other WindowsGraphics constructor if not preserving Graphics properties." ); WindowsRegion wr = null; float[] elements = null; Region clipRgn = null; Matrix worldTransf = null; if ((properties & ApplyGraphicsProperties.TranslateTransform) != 0 || (properties & ApplyGraphicsProperties.Clipping) != 0) { object[] data = g.GetContextInfo() as object[]; if( data != null && data.Length == 2 ) { clipRgn = data[0] as Region; worldTransf = data[1] as Matrix; } if( worldTransf != null ) { if ((properties & ApplyGraphicsProperties.TranslateTransform) != 0) { elements = worldTransf.Elements; } worldTransf.Dispose(); } if( clipRgn != null ) { if ((properties & ApplyGraphicsProperties.Clipping) != 0) { // We have to create the WindowsRegion and dipose the Region object before locking the Graphics object, // in case of an unlikely exception before releasing the WindowsRegion, the finalizer will do it for us. // (no try-finally block since this method is used frequently - perf). // See VSWhidbey#383762 // If the Graphics.Clip has not been set (Region.IsInfinite) we don't need to apply it to the DC. if (!clipRgn.IsInfinite(g)) { wr = WindowsRegion.FromRegion(clipRgn, g); // WindowsRegion will take ownership of the hRegion. } } clipRgn.Dispose(); // Disposing the Region object doesn't destroy the hRegion. } } WindowsGraphics wg = WindowsGraphics.FromHdc( g.GetHdc() ); // This locks the Graphics object. wg.graphics = g; // Apply transform and clip if (wr != null) { using (wr) { // If the Graphics object was created from a native DC the actual clipping region is the intersection // beteween the original DC clip region and the GDI+ one - for display Graphics it is the same as // Graphics.VisibleClipBounds. See VSW#490404. wg.DeviceContext.IntersectClip(wr); } } if (elements != null) { // elements (XFORM) = [eM11, eM12, eM21, eM22, eDx, eDy], eDx/eDy specify the translation offset. wg.DeviceContext.TranslateTransform((int)elements[4], (int)elements[5]); } return wg; } ///~WindowsGraphics() { Dispose(false); } public DeviceContext DeviceContext { [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")] get { return this.dc; } } /// // Okay to suppress. From [....]: //"WindowsGraphics object does not own the Graphics object. For instance in a control’s Paint event we pass the //GraphicsContainer object to TextRenderer, which uses WindowsGraphics; //if the Graphics object is disposed then further painting will be broken." [SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed")] public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } [SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed")] [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] internal void Dispose(bool disposing) { if (this.dc != null ) { DbgUtil.AssertFinalization(this, disposing); try { // Restore original dc. this.dc.RestoreHdc(); if( this.disposeDc) { this.dc.Dispose(disposing); } if( this.graphics != null ) // if created from a Graphics object... { this.graphics.ReleaseHdcInternal(this.dc.Hdc); this.graphics = null; } } catch(Exception ex ) { if( ClientUtils.IsSecurityOrCriticalException( ex ) ) { throw; // rethrow the original exception. } Debug.Fail("Exception thrown during disposing: \r\n" + ex.ToString()); } finally { this.dc = null; } } } /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public IntPtr GetHdc() { return this.dc.Hdc; } /// public void ReleaseHdc() { this.dc.Dispose(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- securitycriticaldataformultiplegetandset.cs
- WorkflowMarkupElementEventArgs.cs
- SafeNativeMethods.cs
- ColorConvertedBitmap.cs
- CompilationLock.cs
- Identifier.cs
- ErrorEventArgs.cs
- ResourcePool.cs
- DataKey.cs
- AttributeCollection.cs
- DataGridCell.cs
- WebEncodingValidatorAttribute.cs
- TcpSocketManager.cs
- pingexception.cs
- ReferencedAssembly.cs
- UnauthorizedWebPart.cs
- FlowDocumentView.cs
- DoubleStorage.cs
- SecurityDocument.cs
- PreviewPrintController.cs
- BinaryVersion.cs
- ProtocolViolationException.cs
- CollectionType.cs
- NTAccount.cs
- TemplateControl.cs
- AliasGenerator.cs
- SelectionProviderWrapper.cs
- ProcessModelInfo.cs
- PEFileReader.cs
- Application.cs
- ScriptManager.cs
- XPathQilFactory.cs
- XPathParser.cs
- TraceShell.cs
- XamlGridLengthSerializer.cs
- InheritablePropertyChangeInfo.cs
- WindowsImpersonationContext.cs
- MenuItem.cs
- DesignerVerbCollection.cs
- Brushes.cs
- XmlSchemaAnnotation.cs
- NonSerializedAttribute.cs
- SamlAssertionKeyIdentifierClause.cs
- DataControlField.cs
- DecoderReplacementFallback.cs
- StringInfo.cs
- XmlSchemaType.cs
- ImmutableCollection.cs
- UserControlBuildProvider.cs
- StorageEntityContainerMapping.cs
- _LazyAsyncResult.cs
- DataTable.cs
- AssociativeAggregationOperator.cs
- DataSourceControl.cs
- BrushMappingModeValidation.cs
- PrimitiveSchema.cs
- ExpressionNode.cs
- HtmlFormWrapper.cs
- QueryValue.cs
- TypeDescriptionProviderAttribute.cs
- ManipulationVelocities.cs
- Control.cs
- PropagatorResult.cs
- _ScatterGatherBuffers.cs
- MailMessage.cs
- GridViewRow.cs
- CustomBindingElementCollection.cs
- CompiledQuery.cs
- DataGridViewRowPostPaintEventArgs.cs
- ScriptHandlerFactory.cs
- XmlSchemaSimpleTypeUnion.cs
- xmlsaver.cs
- RsaSecurityToken.cs
- GeometryGroup.cs
- CaseInsensitiveHashCodeProvider.cs
- CustomErrorsSectionWrapper.cs
- ImmComposition.cs
- RC2CryptoServiceProvider.cs
- TextFormatterHost.cs
- _FtpControlStream.cs
- TcpConnectionPoolSettingsElement.cs
- MarkerProperties.cs
- DivideByZeroException.cs
- SafeNativeMethods.cs
- SessionEndedEventArgs.cs
- shaperfactoryquerycachekey.cs
- NotifyInputEventArgs.cs
- IDReferencePropertyAttribute.cs
- DataListItemEventArgs.cs
- DesignerTransaction.cs
- DesignBindingConverter.cs
- WindowsBrush.cs
- COM2PropertyDescriptor.cs
- DataControlFieldCollection.cs
- DataListGeneralPage.cs
- NamespaceQuery.cs
- DataGridViewRowConverter.cs
- CompositeScriptReference.cs
- SerializationSectionGroup.cs
- PaperSource.cs