PixelColorPickerWindow.xaml.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. using GeekDesk.Interface;
  2. using GeekDesk.Util;
  3. using HandyControl.Controls;
  4. using System;
  5. using System.Reflection;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Controls.Primitives;
  9. using System.Windows.Forms;
  10. using System.Windows.Input;
  11. using System.Windows.Interop;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Imaging;
  14. using static System.Windows.Forms.VisualStyles.VisualStyleElement;
  15. using Cursors = System.Windows.Input.Cursors;
  16. using KeyEventArgs = System.Windows.Input.KeyEventArgs;
  17. using MouseEventArgs = System.Windows.Input.MouseEventArgs;
  18. namespace GeekDesk.Control.Windows
  19. {
  20. /// <summary>
  21. /// ColorPickerWindow.xaml 的交互逻辑
  22. /// </summary>
  23. public partial class PixelColorPickerWindow : IWindowCommon
  24. {
  25. private static int PIXEL_REC_LENGTH = 10;
  26. private static readonly int MIN_LENGTH = 10;
  27. private static readonly int MAX_LENGTH = 50;
  28. //private static System.Drawing.Bitmap bgBitmap;
  29. private static RenderTargetBitmap renderTargetBitmap;
  30. private readonly ColorPicker colorPicker;
  31. [System.Runtime.InteropServices.DllImport("user32.dll")]
  32. private static extern bool SetProcessDPIAware();
  33. public PixelColorPickerWindow(ColorPicker colorPicker)
  34. {
  35. InitializeComponent();
  36. this.colorPicker = colorPicker;
  37. try
  38. {
  39. SetProcessDPIAware();
  40. }
  41. catch (Exception e) { }
  42. ColorPickerWindow_Init();
  43. }
  44. private void ColorPickerWindow_Init()
  45. {
  46. this.WindowState = WindowState.Normal;//还原窗口(非最小化和最大化)
  47. var screens = Screen.AllScreens;
  48. int allWidth = 0;
  49. int allHeight = 0;
  50. int x = 0;
  51. int y = 0;
  52. foreach (var screen in screens)
  53. {
  54. var rect = screen.Bounds;
  55. allWidth += rect.Width;
  56. allHeight += rect.Height;
  57. x = Math.Min(x, rect.X);
  58. y = Math.Min(y, rect.Y);
  59. }
  60. //获取缩放比例
  61. double scale = ScreenUtil.GetScreenScalingFactor();
  62. this.Width = allWidth;
  63. this.Height = allHeight;
  64. this.Left = x;
  65. this.Top = y;
  66. DesktopBG.Width = this.Width;
  67. DesktopBG.Height = this.Height;
  68. this.Topmost = true;
  69. System.Drawing.Bitmap bgBitmap = new System.Drawing.Bitmap(
  70. (int)(Width * scale),
  71. (int)(Height * scale),
  72. System.Drawing.Imaging.PixelFormat.Format32bppArgb
  73. );
  74. using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bgBitmap))
  75. {
  76. g.CopyFromScreen(
  77. (int)this.Left,
  78. (int)this.Top,
  79. 0,
  80. 0,
  81. bgBitmap.Size
  82. );
  83. }
  84. BitmapSource bs = Imaging.CreateBitmapSourceFromHBitmap(
  85. bgBitmap.GetHbitmap(),
  86. IntPtr.Zero,
  87. Int32Rect.Empty,
  88. BitmapSizeOptions.FromEmptyOptions()
  89. );
  90. DesktopBG.Source = bs;
  91. VisualBrush b = (VisualBrush)PixelBG.Fill;
  92. b.Visual = DesktopBG;
  93. Mouse.OverrideCursor = Cursors.Cross;
  94. }
  95. private void Window_Loaded(object sender, RoutedEventArgs e)
  96. {
  97. // 创建一个RenderTargetBitmap,捕获窗口的内容
  98. renderTargetBitmap = new RenderTargetBitmap((int)this.Width, (int)this.Height, 96, 96, PixelFormats.Pbgra32);
  99. renderTargetBitmap.Render(this);
  100. SetPixelAbout(null);
  101. }
  102. public void OnKeyDown(object sender, KeyEventArgs e)
  103. {
  104. if (e.Key == Key.Escape)
  105. {
  106. this.DataContext = null;
  107. this.Close();
  108. }
  109. }
  110. private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  111. {
  112. Mouse.OverrideCursor = null;
  113. Point pos = e.MouseDevice.GetPosition(DesktopBG);
  114. colorPicker.SelectedBrush = new SolidColorBrush(GetColorAtPosition(Mouse.GetPosition(this)));
  115. this.Close();
  116. ClickColorPickerToggleButton(colorPicker);
  117. }
  118. public void ClickColorPickerToggleButton(ColorPicker colorPicker)
  119. {
  120. const BindingFlags InstanceBindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
  121. Type type = colorPicker.GetType();
  122. FieldInfo fi = type.GetField("_toggleButtonDropper", InstanceBindFlags);
  123. ToggleButton tb = (ToggleButton)fi.GetValue(colorPicker);
  124. if (tb != null && tb.IsChecked == true)
  125. {
  126. tb.IsChecked = false;
  127. MethodInfo mi = type.GetMethod("ToggleButtonDropper_Click", InstanceBindFlags);
  128. mi.Invoke(colorPicker, new object[] { null, null });
  129. }
  130. }
  131. private void Window_PreviewMouseMove(object sender, MouseEventArgs e)
  132. {
  133. SetPixelAbout(e);
  134. }
  135. [System.Runtime.InteropServices.DllImport("gdi32.dll")]
  136. public static extern bool DeleteObject(IntPtr onj);
  137. // Constants for DPI
  138. private const int HORZRES = 8;
  139. private const int VERTRES = 10;
  140. private const int LOGPIXELSX = 88;
  141. private const int LOGPIXELSY = 90;
  142. private static float GetDpi(bool isX)
  143. {
  144. IntPtr hdc = WindowUtil.GetDC(IntPtr.Zero);
  145. int dpi = isX ? WindowUtil.GetDeviceCaps(hdc, LOGPIXELSX) : WindowUtil.GetDeviceCaps(hdc, LOGPIXELSY);
  146. WindowUtil.ReleaseDC(IntPtr.Zero, hdc);
  147. return dpi / 96f;
  148. }
  149. private void SetPixelAbout(MouseEventArgs e)
  150. {
  151. VisualBrush b = (VisualBrush)PixelBG.Fill;
  152. Point pos = Mouse.GetPosition(this);
  153. Rect viewBox = b.Viewbox;
  154. viewBox.Width = PIXEL_REC_LENGTH;
  155. viewBox.Height = PIXEL_REC_LENGTH;
  156. viewBox.X = pos.X - PIXEL_REC_LENGTH / 2;
  157. viewBox.Y = pos.Y - PIXEL_REC_LENGTH / 2;
  158. b.Viewbox = viewBox;
  159. double x = pos.X + 10;
  160. double y = pos.Y + 10;
  161. //获取缩放比例
  162. double scale = ScreenUtil.GetScreenScalingFactor();
  163. if (x + ColorCanvas.Width > this.Width / scale)
  164. {
  165. x = pos.X - ColorCanvas.Width - 10;
  166. }
  167. if (y + ColorCanvas.Height > this.Height / scale)
  168. {
  169. y = pos.Y - ColorCanvas.Height - 10;
  170. }
  171. Canvas.SetLeft(ColorCanvas, x);
  172. Canvas.SetTop(ColorCanvas, y);
  173. Color wColor = GetColorAtPosition(pos);
  174. System.Drawing.Color dColor = System.Drawing.Color.FromArgb(wColor.A, wColor.R, wColor.G, wColor.B);
  175. PixelColor_HTML.Text = "#" + dColor.Name.ToUpper().Substring(2);
  176. PixelColor_RGB.Text = dColor.R + "," + dColor.G + "," + dColor.B;
  177. Pixel_XY.Text = (int)pos.X + "*" + (int)pos.Y;
  178. SolidColorBrush scb = (SolidColorBrush)PixelColor.Fill;
  179. scb.Color = wColor;
  180. //scb.Color = Color.FromArgb(dColor.A, dColor.R, dColor.G, dColor.B);
  181. }
  182. private Color GetColorAtPosition(Point position)
  183. {
  184. // 使用CroppedBitmap裁剪出鼠标位置的一个像素
  185. CroppedBitmap croppedBitmap = new CroppedBitmap(renderTargetBitmap, new Int32Rect((int)position.X, (int)position.Y, 1, 1));
  186. // 将像素数据复制到数组中
  187. byte[] pixels = new byte[4];
  188. croppedBitmap.CopyPixels(pixels, 4, 0);
  189. // 如果像素数据有效,则返回颜色
  190. //if (pixels.Length == 4)
  191. //{
  192. //}
  193. return Color.FromArgb(pixels[3], pixels[2], pixels[1], pixels[0]);
  194. //return Color.FromArgb(0, 0, 0, 0);
  195. }
  196. /// <summary>
  197. /// 滚轮控制缩放区域
  198. /// </summary>
  199. /// <param name="sender"></param>
  200. /// <param name="e"></param>
  201. private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
  202. {
  203. if (e.Delta < 0 && PIXEL_REC_LENGTH < MAX_LENGTH)
  204. {
  205. //缩小
  206. PIXEL_REC_LENGTH += 5;
  207. }
  208. else if (e.Delta > 0 && PIXEL_REC_LENGTH > MIN_LENGTH)
  209. {
  210. //放大
  211. PIXEL_REC_LENGTH -= 5;
  212. }
  213. SetPixelAbout(e);
  214. }
  215. /// <summary>
  216. /// 右键按下
  217. /// </summary>
  218. /// <param name="sender"></param>
  219. /// <param name="e"></param>
  220. private void Window_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
  221. {
  222. Mouse.OverrideCursor = null;
  223. GlobalColorPickerWindow.ShowOrHide();
  224. //关闭
  225. this.Close();
  226. }
  227. }
  228. }