ShowWindowFollowMouse.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. using GeekDesk.Constant;
  2. using System;
  3. using System.Drawing;
  4. using System.Runtime.InteropServices;
  5. using System.Windows;
  6. using System.Windows.Forms;
  7. namespace GeekDesk.Util
  8. {
  9. public class ShowWindowFollowMouse
  10. {
  11. public enum MousePosition
  12. {
  13. CENTER = 1,
  14. LEFT_TOP = 2,
  15. LEFT_BOTTOM = 3,
  16. RIGHT_TOP = 4,
  17. RIGHT_BOTTOM = 5,
  18. LEFT_CENTER = 6,
  19. RIGHT_CENTER = 7
  20. }
  21. public static void FollowMouse(Window window)
  22. {
  23. // Get the mouse position
  24. var mousePosition = System.Windows.Forms.Control.MousePosition;
  25. // Get the window size
  26. var windowWidth = window.Width;
  27. var windowHeight = window.Height;
  28. Console.WriteLine("windowWidth + windowHeight:" + windowWidth + "+" + windowHeight);
  29. // Get the screen where the mouse is located
  30. var screen = System.Windows.Forms.Screen.FromPoint(new System.Drawing.Point(mousePosition.X, mousePosition.Y));
  31. var workingArea = screen.WorkingArea;
  32. // Get the DPI scaling factor for the screen
  33. //float dpiX, dpiY;
  34. //using (var graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero))
  35. //{
  36. // dpiX = graphics.DpiX / 96f; // 96 is the default DPI
  37. // dpiY = graphics.DpiY / 96f; // 96 is the default DPI
  38. //}
  39. float dpiX = GetDpi( true);
  40. float dpiY = GetDpi(false);
  41. // Convert mouse position to logical pixels based on DPI
  42. double mouseX = mousePosition.X / dpiX;
  43. double mouseY = mousePosition.Y / dpiY;
  44. // Calculate target position to center the window on the mouse
  45. double targetLeft = mouseX - windowWidth / 2;
  46. double targetTop = mouseY - windowHeight / 2;
  47. // Ensure the window does not exceed the screen boundaries
  48. if (targetLeft < workingArea.Left / dpiX)
  49. targetLeft = workingArea.Left / dpiX;
  50. if (targetLeft + windowWidth / dpiX > workingArea.Right / dpiX)
  51. targetLeft = workingArea.Right / dpiX - windowWidth / dpiX;
  52. if (targetTop < workingArea.Top / dpiY)
  53. targetTop = workingArea.Top / dpiY;
  54. if (targetTop + windowHeight / dpiY > workingArea.Bottom / dpiY)
  55. targetTop = workingArea.Bottom / dpiY - windowHeight / dpiY;
  56. // Update window position
  57. window.Left = targetLeft * dpiX;
  58. window.Top = targetTop * dpiY;
  59. }
  60. private static float GetDpi(bool isX)
  61. {
  62. IntPtr hdc = WindowUtil.GetDC(IntPtr.Zero);
  63. int dpi = isX ? WindowUtil.GetDeviceCaps(hdc, LOGPIXELSX) : WindowUtil.GetDeviceCaps(hdc, LOGPIXELSY);
  64. WindowUtil.ReleaseDC(IntPtr.Zero, hdc);
  65. return dpi / 96f;
  66. }
  67. private static IntPtr GetScreenHandleFromMouse()
  68. {
  69. // Get the mouse position
  70. var mousePosition = System.Windows.Forms.Control.MousePosition;
  71. // Convert mouse position to a POINT structure
  72. System.Drawing.Point point = new System.Drawing.Point(mousePosition.X, mousePosition.Y);
  73. // Get the window handle from the point
  74. IntPtr windowHandle = WindowUtil.WindowFromPoint(point);
  75. return windowHandle;
  76. }
  77. // Constants for DPI
  78. private const int HORZRES = 8;
  79. private const int VERTRES = 10;
  80. private const int LOGPIXELSX = 88;
  81. private const int LOGPIXELSY = 90;
  82. /// <summary>
  83. /// 随鼠标位置显示面板
  84. /// </summary>
  85. public static void Show(Window window, MousePosition position, double widthOffset = 0, double heightOffset = 0)
  86. {
  87. //获取鼠标位置
  88. System.Windows.Point p = MouseUtil.GetMousePosition();
  89. float dpiX = GetDpi(true);
  90. float dpiY = GetDpi(false);
  91. p.X = p.X / dpiX;
  92. p.Y = p.Y / dpiY;
  93. double left = SystemParameters.VirtualScreenLeft;
  94. double top = SystemParameters.VirtualScreenTop;
  95. double width = SystemParameters.VirtualScreenWidth;
  96. double height = SystemParameters.WorkArea.Height;
  97. double right = width - Math.Abs(left);
  98. double bottom = height - Math.Abs(top);
  99. double afterWidth;
  100. double afterHeight;
  101. switch (position)
  102. {
  103. case MousePosition.LEFT_BOTTOM:
  104. afterWidth = 0;
  105. afterHeight = window.Height;
  106. break;
  107. case MousePosition.LEFT_TOP:
  108. afterWidth = 0;
  109. afterHeight = 0;
  110. break;
  111. case MousePosition.LEFT_CENTER:
  112. afterWidth = 0;
  113. afterHeight = window.Height / 2;
  114. break;
  115. case MousePosition.RIGHT_BOTTOM:
  116. afterWidth = window.Width;
  117. afterHeight = window.Height;
  118. break;
  119. case MousePosition.RIGHT_TOP:
  120. afterWidth = window.Width;
  121. afterHeight = 0;
  122. break;
  123. case MousePosition.RIGHT_CENTER:
  124. afterWidth = window.Width;
  125. afterHeight = window.Height / 2;
  126. break;
  127. default:
  128. afterWidth = window.Width / 2;
  129. afterHeight = window.Height / 2;
  130. break;
  131. }
  132. afterWidth += widthOffset;
  133. afterHeight -= heightOffset;
  134. if (p.X - afterWidth < left)
  135. {
  136. //判断是否在最左边缘
  137. window.Left = left - Constants.SHADOW_WIDTH;
  138. }
  139. else if (p.X + afterWidth > right)
  140. {
  141. //判断是否在最右边缘
  142. window.Left = right - window.Width + Constants.SHADOW_WIDTH;
  143. }
  144. else
  145. {
  146. window.Left = p.X - afterWidth;
  147. }
  148. if (p.Y - afterHeight < top)
  149. {
  150. //判断是否在最上边缘
  151. window.Top = top - Constants.SHADOW_WIDTH;
  152. }
  153. else if (p.Y + afterHeight > bottom)
  154. {
  155. //判断是否在最下边缘
  156. window.Top = bottom - window.Height + Constants.SHADOW_WIDTH;
  157. }
  158. else
  159. {
  160. window.Top = p.Y - afterHeight;
  161. }
  162. }
  163. }
  164. }