///<summary> /// Creates a new clipping region from the intersection of the current clipping region and the specified rectangle. ///</summary> public void IntersectClip(WindowsRegion wr) { //if the incoming windowsregion is infinite, there is no need to do any intersecting. if (wr.HRegion == IntPtr.Zero) { return; } WindowsRegion clip = new WindowsRegion(0, 0, 0, 0); try { int result = IntUnsafeNativeMethods.GetClipRgn(new HandleRef(this, _hDC), new HandleRef(clip, clip.HRegion)); // If the function succeeds and there is a clipping region for the given device context, the return value is 1. if (result == 1) { Debug.Assert(clip.HRegion != IntPtr.Zero); wr.CombineRegion(clip, wr, RegionCombineMode.AND); //1 = AND (or Intersect) } SetClip(wr); } finally { clip.Dispose(); } }
internal void Dispose(bool disposing) { if (!this.disposed) { if (this.Disposing != null) { this.Disposing(this, EventArgs.Empty); } this.disposed = true; switch (this.dcType) { case System.Drawing.Internal.DeviceContextType.Unknown: case System.Drawing.Internal.DeviceContextType.NCWindow: return; case System.Drawing.Internal.DeviceContextType.Display: ((IDeviceContext)this).ReleaseHdc(); return; case System.Drawing.Internal.DeviceContextType.NamedDevice: case System.Drawing.Internal.DeviceContextType.Information: IntUnsafeNativeMethods.DeleteHDC(new HandleRef(this, this.hDC)); this.hDC = IntPtr.Zero; return; case System.Drawing.Internal.DeviceContextType.Memory: IntUnsafeNativeMethods.DeleteDC(new HandleRef(this, this.hDC)); this.hDC = IntPtr.Zero; return; } } }
/// <summary> /// Selects a region as the current clipping region for the device context. /// Remarks (From MSDN): /// - Only a copy of the selected region is used. The region itself can be selected for any number of other device contexts or it can be deleted. /// - The SelectClipRgn function assumes that the coordinates for a region are specified in device units. /// - To remove a device-context's clipping region, specify a NULL region handle. /// </summary> public void SetClip(WindowsRegion region) { HandleRef hdc = new HandleRef(this, _hDC); HandleRef hRegion = new HandleRef(region, region.HRegion); IntUnsafeNativeMethods.SelectClipRgn(hdc, hRegion); }
private void CacheInitialState() { this.hCurrentPen = this.hInitialPen = IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(this, this.hDC), 1); this.hCurrentBrush = this.hInitialBrush = IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(this, this.hDC), 2); this.hCurrentBmp = this.hInitialBmp = IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(this, this.hDC), 7); this.hCurrentFont = this.hInitialFont = IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(this, this.hDC), 6); }
/// <summary> /// 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. /// </summary> 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, _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}, state={2})", result, unchecked ((int)_hDC), restoreState))); #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 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(_hDC); #endif }
public void SetClip(WindowsRegion region) { HandleRef hDC = new HandleRef(this, this.Hdc); HandleRef hRgn = new HandleRef(region, region.HRegion); IntUnsafeNativeMethods.SelectClipRgn(hDC, hRgn); }
public void DeleteObject(IntPtr handle, GdiObjectType type) { IntPtr zero = IntPtr.Zero; switch (type) { case GdiObjectType.Pen: if (handle == this.hCurrentPen) { IntUnsafeNativeMethods.SelectObject(new HandleRef(this, this.Hdc), new HandleRef(this, this.hInitialPen)); this.hCurrentPen = IntPtr.Zero; } zero = handle; break; case GdiObjectType.Brush: if (handle == this.hCurrentBrush) { IntUnsafeNativeMethods.SelectObject(new HandleRef(this, this.Hdc), new HandleRef(this, this.hInitialBrush)); this.hCurrentBrush = IntPtr.Zero; } zero = handle; break; case GdiObjectType.Bitmap: if (handle == this.hCurrentBmp) { IntUnsafeNativeMethods.SelectObject(new HandleRef(this, this.Hdc), new HandleRef(this, this.hInitialBmp)); this.hCurrentBmp = IntPtr.Zero; } zero = handle; break; } IntUnsafeNativeMethods.DeleteObject(new HandleRef(this, zero)); }
/// <summary> /// 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. /// </summary> public int SaveHdc() { HandleRef hdc = new HandleRef(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; _contextStack.Push(g); #if TRACK_HDC Debug.WriteLine(DbgUtil.StackTraceToStr(String.Format("state[0]=DC.SaveHdc(hDc=0x{1:x8})", state, unchecked ((int)_hDC)))); #endif return(state); }
IntPtr IDeviceContext.GetHdc() { if (this.hDC == IntPtr.Zero) { this.hDC = IntUnsafeNativeMethods.GetDC(new HandleRef(this, this.hWnd)); } return(this.hDC); }
void IDeviceContext.ReleaseHdc() { if ((this.hDC != IntPtr.Zero) && (this.dcType == System.Drawing.Internal.DeviceContextType.Display)) { IntUnsafeNativeMethods.ReleaseDC(new HandleRef(this, this.hWnd), new HandleRef(this, this.hDC)); this.hDC = IntPtr.Zero; } }
/// <summary> /// CreateIC creates a DeviceContext object wrapping an hdc created with the Win32 CreateIC function. /// </summary> public static DeviceContext CreateIC(string driverName, string deviceName, string fileName, HandleRef devMode) { // Note: All input params can be null but not at the same time. See MSDN for information. IntPtr hdc = IntUnsafeNativeMethods.CreateIC(driverName, deviceName, fileName, devMode); return(new DeviceContext(hdc, DeviceContextType.Information)); }
// Due to a problem with calling DeleteObject() on currently selected GDI objects, we now track the initial set // of objects when a DeviceContext is created. Then, we also track which objects are currently selected in the // DeviceContext. When a currently selected object is disposed, it is first replaced in the DC and then deleted. private void CacheInitialState() { Debug.Assert(_hDC != IntPtr.Zero, "Cannot get initial state without a valid HDC"); _hCurrentPen = _hInitialPen = IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(this, _hDC), IntNativeMethods.OBJ_PEN); _hCurrentBrush = _hInitialBrush = IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(this, _hDC), IntNativeMethods.OBJ_BRUSH); _hCurrentBmp = _hInitialBmp = IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(this, _hDC), IntNativeMethods.OBJ_BITMAP); _hCurrentFont = _hInitialFont = IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(this, _hDC), IntNativeMethods.OBJ_FONT); }
/// <include file='doc\IDeviceContext.uex' path='docs/doc[@for="DeviceContext.Dispose1"]/*' /> internal void Dispose(bool disposing) { if (_disposed) { return; } if (Disposing != null) { Disposing(this, EventArgs.Empty); } _disposed = true; switch (_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)_hDC)))); #endif IntUnsafeNativeMethods.DeleteHDC(new HandleRef(this, _hDC)); _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)_hDC)))); #endif IntUnsafeNativeMethods.DeleteDC(new HandleRef(this, _hDC)); _hDC = IntPtr.Zero; break; // case DeviceContextType.Metafile: - not yet supported. 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); }
public Rectangle ToRectangle() { if (this.IsInfinite) { return(new Rectangle(-2147483647, -2147483647, 0x7fffffff, 0x7fffffff)); } IntNativeMethods.RECT clipRect = new IntNativeMethods.RECT(); IntUnsafeNativeMethods.GetRgnBox(new HandleRef(this, this.nativeHandle), ref clipRect); return(new Rectangle(new Point(clipRect.left, clipRect.top), clipRect.Size)); }
/// <devdoc> /// A rectangle representing the window region set with the SetWindowRgn function. /// </devdoc> public Rectangle ToRectangle() { if (IsInfinite) { return(new Rectangle(-Int32.MaxValue, -Int32.MaxValue, Int32.MaxValue, Int32.MaxValue)); } IntNativeMethods.RECT rect = new IntNativeMethods.RECT(); IntUnsafeNativeMethods.GetRgnBox(new HandleRef(this, _nativeHandle), ref rect); return(new Rectangle(new Point(rect.left, rect.top), rect.Size)); }
/// <summary> /// Creates a DeviceContext object wrapping a memory DC compatible with the specified device. /// </summary> public static DeviceContext FromCompatibleDC(IntPtr hdc) { // If hdc is null, the function creates a memory DC compatible with the application's current screen. // Win2K+: (See CreateCompatibleDC in the MSDN). // In this case the thread that calls CreateCompatibleDC owns the HDC that is created. When this thread is destroyed, // the HDC is no longer valid. IntPtr compatibleDc = IntUnsafeNativeMethods.CreateCompatibleDC(new HandleRef(null, hdc)); return(new DeviceContext(compatibleDc, DeviceContextType.Memory)); }
public void RestoreHdc() { IntUnsafeNativeMethods.RestoreDC(new HandleRef(this, this.hDC), -1); if (this.contextStack != null) { GraphicsState state = (GraphicsState)this.contextStack.Pop(); this.hCurrentBmp = state.hBitmap; this.hCurrentBrush = state.hBrush; this.hCurrentPen = state.hPen; this.hCurrentFont = state.hFont; } }
private DeviceContext(IntPtr hDC, System.Drawing.Internal.DeviceContextType dcType) { this.hWnd = (IntPtr)(-1); this.hDC = hDC; this.dcType = dcType; this.CacheInitialState(); DeviceContexts.AddDeviceContext(this); if (dcType == System.Drawing.Internal.DeviceContextType.Display) { this.hWnd = IntUnsafeNativeMethods.WindowFromDC(new HandleRef(this, this.hDC)); } }
public void IntersectClip(WindowsRegion wr) { if (wr.HRegion != IntPtr.Zero) { using (WindowsRegion region = new WindowsRegion(0, 0, 0, 0)) { if (IntUnsafeNativeMethods.GetClipRgn(new HandleRef(this, this.Hdc), new HandleRef(region, region.HRegion)) == 1) { wr.CombineRegion(region, wr, RegionCombineMode.AND); } this.SetClip(wr); } } }
public void Dispose(bool disposing) { if (this.nativeHandle != IntPtr.Zero) { if (this.ownHandle) { IntUnsafeNativeMethods.DeleteObject(new HandleRef(this, this.nativeHandle)); } this.nativeHandle = IntPtr.Zero; if (disposing) { GC.SuppressFinalize(this); } } }
///<summary> /// If the object was created from a DC, this object doesn't 'own' the dc so we just ignore this call. ///</summary> void IDeviceContext.ReleaseHdc() { if (_hDC != IntPtr.Zero && _dcType == DeviceContextType.Display) { #if TRACK_HDC int retVal = #endif IntUnsafeNativeMethods.ReleaseDC(new HandleRef(this, _hWnd), new HandleRef(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)_hDC), unchecked ((int)_hWnd)))); #endif _hDC = IntPtr.Zero; } }
/// <summary> /// Constructor to construct a DeviceContext object from an existing Win32 device context handle. /// </summary> private DeviceContext(IntPtr hDC, DeviceContextType dcType) { _hDC = hDC; _dcType = dcType; CacheInitialState(); DeviceContexts.AddDeviceContext(this); if (dcType == DeviceContextType.Display) { _hWnd = IntUnsafeNativeMethods.WindowFromDC(new HandleRef(this, _hDC)); } #if TRACK_HDC Debug.WriteLine(DbgUtil.StackTraceToStr(string.Format("DeviceContext( hDC=0x{0:X8}, Type={1} )", unchecked ((int)hDC), dcType))); #endif }
/// <summary> /// 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. /// </summary> IntPtr IDeviceContext.GetHdc() { if (_hDC == IntPtr.Zero) { Debug.Assert(_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. _hDC = IntUnsafeNativeMethods.GetDC(new HandleRef(this, _hWnd)); #if TRACK_HDC Debug.WriteLine(DbgUtil.StackTraceToStr(string.Format("hdc[0x{0:x8}]=DC.GetHdc(hWnd=0x{1:x8})", unchecked ((int)_hDC), unchecked ((int)_hWnd)))); #endif } return(_hDC); }
public void Dispose(bool disposing) { if (_nativeHandle != IntPtr.Zero) { DbgUtil.AssertFinalization(this, disposing); if (_ownHandle) { IntUnsafeNativeMethods.DeleteObject(new HandleRef(this, _nativeHandle)); } _nativeHandle = IntPtr.Zero; if (disposing) { GC.SuppressFinalize(this); } } }
public int SaveHdc() { HandleRef hDC = new HandleRef(this, this.Hdc); int num = IntUnsafeNativeMethods.SaveDC(hDC); if (this.contextStack == null) { this.contextStack = new Stack(); } GraphicsState state = new GraphicsState { hBitmap = this.hCurrentBmp, hBrush = this.hCurrentBrush, hPen = this.hCurrentPen, hFont = this.hCurrentFont }; this.contextStack.Push(state); return(num); }
public static int GetTextMetrics(HandleRef hDC, ref IntNativeMethods.TEXTMETRIC lptm) { int retVal; if (Marshal.SystemDefaultCharSize == 1) { // ANSI IntNativeMethods.TEXTMETRICA lptmA = new IntNativeMethods.TEXTMETRICA(); retVal = IntUnsafeNativeMethods.GetTextMetricsA(hDC, ref lptmA); lptm.tmHeight = lptmA.tmHeight; lptm.tmAscent = lptmA.tmAscent; lptm.tmDescent = lptmA.tmDescent; lptm.tmInternalLeading = lptmA.tmInternalLeading; lptm.tmExternalLeading = lptmA.tmExternalLeading; lptm.tmAveCharWidth = lptmA.tmAveCharWidth; lptm.tmMaxCharWidth = lptmA.tmMaxCharWidth; lptm.tmWeight = lptmA.tmWeight; lptm.tmOverhang = lptmA.tmOverhang; lptm.tmDigitizedAspectX = lptmA.tmDigitizedAspectX; lptm.tmDigitizedAspectY = lptmA.tmDigitizedAspectY; lptm.tmFirstChar = (char)lptmA.tmFirstChar; lptm.tmLastChar = (char)lptmA.tmLastChar; lptm.tmDefaultChar = (char)lptmA.tmDefaultChar; lptm.tmBreakChar = (char)lptmA.tmBreakChar; lptm.tmItalic = lptmA.tmItalic; lptm.tmUnderlined = lptmA.tmUnderlined; lptm.tmStruckOut = lptmA.tmStruckOut; lptm.tmPitchAndFamily = lptmA.tmPitchAndFamily; lptm.tmCharSet = lptmA.tmCharSet; } else { // Unicode retVal = IntUnsafeNativeMethods.GetTextMetricsW(hDC, ref lptm); } DbgUtil.AssertWin32(retVal != 0, "GetTextMetrics(hdc=[0x{0:X8}], [out TEXTMETRIC] failed.", hDC.Handle); return(retVal); }
internal void Dispose(bool disposing) { if (_disposed) { return; } Disposing?.Invoke(this, EventArgs.Empty); _disposed = true; switch (_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: IntUnsafeNativeMethods.DeleteDC(new HandleRef(this, _hDC)); _hDC = IntPtr.Zero; break; case DeviceContextType.Memory: IntUnsafeNativeMethods.DeleteDC(new HandleRef(this, _hDC)); _hDC = IntPtr.Zero; break; // case DeviceContextType.Metafile: - not yet supported. 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); }
public void DeleteObject(IntPtr handle, GdiObjectType type) { IntPtr handleToDelete = IntPtr.Zero; switch (type) { case GdiObjectType.Pen: if (handle == _hCurrentPen) { IntPtr currentPen = IntUnsafeNativeMethods.SelectObject(new HandleRef(this, Hdc), new HandleRef(this, _hInitialPen)); Debug.Assert(currentPen == _hCurrentPen, "DeviceContext thinks a different pen is selected than the HDC"); _hCurrentPen = IntPtr.Zero; } handleToDelete = handle; break; case GdiObjectType.Brush: if (handle == _hCurrentBrush) { IntPtr currentBrush = IntUnsafeNativeMethods.SelectObject(new HandleRef(this, Hdc), new HandleRef(this, _hInitialBrush)); Debug.Assert(currentBrush == _hCurrentBrush, "DeviceContext thinks a different brush is selected than the HDC"); _hCurrentBrush = IntPtr.Zero; } handleToDelete = handle; break; case GdiObjectType.Bitmap: if (handle == _hCurrentBmp) { IntPtr currentBmp = IntUnsafeNativeMethods.SelectObject(new HandleRef(this, Hdc), new HandleRef(this, _hInitialBmp)); Debug.Assert(currentBmp == _hCurrentBmp, "DeviceContext thinks a different brush is selected than the HDC"); _hCurrentBmp = IntPtr.Zero; } handleToDelete = handle; break; } IntUnsafeNativeMethods.DeleteObject(new HandleRef(this, handleToDelete)); }
public static int GetTextExtentPoint32(HandleRef hDC, string text, [In, Out] IntNativeMethods.SIZE size) { int retVal; int byteCount = text.Length; if (Marshal.SystemDefaultCharSize == 1) { // Convert Unicode string to ANSI. byteCount = IntUnsafeNativeMethods.WideCharToMultiByte(IntNativeMethods.CP_ACP, 0, text, text.Length, null, 0, IntPtr.Zero, IntPtr.Zero); byte[] textBytes = new byte[byteCount]; IntUnsafeNativeMethods.WideCharToMultiByte(IntNativeMethods.CP_ACP, 0, text, text.Length, textBytes, textBytes.Length, IntPtr.Zero, IntPtr.Zero); // Security: Windows 95/98/Me: This value may not exceed 8192. byteCount = Math.Min(text.Length, IntNativeMethods.MaxTextLengthInWin9x); retVal = GetTextExtentPoint32A(hDC, textBytes, byteCount, size); } else { retVal = GetTextExtentPoint32W(hDC, text, text.Length, size); } DbgUtil.AssertWin32(retVal != 0, "GetTextExtentPoint32(hdc=[0x{0:X8}], text=[{1}], size=[{2}] failed.", hDC.Handle, text, size); return(retVal); }
/// <summary> /// Combines region1 & region2 into this region. The regions cannot be null. The three regions need not be /// distinct. For example, the sourceRgn1 can equal this region. /// </summary> public IntNativeMethods.RegionFlags CombineRegion(WindowsRegion region1, WindowsRegion region2, RegionCombineMode mode) { return(IntUnsafeNativeMethods.CombineRgn(new HandleRef(this, HRegion), new HandleRef(region1, region1.HRegion), new HandleRef(region2, region2.HRegion), mode)); }