예제 #1
0
            public IntPtr MarshalManagedToNative(object obj)
            {
                Font font = (Font)obj;

                User32.LOGFONTW logFont  = User32.LOGFONTW.FromFont(font);
                var             fontDesc = new Oleaut32.FONTDESC
                {
                    cbSizeOfStruct = (uint)Marshal.SizeOf <Oleaut32.FONTDESC>(),
                    lpstrName      = font.Name,
                    cySize         = (long)(font.SizeInPoints * 10000),
                    sWeight        = (short)logFont.lfWeight,
                    sCharset       = logFont.lfCharSet,
                    fItalic        = font.Italic.ToBOOL(),
                    fUnderline     = font.Underline.ToBOOL(),
                    fStrikethrough = font.Strikeout.ToBOOL(),
                };
                Guid iid = typeof(Ole32.IFont).GUID;

                Ole32.IFont oleFont = Oleaut32.OleCreateFontIndirect(ref fontDesc, ref iid);
                IntPtr      pFont   = Marshal.GetIUnknownForObject(oleFont);

                int hr = Marshal.QueryInterface(pFont, ref iid, out IntPtr pIFont);

                Marshal.Release(pFont);

                if (((HRESULT)hr).Failed())
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                return(pIFont);
            }
예제 #2
0
        /// <summary>
        ///  Creates the font handle.
        /// </summary>
        private unsafe WindowsFont(User32.LOGFONTW logFont, FontStyle style, bool createHandle)
        {
            Debug.Assert(Hfont == IntPtr.Zero, "hFont is not null, this will generate a handle leak.");

            _logFont = logFont;
            if (_logFont.FaceName.Length == 0)
            {
                _logFont.FaceName = DefaultFaceName;
            }
            Style = style;

            if (createHandle)
            {
                Hfont = Gdi32.CreateFontIndirectW(ref _logFont);

                if (Hfont == IntPtr.Zero)
                {
                    _logFont.FaceName       = DefaultFaceName;
                    _logFont.lfOutPrecision = Gdi32.OUT_PRECIS.TT_ONLY; // TrueType only.

                    Hfont = Gdi32.CreateFontIndirectW(ref _logFont);
                }

                // Update logFont height and other adjusted parameters.
                Gdi32.GetObjectW(new HandleRef(this, Hfont), out _logFont);

                // We created the hFont, we will delete it on dispose.
                _ownHandle = true;
            }
        }
예제 #3
0
        public unsafe void CreateFontIndirect()
        {
            User32.LOGFONTW logFont = default;
            IntPtr          handle  = Gdi32.CreateFontIndirectW(ref logFont);

            Assert.NotEqual(IntPtr.Zero, handle);
            Assert.True(Gdi32.DeleteObject(handle).IsTrue());
        }
예제 #4
0
            /// <summary>
            ///  Constructs a WindowsFont object from an existing System.Drawing.Font object (GDI+), based on the screen dc
            ///  MapMode and resolution (normally: MM_TEXT and 96 dpi).
            /// </summary>
            private static Gdi32.HFONT FromFont(Font font, Gdi32.QUALITY quality = Gdi32.QUALITY.DEFAULT)
            {
                string familyName = font.FontFamily.Name;

                // Strip vertical-font mark from the name if needed.
                if (familyName != null && familyName.Length > 1 && familyName[0] == '@')
                {
                    familyName = familyName.Substring(1);
                }

                // Now, creating it using the Font.SizeInPoints makes it GraphicsUnit-independent.

                Debug.Assert(font.SizeInPoints > 0.0f, "size has a negative value.");

                // Get the font height from the specified size. The size is in point units and height in logical units
                // (pixels when using MM_TEXT) so we need to make the conversion using the number of pixels per logical
                // inch along the screen height. (1 point = 1/72 inch.)
                int pixelsY = (int)Math.Ceiling(DpiHelper.DeviceDpi * font.SizeInPoints / 72);

                // The lfHeight represents the font cell height (line spacing) which includes the internal leading; we
                // specify a negative size value (in pixels) for the height so the font mapper provides the closest match
                // for the character height rather than the cell height.

                User32.LOGFONTW logFont = new User32.LOGFONTW
                {
                    lfHeight       = -pixelsY,
                    lfCharSet      = font.GdiCharSet,
                    lfOutPrecision = Gdi32.OUT_PRECIS.TT,
                    lfQuality      = quality,
                    lfWeight       = (font.Style & FontStyle.Bold) == FontStyle.Bold ? Gdi32.FW.BOLD : Gdi32.FW.NORMAL,
                    lfItalic       = (font.Style & FontStyle.Italic) == FontStyle.Italic ? True : False,
                    lfUnderline    = (font.Style & FontStyle.Underline) == FontStyle.Underline ? True : False,
                    lfStrikeOut    = (font.Style & FontStyle.Strikeout) == FontStyle.Strikeout ? True : False,
                    FaceName       = familyName
                };

                if (logFont.FaceName.IsEmpty)
                {
                    logFont.FaceName = DefaultFaceName;
                }

                Gdi32.HFONT hfont = Gdi32.CreateFontIndirectW(ref logFont);

                if (hfont.IsNull)
                {
                    // Get the default font if we couldn't get what we requested.
                    logFont.FaceName       = DefaultFaceName;
                    logFont.lfOutPrecision = Gdi32.OUT_PRECIS.TT_ONLY;
                    hfont = Gdi32.CreateFontIndirectW(ref logFont);

                    Debug.Assert(!hfont.IsNull);
                }

                return(hfont);
            }
예제 #5
0
            protected unsafe override void WndProc(ref Message m)
            {
                if (m.Msg == (int)User32.WM.CHOOSEFONT_GETLOGFONT)
                {
                    using var font = new Font("Arial", 8.25f);
                    User32.LOGFONTW *pLogfont = (User32.LOGFONTW *)m.LParam;
                    object           lf       = new User32.LOGFONTW();
                    font.ToLogFont(lf);
                    *pLogfont = (User32.LOGFONTW)lf;
                }

                base.WndProc(ref m);
            }
예제 #6
0
        public unsafe void LogFont_FaceName()
        {
            User32.LOGFONTW logFont = default;
            logFont.FaceName = "TwoFace";
            Assert.Equal("TwoFace", logFont.FaceName.ToString());

            // Set a smaller name to make sure it gets terminated properly.
            logFont.FaceName = "Face";
            Assert.Equal("Face", logFont.FaceName.ToString());

            // LOGFONT has space for 32 characters, we want to see it gets
            // cut to 31 to make room for the null.
            string bigString = new string('*', 32);

            logFont.FaceName = bigString;
            Assert.True(logFont.FaceName.SequenceEqual(bigString.AsSpan().Slice(1)));
        }
        public Font GetFont(IDeviceContext dc, FontProperty prop)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            //valid values are 0xa29 to 0xa29
            if (!ClientUtils.IsEnumValid(prop, (int)prop, (int)FontProperty.GlyphFont, (int)FontProperty.GlyphFont))
            {
                throw new InvalidEnumArgumentException(nameof(prop), (int)prop, typeof(FontProperty));
            }

            User32.LOGFONTW logfont = new User32.LOGFONTW();

            using (WindowsGraphicsWrapper wgr = new WindowsGraphicsWrapper(dc, AllGraphicsProperties))
            {
                HandleRef hdc = new HandleRef(wgr, wgr.WindowsGraphics.DeviceContext.Hdc);
                lastHResult = UxTheme.GetThemeFont(new HandleRef(this, Handle), hdc, part, state, (int)prop, ref logfont);
            }

            Font font = null;

            //check for a failed HR.
            if (lastHResult.Succeeded())
            {
                try
                {
                    font = Font.FromLogFont(logfont);
                }
                catch (Exception e)
                {
                    if (ClientUtils.IsSecurityOrCriticalException(e))
                    {
                        throw;
                    }

                    //Looks like the font was not true type
                    font = null;
                }
            }

            return(font);
        }
예제 #8
0
        /// <summary>
        ///  Contructs a WindowsFont object from an existing System.Drawing.Font object (GDI+), based on the screen dc MapMode
        ///  and resolution (normally: MM_TEXT and 96 dpi).
        /// </summary>
        public static WindowsFont FromFont(Font font, Gdi32.QUALITY fontQuality = Gdi32.QUALITY.DEFAULT)
        {
            string familyName = font.FontFamily.Name;

            // Strip vertical-font mark from the name if needed.
            if (familyName != null && familyName.Length > 1 && familyName[0] == '@')
            {
                familyName = familyName.Substring(1);
            }

            // Note: Creating the WindowsFont from Font using a LOGFONT structure from GDI+ (Font.ToLogFont(logFont)) may sound like
            // a better choice (more accurate) for doing this but tests show that is not the case (see WindowsFontTests test suite),
            // the results are the same.  Also, that approach has some issues when the Font is created in a different application
            // domain since the LOGFONT cannot be marshalled properly.

            // Now, creating it using the Font.SizeInPoints makes it GraphicsUnit-independent.

            Debug.Assert(font.SizeInPoints > 0.0f, "size has a negative value.");

            // Get the font height from the specified size.  size is in point units and height in logical
            // units (pixels when using MM_TEXT) so we need to make the conversion using the number of
            // pixels per logical inch along the screen height. (1 point = 1/72 inch.)
            int pixelsY = (int)Math.Ceiling(WindowsGraphicsCacheManager.MeasurementGraphics.DeviceContext.DpiY * font.SizeInPoints / 72);

            // The lfHeight represents the font cell height (line spacing) which includes the internal
            // leading; we specify a negative size value (in pixels) for the height so the font mapper
            // provides the closest match for the character height rather than the cell height (MSDN).

            User32.LOGFONTW logFont = new User32.LOGFONTW()
            {
                lfHeight       = -pixelsY,
                lfCharSet      = font.GdiCharSet,
                lfOutPrecision = Gdi32.OUT_PRECIS.TT,
                lfQuality      = fontQuality,
                lfWeight       = (font.Style & FontStyle.Bold) == FontStyle.Bold ? Gdi32.FW.BOLD : Gdi32.FW.NORMAL,
                lfItalic       = (font.Style & FontStyle.Italic) == FontStyle.Italic ? True : False,
                lfUnderline    = (font.Style & FontStyle.Underline) == FontStyle.Underline ? True : False,
                lfStrikeOut    = (font.Style & FontStyle.Strikeout) == FontStyle.Strikeout ? True : False,
                FaceName       = familyName
            };

            return(new WindowsFont(logFont, font.Style, createHandle: true));
        }
 public static extern HFONT CreateFontIndirectW(ref User32.LOGFONTW lplf);
예제 #10
0
        public static HRESULT GetThemeFont(IHandle hTheme, HandleRef hdc, int iPartId, int iStateId, int iPropId, out User32.LOGFONTW pFont)
        {
            HRESULT result = GetThemeFont(hTheme.Handle, hdc.Handle, iPartId, iStateId, iPropId, out pFont);

            GC.KeepAlive(hTheme);
            GC.KeepAlive(hdc.Wrapper);
            return(result);
        }
예제 #11
0
 public static extern HRESULT GetThemeFont(IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, int iPropId, out User32.LOGFONTW pFont);
예제 #12
0
 public static partial HRESULT GetThemeFont(IntPtr hTheme, Gdi32.HDC hdc, int iPartId, int iStateId, int iPropId, out User32.LOGFONTW pFont);