コード例 #1
0
 public DRAWTEXTPARAMS(IntNativeMethods.DRAWTEXTPARAMS original)
 {
     this.cbSize       = Marshal.SizeOf(typeof(IntNativeMethods.DRAWTEXTPARAMS));
     this.iLeftMargin  = original.iLeftMargin;
     this.iRightMargin = original.iRightMargin;
     this.iTabLength   = original.iTabLength;
 }
コード例 #2
0
        internal static IntNativeMethods.DRAWTEXTPARAMS GetTextMargins(WindowsGraphics wg, WindowsFont font)
        {
            CachedInfo cachedMeasurementDCInfo = MeasurementDCInfo.cachedMeasurementDCInfo;

            if (((cachedMeasurementDCInfo == null) || (cachedMeasurementDCInfo.LeftTextMargin <= 0)) || ((cachedMeasurementDCInfo.RightTextMargin <= 0) || (font != cachedMeasurementDCInfo.LastUsedFont)))
            {
                if (cachedMeasurementDCInfo == null)
                {
                    cachedMeasurementDCInfo = new CachedInfo();
                    MeasurementDCInfo.cachedMeasurementDCInfo = cachedMeasurementDCInfo;
                }
                IntNativeMethods.DRAWTEXTPARAMS textMargins = wg.GetTextMargins(font);
                cachedMeasurementDCInfo.LeftTextMargin  = textMargins.iLeftMargin;
                cachedMeasurementDCInfo.RightTextMargin = textMargins.iRightMargin;
            }
            return(new IntNativeMethods.DRAWTEXTPARAMS(cachedMeasurementDCInfo.LeftTextMargin, cachedMeasurementDCInfo.RightTextMargin));
        }
コード例 #3
0
        public Size MeasureText(string text, WindowsFont font, Size proposedSize, IntTextFormatFlags flags)
        {
            if (string.IsNullOrEmpty(text))
            {
                return(Size.Empty);
            }
            IntNativeMethods.DRAWTEXTPARAMS lpDTParams = null;
            if (MeasurementDCInfo.IsMeasurementDC(this.DeviceContext))
            {
                lpDTParams = MeasurementDCInfo.GetTextMargins(this, font);
            }
            if (lpDTParams == null)
            {
                lpDTParams = this.GetTextMargins(font);
            }
            int num = (1 + lpDTParams.iLeftMargin) + lpDTParams.iRightMargin;

            if (proposedSize.Width <= num)
            {
                proposedSize.Width = num;
            }
            if (proposedSize.Height <= 0)
            {
                proposedSize.Height = 1;
            }
            IntNativeMethods.RECT lpRect = IntNativeMethods.RECT.FromXYWH(0, 0, proposedSize.Width, proposedSize.Height);
            HandleRef             hDC    = new HandleRef(null, this.dc.Hdc);

            if (font != null)
            {
                this.dc.SelectFont(font);
            }
            if ((proposedSize.Height >= MaxSize.Height) && ((flags & IntTextFormatFlags.SingleLine) != IntTextFormatFlags.Default))
            {
                flags &= ~(IntTextFormatFlags.Bottom | IntTextFormatFlags.VerticalCenter);
            }
            if (proposedSize.Width == MaxSize.Width)
            {
                flags &= ~IntTextFormatFlags.WordBreak;
            }
            flags |= IntTextFormatFlags.CalculateRectangle;
            IntUnsafeNativeMethods.DrawTextEx(hDC, text, ref lpRect, (int)flags, lpDTParams);
            return(lpRect.Size);
        }
コード例 #4
0
 public void DrawText(string text, WindowsFont font, Rectangle bounds, Color foreColor, Color backColor, IntTextFormatFlags flags)
 {
     if (!string.IsNullOrEmpty(text) && (foreColor != Color.Transparent))
     {
         HandleRef hdc = new HandleRef(this.dc, this.dc.Hdc);
         if (this.dc.TextAlignment != DeviceContextTextAlignment.Top)
         {
             this.dc.SetTextAlignment(DeviceContextTextAlignment.Top);
         }
         if (!foreColor.IsEmpty && (foreColor != this.dc.TextColor))
         {
             this.dc.SetTextColor(foreColor);
         }
         if (font != null)
         {
             this.dc.SelectFont(font);
         }
         DeviceContextBackgroundMode newMode = (backColor.IsEmpty || (backColor == Color.Transparent)) ? DeviceContextBackgroundMode.Transparent : DeviceContextBackgroundMode.Opaque;
         if (this.dc.BackgroundMode != newMode)
         {
             this.dc.SetBackgroundMode(newMode);
         }
         if ((newMode != DeviceContextBackgroundMode.Transparent) && (backColor != this.dc.BackgroundColor))
         {
             this.dc.SetBackgroundColor(backColor);
         }
         IntNativeMethods.DRAWTEXTPARAMS textMargins = this.GetTextMargins(font);
         bounds = AdjustForVerticalAlignment(hdc, text, bounds, flags, textMargins);
         if (bounds.Width == MaxSize.Width)
         {
             bounds.Width -= bounds.X;
         }
         if (bounds.Height == MaxSize.Height)
         {
             bounds.Height -= bounds.Y;
         }
         IntNativeMethods.RECT lpRect = new IntNativeMethods.RECT(bounds);
         IntUnsafeNativeMethods.DrawTextEx(hdc, text, ref lpRect, (int)flags, textMargins);
     }
 }
コード例 #5
0
 public static int DrawTextEx(HandleRef hDC, string text, ref IntNativeMethods.RECT lpRect, int nFormat, [In, Out] IntNativeMethods.DRAWTEXTPARAMS lpDTParams)
 {
     if (Marshal.SystemDefaultCharSize == 1)
     {
         lpRect.top    = Math.Min(0x7fff, lpRect.top);
         lpRect.left   = Math.Min(0x7fff, lpRect.left);
         lpRect.right  = Math.Min(0x7fff, lpRect.right);
         lpRect.bottom = Math.Min(0x7fff, lpRect.bottom);
         int    num2      = WideCharToMultiByte(0, 0, text, text.Length, null, 0, IntPtr.Zero, IntPtr.Zero);
         byte[] pOutBytes = new byte[num2];
         WideCharToMultiByte(0, 0, text, text.Length, pOutBytes, pOutBytes.Length, IntPtr.Zero, IntPtr.Zero);
         num2 = Math.Min(num2, 0x2000);
         return(DrawTextExA(hDC, pOutBytes, num2, ref lpRect, nFormat, lpDTParams));
     }
     return(DrawTextExW(hDC, text, text.Length, ref lpRect, nFormat, lpDTParams));
 }
コード例 #6
0
 public static extern int DrawTextExW(HandleRef hDC, string lpszString, int nCount, ref IntNativeMethods.RECT lpRect, int nFormat, [In, Out] IntNativeMethods.DRAWTEXTPARAMS lpDTParams);
コード例 #7
0
        /// <summary>
        ///  The GDI DrawText does not do multiline alignment when IntTextFormatFlags.SingleLine is not set. This
        ///  adjustment is to workaround that limitation. We don't want to duplicate SelectObject calls here,
        ///  so put your Font in the dc before calling this.
        ///
        ///  AdjustForVerticalAlignment is only used when the text is multiline and it fits inside the bounds passed in.
        ///  In that case we want the horizontal center of the multiline text to be at the horizontal center of the bounds.
        ///
        ///  If the text is multiline and it does not fit inside the bounds passed in, then return the bounds that were passed in.
        ///  This way we paint the top of the text at the top of the bounds passed in.
        /// </summary>
        public static Rectangle AdjustForVerticalAlignment(HandleRef hdc, string text, Rectangle bounds, IntTextFormatFlags flags, IntNativeMethods.DRAWTEXTPARAMS dtparams)
        {
            Debug.Assert(((uint)flags & GdiUnsupportedFlagMask) == 0, "Some custom flags were left over and are not GDI compliant!");

            // Ok if any Top (Cannot test IntTextFormatFlags.Top because it is 0), single line text or measuring text.
            bool isTop = (flags & IntTextFormatFlags.Bottom) == 0 && (flags & IntTextFormatFlags.VerticalCenter) == 0;

            if (isTop || ((flags & IntTextFormatFlags.SingleLine) != 0) || ((flags & IntTextFormatFlags.CalculateRectangle) != 0))
            {
                return(bounds);
            }

            IntNativeMethods.RECT rect = new IntNativeMethods.RECT(bounds);

            // Get the text bounds.
            flags |= IntTextFormatFlags.CalculateRectangle;
            int textHeight = IntUnsafeNativeMethods.DrawTextEx(hdc, text, ref rect, (int)flags, dtparams);

            // if the text does not fit inside the bounds then return the bounds that were passed in
            if (textHeight > bounds.Height)
            {
                return(bounds);
            }

            Rectangle adjustedBounds = bounds;

            if ((flags & IntTextFormatFlags.VerticalCenter) != 0)  // Middle
            {
                adjustedBounds.Y = adjustedBounds.Top + adjustedBounds.Height / 2 - textHeight / 2;
            }
            else // Bottom.
            {
                adjustedBounds.Y = adjustedBounds.Bottom - textHeight;
            }

            return(adjustedBounds);
        }
コード例 #8
0
        /// <summary>
        ///  Returns the Size in logical units of the given text using the given Font, and according to the formatting flags.
        ///  The proposed size is used to create a bounding rectangle as follows:
        ///  - If there are multiple lines of text, DrawText uses the width of the rectangle pointed to by
        ///  the lpRect parameter and extends the base of the rectangle to bound the last line of text.
        ///  - If the largest word is wider than the rectangle, the width is expanded.
        ///  - If the text is less than the width of the rectangle, the width is reduced.
        ///  - If there is only one line of text, DrawText modifies the right side of the rectangle so that
        ///  it bounds the last character in the line.
        ///  If the font is null, the hdc's current font will be used.
        ///
        ///  Note for vertical fonts (if ever supported): DrawTextEx uses GetTextExtentPoint32 for measuring the text and this
        ///  function has the following limitation (from MSDN):
        ///  - This function assumes that the text is horizontal, that is, that the escapement is always 0. This is true for both
        ///  the horizontal and vertical measurements of the text.  The application must convert it explicitly.
        /// </summary>
        public Size MeasureText(string text, WindowsFont font, Size proposedSize, IntTextFormatFlags flags)
        {
            Debug.Assert(((uint)flags & GdiUnsupportedFlagMask) == 0, "Some custom flags were left over and are not GDI compliant!");

            if (string.IsNullOrEmpty(text))
            {
                return(Size.Empty);
            }

            //
            // DrawText returns a rectangle useful for aligning, but not guaranteed to encompass all
            // pixels (its not a FitBlackBox, if the text is italicized, it will overhang on the right.)
            // So we need to account for this.
            //
            IntNativeMethods.DRAWTEXTPARAMS dtparams = null;

#if OPTIMIZED_MEASUREMENTDC
            // use the cache if we've got it
            if (MeasurementDCInfo.IsMeasurementDC(DeviceContext))
            {
                dtparams = MeasurementDCInfo.GetTextMargins(this, font);
            }
#endif

            if (dtparams == null)
            {
                dtparams = GetTextMargins(font);
            }

            //
            // If Width / Height are < 0, we need to make them larger or DrawText will return
            // an unbounded measurement when we actually trying to make it very narrow.
            //

            int minWidth = 1 + dtparams.iLeftMargin + dtparams.iRightMargin;

            if (proposedSize.Width <= minWidth)
            {
                proposedSize.Width = minWidth;
            }
            if (proposedSize.Height <= 0)
            {
                proposedSize.Height = 1;
            }

            IntNativeMethods.RECT rect = IntNativeMethods.RECT.FromXYWH(0, 0, proposedSize.Width, proposedSize.Height);

            HandleRef hdc = new HandleRef(null, dc.Hdc);

            if (font != null)
            {
                dc.SelectFont(font);
            }

            // If proposedSize.Height >= MaxSize.Height it is assumed bounds needed.  If flags contain SingleLine and
            // VerticalCenter or Bottom options, DrawTextEx does not bind the rectangle to the actual text height since
            // it assumes the text is to be vertically aligned; we need to clear the VerticalCenter and Bottom flags to
            // get the actual text bounds.
            if (proposedSize.Height >= MaxSize.Height && (flags & IntTextFormatFlags.SingleLine) != 0)
            {
                // Clear vertical-alignment flags.
                flags &= ~(IntTextFormatFlags.Bottom | IntTextFormatFlags.VerticalCenter);
            }

            if (proposedSize.Width == MaxSize.Width)
            {
                // PERF: No constraining width means no word break.
                // in this case, we dont care about word wrapping - there should be enough room to fit it all
                flags &= ~(IntTextFormatFlags.WordBreak);
            }

            flags |= IntTextFormatFlags.CalculateRectangle;
            IntUnsafeNativeMethods.DrawTextEx(hdc, text, ref rect, (int)flags, dtparams);

            /* No need to restore previous objects into the dc (see comments on top of the class).
             *
             * if( hOldFont != IntPtr.Zero )
             * {
             *  this.dc.SelectObject(hOldFont);
             * }
             */

            return(rect.Size);
        }
コード例 #9
0
        /// <summary>
        ///  Draws the text in the given bounds, using the given Font, foreColor and backColor, and according to the specified
        ///  TextFormatFlags flags.
        ///  If font is null, the font currently selected in the hdc is used.
        ///  If foreColor and/or backColor are Color.Empty, the hdc current text and/or background color are used.
        /// </summary>
        public void DrawText(string text, WindowsFont font, Rectangle bounds, Color foreColor, Color backColor, IntTextFormatFlags flags)
        {
            if (string.IsNullOrEmpty(text) || foreColor == Color.Transparent)
            {
                return;
            }

            Debug.Assert(((uint)flags & GdiUnsupportedFlagMask) == 0, "Some custom flags were left over and are not GDI compliant!");
            Debug.Assert((flags & IntTextFormatFlags.CalculateRectangle) == 0, "CalculateRectangle flag is set, text won't be drawn");

            HandleRef hdc = new HandleRef(dc, dc.Hdc);

            // DrawText requires default text alignment.
            if (dc.TextAlignment != DeviceContextTextAlignment.Default)
            {
                dc.SetTextAlignment(DeviceContextTextAlignment.Default);
            }

            // color empty means use the one currently selected in the dc.

            if (!foreColor.IsEmpty && foreColor != dc.TextColor)
            {
                dc.SetTextColor(foreColor);
            }

            if (font != null)
            {
                dc.SelectFont(font);
            }

            DeviceContextBackgroundMode newBackGndMode = (backColor.IsEmpty || backColor == Color.Transparent) ?
                                                         DeviceContextBackgroundMode.Transparent :
                                                         DeviceContextBackgroundMode.Opaque;

            if (dc.BackgroundMode != newBackGndMode)
            {
                dc.SetBackgroundMode(newBackGndMode);
            }

            if (newBackGndMode != DeviceContextBackgroundMode.Transparent && backColor != dc.BackgroundColor)
            {
                dc.SetBackgroundColor(backColor);
            }

            IntNativeMethods.DRAWTEXTPARAMS dtparams = GetTextMargins(font);

            bounds = AdjustForVerticalAlignment(hdc, text, bounds, flags, dtparams);

            // Adjust unbounded rect to avoid overflow since Rectangle ctr does not do param validation.
            if (bounds.Width == MaxSize.Width)
            {
                bounds.Width -= bounds.X;
            }
            if (bounds.Height == MaxSize.Height)
            {
                bounds.Height -= bounds.Y;
            }

            IntNativeMethods.RECT rect = new IntNativeMethods.RECT(bounds);

            IntUnsafeNativeMethods.DrawTextEx(hdc, text, ref rect, (int)flags, dtparams);

            // No need to restore previous objects into the dc (see comments on top of the class).
        }
コード例 #10
0
        public static int DrawTextEx(HandleRef hDC, string text, ref IntNativeMethods.RECT lpRect, int nFormat, [In, Out] IntNativeMethods.DRAWTEXTPARAMS lpDTParams)
        {
            int retVal = DrawTextExW(hDC, text, text.Length, ref lpRect, nFormat, lpDTParams);

            DbgUtil.AssertWin32(retVal != 0, "DrawTextEx(hdc=[0x{0:X8}], text=[{1}], rect=[{2}], flags=[{3}] failed.", hDC.Handle, text, lpRect, nFormat);
            return(retVal);
        }
コード例 #11
0
        public static Rectangle AdjustForVerticalAlignment(HandleRef hdc, string text, Rectangle bounds, IntTextFormatFlags flags, IntNativeMethods.DRAWTEXTPARAMS dtparams)
        {
            if (((((flags & IntTextFormatFlags.Bottom) == IntTextFormatFlags.Default) && ((flags & IntTextFormatFlags.VerticalCenter) == IntTextFormatFlags.Default)) || ((flags & IntTextFormatFlags.SingleLine) != IntTextFormatFlags.Default)) || ((flags & IntTextFormatFlags.CalculateRectangle) != IntTextFormatFlags.Default))
            {
                return(bounds);
            }
            IntNativeMethods.RECT lpRect = new IntNativeMethods.RECT(bounds);
            flags |= IntTextFormatFlags.CalculateRectangle;
            int num = IntUnsafeNativeMethods.DrawTextEx(hdc, text, ref lpRect, (int)flags, dtparams);

            if (num > bounds.Height)
            {
                return(bounds);
            }
            Rectangle rectangle = bounds;

            if ((flags & IntTextFormatFlags.VerticalCenter) != IntTextFormatFlags.Default)
            {
                rectangle.Y = (rectangle.Top + (rectangle.Height / 2)) - (num / 2);
                return(rectangle);
            }
            rectangle.Y = rectangle.Bottom - num;
            return(rectangle);
        }