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); }
/// <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; } }
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()); }
/// <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); }
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); }
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); }
/// <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);
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); }
public static extern HRESULT GetThemeFont(IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, int iPropId, out User32.LOGFONTW pFont);
public static partial HRESULT GetThemeFont(IntPtr hTheme, Gdi32.HDC hdc, int iPartId, int iStateId, int iPropId, out User32.LOGFONTW pFont);