using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.ComponentModel; using System.Drawing.Imaging; using DevComponents.DotNetBar.Rendering; namespace DevComponents.DotNetBar { [ToolboxItem(false)] public class RadialMenuPopup : Control { #region Constructor /// /// Initializes a new instance of the RadialMenuPopup class. /// public RadialMenuPopup() { //this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.Text = "RadialMenuPopup"; //this.ShowInTaskbar = false; this.SetStyle(ControlStyles.Selectable, false); //this.StartPosition = FormStartPosition.Manual; //this.TopMost = true; } protected override void OnLocationChanged(EventArgs e) { base.OnLocationChanged(e); } #endregion #region Implementation private bool _Painting = false; protected override void OnInvalidated(InvalidateEventArgs e) { if (!this.IsHandleCreated || this.IsDisposed || _DisplayItem == null || _Painting) return; _Painting = true; try { if (_DisplayItem.NeedRecalcSize) _DisplayItem.RecalcSize(); Bitmap oldContent = this.ContentImage; Bitmap b = null; bool clearBitmap = false; if (oldContent != null && oldContent.Width == _DisplayItem.WidthInternal && oldContent.Height == _DisplayItem.HeightInternal) { b = oldContent; clearBitmap = true; } else { if (oldContent != null) oldContent.Dispose(); b = new Bitmap(_DisplayItem.WidthInternal, _DisplayItem.HeightInternal, PixelFormat.Format32bppArgb); } using (Graphics g = Graphics.FromImage(b)) { if (clearBitmap) g.Clear(Color.Transparent); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; ItemPaintArgs p = GetItemPaintArgs(g); _DisplayItem.Paint(p); } this.ContentImage = b; //if (oldContent != null) oldContent.Dispose(); } finally { _Painting = false; } base.OnInvalidated(e); } internal ItemPaintArgs GetItemPaintArgs(System.Drawing.Graphics g) { ItemPaintArgs pa = new ItemPaintArgs(this as IOwner, this, g, GetColorScheme()); pa.Renderer = this.GetRenderer(); if (_DisplayItem.DesignMode) { ISite site = this.GetSite(); if (site != null && site.DesignMode) pa.DesignerSelection = true; } pa.GlassEnabled = !this.DesignMode && WinApi.IsGlassEnabled; return pa; } private ISite GetSite() { ISite site = null; if (site == null && _DisplayItem != null) { BaseItem item = _DisplayItem; while (site == null && item != null) { if (item.Site != null && item.Site.DesignMode) site = item.Site; else item = item.Parent; } } return site; } private RadialMenuContainer _DisplayItem; /// /// Identifies the item displayed by this popup. /// public RadialMenuContainer DisplayItem { get { return _DisplayItem; } set { if (value != _DisplayItem) { RadialMenuContainer oldValue = _DisplayItem; _DisplayItem = value; OnDisplayItemChanged(oldValue, value); } } } /// /// Called when DisplayItem property has changed. /// /// Old property value /// New property value protected virtual void OnDisplayItemChanged(RadialMenuContainer oldValue, RadialMenuContainer newValue) { if (oldValue != null) oldValue.ContainerControl = null; if (newValue != null) { newValue.ContainerControl = this; } this.Invalidate(); //OnPropertyChanged(new PropertyChangedEventArgs("DisplayItem")); } const uint WS_POPUP = 0x80000000; const uint WS_CLIPSIBLINGS = 0x04000000; const uint WS_CLIPCHILDREN = 0x02000000; const uint WS_EX_TOPMOST = 0x00000008; const uint WS_EX_TOOLWINDOW = 0x00000080; protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; //cp.ExStyle |= 0x00080000; // Sets WS_EX_LAYERED extended style cp.Style = unchecked((int)(WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)); cp.ExStyle = (int)(WS_EX_TOPMOST | WS_EX_TOOLWINDOW | 0x00080000); // Sets WS_EX_LAYERED extended style cp.Caption = ""; // Setting caption would show window under tasks in Windows Task Manager return cp; } } protected override void OnPaint(PaintEventArgs e) { PaintLayeredWindow(_ContentImage); } private Bitmap _ContentImage = null; /// /// Gets or sets the content image displayed on the window. /// public Bitmap ContentImage { get { return _ContentImage; } set { _ContentImage = value; if (_ContentImage != null && _ContentImage.Size != this.Size) this.Size = _ContentImage.Size; PaintLayeredWindow(_ContentImage); } } private void PaintLayeredWindow(Bitmap windowContentImage) { if (!this.IsHandleCreated) return; IntPtr screenDc = NativeFunctions.GetDC(IntPtr.Zero); IntPtr memDc = WinApi.CreateCompatibleDC(screenDc); IntPtr hBitmap = IntPtr.Zero; IntPtr oldBitmap = IntPtr.Zero; try { //Display-image hBitmap = windowContentImage.GetHbitmap(Color.FromArgb(0)); //Set the fact that background is transparent oldBitmap = WinApi.SelectObject(memDc, hBitmap); //Display-rectangle Size size = windowContentImage.Size; Point pointSource = new Point(0, 0); Point topPos = new Point(this.Left, this.Top); //Set up blending options NativeFunctions.BLENDFUNCTION blend = new NativeFunctions.BLENDFUNCTION(); blend.BlendOp = (byte)NativeFunctions.Win23AlphaFlags.AC_SRC_OVER; blend.BlendFlags = 0; blend.SourceConstantAlpha = 255; blend.AlphaFormat = (byte)NativeFunctions.Win23AlphaFlags.AC_SRC_ALPHA; NativeFunctions.UpdateLayeredWindow(this.Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, (int)NativeFunctions.Win32UpdateLayeredWindowsFlags.ULW_ALPHA); //Clean-up WinApi.ReleaseDC(IntPtr.Zero, screenDc); if (hBitmap != IntPtr.Zero) { WinApi.SelectObject(memDc, oldBitmap); WinApi.DeleteObject(hBitmap); } WinApi.DeleteDC(memDc); } catch (Exception) { } } protected override void WndProc(ref Message m) { if (m.Msg == (int)WinApi.WindowsMessages.WM_MOUSEACTIVATE) { m.Result = new System.IntPtr(NativeFunctions.MA_NOACTIVATE); return; } base.WndProc(ref m); } #region BaseItem Forwarding protected override void OnClick(EventArgs e) { Point p = this.PointToClient(MousePosition); InternalOnClick(MouseButtons, p); base.OnClick(e); } protected virtual void InternalOnClick(MouseButtons mb, Point mousePos) { _DisplayItem.InternalClick(mb, mousePos); } protected override void OnDoubleClick(EventArgs e) { _DisplayItem.InternalDoubleClick(MouseButtons, MousePosition); base.OnDoubleClick(e); } protected override void OnKeyDown(KeyEventArgs e) { ExKeyDown(e); base.OnKeyDown(e); } internal virtual void ExKeyDown(KeyEventArgs e) { _DisplayItem.InternalKeyDown(e); } protected override void OnMouseDown(MouseEventArgs e) { _DisplayItem.InternalMouseDown(e); base.OnMouseDown(e); } protected override void OnMouseHover(EventArgs e) { base.OnMouseHover(e); _DisplayItem.InternalMouseHover(); } protected override void OnMouseLeave(EventArgs e) { _DisplayItem.InternalMouseLeave(); base.OnMouseLeave(e); } protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); _DisplayItem.InternalMouseUp(e); } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); InternalMouseMove(e); } protected virtual void InternalMouseMove(MouseEventArgs e) { _DisplayItem.InternalMouseMove(e); } #endregion #region Renderer Handling private Rendering.BaseRenderer m_DefaultRenderer = null; private Rendering.BaseRenderer m_Renderer = null; private eRenderMode m_RenderMode = eRenderMode.Global; /// /// Returns the renderer control will be rendered with. /// /// The current renderer. public virtual Rendering.BaseRenderer GetRenderer() { if (m_RenderMode == eRenderMode.Global && Rendering.GlobalManager.Renderer != null) return Rendering.GlobalManager.Renderer; else if (m_RenderMode == eRenderMode.Custom && m_Renderer != null) return m_Renderer; if (m_DefaultRenderer == null) m_DefaultRenderer = new Rendering.Office2007Renderer(); return m_DefaultRenderer; } /// /// Gets or sets the rendering mode used by control. Default value is eRenderMode.Global which means that static GlobalManager.Renderer is used. If set to Custom then Renderer property must /// also be set to the custom renderer that will be used. /// [Browsable(false), DefaultValue(eRenderMode.Global)] public eRenderMode RenderMode { get { return m_RenderMode; } set { if (m_RenderMode != value) { m_RenderMode = value; this.Invalidate(true); } } } /// /// Gets or sets the custom renderer used by the items on this control. RenderMode property must also be set to eRenderMode.Custom in order renderer /// specified here to be used. /// [Browsable(false), DefaultValue(null)] public DevComponents.DotNetBar.Rendering.BaseRenderer Renderer { get { return m_Renderer; } set { m_Renderer = value; } } private ColorScheme m_ColorScheme = null; /// /// Returns the color scheme used by control. Color scheme for Office2007 style will be retrieved from the current renderer instead of /// local color scheme referenced by ColorScheme property. /// /// An instance of ColorScheme object. protected virtual ColorScheme GetColorScheme() { BaseRenderer r = GetRenderer(); if (r is Office2007Renderer) return ((Office2007Renderer)r).ColorTable.LegacyColors; if (m_ColorScheme == null) m_ColorScheme = new ColorScheme(eDotNetBarStyle.Metro); return m_ColorScheme; } #endregion #endregion } }