无边框窗体
写代码实在没啥思路,就发个之前做的无边框窗体吧。主要实现了无边框窗体的拖动,调整大小,四周阴影及淡入淡出。之前花了不少时间去查资料,最后综合好几篇文章做出来的,代码比较乱,但想想可能有人需要,还是放出来:
public partial class HtLiteFormBase : System.Windows.Forms.Form
{
#region 边框及阴影处理
[DllImport("dwmapi.dll")]
public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
[DllImport("dwmapi.dll")]
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
[DllImport("dwmapi.dll")]
public static extern int DwmIsCompositionEnabled(ref int pfEnabled);
[DllImport("user32.dll")] //拖动无窗体的控件
public static extern bool ReleaseCapture();
[DllImport("user32.dll")]
public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
private bool m_aeroEnabled; // variables for box shadow
public struct MARGINS // struct for box shadow
{
public int leftWidth;
public int rightWidth;
public int topHeight;
public int bottomHeight;
}
protected override CreateParams CreateParams
{
get
{
m_aeroEnabled = CheckAeroEnabled();
CreateParams cp = base.CreateParams;
if (!m_aeroEnabled)
cp.ClassStyle |= 0x00020000;
return cp;
}
}
private bool CheckAeroEnabled()
{
if (Environment.OSVersion.Version.Major >= 6)
{
int enabled = 0;
DwmIsCompositionEnabled(ref enabled);
return (enabled == 1) ? true : false;
}
return false;
}
private bool _enableSize = true;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x0084:
base.WndProc(ref m);
if (_enableSize)
{
Point vPoint = new Point((int)m.LParam & 0xFFFF,
(int)m.LParam >> 16 & 0xFFFF);
vPoint = PointToClient(vPoint);
if (vPoint.X <= 5)
if (vPoint.Y <= 5)
m.Result = (IntPtr)13;
else if (vPoint.Y >= ClientSize.Height - 5)
m.Result = (IntPtr)0x10;
else m.Result = (IntPtr)10;
else if (vPoint.X >= ClientSize.Width - 5)
if (vPoint.Y <= 5)
m.Result = (IntPtr)14;
else if (vPoint.Y >= ClientSize.Height - 5)
m.Result = (IntPtr)17;
else m.Result = (IntPtr)11;
else if (vPoint.Y <= 5)
m.Result = (IntPtr)12;
else if (vPoint.Y >= ClientSize.Height - 5)
m.Result = (IntPtr)15;
}
break;
case 0x0085: //窗体阴影
if (m_aeroEnabled)
{
var v = 2;
DwmSetWindowAttribute(this.Handle, 2, ref v, 4);
MARGINS margins = new MARGINS()
{
bottomHeight = 1,
leftWidth = 1,
rightWidth = 1,
topHeight = 1
};
DwmExtendFrameIntoClientArea(this.Handle, ref margins);
}
base.WndProc(ref m);
break;
case 0x0201: //鼠标左键按下的消息
m.Msg = 0x00A1; //更改消息为非客户区按下鼠标
m.LParam = IntPtr.Zero; //默认值
m.WParam = new IntPtr(2); //鼠标放在标题栏内
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
#endregion
#region 淡入
public class Win32
{
public const Int32 AW_HOR_POSITIVE = 0x00000001; // 从左到右打开窗口
public const Int32 AW_HOR_NEGATIVE = 0x00000002; // 从右到左打开窗口
public const Int32 AW_VER_POSITIVE = 0x00000004; // 从上到下打开窗口
public const Int32 AW_VER_NEGATIVE = 0x00000008; // 从下到上打开窗口
public const Int32 AW_CENTER = 0x00000010;
public const Int32 AW_HIDE = 0x00010000; // 在窗体卸载时若想使用本函数就得加上此常量
public const Int32 AW_ACTIVATE = 0x00020000; //在窗体通过本函数打开后,默认情况下会失去焦点,除非加上本常量
public const Int32 AW_SLIDE = 0x00040000;
public const Int32 AW_BLEND = 0x00080000; // 淡入淡出效果
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool AnimateWindow(IntPtr hwnd, int dwTime, int dwFlags);
}
#endregion
public HtLiteFormBase()
{
InitializeComponent();
}
private void HtLiteFormBase_Load(object sender, EventArgs e)
{
/*淡入窗体*/
if (m_aeroEnabled)
{
var v = 2;
DwmSetWindowAttribute(this.Handle, 2, ref v, 4);
MARGINS margins = new MARGINS()
{
bottomHeight = 1,
leftWidth = 1,
rightWidth = 1,
topHeight = 1
};
DwmExtendFrameIntoClientArea(this.Handle, ref margins);
}
Win32.AnimateWindow(this.Handle, 100, Win32.AW_BLEND);
}
private void HtLiteFormBase_FormClosing(object sender, FormClosingEventArgs e)
{
Win32.AnimateWindow(this.Handle, 100, Win32.AW_SLIDE | Win32.AW_HIDE | Win32.AW_BLEND);
}
private void HtLiteFormBase_MouseDown(object sender, MouseEventArgs e)
{
//拖动窗体
ReleaseCapture();
SendMessage(this.Handle, 0x0112, 0xF010 + 0x0002, 0);
}
#region 自定义变量
/// <summary>
/// 是否允许调整窗体大小
/// </summary>
[Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
EditorBrowsable(EditorBrowsableState.Always), Bindable(true)]
public bool EnableSize
{
get { return _enableSize; }
set { _enableSize = value; }
}
#endregion
}
自定义消息框
感觉系统消息框比较丑,就花了点时间自己做了个简单的,继承自上面的窗体,单例模式(不晓得用的对不对)。
先放个效果图:
主要代码如下:
public sealed partial class HtMessageBox : HtLiteFormBase
{
private static HtMessageBox instance;
private HtMessageBox()
{
InitializeComponent();
this.EnableSize = false;
btnYes.Click += btnYes_Click;
btnNo.Click += btnNo_Click;
btnCancel.Click += btnCancel_Click;
}
private static DialogResult _dialogResult;
public static DialogResult Show(string tip, string caption = "提示")
{
if (instance == null || instance.IsDisposed)
instance = new HtMessageBox();
panelTitle.Text = caption;
labelTip.Text = tip;
instance.ShowDialog();
return _dialogResult;
}
private void btnYes_Click(object sender, EventArgs e)
{
_dialogResult = DialogResult.Yes;
instance.Close();
}
private void btnNo_Click(object sender, EventArgs e)
{
_dialogResult = DialogResult.No;
instance.Close();
}
private void btnCancel_Click(object sender, EventArgs e)
{
_dialogResult = DialogResult.Cancel;
instance.Close();
}
private void panelTitle_MouseDown(object sender, MouseEventArgs e)
{
//拖动窗体
ReleaseCapture();
SendMessage(this.Handle, 0x0112, 0xF010 + 0x0002, 0);
}
private void labelTip_MouseDown(object sender, MouseEventArgs e)
{
//拖动窗体
ReleaseCapture();
SendMessage(this.Handle, 0x0112, 0xF010 + 0x0002, 0);
}
}
运行:
这里也能看出部分自定义窗体的效果,有兴趣的童鞋自己Copy测试吧,需要完整源码可以联系我哦。