17 using System.Collections.Generic;
18 using System.ComponentModel;
20 using System.Runtime.InteropServices;
21 using System.Windows.Forms;
25 namespace sage.ew.formul.ButtonTittle
30 internal class ActiveMenuImpl : Form, IActiveMenu
36 private static readonly Dictionary<Form, IActiveMenu> parents;
43 private readonly ActiveItemsImpl items;
45 private readonly Size originalMinSize;
50 private readonly Form parentForm;
52 private readonly SpillOverMode spillOverMode;
53 private readonly ThemeFactory themeFactory;
59 private int containerMaxWidth;
61 private bool isActivated;
63 private ToolTip tooltip;
66 private bool _disposed =
false;
68 static ActiveMenuImpl()
70 parents =
new Dictionary<Form, IActiveMenu>();
78 private ActiveMenuImpl(Form form)
80 InitializeComponent();
81 items =
new ActiveItemsImpl();
82 items.CollectionModified += ItemsCollectionModified;
85 parentForm.Disposed += ParentFormDisposed;
87 isActivated = form.WindowState != FormWindowState.Minimized;
88 themeFactory =
new ThemeFactory(form);
89 theme = themeFactory.GetTheme();
90 originalMinSize = form.MinimumSize;
92 ToolTip.ShowAlways =
true;
93 TopMost = form.TopMost;
95 spillOverMode = SpillOverMode.IncreaseSize;
106 protected override CreateParams CreateParams
110 CreateParams p = base.CreateParams;
111 p.Style = (int) Win32.WS_CHILD;
112 p.Style |= (
int) Win32.WS_CLIPSIBLINGS;
113 p.ExStyle &= (int) Win32.WS_EX_LAYERED;
114 p.Parent = Win32.GetDesktopWindow();
119 #region IActiveMenu Members 124 public IActiveItems Items
126 get {
return items; }
133 public ToolTip ToolTip
135 get {
return tooltip ?? (tooltip =
new ToolTip()); }
136 set { tooltip = value; }
140 private Color InactiveTittleColor
144 if (inactiveTittleColor == null)
146 Point actmenupos =
new Point(Left - 1, Top);
147 inactiveTittleColor = GetPixel(actmenupos);
150 return inactiveTittleColor;
153 private dynamic inactiveTittleColor = null;
160 public static IActiveMenu GetInstance(Form form)
162 if (!parents.ContainsKey(form))
164 parents.Add(form,
new ActiveMenuImpl(form));
166 return parents[form];
173 protected override void OnLoad(EventArgs e)
184 private void ItemsCollectionModified(
object sender, ListModificationEventArgs e)
187 foreach (ActiveButton button
in Items)
189 Controls.Add(button);
198 private void ParentFormDisposed(
object sender, EventArgs e)
200 var form = (Form)sender;
205 if (parents.ContainsKey(form))
207 parents.Remove(form);
215 protected void AttachHandlers()
217 parentForm.Deactivate += ParentFormDeactivate;
218 parentForm.Activated += ParentFormActivated;
219 parentForm.SizeChanged += ParentRefresh;
220 parentForm.VisibleChanged += ParentRefresh;
221 parentForm.Move += ParentRefresh;
222 parentForm.SystemColorsChanged += TitleButtonSystemColorsChanged;
224 if (Win32.DwmIsCompositionEnabled)
228 TransparencyKey =
Color.LightGray;
241 private void CancelAttachHandlers()
243 if (parentForm == null)
246 parentForm.Deactivate -= ParentFormDeactivate;
247 parentForm.Activated -= ParentFormActivated;
248 parentForm.SizeChanged -= ParentRefresh;
249 parentForm.VisibleChanged -= ParentRefresh;
250 parentForm.Move -= ParentRefresh;
251 parentForm.SystemColorsChanged -= TitleButtonSystemColorsChanged;
257 public bool _ParentFormActivated =
true;
264 private void ParentFormDeactivate(
object sender, EventArgs e)
266 ToolTip.ShowAlways =
false;
267 _ParentFormActivated =
false;
269 foreach (Control loCtrl
in Controls)
281 private void ParentFormActivated(
object sender, EventArgs e)
283 ToolTip.ShowAlways =
true;
284 _ParentFormActivated =
true;
286 foreach (Control loCtrl
in Controls)
295 private void TitleButtonSystemColorsChanged(
object sender, EventArgs e)
297 theme = themeFactory.GetTheme();
306 private void CalcSize()
309 for (
int i = (Items.Count - 1); i >= 0; i--)
311 var button = (ThemedItem) Items[i];
312 button.Theme = theme;
314 left += Items[i].Width;
315 button.Top = theme.ButtonOffset.Y;
317 containerMaxWidth = left;
319 if (spillOverMode == SpillOverMode.IncreaseSize)
321 int w = containerMaxWidth + theme.ControlBoxSize.Width + theme.FrameBorder.Width + theme.FrameBorder.Width;
323 parentForm.MinimumSize = originalMinSize;
325 if (parentForm.MinimumSize.Width <= w)
327 parentForm.MinimumSize =
new Size(w, parentForm.MinimumSize.Height);
335 protected void ParentRefresh(
object sender, EventArgs e)
337 if (parentForm.WindowState == FormWindowState.Minimized || !parentForm.Visible)
349 private Color GetPixel(Point position)
351 Color colorpicked = SystemColors.ActiveCaption;
355 using (var bitmap =
new Bitmap(1, 1))
357 using (var graphics = Graphics.FromImage(bitmap))
359 graphics.CopyFromScreen(position,
new Point(0, 0),
new Size(1, 1));
361 colorpicked = bitmap.GetPixel(0, 0);
372 public Color GetChromeColor()
374 int hr1 = DwmIsCompositionEnabled(out
bool isEnabled);
375 if ((hr1 != 0) || !isEnabled)
377 return SystemColors.ActiveCaption;
380 DWMCOLORIZATIONPARAMS parameters;
384 int hr2 = DwmGetColorizationParameters(out parameters);
387 return SystemColors.ActiveCaption;
392 return SystemColors.ActiveCaption;
397 (byte)(parameters.colorizationColor >> 16),
398 (byte)(parameters.colorizationColor >> 8),
399 (byte)parameters.colorizationColor);
402 Color baseColor =
Color.FromArgb(217, 217, 217);
405 return BlendColor(targetColor, baseColor, 100 - parameters.colorizationColorBalance);
408 private Color BlendColor(Color color1, Color color2,
double color2Perc)
410 if ((color2Perc < 0) || (100 < color2Perc))
412 throw new ArgumentOutOfRangeException(
"color2Perc");
415 return Color.FromArgb(
416 BlendColorChannel(color1.R, color2.R, color2Perc),
417 BlendColorChannel(color1.G, color2.G, color2Perc),
418 BlendColorChannel(color1.B, color2.B, color2Perc));
421 private byte BlendColorChannel(
double channel1,
double channel2,
double channel2Perc)
423 var buff = channel1 + (channel2 - channel1) * channel2Perc / 100D;
424 return Math.Min((byte)Math.Round(buff), (byte)255);
427 [DllImport(
"Dwmapi.dll")]
428 private static extern int DwmIsCompositionEnabled([MarshalAs(UnmanagedType.Bool)] out
bool pfEnabled);
430 [DllImport(
"Dwmapi.dll", EntryPoint =
"#127")]
431 private static extern int DwmGetColorizationParameters(out DWMCOLORIZATIONPARAMS parameters);
433 [StructLayout(LayoutKind.Sequential)]
434 private struct DWMCOLORIZATIONPARAMS
436 public uint colorizationColor;
437 public uint colorizationAfterglow;
438 public uint colorizationColorBalance;
439 public uint colorizationAfterglowBalance;
440 public uint colorizationBlurBalance;
441 public uint colorizationGlassReflectionIntensity;
442 public uint colorizationOpaqueBlend;
448 private void OnPosition()
452 if (theme == null || !theme.IsDisplayed)
458 int top = theme.FrameBorder.Height;
459 int left = theme.FrameBorder.Width + theme.ControlBoxSize.Width;
461 Top = top + parentForm.Top;
462 Left = parentForm.Left + parentForm.Width - containerMaxWidth - left ;
468 else if (theme is Aero)
470 if (
System.Diagnostics.Debugger.IsAttached)
472 switch (parentForm.FormBorderStyle)
474 case FormBorderStyle.Sizable:
477 case FormBorderStyle.FixedSingle:
478 case FormBorderStyle.FixedDialog:
484 else if (theme is Aero8)
486 switch (parentForm.FormBorderStyle)
488 case FormBorderStyle.Sizable:
491 case FormBorderStyle.FixedSingle:
492 case FormBorderStyle.FixedDialog:
497 else if (theme is Aero10)
499 switch (parentForm.FormBorderStyle)
501 case FormBorderStyle.FixedDialog:
507 if (!(theme is Aero) && Left - 1 > 0 && Top > 0)
509 Point actmenupos =
new Point(Left - 1, Top);
512 if (_ParentFormActivated)
516 backColor =
Color.White;
520 backColor = GetChromeColor();
525 backColor = InactiveTittleColor;
528 if (Convert.ToInt32(backColor.R) > 0 || Convert.ToInt32(backColor.G) > 0 || Convert.ToInt32(backColor.B) > 0)
531 Math.Min(255, Convert.ToInt32(backColor.R * 1.01)),
532 Math.Min(255, Convert.ToInt32(backColor.G * 1.01f)),
533 Math.Min(255, Convert.ToInt32(backColor.B * 1.01f)));
536 foreach (ActiveButton button
in Items)
538 button.ChangeColors();
542 Visible = theme.IsDisplayed && isActivated;
548 if (theme is Aero || theme is Aero8 || theme is Aero10)
551 Opacity = parentForm.Opacity;
553 if (parentForm.Visible)
555 if (theme is Aero || theme is Aero8 || theme is Aero10)
558 Opacity = parentForm.Opacity;
565 if (spillOverMode == SpillOverMode.Hide)
567 foreach (ActiveButton b
in Items)
569 if (b.Left + Left - theme.FrameBorder.Width + 2 < parentForm.Left)
587 protected override void Dispose(
bool disposing)
593 CancelAttachHandlers();
595 base.Dispose(disposing);
605 private void InitializeComponent()
607 this.SuspendLayout();
611 this.AutoSize =
true;
612 this.AutoSizeMode =
System.Windows.Forms.AutoSizeMode.GrowAndShrink;
613 this.ClientSize =
new System.Drawing.Size(10, 10);
614 this.ControlBox =
false;
615 this.Font =
new System.Drawing.Font(
"Segoe UI", 9F,
System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
616 this.FormBorderStyle =
System.Windows.Forms.FormBorderStyle.None;
617 this.MaximizeBox =
false;
618 this.MinimizeBox =
false;
619 this.Name =
"ActiveMenuImpl";
620 this.ShowIcon =
false;
621 this.ShowInTaskbar =
false;
622 this.SizeGripStyle =
System.Windows.Forms.SizeGripStyle.Hide;
623 this.ResumeLayout(
false);