ToolStripFontComboBox.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Windows.Forms;
  4. using System.Drawing;
  5. using System.Runtime.InteropServices;
  6. using System.ComponentModel;
  7. using FastReport.Utils;
  8. namespace FastReport.Controls
  9. {
  10. internal class ToolStripFontComboBox : ToolStripComboBox
  11. {
  12. private List<string> mruFonts;
  13. private List<string> existingFonts;
  14. private FontStyle[] styles;
  15. private string fontName;
  16. public event EventHandler FontSelected;
  17. public new Control Owner { get; set; }
  18. [Browsable(false)]
  19. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  20. public string FontName
  21. {
  22. get { return (string)ComboBox.SelectedItem; }
  23. set
  24. {
  25. fontName = value;
  26. int i = ComboBox.Items.IndexOf(value);
  27. if (i != -1)
  28. ComboBox.SelectedIndex = i;
  29. else
  30. ComboBox.SelectedItem = null;
  31. }
  32. }
  33. [Browsable(false)]
  34. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  35. public string MruFonts
  36. {
  37. get
  38. {
  39. string result = "";
  40. foreach (string s in mruFonts)
  41. result += "," + s;
  42. if (result.StartsWith(","))
  43. result = result.Substring(1);
  44. return result;
  45. }
  46. set
  47. {
  48. mruFonts.Clear();
  49. if (!String.IsNullOrEmpty(value))
  50. {
  51. string[] fonts = value.Split(',');
  52. foreach (string s in fonts)
  53. mruFonts.Add(s);
  54. }
  55. UpdateFonts();
  56. }
  57. }
  58. [Browsable(false)]
  59. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  60. public new System.Windows.Forms.ComboBox.ObjectCollection Items
  61. {
  62. get { return base.Items; }
  63. }
  64. private FontStyle GetFirstAvailableFontStyle(FontFamily family)
  65. {
  66. foreach (FontStyle style in styles)
  67. {
  68. if (family.IsStyleAvailable(style))
  69. return style;
  70. }
  71. return FontStyle.Regular;
  72. }
  73. private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
  74. {
  75. if (!Enabled)
  76. return;
  77. Graphics g = e.Graphics;
  78. e.DrawBackground();
  79. if ((e.State & DrawItemState.ComboBoxEdit) > 0)
  80. {
  81. if (!String.IsNullOrEmpty(fontName))
  82. TextRenderer.DrawText(g, fontName, e.Font, e.Bounds.Location, e.ForeColor);
  83. }
  84. else if (e.Index >= 0)
  85. {
  86. string name = (string)Items[e.Index];
  87. if (!existingFonts.Contains(name))
  88. return;
  89. using (FontFamily family = new FontFamily(name))
  90. using (Font font = Owner.LogicalToDevice(new Font(name, 14, GetFirstAvailableFontStyle(family)), true))
  91. {
  92. g.DrawImage(Owner.GetImage(59), e.Bounds.X + 2, e.Bounds.Y + 2);
  93. LOGFONT lf = new LOGFONT();
  94. font.ToLogFont(lf);
  95. SizeF sz;
  96. if (lf.lfCharSet == 2)
  97. {
  98. sz = g.MeasureString(name, e.Font);
  99. int w = (int)sz.Width;
  100. TextRenderer.DrawText(g, name, e.Font, new Point(e.Bounds.X + 20, e.Bounds.Y + (e.Bounds.Height - (int)sz.Height) / 2), e.ForeColor);
  101. sz = g.MeasureString(name, font);
  102. TextRenderer.DrawText(g, name, font, new Point(e.Bounds.X + w + 28, e.Bounds.Y + (e.Bounds.Height - (int)sz.Height) / 2), e.ForeColor);
  103. }
  104. else
  105. {
  106. sz = g.MeasureString(name, font);
  107. TextRenderer.DrawText(g, name, font, new Point(e.Bounds.X + 20, e.Bounds.Y + (e.Bounds.Height - (int)sz.Height) / 2), e.ForeColor);
  108. }
  109. if (e.Index == mruFonts.Count - 1)
  110. {
  111. g.DrawLine(Pens.Gray, e.Bounds.Left, e.Bounds.Bottom - 3, e.Bounds.Right, e.Bounds.Bottom - 3);
  112. g.DrawLine(Pens.Gray, e.Bounds.Left, e.Bounds.Bottom - 1, e.Bounds.Right, e.Bounds.Bottom - 1);
  113. }
  114. }
  115. }
  116. }
  117. private void ComboBox_MeasureItem(object sender, MeasureItemEventArgs e)
  118. {
  119. if (Owner != null)
  120. e.ItemHeight = Owner.LogicalToDevice(24);
  121. }
  122. private void ComboBox_SelectionChangeCommitted(object sender, EventArgs e)
  123. {
  124. OnFontSelected();
  125. if (mruFonts.Contains(FontName))
  126. mruFonts.Remove(FontName);
  127. mruFonts.Insert(0, FontName);
  128. while (mruFonts.Count > 5)
  129. mruFonts.RemoveAt(5);
  130. UpdateFonts();
  131. }
  132. private void OnFontSelected()
  133. {
  134. if (FontSelected != null)
  135. FontSelected(this, EventArgs.Empty);
  136. }
  137. private void UpdateFonts()
  138. {
  139. Items.Clear();
  140. foreach (string s in mruFonts)
  141. {
  142. if (existingFonts.Contains(s))
  143. Items.Add(s);
  144. }
  145. foreach (string s in existingFonts)
  146. {
  147. Items.Add(s);
  148. }
  149. }
  150. public void UpdateDpiDependencies()
  151. {
  152. ComboBox.ItemHeight = Owner.LogicalToDevice(15);
  153. DropDownHeight = Owner.LogicalToDevice(302);
  154. DropDownWidth = Owner.LogicalToDevice(270);
  155. }
  156. public ToolStripFontComboBox()
  157. {
  158. mruFonts = new List<string>();
  159. existingFonts = new List<string>();
  160. styles = new FontStyle[] { FontStyle.Regular, FontStyle.Bold, FontStyle.Italic,
  161. FontStyle.Strikeout, FontStyle.Underline };
  162. foreach (FontFamily family in FontFamily.Families)
  163. {
  164. existingFonts.Add(family.Name);
  165. }
  166. existingFonts.Sort();
  167. AutoSize = false;
  168. ComboBox.DrawMode = DrawMode.OwnerDrawVariable;
  169. ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
  170. ComboBox.DrawItem += ComboBox_DrawItem;
  171. ComboBox.MeasureItem += ComboBox_MeasureItem;
  172. ComboBox.SelectionChangeCommitted += ComboBox_SelectionChangeCommitted;
  173. UpdateFonts();
  174. }
  175. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  176. private class LOGFONT
  177. {
  178. public int lfHeight;
  179. public int lfWidth;
  180. public int lfEscapement;
  181. public int lfOrientation;
  182. public int lfWeight;
  183. public byte lfItalic;
  184. public byte lfUnderline;
  185. public byte lfStrikeOut;
  186. public byte lfCharSet;
  187. public byte lfOutPrecision;
  188. public byte lfClipPrecision;
  189. public byte lfQuality;
  190. public byte lfPitchAndFamily;
  191. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
  192. public string lfFaceName;
  193. }
  194. }
  195. }