Ejemplo n.º 1
0
 public static int GetTextHeight(IDeviceContext dc, string mainInstruction, string content, Font mainInstructionFallbackFont, Font contentFallbackFont, int width)
 {
     // compute the height the text needs at the current dialog width.
     Point location = Point.Empty;
     DrawText(dc, mainInstruction, content, ref location, mainInstructionFallbackFont, contentFallbackFont, true, width);
     return location.Y;
 }
Ejemplo n.º 2
0
        /// <include file='doc\TextRenderer.uex' path='docs/doc[@for="TextRenderer.DrawText1"]/*' />
        public static void DrawText(IDeviceContext dc, string text, Font font, Point pt, Color foreColor, Color backColor)
        {
            if (dc == null)
            {
                throw new ArgumentNullException("dc");
            }

            WindowsFontQuality fontQuality = WindowsFont.WindowsFontQualityFromTextRenderingHint(dc as Graphics);

            IntPtr hdc = dc.GetHdc();

            try
            {
                using( WindowsGraphics wg = WindowsGraphics.FromHdc( hdc ))
                {
                    using (WindowsFont wf = WindowsGraphicsCacheManager.GetWindowsFont(font, fontQuality)) {
                        wg.DrawText(text, wf, pt, foreColor, backColor);
                    }
                }
            }
            finally
            {
                dc.ReleaseHdc();
            }
        }
Ejemplo n.º 3
0
        public static Size SizeDialog(IDeviceContext dc, string mainInstruction, string content, Screen screen, Font mainInstructionFallbackFont, Font contentFallbackFont, int horizontalSpacing, int verticalSpacing, int minimumWidth, int textMinimumHeight)
        {
            int width = minimumWidth - horizontalSpacing;
            int height = GetTextHeight(dc, mainInstruction, content, mainInstructionFallbackFont, contentFallbackFont, width);

            while( height > width )
            {
                int area = height * width;
                width = (int)(Math.Sqrt(area) * 1.1);
                height = GetTextHeight(dc, mainInstruction, content, mainInstructionFallbackFont, contentFallbackFont, width);
            }

            if( height < textMinimumHeight )
                height = textMinimumHeight;

            int newWidth = width + horizontalSpacing;
            int newHeight = height + verticalSpacing;

            Rectangle workingArea = screen.WorkingArea;
            if( newHeight > 0.9 * workingArea.Height )
            {
                int area = height * width;
                newHeight = (int)(0.9 * workingArea.Height);
                height = newHeight - verticalSpacing;
                width = area / height;
                newWidth = width + horizontalSpacing;
            }

            // If this happens the text won't display correctly, but even at 800x600 you need
            // to put so much text in the input box for this to happen that I don't care.
            if( newWidth > 0.9 * workingArea.Width )
                newWidth = (int)(0.9 * workingArea.Width);

            return new Size(newWidth, newHeight);
        }
 public static void DrawCloseButton(IDeviceContext dc, Rectangle rect, Padding padding, ToolTipBalloonCloseButtonState buttonState)
 {
     VisualStyleElement btn = GetCloseButtonVS(buttonState);
     VisualStyleRenderer renderer = new VisualStyleRenderer(btn);
     Rectangle btnRect = GetCloseButtonRect(dc, rect, padding, buttonState);
     renderer.DrawBackground(dc, btnRect);
 }
 public Rectangle DrawEdge(IDeviceContext dc, Rectangle bounds, Edges edges, EdgeStyle style, EdgeEffects effects)
 {
     if (dc == null)
     {
         throw new ArgumentNullException("dc");
     }
     if (!System.Windows.Forms.ClientUtils.IsEnumValid_Masked(edges, (int) edges, 0x1f))
     {
         throw new InvalidEnumArgumentException("edges", (int) edges, typeof(Edges));
     }
     if (!System.Windows.Forms.ClientUtils.IsEnumValid_NotSequential(style, (int) style, new int[] { 5, 10, 6, 9 }))
     {
         throw new InvalidEnumArgumentException("style", (int) style, typeof(EdgeStyle));
     }
     if (!System.Windows.Forms.ClientUtils.IsEnumValid_Masked(effects, (int) effects, 0xd800))
     {
         throw new InvalidEnumArgumentException("effects", (int) effects, typeof(EdgeEffects));
     }
     System.Windows.Forms.NativeMethods.COMRECT pContentRect = new System.Windows.Forms.NativeMethods.COMRECT();
     using (WindowsGraphicsWrapper wrapper = new WindowsGraphicsWrapper(dc, TextFormatFlags.PreserveGraphicsTranslateTransform | TextFormatFlags.PreserveGraphicsClipping))
     {
         HandleRef hdc = new HandleRef(wrapper, wrapper.WindowsGraphics.DeviceContext.Hdc);
         this.lastHResult = System.Windows.Forms.SafeNativeMethods.DrawThemeEdge(new HandleRef(this, this.Handle), hdc, this.part, this.state, new System.Windows.Forms.NativeMethods.COMRECT(bounds), (int) style, ((int) (edges | ((Edges) ((int) effects)))) | 0x2000, pContentRect);
     }
     return Rectangle.FromLTRB(pContentRect.left, pContentRect.top, pContentRect.right, pContentRect.bottom);
 }
Ejemplo n.º 6
0
 private static void BuildLookupList(IDeviceContext g, Font font, ref SizeF[] size)
 {
     size = new SizeF[char.MaxValue];
     for (var i = (char)0; i < (char)256; i++)
     {
         size[i] = MeasureString(g, font, i.ToString());
     }
 }
Ejemplo n.º 7
0
 private static void DrawThemeBackground(IDeviceContext dc, VisualStyleElement element, Rectangle bounds, Rectangle clipRectangle)
 {
     if( DialogHelper.IsTaskDialogThemeSupported )
     {
         VisualStyleRenderer renderer = new VisualStyleRenderer(element);
         renderer.DrawBackground(dc, bounds, clipRectangle);
     }
 }
        public WindowsGraphicsWrapper( IDeviceContext idc, TextFormatFlags flags)
        {
            if( idc is Graphics )
            {
                ApplyGraphicsProperties properties = ApplyGraphicsProperties.None;

                if( (flags & TextFormatFlags.PreserveGraphicsClipping) != 0)
                {
                    properties |= ApplyGraphicsProperties.Clipping;
                }

                if( (flags & TextFormatFlags.PreserveGraphicsTranslateTransform) != 0)
                {
                    properties |= ApplyGraphicsProperties.TranslateTransform;
                }

                // Create the WindowsGraphics from the Grahpics object only if Graphics properties need
                // to be reapplied to the DC wrapped by the WindowsGraphics.
                if( properties != ApplyGraphicsProperties.None )
                {
                    this.wg = WindowsGraphics.FromGraphics( idc as Graphics, properties);
                }
            }
            else
            {
                // If passed-in IDeviceContext object is a WindowsGraphics we can use it directly.
                this.wg = idc as WindowsGraphics;

                if( this.wg != null )
                {
                    // In this case we cache the idc to compare it against the wg in the Dispose method to avoid
                    // disposing of the wg.
                    this.idc = idc;
                }
            }

            if( this.wg == null )
            {
                // The IDeviceContext object is not a WindowsGraphics, or it is a custom IDeviceContext, or
                // it is a Graphics object but we did not need to re-apply Graphics propertiesto the hdc.  
                // So create the WindowsGraphics from the hdc directly. 
                // Cache the IDC so the hdc can be released on dispose.
                this.idc = idc;
                this.wg = WindowsGraphics.FromHdc( idc.GetHdc() );
            }

            // Set text padding on the WindowsGraphics (if any).
            if( (flags & TextFormatFlags.LeftAndRightPadding) != 0 )
            {
                wg.TextPadding = TextPaddingOptions.LeftAndRightPadding;
            }
            else if ((flags & TextFormatFlags.NoPadding) != 0 )
            {
                wg.TextPadding = TextPaddingOptions.NoPadding;
            }
            // else wg.TextPadding = TextPaddingOptions.GlyphOverhangPadding - the default value.
        }
Ejemplo n.º 9
0
 private static SizeF MeasureString(IDeviceContext g, IList text, Font font, FontData data)
 {
     SizeF ans = new SizeF();
     foreach (char chr in text)
     {
         SizeF temp = MeasureString(g, chr, font, data);
         ans = new SizeF(ans.Width + temp.Width, temp.Height);
     }
     return ans;
 }
Ejemplo n.º 10
0
        //
        // Summary:
        //     Draws the specified text at the specified location using the specified device
        //     context, font, color, and formatting instructions.
        //
        // Parameters:
        //   foreColor:
        //     The System.Drawing.Color to apply to the drawn text.
        //
        //   font:
        //     The System.Drawing.Font to apply to the drawn text.
        //
        //   dc:
        //     The device context in which to draw the text.
        //
        //   pt:
        //     The System.Drawing.Point that represents the upper-left corner of the drawn
        //     text.
        //
        //   flags:
        //     A bitwise combination of the System.Drawing.GDI.TextFormatFlags values.
        //
        //   text:
        //     The text to draw.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     dc is null.
        public static void DrawText(IDeviceContext dc, string text, Font font, Rectangle rc, Color foreColor, TextFormatFlags flags)
        {
            Graphics grfx = dc as Graphics;

            if (grfx != null)
            {
                rc.X += (int) grfx.Transform.OffsetX;
                rc.Y += (int) grfx.Transform.OffsetY;
            }
            TextRenderer.DrawText(dc, text, font, rc, foreColor, flags);
        }
Ejemplo n.º 11
0
        public static void DrawText(IDeviceContext dc, string mainInstruction, string content, ref Point location, Font mainInstructionFallbackFont, Font contentFallbackFont, bool measureOnly, int width)
        {
            if( !string.IsNullOrEmpty(mainInstruction) )
                DrawText(dc, mainInstruction, AdditionalVisualStyleElements.TextStyle.MainInstruction, mainInstructionFallbackFont, ref location, measureOnly, width);

            if( !string.IsNullOrEmpty(content) )
            {
                if( !string.IsNullOrEmpty(mainInstruction) )
                    content = Environment.NewLine + content;

                DrawText(dc, content, AdditionalVisualStyleElements.TextStyle.BodyText, contentFallbackFont, ref location, measureOnly, width);
            }
        }
 public void DrawBackground(IDeviceContext dc, Rectangle bounds, Rectangle clipRectangle)
 {
     if (dc == null)
     {
         throw new ArgumentNullException("dc");
     }
     if (((bounds.Width >= 0) && (bounds.Height >= 0)) && ((clipRectangle.Width >= 0) && (clipRectangle.Height >= 0)))
     {
         using (WindowsGraphicsWrapper wrapper = new WindowsGraphicsWrapper(dc, TextFormatFlags.PreserveGraphicsTranslateTransform | TextFormatFlags.PreserveGraphicsClipping))
         {
             HandleRef hdc = new HandleRef(wrapper, wrapper.WindowsGraphics.DeviceContext.Hdc);
             this.lastHResult = System.Windows.Forms.SafeNativeMethods.DrawThemeBackground(new HandleRef(this, this.Handle), hdc, this.part, this.state, new System.Windows.Forms.NativeMethods.COMRECT(bounds), new System.Windows.Forms.NativeMethods.COMRECT(clipRectangle));
         }
     }
 }
Ejemplo n.º 13
0
        public static SizeF MeasureString(IDeviceContext g, Font font, string text)
        {
            FontData data;
            if (!Fonts.ContainsKey(font))
            {
                data = new FontData(g, font);
                Fonts.Add(font, data);
            }
            else
            {
                data = Fonts[font];
            }

            return MeasureString(g, text.ToCharArray(), font, data);
        }
Ejemplo n.º 14
0
        /// <include file='doc\TextRenderer.uex' path='docs/doc[@for="TextRenderer.DrawText2"]/*' />
        public static void DrawText(IDeviceContext dc, string text, Font font, Point pt, Color foreColor, TextFormatFlags flags)
        {
            if (dc == null)
            {
                throw new ArgumentNullException("dc");
            }

            WindowsFontQuality fontQuality = WindowsFont.WindowsFontQualityFromTextRenderingHint(dc as Graphics);

            using( WindowsGraphicsWrapper wgr = new WindowsGraphicsWrapper( dc, flags ))
            {
                using (WindowsFont wf = WindowsGraphicsCacheManager.GetWindowsFont(font, fontQuality)) {
                    wgr.WindowsGraphics.DrawText(text, wf, pt, foreColor, GetIntTextFormatFlags(flags));
                }
            }
        }
 public void Dispose(bool disposing)
 {
     if (this.wg != null)
     {
         if (this.wg != this.idc)
         {
             this.wg.Dispose();
             if (this.idc != null)
             {
                 this.idc.ReleaseHdc();
             }
         }
         this.idc = null;
         this.wg = null;
     }
 }
 public WindowsGraphicsWrapper(IDeviceContext idc, TextFormatFlags flags)
 {
     if (idc is Graphics)
     {
         ApplyGraphicsProperties none = ApplyGraphicsProperties.None;
         if ((flags & TextFormatFlags.PreserveGraphicsClipping) != TextFormatFlags.Default)
         {
             none |= ApplyGraphicsProperties.Clipping;
         }
         if ((flags & TextFormatFlags.PreserveGraphicsTranslateTransform) != TextFormatFlags.Default)
         {
             none |= ApplyGraphicsProperties.TranslateTransform;
         }
         if (none != ApplyGraphicsProperties.None)
         {
             this.wg = System.Windows.Forms.Internal.WindowsGraphics.FromGraphics(idc as Graphics, none);
         }
     }
     else
     {
         this.wg = idc as System.Windows.Forms.Internal.WindowsGraphics;
         if (this.wg != null)
         {
             this.idc = idc;
         }
     }
     if (this.wg == null)
     {
         this.idc = idc;
         this.wg = System.Windows.Forms.Internal.WindowsGraphics.FromHdc(idc.GetHdc());
     }
     if ((flags & TextFormatFlags.LeftAndRightPadding) != TextFormatFlags.Default)
     {
         this.wg.TextPadding = TextPaddingOptions.LeftAndRightPadding;
     }
     else if ((flags & TextFormatFlags.NoPadding) != TextFormatFlags.Default)
     {
         this.wg.TextPadding = TextPaddingOptions.NoPadding;
     }
 }
Ejemplo n.º 17
0
 public static void DrawText(IDeviceContext dc, string text, VisualStyleElement element, Font fallbackFont, ref Point location, bool measureOnly, int width)
 {
     // For Windows 2000, using Int32.MaxValue for the height doesn't seem to work, so we'll just pick another arbitrary large value
     // that does work.
     Rectangle textRect = new Rectangle(location.X, location.Y, width, NativeMethods.IsWindowsXPOrLater ? Int32.MaxValue : 100000);
     TextFormatFlags flags = TextFormatFlags.WordBreak;
     if( IsTaskDialogThemeSupported )
     {
         VisualStyleRenderer renderer = new VisualStyleRenderer(element);
         Rectangle textSize = renderer.GetTextExtent(dc, textRect, text, flags);
         location = location + new Size(0, textSize.Height);
         if( !measureOnly )
             renderer.DrawText(dc, textSize, text, false, flags);
     }
     else
     {
         if( !measureOnly )
             TextRenderer.DrawText(dc, text, fallbackFont, textRect, SystemColors.WindowText, flags);
         Size textSize = TextRenderer.MeasureText(dc, text, fallbackFont, new Size(textRect.Width, textRect.Height), flags);
         location = location + new Size(0, textSize.Height);
     }
 }
 public static void DrawText(IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor)
 {
     if (dc == null)
     {
         throw new ArgumentNullException("dc");
     }
     WindowsFontQuality fontQuality = WindowsFont.WindowsFontQualityFromTextRenderingHint(dc as Graphics);
     IntPtr hdc = dc.GetHdc();
     try
     {
         using (WindowsGraphics graphics = WindowsGraphics.FromHdc(hdc))
         {
             using (WindowsFont font2 = WindowsGraphicsCacheManager.GetWindowsFont(font, fontQuality))
             {
                 graphics.DrawText(text, font2, bounds, foreColor);
             }
         }
     }
     finally
     {
         dc.ReleaseHdc();
     }
 }
        public static Rectangle GetBodyRect(IDeviceContext dc, Size minSize, Size maxSize, string text, Rectangle titleRect, ToolTipIcon icon, Padding padding)
        {
            Rectangle ret;
            if (text == null)
            {
                ret = new Rectangle(new Point(0, 0), minSize);
            }
            else
            {
                ret = new Rectangle(new Point(0, 0), maxSize);
                ret.Width -= padding.Horizontal;

                if (Application.RenderWithVisualStyles)
                {
                    VisualStyleRenderer renderer = new VisualStyleRenderer(VisualStyleElement.ToolTip.Balloon.Normal);
                    Rectangle rect = renderer.GetTextExtent(dc, ret, text, TextFormatFlags.Left | TextFormatFlags.WordBreak | TextFormatFlags.VerticalCenter);

                    if (rect.Width + padding.Horizontal > maxSize.Width)
                        ret.Width = maxSize.Width;
                    else if (rect.Width + padding.Horizontal < minSize.Width)
                        ret.Width = minSize.Width;
                    else
                        ret.Width = rect.Width;

                    if (rect.Height > maxSize.Height)
                        ret.Height = maxSize.Height;
                    else
                        ret.Height = rect.Height;

                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            return ret;
        }
Ejemplo n.º 20
0
 internal static void DrawTextInternal(IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, TextFormatFlags flags, bool useDrawString)
 {
     DrawTextInternal(dc, text, font, bounds, foreColor, Color.Transparent, flags, useDrawString);
 }
Ejemplo n.º 21
0
 internal static void DrawTextInternal(IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, bool useDrawString)
 {
     DrawTextInternal(dc, text, font, bounds, foreColor, Color.Transparent, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter, useDrawString);
 }
Ejemplo n.º 22
0
 /// <summary>
 ///  Draws the specified text at the specified location using the specified device context, font, and color.
 /// </summary>
 /// <param name="dc">The device context in which to draw the text.</param>
 /// <param name="text">The text to draw.</param>
 /// <param name="font">The <see cref="Font"/> to apply to the drawn text.</param>
 /// <param name="pt">The <see cref="Point"/> that represents the upper-left corner of the drawn text.</param>
 /// <param name="foreColor">The <see cref="Color"/> to apply to the drawn text.</param>
 /// <exception cref="ArgumentNullException"><paramref name="dc"/> is null.</exception>
 public static void DrawText(IDeviceContext dc, ReadOnlySpan <char> text, Font font, Point pt, Color foreColor)
 => DrawTextInternal(dc, text, font, pt, foreColor, Color.Empty);
Ejemplo n.º 23
0
 public static Size MeasureText(IDeviceContext dc, string text, Font font)
 {
     return(MeasureTextInternal(dc, text, font, Size.Empty, TextFormatFlags.Default, false));
 }
Ejemplo n.º 24
0
 public static void DrawText(IDeviceContext dc, string text, Font font, Point pt, Color foreColor, Color backColor, TextFormatFlags flags)
 {
     DrawTextInternal(dc, text, font, pt, foreColor, backColor, flags, false);
 }
Ejemplo n.º 25
0
 public static void DrawText(IDeviceContext dc, string text, Font font, Point pt, Color foreColor)
 {
     DrawTextInternal(dc, text, font, pt, foreColor, Color.Transparent, TextFormatFlags.Default, false);
 }
Ejemplo n.º 26
0
 /// <summary>
 ///  Convert the <paramref name="deviceContext"/> into a <see cref="Graphics"/> object if possible.
 /// </summary>
 /// <param name="create">
 ///  Will create the <see cref="Graphics"/> if possible and it is not already created.
 /// </param>
 /// <remarks>
 ///  Do NOT dispose of the <see cref="Graphics"/> object. If it was created, the object creating it owns it.
 /// </remarks>
 internal static Graphics?TryGetGraphics(this IDeviceContext deviceContext, bool create = false)
 => deviceContext switch
 {
Ejemplo n.º 27
0
 internal static void DrawTabPage(IDeviceContext deviceContext, Rectangle bounds)
 {
     InitializeRenderer(VisualStyleElement.Tab.Pane.Normal, 0);
     visualStyleRenderer.DrawBackground(deviceContext, bounds);
 }
 public static void DrawStringDisabled(IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)
 {
     ThemeEngine.Current.CPDrawStringDisabled(dc, s, font, color, layoutRectangle, format);
 }
Ejemplo n.º 29
0
        public WindowsGraphicsWrapper(IDeviceContext deviceContext, TextFormatFlags flags)
        {
            if (deviceContext is Graphics)
            {
                ApplyGraphicsProperties properties = ApplyGraphicsProperties.None;

                if ((flags & TextFormatFlags.PreserveGraphicsClipping) != 0)
                {
                    properties |= ApplyGraphicsProperties.Clipping;
                }

                if ((flags & TextFormatFlags.PreserveGraphicsTranslateTransform) != 0)
                {
                    properties |= ApplyGraphicsProperties.TranslateTransform;
                }

                // Create the WindowsGraphics from the Grahpics object only if Graphics properties need
                // to be reapplied to the DC wrapped by the WindowsGraphics.
                if (properties != ApplyGraphicsProperties.None)
                {
                    try
                    {
                        _windowsGraphics = WindowsGraphics.FromGraphics(deviceContext as Graphics, properties);
                    }
                    catch
                    {
                        GC.SuppressFinalize(this);
                        throw;
                    }
                }
            }
            else
            {
                // If passed-in IDeviceContext object is a WindowsGraphics we can use it directly.
                _windowsGraphics = deviceContext as WindowsGraphics;

                if (_windowsGraphics != null)
                {
                    // In this case we cache the idc to compare it against the wg in the Dispose method to avoid
                    // disposing of the wg.
                    _deviceContext = deviceContext;
                }
            }

            if (_windowsGraphics == null)
            {
                // The IDeviceContext object is not a WindowsGraphics, or it is a custom IDeviceContext, or
                // it is a Graphics object but we did not need to re-apply Graphics propertiesto the hdc.
                // So create the WindowsGraphics from the hdc directly.
                // Cache the IDC so the hdc can be released ons dispose.
                try
                {
                    _deviceContext   = deviceContext;
                    _windowsGraphics = WindowsGraphics.FromHdc((Gdi32.HDC)deviceContext.GetHdc());
                }
                catch
                {
                    SuppressFinalize();
                    deviceContext.ReleaseHdc();
                    throw;
                }
            }

            // Set text padding on the WindowsGraphics (if any).
            if ((flags & TextFormatFlags.LeftAndRightPadding) != 0)
            {
                _windowsGraphics.TextPadding = TextPaddingOptions.LeftAndRightPadding;
            }
            else if ((flags & TextFormatFlags.NoPadding) != 0)
            {
                _windowsGraphics.TextPadding = TextPaddingOptions.NoPadding;
            }
            // else wg.TextPadding = TextPaddingOptions.GlyphOverhangPadding - the default value.
        }
Ejemplo n.º 30
0
        /// <summary>
        ///  Prefer to use <see cref="DeviceContextHdcScope(IDeviceContext, bool, bool)"/>.
        /// </summary>
        /// <remarks>
        ///  Ideally we'd not bifurcate what properties we apply unless we're absolutely sure we only want one.
        /// </remarks>
        public unsafe DeviceContextHdcScope(
            IDeviceContext deviceContext,
            ApplyGraphicsProperties applyGraphicsState,
            bool saveHdcState = false)
        {
            if (deviceContext is null)
            {
                DisposalTracking.SuppressFinalize(this !);
                throw new ArgumentNullException(nameof(deviceContext));
            }

            DeviceContext  = deviceContext;
            _savedHdcState = 0;

            HDC = default;

            IGraphicsHdcProvider?provider = deviceContext as IGraphicsHdcProvider;
            Graphics?            graphics = deviceContext as Graphics;

            // If we weren't passed a Graphics object we can't save state, so it is effectively the same as apply none.
            // If we were passed an IGraphicsHdcProvider and it tells us we're clean, we also don't need to save state.
            if (applyGraphicsState == ApplyGraphicsProperties.None || graphics is null || provider?.IsGraphicsStateClean == true)
            {
                if (provider is null)
                {
                    // We have an IDeviceContext
                    HDC = (Gdi32.HDC)deviceContext.GetHdc();
                }
                else
                {
                    // We have a provider
                    HDC = provider.GetHDC();

                    if (HDC.IsNull)
                    {
                        graphics = provider.GetGraphics(createIfNeeded: true);
                        if (graphics is null)
                        {
                            throw new InvalidOperationException();
                        }
                        HDC           = (Gdi32.HDC)graphics.GetHdc();
                        DeviceContext = graphics;
                    }
                }

                _savedHdcState = saveHdcState ? Gdi32.SaveDC(HDC) : 0;
                return;
            }

            _savedHdcState = saveHdcState ? Gdi32.SaveDC(HDC) : 0;
            bool applyTransform = applyGraphicsState.HasFlag(ApplyGraphicsProperties.TranslateTransform);
            bool applyClipping  = applyGraphicsState.HasFlag(ApplyGraphicsProperties.Clipping);

            // This API is very expensive
            object[]? data = applyTransform || applyClipping ? (object[])graphics.GetContextInfo() : null;

            using Region? clipRegion     = (Region?)data?[0];
            using Matrix? worldTransform = (Matrix?)data?[1];

            // elements (XFORM) = [eM11, eM12, eM21, eM22, eDx, eDy], eDx/eDy specify the translation offset.
            float[]? elements = applyTransform ? worldTransform?.Elements : null;
            int dx = elements != null ? (int)elements[4] : 0;
            int dy = elements != null ? (int)elements[5] : 0;

            applyTransform = applyTransform && elements != null && (dx != 0 || dy != 0);

            using var graphicsRegion = applyClipping ? new Gdi32.RegionScope(clipRegion !, graphics) : default;
Ejemplo n.º 31
0
 public abstract void CPDrawStringDisabled(IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format);
Ejemplo n.º 32
0
        internal static void DrawTextInternal(IDeviceContext dc, string text, Font font, Point pt, Color foreColor, Color backColor, TextFormatFlags flags, bool useDrawString)
        {
            Size sz = MeasureTextInternal(dc, text, font, useDrawString);

            DrawTextInternal(dc, text, font, new Rectangle(pt, sz), foreColor, backColor, flags, useDrawString);
        }
Ejemplo n.º 33
0
 internal static Size MeasureTextInternal(IDeviceContext dc, string text, Font font, Size proposedSize, bool useMeasureString)
 {
     return(MeasureTextInternal(dc, text, font, proposedSize, TextFormatFlags.Default, useMeasureString));
 }
Ejemplo n.º 34
0
 public static void DrawStringDisabled(IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)
 {
     throw null;
 }
Ejemplo n.º 35
0
 public static void DrawText(IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, Color backColor)
 {
     DrawTextInternal(dc, text, font, bounds, foreColor, backColor, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter, false);
 }
Ejemplo n.º 36
0
 public static Size MeasureText(IDeviceContext dc, string text, Font font, Size proposedSize, TextFormatFlags flags)
 {
     return(MeasureTextInternal(dc, text, font, proposedSize, flags, false));
 }
Ejemplo n.º 37
0
 public static void DrawText(IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, Color backColor, TextFormatFlags flags)
 {
     DrawTextInternal(dc, text, font, bounds, foreColor, backColor, flags, false);
 }
Ejemplo n.º 38
0
        internal static void DrawTextInternal(IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, Color backColor, TextFormatFlags flags, bool useDrawString)
        {
            if (dc == null)
            {
                throw new ArgumentNullException("dc");
            }

            if ((text == null || text.Length == 0) && (backColor == Color.Transparent || backColor == Color.Empty))
            {
                return;
            }

            // We use MS GDI API's unless told not to, or we aren't on Windows
            if (!useDrawString && !XplatUI.RunningOnUnix)
            {
                if ((flags & TextFormatFlags.VerticalCenter) == TextFormatFlags.VerticalCenter || (flags & TextFormatFlags.Bottom) == TextFormatFlags.Bottom)
                {
                    flags |= TextFormatFlags.SingleLine;
                }

                // Calculate the text bounds (there is often padding added)
                Rectangle new_bounds = PadRectangle(bounds, flags);
                new_bounds.Offset((int)(dc as Graphics).Transform.OffsetX, (int)(dc as Graphics).Transform.OffsetY);

                IntPtr hdc = IntPtr.Zero;
                bool   clear_clip_region = false;

                // If we need to use the graphics clipping region, add it to our hdc
                if ((flags & TextFormatFlags.PreserveGraphicsClipping) == TextFormatFlags.PreserveGraphicsClipping)
                {
                    Graphics graphics    = (Graphics)dc;
                    Region   clip_region = graphics.Clip;

                    if (!clip_region.IsInfinite(graphics))
                    {
                        IntPtr hrgn = clip_region.GetHrgn(graphics);
                        hdc = dc.GetHdc();
                        SelectClipRgn(hdc, hrgn);
                        DeleteObject(hrgn);

                        clear_clip_region = true;
                    }
                }

                if (hdc == IntPtr.Zero)
                {
                    hdc = dc.GetHdc();
                }

                // Set the fore color
                if (foreColor != Color.Empty)
                {
                    SetTextColor(hdc, ColorTranslator.ToWin32(foreColor));
                }

                // Set the back color
                if (backColor != Color.Transparent && backColor != Color.Empty)
                {
                    SetBkMode(hdc, 2);                          //1-Transparent, 2-Opaque
                    SetBkColor(hdc, ColorTranslator.ToWin32(backColor));
                }
                else
                {
                    SetBkMode(hdc, 1);                          //1-Transparent, 2-Opaque
                }

                XplatUIWin32.RECT r = XplatUIWin32.RECT.FromRectangle(new_bounds);

                IntPtr prevobj;

                if (text == null || text.Length == 0)
                {
                    Win32DrawText(hdc, String.Empty, 0, ref r, (int)flags);
                }
                else if (font != null)
                {
                    prevobj = SelectObject(hdc, font.ToHfont());
                    Win32DrawText(hdc, text, text.Length, ref r, (int)flags);
                    prevobj = SelectObject(hdc, prevobj);
                    DeleteObject(prevobj);
                }
                else
                {
                    Win32DrawText(hdc, text, text.Length, ref r, (int)flags);
                }

                if (clear_clip_region)
                {
                    SelectClipRgn(hdc, IntPtr.Zero);
                }

                dc.ReleaseHdc();
            }
            // Use Graphics.DrawString as a fallback method
            else
            {
                Graphics g;
                IntPtr   hdc = IntPtr.Zero;

                if (dc is Graphics)
                {
                    g = (Graphics)dc;
                }
                else
                {
                    hdc = dc.GetHdc();
                    g   = Graphics.FromHdc(hdc);
                }

                if (backColor != Color.Transparent && backColor != Color.Empty)
                {
                    using (SolidBrush b = new SolidBrush(backColor))
                        g.FillRectangle(b, bounds);
                }

                if (text != null && text.Length > 0)
                {
                    StringFormat sf = FlagsToStringFormat(flags);

                    // It seems that Win32 TextRenderer behaves likes this
                    if ((flags & TextFormatFlags.WordBreak) == 0 && (flags & TextFormatFlags.TextBoxControl) == 0)
                    {
                        sf.FormatFlags |= StringFormatFlags.NoWrap;
                    }

                    Rectangle new_bounds = PadDrawStringRectangle(bounds, flags);
                    g.DrawString(text, font, ThemeEngine.Current.ResPool.GetSolidBrush(foreColor), new_bounds, sf);
                }

                if (!(dc is Graphics))
                {
                    g.Dispose();
                    dc.ReleaseHdc();
                }
            }
        }
Ejemplo n.º 39
0
        internal static Size MeasureTextInternal(IDeviceContext dc, string text, Font font, Size proposedSize, TextFormatFlags flags, bool useMeasureString)
        {
            proposedSize.Width  = Math.Max(0, proposedSize.Width);
            proposedSize.Height = Math.Max(0, proposedSize.Height);

            if (!useMeasureString && !XplatUI.RunningOnUnix)
            {
                // Tell DrawText to calculate size instead of draw
                flags |= (TextFormatFlags)1024;                         // DT_CALCRECT

                IntPtr hdc = dc.GetHdc();

                XplatUIWin32.RECT r = XplatUIWin32.RECT.FromRectangle(new Rectangle(Point.Empty, proposedSize));

                IntPtr prevobj;

                if (font != null)
                {
                    prevobj = SelectObject(hdc, font.ToHfont());
                    Win32DrawText(hdc, text, text.Length, ref r, (int)flags);
                    prevobj = SelectObject(hdc, prevobj);
                    DeleteObject(prevobj);
                }
                else
                {
                    Win32DrawText(hdc, text, text.Length, ref r, (int)flags);
                }

                dc.ReleaseHdc();

                // Really, I am just making something up here, which as far as I can tell, MS
                // just makes something up as well.  This will require lots of tweaking to match MS.  :(
                Size retval = r.ToRectangle().Size;

                if (retval.Width > 0 && (flags & TextFormatFlags.NoPadding) == 0)
                {
                    retval.Width += 6;
                    retval.Width += (int)retval.Height / 8;
                }

                return(retval);
            }
            else
            {
                StringFormat sf = FlagsToStringFormat(flags);

                Size retval;

                int proposedWidth;
                if (proposedSize.Width == 0)
                {
                    proposedWidth = Int32.MaxValue;
                }
                else
                {
                    proposedWidth = proposedSize.Width;
                    if ((flags & TextFormatFlags.NoPadding) == 0)
                    {
                        proposedWidth -= 9;
                    }
                }
                if (dc is Graphics)
                {
                    retval = (dc as Graphics).MeasureString(text, font, proposedWidth, sf).ToSize();
                }
                else
                {
                    retval = TextRenderer.MeasureString(text, font, proposedWidth, sf).ToSize();
                }

                if (retval.Width > 0 && (flags & TextFormatFlags.NoPadding) == 0)
                {
                    retval.Width += 9;
                }

                return(retval);
            }
        }
Ejemplo n.º 40
0
 /// <summary>
 ///  Provides the size, in pixels, of the specified text when drawn with the specified font in the specified
 ///  device context, using the specified size to create an initial bounding rectangle for the text.
 /// </summary>
 /// <param name="dc">The device context in which to measure the text.</param>
 /// <param name="text">The text to measure.</param>
 /// <param name="font">The <see cref="Font"/> to apply to the measured text.</param>
 /// <param name="proposedSize">The <see cref="Size"/> of the initial bounding rectangle.</param>
 /// <returns>
 ///  The <see cref="Size"/>, in pixels, of <paramref name="text"/> drawn with the specified
 ///  <paramref name="font"/>.
 /// </returns>
 /// <exception cref="ArgumentNullException"><paramref name="dc"/> is null.</exception>
 public static Size MeasureText(IDeviceContext dc, ReadOnlySpan <char> text, Font?font, Size proposedSize)
 => MeasureTextInternal(dc, text, font, proposedSize);
 public static void DrawStringDisabled(IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)
 {
     if (dc == null)
     {
         throw new ArgumentNullException("dc");
     }
     layoutRectangle.Offset(1, 1);
     Color foreColor = LightLight(color);
     TextRenderer.DrawText(dc, s, font, layoutRectangle, foreColor, format);
     layoutRectangle.Offset(-1, -1);
     foreColor = Dark(color);
     TextRenderer.DrawText(dc, s, font, layoutRectangle, foreColor, format);
 }
Ejemplo n.º 42
0
		public static void DrawText (IDeviceContext dc, string text, Font font, Point pt, Color foreColor, Color backColor, TextFormatFlags flags)
		{
			DrawTextInternal (dc, text, font, pt, foreColor, backColor, flags, false);
		}
Ejemplo n.º 43
0
		public static void DrawText (IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, Color backColor, TextFormatFlags flags)
		{
			DrawTextInternal (dc, text, font, bounds, foreColor, backColor, flags, false);
		}
Ejemplo n.º 44
0
		public static void DrawText (IDeviceContext dc, string text, Font font, Point pt, Color foreColor)
		{
			DrawTextInternal (dc, text, font, pt, foreColor, Color.Transparent, TextFormatFlags.Default, false);
		}
Ejemplo n.º 45
0
		public static void DrawText (IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, Color backColor)
		{
			DrawTextInternal (dc, text, font, bounds, foreColor, backColor, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter, false);
		}
Ejemplo n.º 46
0
 public static Size MeasureText(IDeviceContext dc, string?text, Font?font)
 => MeasureTextInternal(dc, text, font, WindowsGraphics.MaxSize);
Ejemplo n.º 47
0
		internal static Size MeasureTextInternal (IDeviceContext dc, string text, Font font, Size proposedSize, bool useMeasureString)
		{
			return MeasureTextInternal (dc, text, font, proposedSize, TextFormatFlags.Default, useMeasureString);
		}
Ejemplo n.º 48
0
 public static void DrawText(IDeviceContext dc, string text, Font font, Point pt, Color foreColor, Color backColor)
 {
     throw null;
 }
 internal static void CopyPixels(IntPtr sourceHwnd, IDeviceContext targetDC, Point sourceLocation, Point destinationLocation, Size blockRegionSize, CopyPixelOperation copyPixelOperation)
 {
     int width = blockRegionSize.Width;
     int height = blockRegionSize.Height;
     DeviceContext context = DeviceContext.FromHwnd(sourceHwnd);
     HandleRef hDC = new HandleRef(null, targetDC.GetHdc());
     HandleRef hSrcDC = new HandleRef(null, context.Hdc);
     try
     {
         if (!System.Windows.Forms.SafeNativeMethods.BitBlt(hDC, destinationLocation.X, destinationLocation.Y, width, height, hSrcDC, sourceLocation.X, sourceLocation.Y, (int) copyPixelOperation))
         {
             throw new Win32Exception();
         }
     }
     finally
     {
         targetDC.ReleaseHdc();
         context.Dispose();
     }
 }
Ejemplo n.º 50
0
        private static void DrawThemedGroupBoxWithText(
            IDeviceContext deviceContext,
            Rectangle bounds,
            string groupBoxText,
            Font font,
            Color textColor,
            TextFormatFlags flags,
            GroupBoxState state)
        {
            InitializeRenderer((int)state);

            // Calculate text area, and render text inside it
            Rectangle textBounds = bounds;

            textBounds.Width -= 2 * BoxHeaderWidth;
            Size measuredBounds = TextRenderer.MeasureText(
                deviceContext,
                groupBoxText,
                font,
                new Size(textBounds.Width, textBounds.Height),
                flags);

            textBounds.Width  = measuredBounds.Width;
            textBounds.Height = measuredBounds.Height;

            if ((flags & TextFormatFlags.Right) == TextFormatFlags.Right)
            {
                // +1 to account for the margin built in the MeasureText result
                textBounds.X = bounds.Right - textBounds.Width - BoxHeaderWidth + 1;
            }
            else
            {
                // -1 to account for the margin built in the MeasureText result
                textBounds.X += BoxHeaderWidth - 1;
            }

            TextRenderer.DrawText(deviceContext, groupBoxText, font, textBounds, textColor, flags);

            // Calculate area for background box
            Rectangle boxBounds = bounds;

            boxBounds.Y      += font.Height / 2;
            boxBounds.Height -= font.Height / 2;

            // Break box into three segments, that don't overlap the text area
            Rectangle clipLeft   = boxBounds;
            Rectangle clipMiddle = boxBounds;
            Rectangle clipRight  = boxBounds;

            clipLeft.Width   = BoxHeaderWidth;
            clipMiddle.Width = Math.Max(0, textBounds.Width - 3);  // -3 to account for the margin built in the MeasureText result
            if ((flags & TextFormatFlags.Right) == TextFormatFlags.Right)
            {
                clipLeft.X      = boxBounds.Right - BoxHeaderWidth;
                clipMiddle.X    = clipLeft.Left - clipMiddle.Width;
                clipRight.Width = clipMiddle.X - boxBounds.X;
            }
            else
            {
                clipMiddle.X    = clipLeft.Right;
                clipRight.X     = clipMiddle.Right;
                clipRight.Width = boxBounds.Right - clipRight.X;
            }
            clipMiddle.Y       = textBounds.Bottom;
            clipMiddle.Height -= (textBounds.Bottom - boxBounds.Top);

            Debug.Assert(textBounds.Y <= boxBounds.Y, "if text below box, need to render area of box above text");

            // Render clipped portion of background in each segment
            t_visualStyleRenderer.DrawBackground(deviceContext, boxBounds, clipLeft);
            t_visualStyleRenderer.DrawBackground(deviceContext, boxBounds, clipMiddle);
            t_visualStyleRenderer.DrawBackground(deviceContext, boxBounds, clipRight);
        }
Ejemplo n.º 51
0
        private static void DrawUnthemedGroupBoxWithText(
            IDeviceContext deviceContext,
            Rectangle bounds,
            string groupBoxText,
            Font font,
            Color textColor,
            TextFormatFlags flags)
        {
            // Calculate text area, and render text inside it
            Rectangle textBounds = bounds;

            textBounds.Width -= TextOffset;
            Size measuredBounds = TextRenderer.MeasureText(
                deviceContext,
                groupBoxText,
                font,
                new Size(textBounds.Width, textBounds.Height),
                flags);

            textBounds.Width  = measuredBounds.Width;
            textBounds.Height = measuredBounds.Height;

            if ((flags & TextFormatFlags.Right) == TextFormatFlags.Right)
            {
                textBounds.X = bounds.Right - textBounds.Width - TextOffset;
            }
            else
            {
                textBounds.X += TextOffset;
            }

            TextRenderer.DrawText(deviceContext, groupBoxText, font, textBounds, textColor, flags);

            // Pad text area to stop background from touching text
            if (textBounds.Width > 0)
            {
                textBounds.Inflate(2, 0);
            }

            int boxTop = bounds.Top + font.Height / 2;

            using var hdc = new DeviceContextHdcScope(deviceContext);

            ReadOnlySpan <int> darkLines = stackalloc int[]
            {
                bounds.Left, boxTop - 1, bounds.Left, bounds.Height - 2,                            // Left
                bounds.Left, bounds.Height - 2, bounds.Width - 1, bounds.Height - 2,                // Right
                bounds.Left, boxTop - 1, textBounds.X - 3, boxTop - 1,                              // Top-left
                textBounds.X + textBounds.Width + 2, boxTop - 1, bounds.Width - 2, boxTop - 1,      // Top-right
                bounds.Width - 2, boxTop - 1, bounds.Width - 2, bounds.Height - 2                   // Right
            };

            using var hpenDark = new Gdi32.CreatePenScope(SystemColors.ControlDark);
            hdc.DrawLines(hpenDark, darkLines);

            ReadOnlySpan <int> lightLines = stackalloc int[]
            {
                bounds.Left + 1, boxTop, bounds.Left + 1, bounds.Height - 1,                        // Left
                bounds.Left, bounds.Height - 1, bounds.Width, bounds.Height - 1,                    // Right
                bounds.Left + 1, boxTop, textBounds.X - 2, boxTop,                                  // Top-left
                textBounds.X + textBounds.Width + 1, boxTop, bounds.Width - 1, boxTop,              // Top-right
                bounds.Width - 1, boxTop, bounds.Width - 1, bounds.Height - 1                       // Right
            };

            using var hpenLight = new Gdi32.CreatePenScope(SystemColors.ControlLight);
            hdc.DrawLines(hpenLight, lightLines);
        }
Ejemplo n.º 52
0
 public static void DrawText(IDeviceContext dc, string?text, Font?font, Rectangle bounds, Color foreColor)
 => DrawTextInternal(dc, text, font, bounds, foreColor);
Ejemplo n.º 53
0
 public static void DrawText(IDeviceContext dc, string?text, Font?font, Point pt, Color foreColor, Color backColor)
 => DrawTextInternal(dc, text, font, pt, foreColor, backColor);
Ejemplo n.º 54
0
 public static Size MeasureText(IDeviceContext dc, string?text, Font?font, Size proposedSize)
 => MeasureTextInternal(dc, text, font, proposedSize);
Ejemplo n.º 55
0
		public static Size MeasureText (IDeviceContext dc, string text, Font font)
		{
			return MeasureTextInternal (dc, text, font, Size.Empty, TextFormatFlags.Default, false);
		}
Ejemplo n.º 56
0
 public static void DrawText(IDeviceContext dc, string text, Font font, Point pt, Color foreColor, TextFormatFlags flags)
 {
     throw null;
 }
Ejemplo n.º 57
0
        public unsafe bool TryGetCaptured(IDeviceContext context, IntRectangle clientRectangle, FrameType frameType, int colorDiffThreshold, int mostDetailedMip, out GpuRawFrame capturedFrame)
        {
            stopwatch.Restart();

            var result = texturePool.Extract(clientRectangle.Width, clientRectangle.Height);
            var resultTexture = result.Item;

            d3dDevice.GetFrontBufferData(0, d3dSurface1);
            var sdxRectangle = new Rectangle(clientRectangle.X, clientRectangle.Y, clientRectangle.X + clientRectangle.Width, clientRectangle.Y + clientRectangle.Height);

            var lockedRectangle = d3dSurface1.LockRectangle(sdxRectangle, LockFlags.ReadOnly);
            var mappedSubresource = context.Map(resultTexture, 0, MapType.WriteDiscard, MapFlags.None);
            {
                int commonRowPitch = Math.Min(mappedSubresource.RowPitch, lockedRectangle.Pitch);
                Parallel.For(0, clientRectangle.Height, i =>
                    Memory.CopyBulk(
                        (byte*)mappedSubresource.Data + i * mappedSubresource.RowPitch,
                        (byte*)lockedRectangle.DataPointer + i * lockedRectangle.Pitch,
                        commonRowPitch));
            }
            context.Unmap(resultTexture, 0);
            d3dSurface1.UnlockRectangle();

            var frameInfo = new FrameInfo(frameType, (float)Stopwatch.GetTimestamp() / Stopwatch.Frequency,
                mostDetailedMip, colorDiffThreshold, clientRectangle.Width, clientRectangle.Height,
                Cursor.Position.X - clientRectangle.X, Cursor.Position.Y - clientRectangle.Y);
            capturedFrame = new GpuRawFrame(frameInfo, result);

            stopwatch.Stop();
            statistics.OnCapture(stopwatch.Elapsed.TotalMilliseconds);

            return true;
        }
Ejemplo n.º 58
0
		internal static void DrawTextInternal (IDeviceContext dc, string text, Font font, Point pt, Color foreColor, Color backColor, TextFormatFlags flags, bool useDrawString)
		{
			Size sz = MeasureTextInternal (dc, text, font, useDrawString);
			DrawTextInternal (dc, text, font, new Rectangle (pt, sz), foreColor, backColor, flags, useDrawString);
		}
Ejemplo n.º 59
0
 internal static void DrawTextInternal(IDeviceContext dc, string text, Font font, Point pt, Color foreColor, Color backColor, bool useDrawString)
 {
     DrawTextInternal(dc, text, font, pt, foreColor, backColor, TextFormatFlags.Default, useDrawString);
 }
        public static void Draw(IDeviceContext dc, Size minSize, Size maxSize, string title, string text, Rectangle titleRect, Rectangle rect, ToolTipIcon icon, Padding padding)
        {
            if (Application.RenderWithVisualStyles)
            {
                VisualStyleRenderer titleRenderer = new VisualStyleRenderer(VisualStyleElement.ToolTip.BalloonTitle.Normal);
                VisualStyleRenderer balloonRenderer = new VisualStyleRenderer(VisualStyleElement.ToolTip.Balloon.Normal);
                balloonRenderer.DrawBackground(dc, rect);

                if (icon == ToolTipIcon.None)
                {
                    titleRenderer.DrawText(dc, new Rectangle(padding.Left, padding.Top, rect.Width - (padding.Left + padding.Right), titleRect.Height),
                        title, false, TextFormatFlags.Left | TextFormatFlags.WordEllipsis | TextFormatFlags.VerticalCenter);

                    Rectangle balloonTextBounds = new Rectangle(padding.Left, padding.Top + titleRect.Height, rect.Width - (padding.Left + padding.Right), rect.Height - (padding.Top + titleRect.Height + padding.Bottom));

                    balloonRenderer.DrawText(dc, balloonTextBounds,
                        text, false, TextFormatFlags.Left | TextFormatFlags.WordBreak | TextFormatFlags.VerticalCenter);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }