当我第一次运行Zune时,我为这些美丽的UI所折服。当时就说这肯定不是用WPF做的,因为这些字体是如此的清晰而且UI反映的也非常快速。。而且我从维基百科上也了解到Zune的第一个版本是2006年发布的,而WPF与.NET 3.0却是 2006 年11月发布的。
那么问题来了,如果它不是WPF做的,那它是用什么技术做到的呢?为了找到答案,我使用Process Explorer工具来看看Zune是如何启动的,默认情况下,.NET应用程序都是被用黄色高亮显示的。很好,这说明Zune肯定是.net 应用程序了,然后我们可以看到Zune需要如下库
01
class="comments">// Is this a double-click?
02
if
(DateTime.Now.Subtract(m_headerLastClicked) <= s_doubleClick)
03
{
04
// Execute the code inside the event handler for the
05
// restore button click passing null for the sender
06
// and null for the event args.
07
HandleRestoreClick(
null
,
null
);
08
}
09
10
m_headerLastClicked = DateTime.Now;
11
12
if
(Mouse.LeftButton == MouseButtonState.Pressed)
13
{
14
DragMove();
15
}
该如何任意改变窗体大小? 在主窗体的四个角分别添加一个Shape(比如Rectangle)然后为它们都订阅PreviewMouseDown事件处理:
01
Rectangle clickedRectangle = (Rectangle)sender;
02
03
switch
(clickedRectangle.Name)
04
{
05
case
"top"
:
06
Cursor = Cursors.SizeNS;
07
ResizeWindow(ResizeDirection.Top);
08
break
;
09
case
"bottom"
:
10
Cursor = Cursors.SizeNS;
11
ResizeWindow(ResizeDirection.Bottom);
12
break
;
13
// ...
14
}
下面就是用鼠标重新调整窗体大小的代码
01
/// <summary> /// Resizes the window.
02
/// </summary> /// <param name="direction">The direction.
03
private
void
ResizeWindow(ResizeDirection direction)
04
{
05
NativeMethods.SendMessage(m_hwndSource.Handle, WM_SYSCOMMAND,
06
(IntPtr)(61440 + direction), IntPtr.Zero);
07
}
08
09
[DllImport(
"user32.dll"
, CharSet = CharSet.Auto)]
10
internal
static
extern
IntPtr SendMessage(
11
IntPtr hWnd,
12
UInt32 msg,
13
IntPtr wParam,
14
IntPtr lParam);
如何为窗体添加阴影效果。 实际上有两种做法: 第一种就是试用DWM API。这个方法需要订阅SourceInitialized事件。
01
/// <summary> /// Raises the <see cref="FrameworkElement.Initialized"> event.
02
/// This method is invoked whenever
03
/// <see cref="P:FrameworkElement.IsInitialized"> /// is set to true internally.
04
/// </see></see></summary> /// <param name="e">The <see cref="T:RoutedEventArgs"> /// that contains the event data.
05
protected
override
void
OnInitialized(EventArgs e)
06
{
07
AllowsTransparency =
false
;
08
ResizeMode = ResizeMode.NoResize;
09
Height = 480;
10
Width = 852;
11
WindowStartupLocation = WindowStartupLocation.CenterScreen;
12
WindowStyle = WindowStyle.None;
13
14
SourceInitialized += HandleSourceInitialized;
15
16
base
.OnInitialized(e);
17
}
18
19
/// <summary> /// Handles the source initialized.
20
/// </summary> /// <param name="sender">The sender.
21
/// <param name="e">The <see cref="System.EventArgs"> /// instance containing the event data.
22
private
void
HandleSourceInitialized(Object sender, EventArgs e)
23
{
24
m_hwndSource = (HwndSource)PresentationSource.FromVisual(
this
);
25
26
// Returns the HwndSource object for the window
27
// which presents WPF content in a Win32 window.
28
HwndSource.FromHwnd(m_hwndSource.Handle).AddHook(
29
new
HwndSourceHook(NativeMethods.WindowProc));
30
31
// http://msdn.microsoft.com/en-us/library/aa969524(VS.85).aspx
32
Int32 DWMWA_NCRENDERING_POLICY = 2;
33
NativeMethods.DwmSetWindowAttribute(
34
m_hwndSource.Handle,
35
DWMWA_NCRENDERING_POLICY,
36
ref
DWMWA_NCRENDERING_POLICY,
37
4);
38
39
// http://msdn.microsoft.com/en-us/library/aa969512(VS.85).aspx
40
NativeMethods.ShowShadowUnderWindow(m_hwndSource.Handle);
41
}</see></see>
无阴影的窗体
01
/// <summary> /// Initializes the surrounding windows.
02
/// </summary> private void InitializeSurrounds()
03
{
04
// Top.
05
m_wndT = CreateTransparentWindow();
06
07
// Left.
08
m_wndL = CreateTransparentWindow();
09
10
// Bottom.
11
m_wndB = CreateTransparentWindow();
12
13
// Right.
14
m_wndR = CreateTransparentWindow();
15
16
SetSurroundShadows();
17
}
18
19
/// <summary> /// Creates an empty window.
20
/// </summary> /// <returns></returns> private static Window CreateTransparentWindow()
21
{
22
Window wnd =
new
Window();
23
wnd.AllowsTransparency =
true
;
24
wnd.ShowInTaskbar =
false
;
25
wnd.WindowStyle = WindowStyle.None;
26
wnd.Background =
null
;
27
28
return
wnd;
29
}
30
31
/// <summary> /// Sets the artificial drop shadow.
32
/// </summary> /// <param name="active">if set to <c>true</c> [active].
33
private
void
SetSurroundShadows(Boolean active =
true
)
34
{
35
if
(active)
36
{
37
Double cornerRadius = 1.75;
38
39
m_wndT.Content = GetDecorator(
40
"Images/ACTIVESHADOWTOP.PNG"
);
41
m_wndL.Content = GetDecorator(
42
"Images/ACTIVESHADOWLEFT.PNG"
, cornerRadius);
43
m_wndB.Content = GetDecorator(
44
"Images/ACTIVESHADOWBOTTOM.PNG"
);
45
m_wndR.Content = GetDecorator(
46
"Images/ACTIVESHADOWRIGHT.PNG"
, cornerRadius);
47
}
48
else
49
{
50
m_wndT.Content = GetDecorator(
51
"Images/INACTIVESHADOWTOP.PNG"
);
52
m_wndL.Content = GetDecorator(
53
"Images/INACTIVESHADOWLEFT.PNG"
);
54
m_wndB.Content = GetDecorator(
55
"Images/INACTIVESHADOWBOTTOM.PNG"
);
56
m_wndR.Content = GetDecorator(
57
"Images/INACTIVESHADOWRIGHT.PNG"
);
58
}
59
}
60
61
[DebuggerStepThrough]
62
private
Decorator GetDecorator(String imageUri, Double radius = 0)
63
{
64
Border border =
new
Border();
65
border.CornerRadius =
new
CornerRadius(radius);
66
border.Background =
new
ImageBrush(
67
new
BitmapImage(
68
new
Uri(BaseUriHelper.GetBaseUri(
this
),
69
imageUri)));
70
71
return
border;
72
}
计算位置高度的代码 01
/// <summary> /// Raises the <see cref="FrameworkElement.Initialized"> event.
02
/// This method is invoked whenever
03
/// <see cref="FrameworkElement.IsInitialized"> /// is set to true internally.
04
/// </see></see></summary> /// <param name="e">The <see cref="T:RoutedEventArgs"> /// that contains the event data.
05
protected
override
void
OnInitialized(EventArgs e)
06
{
07
// ...
08
09
LocationChanged += HandleLocationChanged;
10
SizeChanged += HandleLocationChanged;
11
StateChanged += HandleWndStateChanged;
12
13
InitializeSurrounds();
14
ShowSurrounds();
15
16
base
.OnInitialized(e);
17
}
18
19
/// <summary> /// Handles the location changed.
20
/// </summary> /// <param name="sender">The sender.
21
/// <param name="e">The <see cref="System.EventArgs"> /// instance containing the event data.
22
private
void
HandleLocationChanged(Object sender, EventArgs e)
23
{
24
m_wndT.Left = Left - c_edgeWndSize;
25
m_wndT.Top = Top - m_wndT.Height;
26
m_wndT.Width = Width + c_edgeWndSize * 2;
27
m_wndT.Height = c_edgeWndSize;
28
29
m_wndL.Left = Left - m_wndL.Width;
30
m_wndL.Top = Top;
31
m_wndL.Width = c_edgeWndSize;
32
m_wndL.Height = Height;
33
34
m_wndB.Left = Left - c_edgeWndSize;
35
m_wndB.Top = Top + Height;
36
m_wndB.Width = Width + c_edgeWndSize * 2;
37
m_wndB.Height = c_edgeWndSize;
38
39
m_wndR.Left = Left + Width;
40
m_wndR.Top = Top;
41
m_wndR.Width = c_edgeWndSize;
42
m_wndR.Height = Height;
43
}
44
45
/// <summary> /// Handles the windows state changed.
46
/// </summary> /// <param name="sender">The sender.
47
/// <param name="e">The <see cref="System.EventArgs"> /// instance containing the event data.
48
private
void
HandleWndStateChanged(Object sender, EventArgs e)
49
{
50
if
(WindowState == WindowState.Normal)
51
{
52
ShowSurrounds();
53
}
54
else
55
{
56
HideSurrounds();
57
}
58
}</see></see></see>