public
class
GlassInfo: System.Windows.Markup.MarkupExtension
{
public
int
TopMargin {
get
;
set
; }
public
bool
ShowIcon {
get
;
set
; }
public
bool
ShowTitle {
get
;
set
; }
public
GlassInfo()
{
TopMargin
=
-
1
;
ShowIcon
=
true
;
ShowTitle
=
true
;
}
public
override
object
ProvideValue(IServiceProvider serviceProvider)
{
return
this
;
}
}
public
class
GlassEffect
{
public
static
GlassInfo GetInfo(DependencyObject obj)
{
return
(GlassInfo)obj.GetValue(InfoProperty);
}
public
static
void
SetInfo(DependencyObject obj, GlassInfo value)
{
obj.SetValue(InfoProperty, value);
}
public
static
readonly
DependencyProperty InfoProperty
=
DependencyProperty.RegisterAttached(
"
Info
"
,
typeof
(GlassInfo),
typeof
(GlassEffect),
new
FrameworkPropertyMetadata(OnIsEnabledChanged));
public
static
void
OnIsEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if
(System.ComponentModel.DesignerProperties.GetIsInDesignMode(obj))
return
;
(obj
as
Window).Loaded
+=
(s, e)
=>
ApplyGlassEffect(obj
as
Window, args.NewValue
as
GlassInfo);
EnableMouseDrag(obj
as
Window,(args.NewValue
as
GlassInfo).TopMargin);
}
static
void
ApplyGlassEffect(Window window, GlassInfo info)
{
if
(
!
DwmIsCompositionEnabled())
return
;
var originalBackground
=
window.Background;
window.Background
=
Brushes.Transparent;
try
{
IntPtr mainWindowPtr
=
new
WindowInteropHelper(window).Handle;
HwndSource mainWindowSrc
=
HwndSource.FromHwnd(mainWindowPtr);
mainWindowSrc.CompositionTarget.BackgroundColor
=
Color.FromArgb(
0
,
0
,
0
,
0
);
var margins
=
info.TopMargin
==
-
1
?
new
MARGINS(
-
1
,
-
1
,
-
1
,
-
1
) :
new
MARGINS { Top
=
info.TopMargin };
DwmExtendFrameIntoClientArea(mainWindowPtr,
ref
margins);
ApplyWindowThemeAttribute(info, mainWindowPtr);
}
catch
(DllNotFoundException)
{
window.Background
=
originalBackground;
}
}
static
void
ApplyWindowThemeAttribute(GlassInfo info, IntPtr mainWindowPtr)
{
WTA_OPTIONS ops
=
new
WTA_OPTIONS();
//
We Want To Hide the Caption and the Icon
ops.Flags
=
WTNCA_NODRAWCAPTION
|
WTNCA_NODRAWICON
|
WTNCA_NOSYSMENU;
//
If we set the Mask to the same value as the Flags, the Flags are Added. If Not They are Removed
if
(
!
info.ShowTitle)
{
ops.Mask
|=
WTNCA_NODRAWCAPTION;
}
if
(
!
info.ShowIcon)
{
ops.Mask
|=
WTNCA_NODRAWICON
|
WTNCA_NOSYSMENU;
}
//
Set It, The Marshal.Sizeof() stuff is to get the right size of the custom struct, and in UINT/DWORD Form
SetWindowThemeAttribute(mainWindowPtr, WindowThemeAttributeType.WTA_NONCLIENT,
ref
ops, (
uint
)Marshal.SizeOf(
typeof
(WTA_OPTIONS)));
}
#region
设置任意位置拖动效果API
const
int
WM_NCLBUTTONDOWN
=
0xA1
;
const
int
HT_CAPTION
=
0x2
;
[DllImportAttribute(
"
user32.dll
"
)]
static
extern
int
SendMessage(IntPtr hWnd,
int
Msg,
int
wParam,
int
lParam);
[DllImportAttribute(
"
user32.dll
"
)]
static
extern
bool
ReleaseCapture();
static
void
EnableMouseDrag(Window window,
int
topMargin)
{
window.MouseLeftButtonDown
+=
(s, e)
=>
{
var win
=
s
as
Window;
var point
=
e.GetPosition(win);
if
(point.Y
>
topMargin)
return
;
Console.WriteLine(e.OriginalSource);
var mainWindowPtr
=
new
WindowInteropHelper(win).Handle;
ReleaseCapture();
SendMessage(mainWindowPtr, WM_NCLBUTTONDOWN, HT_CAPTION,
0
);
};
}
#endregion
#region
设置玻璃效果API
[StructLayout(LayoutKind.Sequential)]
struct
MARGINS
{
public
int
Left;
public
int
Right;
public
int
Top;
public
int
Bottom;
public
MARGINS(
int
left,
int
right,
int
top,
int
bottom)
{
this
.Left
=
left;
this
.Right
=
right;
this
.Top
=
top;
this
.Bottom
=
bottom;
}
public
MARGINS(Thickness margin)
{
this
.Left
=
(
int
)margin.Left;
this
.Right
=
(
int
)margin.Right;
this
.Top
=
(
int
)margin.Top;
this
.Bottom
=
(
int
)margin.Bottom;
}
};
[DllImport(
"
DwmApi.dll
"
)]
static
extern
int
DwmExtendFrameIntoClientArea(IntPtr hwnd,
ref
MARGINS pMarInset);
[DllImport(
"
dwmapi.dll
"
, PreserveSig
=
false
)]
static
extern
bool
DwmIsCompositionEnabled();
public
static
readonly
DependencyProperty IsEnabledProperty
=
DependencyProperty.RegisterAttached(
"
IsEnabled
"
,
typeof
(Boolean),
typeof
(GlassEffect),
new
FrameworkPropertyMetadata(OnIsEnabledChanged));
#endregion
#region
设置标题栏属性
///
<summary>
///
Do Not Draw The Caption (Text)
///
</summary>
public
static
uint
WTNCA_NODRAWCAPTION
=
0x00000001
;
///
<summary>
///
Do Not Draw the Icon
///
</summary>
public
static
uint
WTNCA_NODRAWICON
=
0x00000002
;
///
<summary>
///
Do Not Show the System Menu
///
</summary>
public
static
uint
WTNCA_NOSYSMENU
=
0x00000004
;
///
<summary>
///
Do Not Mirror the Question mark Symbol
///
</summary>
public
static
uint
WTNCA_NOMIRRORHELP
=
0x00000008
;
///
<summary>
///
The Options of What Attributes to Add/Remove
///
</summary>
[StructLayout(LayoutKind.Sequential)]
struct
WTA_OPTIONS
{
public
uint
Flags;
public
uint
Mask;
}
///
<summary>
///
What Type of Attributes? (Only One is Currently Defined)
///
</summary>
enum
WindowThemeAttributeType
{
WTA_NONCLIENT
=
1
,
};
///
<summary>
///
Set The Window's Theme Attributes
///
</summary>
///
<param name="hWnd">
The Handle to the Window
</param>
///
<param name="wtype">
What Type of Attributes
</param>
///
<param name="attributes">
The Attributes to Add/Remove
</param>
///
<param name="size">
The Size of the Attributes Struct
</param>
///
<returns>
If The Call Was Successful or Not
</returns>
[DllImport(
"
UxTheme.dll
"
)]
static
extern
int
SetWindowThemeAttribute(IntPtr hWnd, WindowThemeAttributeType wtype,
ref
WTA_OPTIONS attributes,
uint
size);
#endregion
}