[导入]Part III: Non-Rectangular Window in WPF (use of Thumb)

There seemed to be quite a lot of interest in my previous post on non-rectangular spash screen and I also received a lot of requests to post code to move around such a window.

The magic to this is to use a thumb and then use the dragdelta event. The code would look something like this:


void b_Click(object sender, RoutedEventArgs e)

{

   HwndSourceParameters sParams = new HwndSourceParameters("Layered window", 200, 200);

   sParams.UsesPerPixelOpacity = true;

   _source = new HwndSource(sParams);

   _source.Disposed += new EventHandler(_source_Disposed);

   Thumb t = new Thumb();

   t.Height = 200;

   t.Width = 200;

   t.DragDelta += MoveImage;

 

   Image vista = new Image();

   vista.Margin = new Thickness(0);

   BitmapImage bi = new BitmapImage();

   bi.BeginInit();

   bi.UriSource = new Uri(@"pack://siteoforigin:,,,/vista.jpg");

   bi.EndInit();

   vista.Source = bi;

   FrameworkElementFactory fe = new FrameworkElementFactory(typeof(Image), "Image");

   fe.SetValue(Image.SourceProperty, bi);

   ControlTemplate ct = new ControlTemplate(typeof(Thumb));

   ct.VisualTree = fe;

   t.Template = ct;

   

   Canvas body = new Canvas();

   body.Width = 200d;

   body.Height = 200d;

   body.Children.Add(t);

   _source.RootVisual = body;

}

void _source_Disposed(object sender, EventArgs e)

{

   Dispatcher.InvokeShutdown();

}

private void MoveImage(object s, DragDeltaEventArgs e)

{

   top += (int)e.HorizontalChange;

   left += (int)e.VerticalChange;

   SetWindowPos(_source.Handle, IntPtr.Zero, top, left, 200, 200, 0);

}

private int top = 0, left = 0;

HwndSource _source;

[DllImport("User32.dll", SetLastError = true)]

internal static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int Flags);

 

The final result consists of an image which you can move around since we make use of a thumb.(below you see two images of vista - bear in mind that the code above can create multiple images but the moving around would work only with the latest window created because we only track the latest :) )

Image hosting by Photobucket

The dragdelta handler calculates the drag and repositions the window. We change the template of the so that the entire window/image acts as a Thumb and consequently, wherever you drag on the image the entire image moves. The simpler thing to do would be to create a simple thumb but then the window can be moved only when you drag the thumb. This would be the common usage since most of the times an app can be moved only on dragging certain parts of the app.  

One thing to note is that I have used a disposed handler. (not really useful if Hwndsource is being created from an existing window)  This is necessary  if you create an HwndSource from the MainApp (OnStartUp). Why? Because if the hwndsource is closed the app still continues to exist the reason being that Application is a Framework concept while Application is a Core concept. The other way to do this is to add a hook to the HwndSource and then listen to the WM_CLOSE msg and  then call the dispatcher. This would be lengthier but is the more appropriate way to do it considering coding style. ;)

btw I have now started using Expression Interactive Designer and it does make things a lot simpler. So hopefully will find time to create something on it and then have it posted. EID for the Feb CTP will be released this month. Let your imagination loose!!!...

 


文章来源:http://blogs.msdn.com/llobo/archive/2006/03/04/543762.aspx

posted on 2006-03-05 09:04 毒菇求Buy 阅读(641) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
<2010年7月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

导航

统计

常用链接

留言簿(7)

随笔分类(133)

随笔档案(111)

文章分类(65)

文章档案(53)

相册

收藏夹(30)

BLOG

Book store

Graphics Design

搜索

最新评论

阅读排行榜

评论排行榜