1010using MahApps . Metro . Native ;
1111using System . Windows . Shapes ;
1212using System . Collections . Generic ;
13+ using System . Reflection ;
1314using System . Windows . Controls . Primitives ;
15+ using System . Windows . Threading ;
1416
1517namespace MahApps . Metro . Controls
1618{
@@ -899,11 +901,23 @@ public override void OnApplyTemplate()
899901 this . SetVisibiltyForAllTitleElements ( this . TitlebarHeight > 0 ) ;
900902 }
901903
904+ protected IntPtr CriticalHandle
905+ {
906+ get
907+ {
908+ var value = typeof ( Window )
909+ . GetProperty ( "CriticalHandle" , BindingFlags . NonPublic | BindingFlags . Instance )
910+ . GetValue ( this , new object [ 0 ] ) ;
911+ return ( IntPtr ) value ;
912+ }
913+ }
914+
902915 private void ClearWindowEvents ( )
903916 {
904917 // clear all event handlers first:
905918 if ( this . windowTitleThumb != null )
906919 {
920+ this . windowTitleThumb . PreviewMouseLeftButtonUp -= WindowTitleThumbOnPreviewMouseLeftButtonUp ;
907921 this . windowTitleThumb . DragDelta -= this . WindowTitleThumbMoveOnDragDelta ;
908922 this . windowTitleThumb . MouseDoubleClick -= this . WindowTitleThumbChangeWindowStateOnMouseDoubleClick ;
909923 this . windowTitleThumb . MouseRightButtonUp -= this . WindowTitleThumbSystemMenuOnMouseRightButtonUp ;
@@ -928,6 +942,7 @@ private void SetWindowEvents()
928942
929943 if ( this . windowTitleThumb != null )
930944 {
945+ this . windowTitleThumb . PreviewMouseLeftButtonUp += WindowTitleThumbOnPreviewMouseLeftButtonUp ;
931946 this . windowTitleThumb . DragDelta += this . WindowTitleThumbMoveOnDragDelta ;
932947 this . windowTitleThumb . MouseDoubleClick += this . WindowTitleThumbChangeWindowStateOnMouseDoubleClick ;
933948 this . windowTitleThumb . MouseRightButtonUp += this . WindowTitleThumbSystemMenuOnMouseRightButtonUp ;
@@ -955,6 +970,11 @@ private void IconMouseDown(object sender, MouseButtonEventArgs e)
955970 }
956971 }
957972
973+ private void WindowTitleThumbOnPreviewMouseLeftButtonUp ( object sender , MouseButtonEventArgs e )
974+ {
975+ DoWindowTitleThumbOnPreviewMouseLeftButtonUp ( this , e ) ;
976+ }
977+
958978 private void WindowTitleThumbMoveOnDragDelta ( object sender , DragDeltaEventArgs dragDeltaEventArgs )
959979 {
960980 DoWindowTitleThumbMoveOnDragDelta ( this , dragDeltaEventArgs ) ;
@@ -970,18 +990,24 @@ private void WindowTitleThumbSystemMenuOnMouseRightButtonUp(object sender, Mouse
970990 DoWindowTitleThumbSystemMenuOnMouseRightButtonUp ( this , e ) ;
971991 }
972992
993+ internal static void DoWindowTitleThumbOnPreviewMouseLeftButtonUp ( MetroWindow window , MouseButtonEventArgs mouseButtonEventArgs )
994+ {
995+ Mouse . Capture ( null ) ;
996+ }
997+
973998 internal static void DoWindowTitleThumbMoveOnDragDelta ( MetroWindow window , DragDeltaEventArgs dragDeltaEventArgs )
974999 {
9751000 // drag only if IsWindowDraggable is set to true
9761001 if ( ! window . IsWindowDraggable ||
977- ( ! ( Math . Abs ( dragDeltaEventArgs . HorizontalChange ) > 2 ) &&
978- ! ( Math . Abs ( dragDeltaEventArgs . VerticalChange ) > 2 ) ) ) return ;
1002+ ( ! ( Math . Abs ( dragDeltaEventArgs . HorizontalChange ) > 2 ) && ! ( Math . Abs ( dragDeltaEventArgs . VerticalChange ) > 2 ) ) )
1003+ {
1004+ return ;
1005+ }
9791006
980- var windowHandle = new WindowInteropHelper ( window ) . Handle ;
981- var cursorPos = Standard . NativeMethods . GetCursorPos ( ) ;
1007+ // tage from DragMove internal code
1008+ window . VerifyAccess ( ) ;
9821009
983- // for the touch usage
984- UnsafeNativeMethods . ReleaseCapture ( ) ;
1010+ var cursorPos = Standard . NativeMethods . GetCursorPos ( ) ;
9851011
9861012 // if the window is maximized dragging is only allowed on title bar (also if not visible)
9871013 var windowIsMaximized = window . WindowState == WindowState . Maximized ;
@@ -991,14 +1017,30 @@ internal static void DoWindowTitleThumbMoveOnDragDelta(MetroWindow window, DragD
9911017 return ;
9921018 }
9931019
994- if ( windowIsMaximized )
995- {
1020+ // for the touch usage
1021+ UnsafeNativeMethods . ReleaseCapture ( ) ;
1022+
1023+ if ( windowIsMaximized ) {
9961024 window . Top = 2 ;
9971025 window . Left = Math . Max ( cursorPos . x - window . RestoreBounds . Width / 2 , 0 ) ;
1026+ EventHandler windowOnStateChanged = null ;
1027+ windowOnStateChanged = ( sender , args ) =>
1028+ {
1029+ window . StateChanged -= windowOnStateChanged ;
1030+ if ( window . WindowState == WindowState . Normal )
1031+ {
1032+ Mouse . Capture ( window . windowTitleThumb , CaptureMode . Element ) ;
1033+ }
1034+ } ;
1035+ window . StateChanged += windowOnStateChanged ;
9981036 }
999- var lParam = ( int ) ( uint ) cursorPos . x | ( cursorPos . y << 16 ) ;
1000- Standard . NativeMethods . SendMessage ( windowHandle , Standard . WM . LBUTTONUP , ( IntPtr ) Standard . HT . CAPTION , ( IntPtr ) lParam ) ;
1001- Standard . NativeMethods . SendMessage ( windowHandle , Standard . WM . SYSCOMMAND , ( IntPtr ) Standard . SC . MOUSEMOVE , IntPtr . Zero ) ;
1037+
1038+ var criticalHandle = window . CriticalHandle ;
1039+ // DragMove works too
1040+ // window.DragMove();
1041+ // instead this 2 lines
1042+ Standard . NativeMethods . SendMessage ( criticalHandle , Standard . WM . SYSCOMMAND , ( IntPtr ) Standard . SC . MOUSEMOVE , IntPtr . Zero ) ;
1043+ Standard . NativeMethods . SendMessage ( criticalHandle , Standard . WM . LBUTTONUP , IntPtr . Zero , IntPtr . Zero ) ;
10021044 }
10031045
10041046 internal static void DoWindowTitleThumbChangeWindowStateOnMouseDoubleClick ( MetroWindow window , MouseButtonEventArgs mouseButtonEventArgs )
0 commit comments