ç¨winformå®ç°ç类似äºWPFä¸PopUpæ§ä»¶çä¸æ®µä»£ç
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace xxxxxxx
{
/// <summary>
/// æµ®å¨å±åºç±»
/// </summary>
public class FloatLayerBase : Form
{
/// <summary>
/// é¼ æ æ¶æ¯çéå¨
/// </summary>
//ç±äºæ¬çªä½ä¸ºWS_CHILDï¼æ以ä¸ä¼æ¶å°å¨çªä½ä»¥å¤ç¹å»é¼ æ çæ¶æ¯
//该æ¶æ¯çéå¨çä½ç¨å°±æ¯è®©æ¬çªä½è·ç¥é¼ æ ç¹å»æ
åµï¼è¿èæ ¹æ®é¼ æ æ¯å¦å¨æ¬çªä½ä»¥å¤çåºåç¹å»ï¼ååºç¸åºå¤ç
readonly AppMouseMessageHandler _mouseMsgFilter;
/// <summary>
/// æ示æ¬çªä½æ¯å¦å·²ShowDialogè¿
/// </summary>
//ç±äºå¤æ¬¡ShowDialogä¼ä½¿OnLoad/OnShownéå
¥ï¼æ
é设置æ¤æ 记以ä¾éå
¥æ¶å¤æ
bool _isShowDialogAgain;
//è¾¹æ¡ç¸å
³å段
BorderStyle _borderType;
Border3DStyle _border3DStyle;
ButtonBorderStyle _borderSingleStyle;
Color _borderColor;
/// <summary>
/// è·åæ设置边æ¡ç±»å
/// </summary>
[Description("è·åæ设置边æ¡ç±»åã")]
[DefaultValue(BorderStyle.Fixed3D)]
public BorderStyle BorderType
{
get { return _borderType; }
set
{
if (_borderType == value) { return; }
_borderType = value;
Invalidate();
}
}
/// <summary>
/// è·åæ设置ä¸ç»´è¾¹æ¡æ ·å¼
/// </summary>
[Description("è·åæ设置ä¸ç»´è¾¹æ¡æ ·å¼ã")]
[DefaultValue(Border3DStyle.RaisedInner)]
public Border3DStyle Border3DStyle
{
get { return _border3DStyle; }
set
{
if (_border3DStyle == value) { return; }
_border3DStyle = value;
Invalidate();
}
}
/// <summary>
/// è·åæ设置线åè¾¹æ¡æ ·å¼
/// </summary>
[Description("è·åæ设置线åè¾¹æ¡æ ·å¼ã")]
[DefaultValue(ButtonBorderStyle.Solid)]
public ButtonBorderStyle BorderSingleStyle
{
get { return _borderSingleStyle; }
set
{
if (_borderSingleStyle == value) { return; }
_borderSingleStyle = value;
Invalidate();
}
}
/// <summary>
/// è·åæ设置边æ¡é¢è²ï¼ä»
å½è¾¹æ¡ç±»å为线åæ¶ææï¼
/// </summary>
[Description("è·åæ设置边æ¡é¢è²ï¼ä»
å½è¾¹æ¡ç±»å为线åæ¶ææï¼ã")]
[DefaultValue(typeof(Color), "DarkGray")]
public Color BorderColor
{
get { return _borderColor; }
set
{
if (_borderColor == value) { return; }
_borderColor = value;
Invalidate();
}
}
protected override sealed CreateParams CreateParams
{
get
{
CreateParams prms = base.CreateParams;
//prms.Style = 0;
//prms.Style |= -2147483648; //WS_POPUP
prms.Style |= 0x40000000; //WS_CHILD éè¦ï¼åªæCHILDçªä½æä¸ä¼æ¢ç¶çªä½ç¦ç¹
prms.Style |= 0x4000000; //WS_CLIPSIBLINGS
prms.Style |= 0x10000; //WS_TABSTOP
prms.Style &= ~0x40000; //WS_SIZEBOX å»é¤
prms.Style &= ~0x800000; //WS_BORDER å»é¤
prms.Style &= ~0x400000; //WS_DLGFRAME å»é¤
//prms.Style &= ~0x20000; //WS_MINIMIZEBOX å»é¤
//prms.Style &= ~0x10000; //WS_MAXIMIZEBOX å»é¤
prms.ExStyle = 0;
//prms.ExStyle |= 0x1; //WS_EX_DLGMODALFRAME ç«ä½è¾¹æ¡
//prms.ExStyle |= 0x8; //WS_EX_TOPMOST
prms.ExStyle |= 0x10000; //WS_EX_CONTROLPARENT
//prms.ExStyle |= 0x80; //WS_EX_TOOLWINDOW
//prms.ExStyle |= 0x100; //WS_EX_WINDOWEDGE
//prms.ExStyle |= 0x8000000; //WS_EX_NOACTIVATE
//prms.ExStyle |= 0x4; //WS_EX_NOPARENTNOTIFY
return prms;
}
}
//æé å½æ°
public FloatLayerBase()
{
//åå§åæ¶æ¯çéå¨ãæ·»å å移é¤å¨æ¾ç¤º/éèæ¶è´è´£
_mouseMsgFilter = new AppMouseMessageHandler(this);
//åå§ååºç±»å±æ§
InitBaseProperties();
//åå§åè¾¹æ¡ç¸å
³
_borderType = BorderStyle.Fixed3D;
_border3DStyle = System.Windows.Forms.Border3DStyle.RaisedInner;
_borderSingleStyle = ButtonBorderStyle.Solid;
_borderColor = Color.DarkGray;
}
protected override void OnLoad(EventArgs e)
{
//é²æ¢éå
¥
if (_isShowDialogAgain) { return; }
//éå¾åæ两å±è¾¹æ¡å®½åº¦ï¼è¿è¡æ¶å°ºå¯¸æä¸è®¾è®¡æ¶å®å
¨ç¸ç¬¦ï¼åå ä¸æ
//ç¡®å®ä¸ControlBoxãFormBorderStyleæå
³ï¼ä½å
·ä½èç³»ä¸æ
if (!DesignMode)
{
Size size = SystemInformation.FrameBorderSize;
this.Size -= size + size;//ä¸å¯ä»¥ç¨ClientSizeï¼åè
ä¼æ ¹æ®çªå£é£æ ¼éæ°è°æ´Size
}
base.OnLoad(e);
}
protected override void OnShown(EventArgs e)
{
//é²æ¢éå
¥
if (_isShowDialogAgain) { return; }
//å¨OnShownä¸ä¸ºé¦æ¬¡ShowDialog设æ è®°
if (Modal) { _isShowDialogAgain = true; }
if (!DesignMode)
{
//æ¿æ´»é¦æ§ä»¶
Control firstControl;
if ((firstControl = GetNextControl(this, true)) != null)
{
firstControl.Focus();
}
}
base.OnShown(e);
}
protected override void WndProc(ref Message m)
{
//å½æ¬çªä½ä½ä¸ºShowDialogå¼¹åºæ¶ï¼å¨æ¶å°WM_SHOWWINDOWåï¼Ownerä¼è¢«Disable
//æ
éå¨æ¶å°è¯¥æ¶æ¯åç«å³Enableå®ï¼ä¸ç¶Ownerçªä½åæ¬çªä½é½å°å¤äºæ ååºç¶æ
if (m.Msg == 0x18 && m.WParam != IntPtr.Zero && m.LParam == IntPtr.Zero
&& Modal && Owner != null && !Owner.IsDisposed)
{
if (Owner.IsMdiChild)
{
//å½Owneræ¯MDIåçªä½æ¶ï¼è¢«Disableçæ¯MDI主çªä½
//并ä¸Parentä¹ä¼æåMDI主çªä½ï¼æ
éæ¹å为Ownerï¼è¿æ ·å¼¹åºçªä½çLocationæä¼ç¸å¯¹äºOwnerèéMDIParent
NativeMethods.EnableWindow(Owner.MdiParent.Handle, true);
NativeMethods.SetParent(this.Handle, Owner.Handle);//åªè½ç¨API设置Parentï¼å 为模å¼çªä½æ¯TopLevelï¼.Netæç»ä¸ºé¡¶çº§çªä½è®¾ç½®Parent
}
else
{
NativeMethods.EnableWindow(Owner.Handle, true);
}
}
base.WndProc(ref m);
}
//ç»è¾¹æ¡
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
if (_borderType == BorderStyle.Fixed3D)//ç»å¶3Dè¾¹æ¡
{
ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle, Border3DStyle);
}
else if (_borderType == BorderStyle.FixedSingle)//ç»å¶çº¿åè¾¹æ¡
{
ControlPaint.DrawBorder(e.Graphics, ClientRectangle, BorderColor, BorderSingleStyle);
}
}
//æ¾ç¤ºåæ·»å é¼ æ æ¶æ¯çéå¨ä»¥å¼å§ææï¼éèæ¶å移é¤çéå¨ãä¹æ以ä¸æ¾Disposeä¸æ¯æ³å°½æ©ç§»é¤çéå¨
protected override void OnVisibleChanged(EventArgs e)
{
if (!DesignMode)
{
if (Visible) { Application.AddMessageFilter(_mouseMsgFilter); }
else { Application.RemoveMessageFilter(_mouseMsgFilter); }
}
base.OnVisibleChanged(e);
}
//å®ç°çªä½å®¢æ·åºæå¨
//å¨WndProcä¸å®ç°è¿ä¸ªè¾éº»ç¦ï¼æ以æ¾å°è¿éå
protected override void OnMouseDown(MouseEventArgs e)
{
//è®©é¼ æ ç¹å»å®¢æ·åºæ¶è¾¾å°ä¸ç¹å»æ é¢æ ä¸æ ·çææï¼ä»¥æ¤å®ç°å®¢æ·åºæå¨
NativeMethods.ReleaseCapture();
NativeMethods.SendMessage(Handle, 0xA1/*WM_NCLBUTTONDOWN*/, (IntPtr)2/*CAPTION*/, IntPtr.Zero);
base.OnMouseDown(e);
}
/// <summary>
/// æ¾ç¤ºä¸ºæ¨¡å¼çªä½
/// </summary>
/// <param name="control">æ¾ç¤ºå¨è¯¥æ§ä»¶ä¸æ¹</param>
public DialogResult ShowDialog(Control control)
{
return ShowDialog(control, 0, control.Height);
}
/// <summary>
/// æ¾ç¤ºä¸ºæ¨¡å¼çªä½
/// </summary>
/// <param name="control">触åå¼¹åºçªä½çæ§ä»¶</param>
/// <param name="offsetX">ç¸å¯¹controlæ°´å¹³å移</param>
/// <param name="offsetY">ç¸å¯¹controlåç´å移</param>
public DialogResult ShowDialog(Control control, int offsetX, int offsetY)
{
return ShowDialog(control, new Point(offsetX, offsetY));
}
/// <summary>
/// æ¾ç¤ºä¸ºæ¨¡å¼çªä½
/// </summary>
/// <param name="control">触åå¼¹åºçªä½çæ§ä»¶</param>
/// <param name="offset">ç¸å¯¹controlå移</param>
public DialogResult ShowDialog(Control control, Point offset)
{
return this.ShowDialogInternal(control, offset);
}
/// <summary>
/// æ¾ç¤ºä¸ºæ¨¡å¼çªä½
/// </summary>
/// <param name="item">æ¾ç¤ºå¨è¯¥å·¥å
·æ 项çä¸æ¹</param>
public DialogResult ShowDialog(ToolStripItem item)
{
return ShowDialog(item, 0, item.Height);
}
/// <summary>
/// æ¾ç¤ºä¸ºæ¨¡å¼çªä½
/// </summary>
/// <param name="item">触åå¼¹åºçªä½çå·¥å
·æ 项</param>
/// <param name="offsetX">ç¸å¯¹itemæ°´å¹³å移</param>
/// <param name="offsetY">ç¸å¯¹itemåç´å移</param>
public DialogResult ShowDialog(ToolStripItem item, int offsetX, int offsetY)
{
return ShowDialog(item, new Point(offsetX, offsetY));
}
/// <summary>
/// æ¾ç¤ºä¸ºæ¨¡å¼çªä½
/// </summary>
/// <param name="item">触åå¼¹åºçªä½çå·¥å
·æ 项</param>
/// <param name="offset">ç¸å¯¹itemå移</param>
public DialogResult ShowDialog(ToolStripItem item, Point offset)
{
return this.ShowDialogInternal(item, offset);
}
/// <summary>
/// æ¾ç¤ºçªä½
/// </summary>
/// <param name="control">æ¾ç¤ºå¨è¯¥æ§ä»¶ä¸æ¹</param>
public void Show(Control control)
{
Show(control, 0, control.Height);
}
/// <summary>
/// æ¾ç¤ºçªä½
/// </summary>
/// <param name="control">触åå¼¹åºçªä½çæ§ä»¶</param>
/// <param name="offsetX">ç¸å¯¹controlæ°´å¹³å移</param>
/// <param name="offsetY">ç¸å¯¹controlåç´å移</param>
public void Show(Control control, int offsetX, int offsetY)
{
Show(control, new Point(offsetX, offsetY));
}
/// <summary>
/// æ¾ç¤ºçªä½
/// </summary>
/// <param name="control">触åå¼¹åºçªä½çæ§ä»¶</param>
/// <param name="offset">ç¸å¯¹controlå移</param>
public void Show(Control control, Point offset)
{
this.ShowInternal(control, offset);
}
/// <summary>
/// æ¾ç¤ºçªä½
/// </summary>
/// <param name="item">æ¾ç¤ºå¨è¯¥å·¥å
·æ ä¸æ¹</param>
public void Show(ToolStripItem item)
{
Show(item, 0, item.Height);
}
/// <summary>
/// æ¾ç¤ºçªä½
/// </summary>
/// <param name="item">触åå¼¹åºçªä½çå·¥å
·æ 项</param>
/// <param name="offsetX">ç¸å¯¹itemæ°´å¹³å移</param>
/// <param name="offsetY">ç¸å¯¹itemåç´å移</param>
public void Show(ToolStripItem item, int offsetX, int offsetY)
{
Show(item, new Point(offsetX, offsetY));
}
/// <summary>
/// æ¾ç¤ºçªä½
/// </summary>
/// <param name="item">触åå¼¹åºçªä½çå·¥å
·æ 项</param>
/// <param name="offset">ç¸å¯¹itemå移</param>
public void Show(ToolStripItem item, Point offset)
{
this.ShowInternal(item, offset);
}
/// <summary>
/// ShowDialogå
é¨æ¹æ³
/// </summary>
private DialogResult ShowDialogInternal(Component controlOrItem, Point offset)
{
//å¿«éè¿ç»å¼¹åºæ¬çªä½å°æå¯è½éå°å°æªHideçæ
åµä¸å次弹åºï¼è¿ä¼å¼åå¼å¸¸ï¼æ
éåå¤ç
if (this.Visible) { return System.Windows.Forms.DialogResult.None; }
this.SetLocationAndOwner(controlOrItem, offset);
return base.ShowDialog();
}
/// <summary>
/// Showå
é¨æ¹æ³
/// </summary>
private void ShowInternal(Component controlOrItem, Point offset)
{
if (this.Visible) { return; }//åå è§ShowDialogInternal
this.SetLocationAndOwner(controlOrItem, offset);
base.Show();
}
/// <summary>
/// 设置åæ åææè
/// </summary>
/// <param name="controlOrItem">æ§ä»¶æå·¥å
·æ 项</param>
/// <param name="offset">ç¸å¯¹å移</param>
private void SetLocationAndOwner(Component controlOrItem, Point offset)
{
Point pt = Point.Empty;
if (controlOrItem is ToolStripItem)
{
ToolStripItem item = (ToolStripItem)controlOrItem;
pt.Offset(item.Bounds.Location);
controlOrItem = item.Owner;
}
Control c = (Control)controlOrItem;
pt.Offset(GetControlLocationInForm(c));
pt.Offset(offset);
this.Location = pt;
//设置Ownerå±æ§ä¸Show[Dialog](Owner)æä¸åï¼å½Owneræ¯MDIChildæ¶ï¼åè
ä¼æ¹Owner为MDIParent
this.Owner = c.FindForm();
}
/// <summary>
/// è·åæ§ä»¶å¨çªä½ä¸çåæ
/// </summary>
private static Point GetControlLocationInForm(Control c)
{
Point pt = c.Location;
while (!((c = c.Parent) is Form))
{
pt.Offset(c.Location);
}
return pt;
}
#region å±è½å¯¹æ¬ç±»å½±åé大çåºç±»æ¹æ³åå±æ§
/// <summary>
/// åå§åé¨ååºç±»å±æ§
/// </summary>
private void InitBaseProperties()
{
base.ControlBox = false; //éè¦
//å¿
é¡»å¾æ¯SizableToolWindowæè½æ¯æè°æ´å¤§å°çåæ¶ï¼ä¸åSystemInformation.MinWindowTrackSizeçéå¶
base.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
base.Text = string.Empty; //éè¦
base.HelpButton = false;
base.Icon = null;
base.IsMdiContainer = false;
base.MaximizeBox = false;
base.MinimizeBox = false;
base.ShowIcon = false;
base.ShowInTaskbar = false;
base.StartPosition = FormStartPosition.Manual; //éè¦
base.TopMost = false;
base.WindowState = FormWindowState.Normal;
}
//å±è½åæ¹æ³
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("请使ç¨å«çéè½½ï¼", true)]
public new DialogResult ShowDialog() { throw new NotImplementedException(); }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("请使ç¨å«çéè½½ï¼", true)]
public new DialogResult ShowDialog(IWin32Window owner) { throw new NotImplementedException(); }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("请使ç¨å«çéè½½ï¼", true)]
public new void Show() { throw new NotImplementedException(); }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("请使ç¨å«çéè½½ï¼", true)]
public new void Show(IWin32Window owner) { throw new NotImplementedException(); }
//å±è½åå±æ§
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public new bool ControlBox { get { return false; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("设置边æ¡è¯·ä½¿ç¨Borderç¸å
³å±æ§ï¼", true)]
public new FormBorderStyle FormBorderStyle { get { return System.Windows.Forms.FormBorderStyle.SizableToolWindow; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public override sealed string Text { get { return string.Empty; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public new bool HelpButton { get { return false; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public new Image Icon { get { return null; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public new bool IsMdiContainer { get { return false; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public new bool MaximizeBox { get { return false; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public new bool MinimizeBox { get { return false; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public new bool ShowIcon { get { return false; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public new bool ShowInTaskbar { get { return false; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public new FormStartPosition StartPosition { get { return FormStartPosition.Manual; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public new bool TopMost { get { return false; } set { } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("ç¦ç¨è¯¥å±æ§ï¼", true)]
public new FormWindowState WindowState { get { return FormWindowState.Normal; } set { } }
#endregion
/// <summary>
/// ç¨åºé¼ æ æ¶æ¯çéå¨
/// </summary>
private class AppMouseMessageHandler : IMessageFilter
{
readonly FloatLayerBase _layerForm;
public AppMouseMessageHandler(FloatLayerBase layerForm)
{
_layerForm = layerForm;
}
public bool PreFilterMessage(ref Message m)
{
//å¦æå¨æ¬çªä½ä»¥å¤ç¹å»é¼ æ ï¼éèæ¬çªä½
//è¥æ³å¨ç¹å»æ é¢æ ãæ»å¨æ¡çé客æ·åºä¹è¦è®©æ¬çªä½æ¶å¤±ï¼åæ¶0xA1ç注éå³å¯
//æ¬ä¾æ¯æ ¹æ®åæ å¤æï¼äº¦å¯ä»¥æ¹ä¸ºæ ¹æ®å¥æï¼ä½è¦èèååæ§ä»¶
//ä¹æ以ç¨APIèä¸ç¨Form.DesktopBoundsæ¯å 为åè
ä¸å¯é
if ((m.Msg == 0x201/*|| m.Msg==0xA1*/)
&& _layerForm.Visible && !NativeMethods.GetWindowRect(_layerForm.Handle).Contains(MousePosition))
{
_layerForm.Hide();//ä¹æ以ä¸Closeæ¯èèåºè¯¥ç±è°ç¨è
è´è´£éæ¯
}
return false;
}
}
/// <summary>
/// APIå°è£
ç±»
/// </summary>
private static class NativeMethods
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public static explicit operator Rectangle(RECT rect)
{
return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
}
}
public static Rectangle GetWindowRect(IntPtr hwnd)
{
RECT rect;
GetWindowRect(hwnd, out rect);
return (Rectangle)rect;
}
//[DllImport("user32.dll", ExactSpelling = true)]
//public static extern IntPtr GetAncestor(IntPtr hwnd, uint flags);
}
}
}