WPF中自制窗口标题栏
在WPF程序开发中,我们常常会发现默认的窗口标题栏过于不合适,而想修改其样式。有不少办法可以达到这一目的,但往往都不那么容易。而最简单的方法就是,直接不要默认的标题栏,转而在窗体内部重新制作一个,这样就可以充分使用我们所熟知的WPF的开发方式。不过,这样一来又有一个问题,即模拟的标题栏毕竟不是真正的标题栏,按住它无法拖动窗口,也无法双击最大化。Aland Li提供了一个好办法解决这一问题。
Windows使用WM_NCHITTEST窗口消息来判断鼠标的位置的类型,比如是否是标题栏,我们可以捕获这个消息,然后检查鼠标的坐标,如果在我们所设计的标题栏内,我们就告诉系统这个位置在标题栏上(返回HTCAPTION(2))。下面是详细代码:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// 添加一个消息过滤器
IntPtr hwnd = new WindowInteropHelper(this).Handle;
HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(WndProc));
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if(msg == WM_NCHITTEST)
{
// 获取屏幕坐标
Point p = new Point();
int pInt = lParam.ToInt32();
p.X = (pInt << 16) >> 16;
p.Y = pInt >> 16;
if(isOnTitleBar(PointFromScreen(p)))
{
// 欺骗系统鼠标在标题栏上
handled = true;
return new IntPtr(2);
}
}
return IntPtr.Zero;
}
private bool isOnTitleBar(Point p)
{
// 假设标题栏在0和100之间
if(p.Y >= 0 && p.Y < 100)
return true;
else
return false;
}
private const int WM_NCHITTEST = 0x0084;如此,只要点击窗口上方0-100的区域,便可以拖动窗口,也可以双击窗口进行最大化了。
而要去掉默认的标题栏,只需要将WindowStyle设为None即可。
BTW,其实并不一定要WPF才行吧,这个方法同时也适用于Winform,不过一般WPF程序更有美化标题栏的需求而已。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mane_yao/archive/2010/07/02/5708487.aspx