一.引子
因为一个同事要这个功能的combobox,索性就在网上查了下相关代码,最后借鉴了一些国内国外朋友的方法,把这些字体加载到了Combobox中,并在前面绘制了一些符号.同时,将一些不符合要求的FontStyle样式做了调整,使得全部的string转化为Font时都变的可用.
二.全部源代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Drawing.Text; namespace JCSControlLibary.JcsFontCombobox { public class FontsAPI { #region API声明 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public class LogFont { public int lfHeight; public int lfWidth; public int lfEscapement; public int lfOrientation; public FontWeight lfWeight; [MarshalAs(UnmanagedType.U1)] public bool lfItalic; [MarshalAs(UnmanagedType.U1)] public bool lfUnderline; [MarshalAs(UnmanagedType.U1)] public bool lfStrikeOut; public FontCharSet lfCharSet; public FontPrecision lfOutPrecision; public FontClipPrecision lfClipPrecision; public FontQuality lfQuality; public FontPitchAndFamily lfPitchAndFamily; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string lfFaceName; } public enum FontWeight : int { FW_DONTCARE = 0, FW_THIN = 100, FW_EXTRALIGHT = 200, FW_LIGHT = 300, FW_NORMAL = 400, FW_MEDIUM = 500, FW_SEMIBOLD = 600, FW_BOLD = 700, FW_EXTRABOLD = 800, FW_HEAVY = 900, } public enum FontCharSet : byte { ANSI_CHARSET = 0, DEFAULT_CHARSET = 1, SYMBOL_CHARSET = 2, SHIFTJIS_CHARSET = 128, HANGEUL_CHARSET = 129, HANGUL_CHARSET = 129, GB2312_CHARSET = 134, CHINESEBIG5_CHARSET = 136, OEM_CHARSET = 255, JOHAB_CHARSET = 130, HEBREW_CHARSET = 177, ARABIC_CHARSET = 178, GREEK_CHARSET = 161, TURKISH_CHARSET = 162, VIETNAMESE_CHARSET = 163, THAI_CHARSET = 222, EASTEUROPE_CHARSET = 238, RUSSIAN_CHARSET = 204, MAC_CHARSET = 77, BALTIC_CHARSET = 186, } public enum FontPrecision : byte { OUT_DEFAULT_PRECIS = 0, OUT_STRING_PRECIS = 1, OUT_CHARACTER_PRECIS = 2, OUT_STROKE_PRECIS = 3, OUT_TT_PRECIS = 4, OUT_DEVICE_PRECIS = 5, OUT_RASTER_PRECIS = 6, OUT_TT_ONLY_PRECIS = 7, OUT_OUTLINE_PRECIS = 8, OUT_SCREEN_OUTLINE_PRECIS = 9, OUT_PS_ONLY_PRECIS = 10, } public enum FontClipPrecision : byte { CLIP_DEFAULT_PRECIS = 0, CLIP_CHARACTER_PRECIS = 1, CLIP_STROKE_PRECIS = 2, CLIP_MASK = 0xf, CLIP_LH_ANGLES = (1 << 4), CLIP_TT_ALWAYS = (2 << 4), CLIP_DFA_DISABLE = (4 << 4), CLIP_EMBEDDED = (8 << 4), } public enum FontQuality : byte { DEFAULT_QUALITY = 0, DRAFT_QUALITY = 1, PROOF_QUALITY = 2, NONANTIALIASED_QUALITY = 3, ANTIALIASED_QUALITY = 4, CLEARTYPE_QUALITY = 5, CLEARTYPE_NATURAL_QUALITY = 6, } [Flags] public enum FontPitchAndFamily : byte { DEFAULT_PITCH = 0, FIXED_PITCH = 1, VARIABLE_PITCH = 2, FF_DONTCARE = (0 << 4), FF_ROMAN = (1 << 4), FF_SWISS = (2 << 4), FF_MODERN = (3 << 4), FF_SCRIPT = (4 << 4), FF_DECORATIVE = (5 << 4), } public const int LF_FACESIZE = 32; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct EnumLogFontEx { public LogFont elfLogFont; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)] public string elfFullName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)] public string elfStyle; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)] public string elfScript; } public delegate int EnumFontExDelegate(ref EnumLogFontEx lpelfe, IntPtr lpntme, int FontType, int lParam); [DllImport("gdi32.dll", EntryPoint = "EnumFontFamiliesEx", CharSet = CharSet.Unicode)] public static extern int EnumFontFamiliesEx(IntPtr hDC, [In, MarshalAs(UnmanagedType.LPStruct)] LogFont logFont, EnumFontExDelegate enumFontExCallback, IntPtr lParam, uint dwFlags); #endregion } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Drawing.Text; namespace Jcs控件Demo { public partial class JCSFontCombobox : ComboBox { public JCSFontCombobox() { InitializeComponent(); this.DrawMode = DrawMode.OwnerDrawFixed; this.DropDownStyle = ComboBoxStyle.DropDownList; this.ItemHeight = 21; DrawTheItem(); } private List list = new List (); private void DrawTheItem() { this.BeginUpdate(); this.Items.Clear(); Bitmap bmp = new Bitmap(10, 10); Graphics g = Graphics.FromImage(bmp); IntPtr hDC = g.GetHdc(); JCSControlLibary.JcsFontCombobox.FontsAPI.LogFont logFont = new JCSControlLibary.JcsFontCombobox.FontsAPI.LogFont(); logFont.lfCharSet = JCSControlLibary.JcsFontCombobox.FontsAPI.FontCharSet.DEFAULT_CHARSET; int intResult = JCSControlLibary.JcsFontCombobox.FontsAPI.EnumFontFamiliesEx(hDC, logFont, enumFontEx, IntPtr.Zero, 0); g.ReleaseHdc(hDC); g.Dispose(); bmp.Dispose(); if (list.Count > 0) { list.Sort(); foreach (string s in list) { this.Items.Add(s); } } this.EndUpdate(); } protected override void OnDrawItem(DrawItemEventArgs e) { base.OnDrawItem(e); if (e.Index < 0) return; Graphics g = e.Graphics; Rectangle rect = e.Bounds; string drawstr = string.Empty; using (SolidBrush b = new SolidBrush(Color.White)) { if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { b.Color = SystemColors.HighlightText; } else { b.Color = e.ForeColor; } //FontFamily item = this.Items[e.Index] as FontFamily; string str = this.Items[e.Index] as string; FontStyle style = FontStyle.Bold;//注意:获取字体时,使用Regular if (str == "Monotype Corsiva" || str == "Brush Script MT" || str == "Harlow Solid Italic" || str == "Palace Script MT" || str == "Vivaldi") { style = style | FontStyle.Italic; } rect.Inflate(-20, 0); //if (item.IsStyleAvailable(style)) e.DrawBackground(); using (SolidBrush br = new SolidBrush(Color.Blue)) { if (str.IndexOf('@') == 0) { drawstr = "ab"; style = style | FontStyle.Underline; g.DrawString(drawstr, new Font("Arial", 8, style), br, new Rectangle(rect.X - 20, rect.Y, 24, rect.Height -1)); //g.DrawString(drawstr, new Font(str, 10, style), br, new Rectangle(rect.X - 12, rect.Y + 3, 16, rect.Height)); } else { drawstr ="T"; g.DrawString(drawstr, new Font(str, 8, style), br, new Rectangle(rect.X - 20, rect.Y, 20, rect.Height -1)); g.DrawString(drawstr, new Font(str, 8, style), br, new Rectangle(rect.X - 16, rect.Y + 3, 20, 17)); } } g.DrawString(str, this.Font,b, rect.X, rect.Y); } } int enumFontEx(ref JCSControlLibary.JcsFontCombobox.FontsAPI.EnumLogFontEx lpelfe, IntPtr lpntme, int FontType, int lParam) { if (list.Contains(lpelfe.elfFullName) == false) { list.Add(lpelfe.elfFullName); } return 1; } } }