378 lines
13 KiB
C#
378 lines
13 KiB
C#
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
|
|
/// <summary>
|
|
/// Initializes a new instance of the RadialMenuPopup class.
|
|
/// </summary>
|
|
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;
|
|
/// <summary>
|
|
/// Identifies the item displayed by this popup.
|
|
/// </summary>
|
|
public RadialMenuContainer DisplayItem
|
|
{
|
|
get { return _DisplayItem; }
|
|
set
|
|
{
|
|
if (value != _DisplayItem)
|
|
{
|
|
RadialMenuContainer oldValue = _DisplayItem;
|
|
_DisplayItem = value;
|
|
OnDisplayItemChanged(oldValue, value);
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Called when DisplayItem property has changed.
|
|
/// </summary>
|
|
/// <param name="oldValue">Old property value</param>
|
|
/// <param name="newValue">New property value</param>
|
|
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;
|
|
/// <summary>
|
|
/// Gets or sets the content image displayed on the window.
|
|
/// </summary>
|
|
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;
|
|
/// <summary>
|
|
/// Returns the renderer control will be rendered with.
|
|
/// </summary>
|
|
/// <returns>The current renderer.</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
[Browsable(false), DefaultValue(eRenderMode.Global)]
|
|
public eRenderMode RenderMode
|
|
{
|
|
get { return m_RenderMode; }
|
|
set
|
|
{
|
|
if (m_RenderMode != value)
|
|
{
|
|
m_RenderMode = value;
|
|
this.Invalidate(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
[Browsable(false), DefaultValue(null)]
|
|
public DevComponents.DotNetBar.Rendering.BaseRenderer Renderer
|
|
{
|
|
get
|
|
{
|
|
return m_Renderer;
|
|
}
|
|
set
|
|
{
|
|
m_Renderer = value;
|
|
}
|
|
}
|
|
|
|
private ColorScheme m_ColorScheme = null;
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <returns>An instance of ColorScheme object.</returns>
|
|
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
|
|
}
|
|
}
|