Advertisement
Guest User

WinformsHost inside a ScrollViewer

a guest
Jul 29th, 2016
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.70 KB | None | 0 0
  1. /// <summary>Top left x position of window region</summary>
  2. private Int32 _topLeftX = -1;
  3.  
  4. /// <summary>Top left y position of window region</summary>
  5. private Int32 _topLeftY = -1;
  6.  
  7. /// <summary>Bottom right x position of window region</summary>
  8. private Int32 _bottomRightX = -1;
  9.  
  10. /// <summary>Bottom right x position of window region</summary>
  11. private Int32 _bottomRightY = -1;
  12.  
  13. // ...
  14.  
  15. /// <summary>Creates a handle to a region specified through upper left and bottom right corner.</summary>
  16. /// <param name="x1">Upper left X</param>
  17. /// <param name="y1">Upper left Y</param>
  18. /// <param name="x2">Bottom right X</param>
  19. /// <param name="y2">Bottom right Y</param>
  20. /// <returns>Returns a handle to the created region.</returns>
  21. [DllImport("GDI32.DLL", EntryPoint = "CreateRectRgn")]
  22. private static extern IntPtr CreateRectRgn(Int32 x1, Int32 y1, Int32 x2, Int32 y2);
  23.  
  24. /// <summary>Sets the specified region to the specified window. That means the specified window can paint
  25. /// itself only in the specified region.</summary>
  26. /// <param name="hWnd">Handle to the window</param>
  27. /// <param name="hRgn">Hanlde to the region</param>
  28. /// <param name="bRedraw">Boolean indicating whether the specified region should be redrawn.</param>
  29. /// <returns>Returns nonzero if success, otherwise zero.</returns>
  30. [DllImport("User32.dll", SetLastError = true)]
  31. private static extern Int32 SetWindowRgn(IntPtr hWnd, IntPtr hRgn, Boolean bRedraw);
  32.  
  33. /// <summary>
  34. /// Gets the handle of the parent
  35. /// </summary>
  36. /// <param name="hWnd">The Childs hWnd</param>
  37. /// <returns></returns>
  38. [DllImport("User32.dll")]
  39. private static extern IntPtr GetParent(IntPtr hWnd);
  40.  
  41. private void OnScrollChanged(object sender, ScrollChangedEventArgs scrollChangedEventArgs)
  42. {
  43.     PresentationSource presentationSource = PresentationSource.FromVisual(this);
  44.  
  45.     Visual rootVisual = presentationSource?.RootVisual;
  46.     if (rootVisual == null)
  47.     {
  48.         return;
  49.     }
  50.  
  51.     var scrollViewer = sender as ScrollViewer;
  52.     if(scrollViewer == null || !scrollViewer.IsDescendantOf(rootVisual)) return;
  53.  
  54.     GeneralTransform transform = scrollViewer.TransformToAncestor(rootVisual);
  55.     Rect scrollRect = transform.TransformBounds(new Rect(0, 0, scrollViewer.ViewportWidth, scrollViewer.ViewportHeight));
  56.  
  57.     // calculate the rect of the scrollable windows forms host instance with 0/0 at upper left corner of root visual
  58.     transform = TransformToAncestor(rootVisual);
  59.     Rect hostRect = transform.TransformBounds(new Rect(Padding.Left, Padding.Right,
  60.       RenderSize.Width, RenderSize.Height));
  61.  
  62.     // calculate the intersection of the two rect
  63.     Rect intersectRect = Rect.Intersect(scrollRect, hostRect);
  64.  
  65.     Int32 topLeftX = 0;
  66.     Int32 topLeftY = 0;
  67.     Int32 bottomRightX = 0;
  68.     Int32 bottomRightY = 0;
  69.  
  70.     if (intersectRect != Rect.Empty)
  71.     {
  72.         // calculate the HRGN points with 0/0 at upper left corner of scrollable windows forms host instance
  73.         topLeftX = (Int32)(intersectRect.TopLeft.X - hostRect.TopLeft.X);
  74.         topLeftY = (Int32)(intersectRect.TopLeft.Y - hostRect.TopLeft.Y);
  75.         bottomRightX = (Int32)(intersectRect.BottomRight.X - hostRect.TopLeft.X);
  76.         bottomRightY = (Int32)(intersectRect.BottomRight.Y - hostRect.TopLeft.Y);
  77.     }
  78.  
  79.     // because the CreateRectRgn / SetWindowRgn api calls are slow we call them only if it has a visual effect
  80.     if (_topLeftX != topLeftX || _topLeftY != topLeftY || _bottomRightX != bottomRightX || _bottomRightY != bottomRightY)
  81.     {
  82.         _topLeftX = topLeftX;
  83.         _topLeftY = topLeftY;
  84.         _bottomRightX = bottomRightX;
  85.         _bottomRightY = bottomRightY;
  86.         // create HRGN object and set it to the windows forms host instance
  87.         IntPtr hrgn = CreateRectRgn(_topLeftX, _topLeftY, _bottomRightX, _bottomRightY);
  88.         SetWindowRgn(GetParent(_webView.Handle), hrgn, true);
  89.     }
  90. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement