win7、win8没试过,不知道效果。
1、winform的实现
必须为无边框的窗体,为了效果好看,这里先建立一个无边框阴影窗体的类:ConextForm.cs
程序代码:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public partial class ConextForm : Form
{
public bool Sizeable = true;
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
private static extern IntPtr CreateRoundRectRgn
(
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect,
int nWidthEllipse,
int nHeightEllipse
);
[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);
private bool m_aeroEnabled = false;
private const int CS_DROPSHADOW = 0x00020000;
private const int WM_NCPAINT = 0x0085;
private const int WM_ACTIVATEAPP = 0x001C;
public struct MARGINS
{
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 |= CS_DROPSHADOW;
return cp;
}
}
private bool CheckAeroEnabled()
{
if (Environment.OSVersion.Version.Major >= 6)
{
int enabled = 0;
DwmIsCompositionEnabled(ref enabled);
return (enabled == 1) ? true : false;
}
return false;
}
const int HTLEFT = 10;
const int HTRIGHT = 11;
const int HTTOP = 12;
const int HTTOPLEFT = 13;
const int HTTOPRIGHT = 14;
const int HTBOTTOM = 15;
const int HTBOTTOMLEFT = 0x10;
const int HTBOTTOMRIGHT = 17;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
switch (m.Msg)
{
case WM_NCPAINT:
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);
}
break;
case 0x0084:
if (Sizeable)
{
base.WndProc(ref m);
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)HTTOPLEFT;
}
else
if (vPoint.Y >= ClientSize.Height - 5)
{
m.Result = (IntPtr)HTBOTTOMLEFT;
}
else
{
m.Result = (IntPtr)HTLEFT;
}
}
else
if (vPoint.X >= ClientSize.Width - 5)
{
if (vPoint.Y <= 5)
{
m.Result = (IntPtr)HTTOPRIGHT;
}
else
if (vPoint.Y >= ClientSize.Height - 5)
{
m.Result = (IntPtr)HTBOTTOMRIGHT;
}
else
{
m.Result = (IntPtr)HTRIGHT;
}
}
else
if (vPoint.Y <= 5)
{
m.Result = (IntPtr)HTTOP;
}
else
{
if (vPoint.Y >= ClientSize.Height - 5)
{
m.Result = (IntPtr)HTBOTTOM;
}
}
}
break;
default:
break;
}
}
private void InitializeComponent()
{
this.SuspendLayout();
this.ClientSize = new Size(284, 261);
this.DoubleBuffered = true;
this.Name = "conextForm";
this.ResumeLayout(false);
}
}
再修改窗体Form1代码
程序代码:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace W_1
{
public partial class Form1 : ConextForm
{
[DllImport("user32.dll")]
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
[StructLayout(LayoutKind.Sequential)]
internal struct WindowCompositionAttributeData
{
public WindowCompositionAttribute Attribute;
public IntPtr Data;
public int SizeOfData;
}
internal enum WindowCompositionAttribute
{
WCA_ACCENT_POLICY = 19
}
internal enum AccentState
{
ACCENT_DISABLED = 0,
ACCENT_ENABLE_GRADIENT = 1,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_INVALID_STATE = 4
}
[StructLayout(LayoutKind.Sequential)]
internal struct AccentPolicy
{
public AccentState AccentState;
public int AccentFlags;
public int GradientColor;
public int AnimationId;
}
internal void EnableBlur()
{
var accent = new AccentPolicy();
var accentStructSize = Marshal.SizeOf(accent);
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;
var accentPtr = Marshal.AllocHGlobal(accentStructSize);
Marshal.StructureToPtr(accent, accentPtr, false);
var data = new WindowCompositionAttributeData();
data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY;
data.SizeOfData = accentStructSize;
data.Data = accentPtr;
SetWindowCompositionAttribute(this.Handle, ref data);
Marshal.FreeHGlobal(accentPtr);
}
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
public Form1()
{
InitializeComponent();
this.Location = new Point(100, 100);
this.Size = new Size(600, 400);
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = Color.Pink;
this.TransparencyKey = Color.Pink;
this.Load += Form1_Load;
this.MouseMove += FormMove_MouseDown;
}
private void Form1_Load(object sender, EventArgs e)
{
EnableBlur();
}
[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 void FormMove_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, 0xA1, 0x02, 0);
}
}
}
}
这样就完成了。美中不足,由于透明了颜色Pink,所以有些字体显示有毛边。解决办法:窗体上面再嵌套一个窗体,设置透明度就可以了,移动最上层窗体,下面的毛玻璃窗体跟着移动就可以了。
2、wpf:
简单多了,直接写
程序代码:
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
namespace W_2
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
[DllImport("user32.dll")]
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
[StructLayout(LayoutKind.Sequential)]
internal struct WindowCompositionAttributeData
{
public WindowCompositionAttribute Attribute;
public IntPtr Data;
public int SizeOfData;
}
internal enum WindowCompositionAttribute
{
WCA_ACCENT_POLICY = 19
}
internal enum AccentState
{
ACCENT_DISABLED = 0,
ACCENT_ENABLE_GRADIENT = 1,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_INVALID_STATE = 4
}
[StructLayout(LayoutKind.Sequential)]
internal struct AccentPolicy
{
public AccentState AccentState;
public int AccentFlags;
public int GradientColor;
public int AnimationId;
}
internal void EnableBlur()
{
var windowHelper = new WindowInteropHelper(this);
var accent = new AccentPolicy();
var accentStructSize = Marshal.SizeOf(accent);
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;
var accentPtr = Marshal.AllocHGlobal(accentStructSize);
Marshal.StructureToPtr(accent, accentPtr, false);
var data = new WindowCompositionAttributeData();
data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY;
data.SizeOfData = accentStructSize;
data.Data = accentPtr;
SetWindowCompositionAttribute(windowHelper.Handle, ref data);
Marshal.FreeHGlobal(accentPtr);
}
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
public MainWindow()
{
InitializeComponent();
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
Background = Brushes.Transparent;
this.Loaded += (s, e) => { EnableBlur(); };
this.MouseMove += MainWindow_MouseMove;
}
private void MainWindow_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
this.DragMove();
}
}
}
}
总之,winform要达到比较好的效果,需无边框阴影窗口,并窗体叠加;wpf直接写就行了。
以前学c#时候google上找的,发到了一些网站上,这里详细给出代码。