Example #1
0
        /// <devdoc>
        ///     Saves the current state of the device context by copying data describing selected objects and graphic
        ///     modes (such as the bitmap, brush, palette, font, pen, region, drawing mode, and mapping mode) to a
        ///     context stack.
        ///     The SaveDC function can be used any number of times to save any number of instances of the DC state.
        ///     A saved state can be restored by using the RestoreHdc method.
        ///     See MSDN for more details.
        /// </devdoc>


        public int SaveHdc()
        {
            HandleRef hdc   = new HandleRef(this, this.Hdc);
            int       state = IntUnsafeNativeMethods.SaveDC(hdc);

            if (contextStack == null)
            {
                contextStack = new Stack();
            }

            GraphicsState g = new GraphicsState();

            g.hBitmap = hCurrentBmp;
            g.hBrush  = hCurrentBrush;
            g.hPen    = hCurrentPen;
            g.hFont   = hCurrentFont;

#if !DRAWING_NAMESPACE
            g.font = new WeakReference(selectedFont);
#endif


            contextStack.Push(g);

#if TRACK_HDC
            Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("state[0]=DC.SaveHdc(hDc=0x{1:x8})", state, unchecked ((int)this.hDC))));
#endif

            return(state);
        }
Example #2
0
        /// <summary>
        ///     Creates the font handle.
        /// </summary>


        private void CreateFont()
        {
            Debug.Assert(hFont == IntPtr.Zero, "hFont is not null, this will generate a handle leak.");
            Debug.Assert(logFont != null, "WindowsFont.logFont not initialized.");

            hFont = IntUnsafeNativeMethods.CreateFontIndirect(logFont);

#if TRACK_HFONT
            Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("HFONT[0x{0:x8}] = CreateFontIndirect( LOGFONT={1} )", (int)this.hFont, this.logFont)));
#endif
            if (hFont == IntPtr.Zero)
            {
                logFont.lfFaceName     = defaultFaceName;
                logFont.lfOutPrecision = IntNativeMethods.OUT_TT_ONLY_PRECIS; // True Type only.

                hFont = IntUnsafeNativeMethods.CreateFontIndirect(logFont);

#if TRACK_HFONT
                Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("HFONT[0x{0:x8}] = CreateFontIndirect( LOGFONT={1} )", (int)this.hFont, this.logFont)));
#endif
            }

            // Update logFont height and other adjusted parameters.
            //
            IntUnsafeNativeMethods.GetObject(new HandleRef(this, hFont), logFont);

            // We created the hFont, we will delete it on dispose.
            ownHandle = true;
        }
Example #3
0
        internal void Dispose(bool disposing)
        {
            bool deletedHandle = false;

            if (ownHandle)
            {
                if (!ownedByCacheManager || !disposing)
                {
                    // If we were ever owned by the CacheManger and we're being disposed
                    // we can be sure that we're not in use by any DC's (otherwise Dispose() wouldn't have been called)
                    // skip the check IsFontInUse check in this case.
                    // Also skip the check if disposing == false, because the cache is thread-static
                    // and that means we're being called from the finalizer.
                    if (everOwnedByCacheManager || !disposing || !DeviceContexts.IsFontInUse(this))
                    {
                        Debug.Assert(hFont != IntPtr.Zero, "Unexpected null hFont.");
                        DbgUtil.AssertFinalization(this, disposing);

                        IntUnsafeNativeMethods.DeleteObject(new HandleRef(this, hFont));
#if TRACK_HFONT
                        Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("DeleteObject(HFONT[0x{0:x8}]))", (int)this.hFont)));
#endif
                        hFont         = IntPtr.Zero;
                        ownHandle     = false;
                        deletedHandle = true;
                    }
                }
            }

            if (disposing && (deletedHandle || !ownHandle))
            {
                GC.SuppressFinalize(this);
            }
        }
        /// <devdoc>
        ///     Dispose of cached memory dc.
        /// </devdoc>
        public static void ResetMeasurementGraphics()
        {
            if (measurementGraphics != null)
            {
#if TRACK_HDC
                //Debug.WriteLine( DbgUtil.StackTraceToStr(string.Format("Disposing measurement DC and WG for thread: [0x{0:x8}]", Thread.CurrentThread.ManagedThreadId)));
                Debug.WriteLine(DbgUtil.StackTraceToStr("Disposing measurement DC and WG"));
#endif
                measurementGraphics.Dispose();
                measurementGraphics = null;
            }
        }
Example #5
0
        //
        // object construction API.  Publicly constructable from static methods only.
        //

        /// <devdoc>
        ///     Constructor to contruct a DeviceContext object from an window handle.
        /// </devdoc>
        private DeviceContext(IntPtr hWnd)
        {
            this.hWnd   = hWnd;
            this.dcType = DeviceContextType.Display;

            DeviceContexts.AddDeviceContext(this);

            // the hDc will be created on demand.

#if TRACK_HDC
            Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("DeviceContext( hWnd=0x{0:x8} )", unchecked ((int)hWnd))));
#endif
        }
Example #6
0
        /// <include file='doc\IDeviceContext.uex' path='docs/doc[@for="DeviceContext.ReleaseHdc"]/*' />
        ///<devdoc>
        ///     If the object was created from a DC, this object doesn't 'own' the dc so we just ignore
        ///     this call.
        ///</devdoc>
        void IDeviceContext.ReleaseHdc()
        {
            if (this.hDC != IntPtr.Zero && this.dcType == DeviceContextType.Display)
            {
#if TRACK_HDC
                int retVal =
#endif
                IntUnsafeNativeMethods.ReleaseDC(new HandleRef(this, this.hWnd), new HandleRef(this, this.hDC));
                // Note: retVal == 0 means it was not released but doesn't necessarily means an error; class or private DCs are never released.
#if TRACK_HDC
                Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("[ret={0}]=DC.ReleaseDC(hDc=0x{1:x8}, hWnd=0x{2:x8})", retVal, unchecked ((int)this.hDC), unchecked ((int)this.hWnd))));
#endif
                this.hDC = IntPtr.Zero;
            }
        }
Example #7
0
        /// <include file='doc\IDeviceContext.uex' path='docs/doc[@for="DeviceContext.GetHdc"]/*' />
        /// <devdoc>
        ///     Explicit interface method implementation to hide them a bit for usability reasons so the object is seen
        ///     as a wrapper around an hdc that is always available, and for performance reasons since it caches the hdc
        ///     if used in this way.
        /// </devdoc>


        IntPtr IDeviceContext.GetHdc()
        {
            if (this.hDC == IntPtr.Zero)
            {
                Debug.Assert(this.dcType == DeviceContextType.Display, "Calling GetDC from a non display/window device.");

                // Note: for common DCs, GetDC assigns default attributes to the DC each time it is retrieved.
                // For example, the default font is System.
                this.hDC = IntUnsafeNativeMethods.GetDC(new HandleRef(this, this.hWnd));
#if TRACK_HDC
                Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("hdc[0x{0:x8}]=DC.GetHdc(hWnd=0x{1:x8})", unchecked ((int)this.hDC), unchecked ((int)this.hWnd))));
#endif
            }

            return(this.hDC);
        }
Example #8
0
        /// <devdoc>
        ///     Constructor to contruct a DeviceContext object from an existing Win32 device context handle.
        /// </devdoc>


        private DeviceContext(IntPtr hDC, DeviceContextType dcType)
        {
            this.hDC    = hDC;
            this.dcType = dcType;

            CacheInitialState();
            DeviceContexts.AddDeviceContext(this);

            if (dcType == DeviceContextType.Display)
            {
                this.hWnd = IntUnsafeNativeMethods.WindowFromDC(new HandleRef(this, this.hDC));
            }
#if TRACK_HDC
            Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("DeviceContext( hDC=0x{0:X8}, Type={1} )", unchecked ((int)hDC), dcType)));
#endif
        }
Example #9
0
        /// <devdoc>
        ///     Restores the device context to the specified state. The DC is restored by popping state information off a
        ///     stack created by earlier calls to the SaveHdc function.
        ///     The stack can contain the state information for several instances of the DC. If the state specified by the
        ///     specified parameter is not at the top of the stack, RestoreDC deletes all state information between the top
        ///     of the stack and the specified instance.
        ///     Specifies the saved state to be restored. If this parameter is positive, nSavedDC represents a specific
        ///     instance of the state to be restored. If this parameter is negative, nSavedDC represents an instance relative
        ///     to the current state. For example, -1 restores the most recently saved state.
        ///     See MSDN for more info.
        /// </devdoc>
        public void RestoreHdc()
        {
#if TRACK_HDC
            bool result =
#endif
            // Note: Don't use the Hdc property here, it would force handle creation.
            IntUnsafeNativeMethods.RestoreDC(new HandleRef(this, this.hDC), -1);
#if TRACK_HDC
            // Note: Winforms may call this method during app exit at which point the DC may have been finalized already causing this assert to popup.
            Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("ret[0]=DC.RestoreHdc(hDc=0x{1:x8})", result, unchecked ((int)this.hDC))));
#endif
            Debug.Assert(contextStack != null, "Someone is calling RestoreHdc() before SaveHdc()");

            if (contextStack != null)
            {
                GraphicsState g = (GraphicsState)contextStack.Pop();

                hCurrentBmp   = g.hBitmap;
                hCurrentBrush = g.hBrush;
                hCurrentPen   = g.hPen;
                hCurrentFont  = g.hFont;

#if !DRAWING_NAMESPACE
                if (g.font != null && g.font.IsAlive)
                {
                    selectedFont = g.font.Target as WindowsFont;
                }
                else
                {
                    WindowsFont previousFont = selectedFont;
                    selectedFont = null;
                    if (previousFont != null && MeasurementDCInfo.IsMeasurementDC(this))
                    {
                        previousFont.Dispose();
                    }
                }
#endif
            }

#if OPTIMIZED_MEASUREMENTDC
            // in this case, GDI will copy back the previously saved font into the DC.
            // we dont actually know what the font is in our measurement DC so
            // we need to clear it off.
            MeasurementDCInfo.ResetIfIsMeasurementDC(this.hDC);
#endif
        }
Example #10
0
        /// <include file='doc\IDeviceContext.uex' path='docs/doc[@for="DeviceContext.Dispose1"]/*' />
        internal void Dispose(bool disposing)
        {
            if (disposed)
            {
                return;
            }

            if (this.Disposing != null)
            {
                this.Disposing(this, EventArgs.Empty);
            }

            this.disposed = true;

#if !DRAWING_NAMESPACE
            DisposeFont(disposing);
#endif

            switch (this.dcType)
            {
            case DeviceContextType.Display:
                Debug.Assert(disposing, "WARNING: Finalizing a Display DeviceContext.\r\nReleaseDC may fail when not called from the same thread GetDC was called from.");

                ((IDeviceContext)this).ReleaseHdc();
                break;

            case DeviceContextType.Information:
            case DeviceContextType.NamedDevice:

                // CreateDC and CreateIC add an HDC handle to the HandleCollector; to remove it properly we need
                // to call DeleteHDC.
#if TRACK_HDC
                Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("DC.DeleteHDC(hdc=0x{0:x8})", unchecked ((int)this.hDC))));
#endif

                IntUnsafeNativeMethods.DeleteHDC(new HandleRef(this, this.hDC));

                this.hDC = IntPtr.Zero;
                break;

            case DeviceContextType.Memory:

                // CreatCompatibleDC adds a GDI handle to HandleCollector, to remove it properly we need to call
                // DeleteDC.
#if TRACK_HDC
                Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("DC.DeleteDC(hdc=0x{0:x8})", unchecked ((int)this.hDC))));
#endif
                IntUnsafeNativeMethods.DeleteDC(new HandleRef(this, this.hDC));

                this.hDC = IntPtr.Zero;
                break;

                // case DeviceContextType.Metafile: - not yet supported.
#if WINFORMS_PUBLIC_GRAPHICS_LIBRARY
            case DeviceContextType.Metafile:
                IntUnsafeNativeMethods.CloseEnhMetaFile(new HandleRef(this, this.Hdc));

                this.hDC = IntPtr.Zero;
                break;
#endif
            case DeviceContextType.Unknown:
            default:
                return;
                // do nothing, the hdc is not owned by this object.
                // in this case it is ok if disposed throught finalization.
            }

            DbgUtil.AssertFinalization(this, disposing);
        }