赞
踩
1.需要添加引用
System.Drawing.Common
2.主界面中添加一个按钮用于出发截图,按钮事件如下:
- 【MainWindow.xaml.cs】
-
- //截图按钮
- private void BTCut_Click(object sender, RoutedEventArgs e)
- {
- //截图时隐藏主窗体
- this.Hide();
- //截取屏幕的一帧,并打开一个窗体显示出来
- ScreenWindow snapWin = new ScreenWindow(CaptureCurrentScreen())
- {
- //ScreenWindow处理完成后回调的处理事件
- sendMessage = GetImageHandler
- };
-
- snapWin.ShowDialog();
- }
-
- private void GetImageHandler(Bitmap bitmap)
- {
- //此处写处理截图的逻辑
- }
-
- /// <summary>
- /// 截取屏幕
- /// </summary>
- /// <returns></returns>
- public static Bitmap CaptureCurrentScreen()
- {
- //创建与屏幕大小相同的位图对象
- var bmpScreen = new Bitmap((int)ScreenUtils.GetScreenWidth(), (int)ScreenUtils.GetScreenHeight(), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
-
- //使用位图对象来创建Graphics的对象
- using (Graphics g = Graphics.FromImage(bmpScreen))
- {
- g.SmoothingMode = SmoothingMode.AntiAlias; //设置平滑模式,抗锯齿
- g.CompositingQuality = CompositingQuality.HighQuality; //设置合成质量
- g.InterpolationMode = InterpolationMode.HighQualityBicubic; //设置插值模式
- g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; //设置文本呈现的质量
- g.PixelOffsetMode = PixelOffsetMode.HighQuality; //设置呈现期间,像素偏移的方式
-
- //利用CopyFromScreen将当前屏幕截图并将内容存储在bmpScreen的位图中
- g.CopyFromScreen(0, 0, 0, 0, bmpScreen.Size, CopyPixelOperation.SourceCopy);
- }
-
- return bmpScreen;
- }
3.截屏后显示的窗体ScreenWindow代码如下
前台样式:
- <Window x:Class="myTestApp.Views.ScreenWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:local="clr-namespace:myTestApp.Views"
- mc:Ignorable="d"
- WindowState="Maximized" WindowStyle="None" AllowsTransparency="True" Background="Transparent"
- Title="ScreenWindow" Height="450" Width="800">
- <Grid>
- <InkCanvas Margin="0,0,0,0" Name="Ink" Visibility="Visible" EditingModeInverted="Select" EditingMode="Select" Cursor="Cross" MouseDown="Ink_MouseDown" MouseMove="Ink_MouseMove" MouseUp="Ink_MouseUp" MouseRightButtonDown="Ink_MouseRightButtonDown">
- </InkCanvas>
- <Border Name="Bord" Visibility="Collapsed" BorderThickness="2" HorizontalAlignment="Left" VerticalAlignment="Top" Cursor="Cross" BorderBrush="#FF09646D"/>
- <Button Name="Cancel" Visibility="Collapsed" Content="✘" FontSize="16" HorizontalAlignment="Left" Height="40" Margin="527,347,0,0" VerticalAlignment="Top" Width="40" BorderBrush="Red" Background="Red" Foreground="White" Click="Cancel_Click"/>
- <Button Name="Conf" Visibility="Collapsed" Content="✔" FontSize="16" HorizontalAlignment="Left" Height="40" Margin="527,347,0,0" VerticalAlignment="Top" Width="40" BorderBrush="#FF32510C" Background="#66C4EF3C" Foreground="White" Click="Conf_Click"/>
- </Grid>
- </Window>
后台代码:
- /// <summary>
- /// ScreenWindow.xaml 的交互逻辑
- /// </summary>
- public partial class ScreenWindow : Window
- {
- public delegate void SendMessage(Bitmap bitmap);
- public SendMessage sendMessage;
- #region Win32 API
- [DllImport("user32.dll")]
- static extern IntPtr GetDC(IntPtr ptr);
- [DllImport("gdi32.dll")]
- static extern int GetDeviceCaps(
- IntPtr hdc, // handle to DC
- int nIndex // index of capability
- );
- [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
- static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
- #endregion
- #region DeviceCaps常量
- const int HORZRES = 8;
- const int VERTRES = 10;
- const int LOGPIXELSX = 88;
- const int LOGPIXELSY = 90;
- const int DESKTOPVERTRES = 117;
- const int DESKTOPHORZRES = 118;
- #endregion
-
- private bool IsSnap = false;
-
- private Bitmap ScreenShot;
- public ScreenWindow(Bitmap bitmap)
- {
- InitializeComponent();
- this.Topmost = true;
- ScreenShot = bitmap;
- MouseDown += Ink_MouseDown;
- MouseUp += Ink_MouseUp;
- MouseMove += Ink_MouseMove;
- MouseRightButtonDown += Ink_MouseRightButtonDown;
- BitmapSource source;
- IsSnap = true;
-
- try
- {
- source = Imaging.CreateBitmapSourceFromHBitmap(ScreenShot.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
- }
- catch
- {
- source = null;
- }
- ImageBrush b = new ImageBrush();
- b.ImageSource = source;
- b.Stretch = Stretch.Fill;
- Ink.Background = b;
- Ink.EditingMode = InkCanvasEditingMode.None;
- this.WindowStartupLocation = WindowStartupLocation.Manual;
- this.Visibility = Visibility.Visible;
- this.Left = 0;
- this.Top = 0;
- this.Height = SystemParameters.VirtualScreenHeight;
- this.Width = SystemParameters.VirtualScreenWidth;
- }
-
- private bool ISDown = false; // 判断是否鼠标左键按下
- System.Windows.Point Startpoint = new System.Windows.Point();
- private void Ink_MouseDown(object sender, MouseButtonEventArgs e)
- {
- ISDown = true;
- Conf.Visibility = Visibility.Collapsed;
- Cancel.Visibility = Visibility.Collapsed;
- Startpoint = Mouse.GetPosition(this);
- }
- Rect rect;
- /// <summary>
- /// 根据鼠标移动画出矩形标识区域
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Ink_MouseMove(object sender, MouseEventArgs e)
- {
- if (IsSnap)
- {
- if (ISDown == true)
- {
- System.Windows.Point point = Mouse.GetPosition(this);
- rect = new Rect(Startpoint, point);
- Bord.Visibility = Visibility.Visible;
- Bord.Margin = new Thickness(rect.Left, rect.Top, 0, 0);
- Bord.Height = rect.Height;
- Bord.Width = rect.Width;
- }
- }
- }
- Rect snapArea = new Rect();
- private void Ink_MouseUp(object sender, MouseButtonEventArgs e)
- {
- if (IsSnap)
- {
- ISDown = false;
- if (Bord.Visibility == Visibility.Collapsed)
- {
- Conf.Visibility = Visibility.Collapsed;
- Cancel.Visibility = Visibility.Collapsed;
- }
- else
- {
- Conf.Visibility = Visibility.Visible;
- Cancel.Visibility = Visibility.Visible;
- }
- if (rect.Width >= 10 && rect.Height >= 10)
- {
-
- if (System.Windows.Forms.SystemInformation.VirtualScreen.Height - rect.Bottom >= 0)
- {
- snapArea = rect;
- Conf.Margin = new Thickness(rect.Right - 40, rect.Bottom, 0, 0);
- Cancel.Margin = new Thickness(rect.Right - 80, rect.Bottom, 0, 0);
-
- }
- else
- {
- snapArea = rect;
- Conf.Margin = new Thickness(rect.Left + 10, rect.Top + 22, 0, 0);
- Cancel.Margin = new Thickness(rect.Left + 50, rect.Top + 22, 0, 0);
- }
- }
-
- }
-
- }
-
- private void Ink_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
- {
- ISDown = false;
- Conf.Visibility = Visibility.Collapsed;
- Cancel.Visibility = Visibility.Collapsed;
- Bord.Visibility = Visibility.Collapsed;
-
- }
-
- private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
- {
- if (e.KeyStates == Keyboard.GetKeyStates(Key.Escape))
- {
- ISDown = false;
- Conf.Visibility = Visibility.Collapsed;
- Cancel.Visibility = Visibility.Collapsed;
- Bord.Visibility = Visibility.Collapsed;
- this.Close();
- }
- }
- /// <summary>
- /// 确认区域
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Conf_Click(object sender, RoutedEventArgs e)
- {
- if (IsSnap)
- {
- double dpi = getDpi();
- System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle((int)((snapArea.X + 2) * dpi), (int)((snapArea.Y + 2) * dpi), (int)((snapArea.Width - 4) * dpi), (int)((snapArea.Height - 4) * dpi));
- var bitmap1 = new Bitmap((int)(snapArea.Width * dpi), (int)(snapArea.Height * dpi), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
-
- using (Graphics g = Graphics.FromImage(bitmap1))
- {
- g.CopyFromScreen(rectangle.X, rectangle.Y, 0, 0, rectangle.Size, CopyPixelOperation.SourceCopy);
- }
- this.Cursor = Cursors.Wait;
- sendMessage(bitmap1);
-
- this.Close();
- }
-
-
- }
-
- private void Cancel_Click(object sender, RoutedEventArgs e)
- {
- sendMessage(null);
- this.Close();
- }
-
- /// <summary>
- /// 获取系统dpi,这一步很重要
- /// </summary>
- /// <returns></returns>
- double getDpi()
- {
- double dDpi = 1;
- IntPtr desktopDc = GetDC(IntPtr.Zero);
- float horizontalDPI = GetDeviceCaps(desktopDc, LOGPIXELSX);
- float verticalDPI = GetDeviceCaps(desktopDc, LOGPIXELSY);
- int dpi = (int)(horizontalDPI + verticalDPI) / 2;
- dDpi = 1 + ((dpi - 96) / 24) * 0.25;
- if (dDpi < 1)
- {
- dDpi = 1;
- }
- ReleaseDC(IntPtr.Zero, desktopDc);
- return dDpi;
- }
- }
4.附:ScreenUtils.cs
-
- public class ScreenUtils
- {
- /// <summary>
- /// 获取DPI百分比
- /// </summary>
- /// <param name="window"></param>
- /// <returns></returns>
- public static double GetDpiRatio(Window window)
- {
- var currentGraphics = Graphics.FromHwnd(new WindowInteropHelper(window).Handle);
- return currentGraphics.DpiX / 96;
- }
-
- public static double GetDpiRatio()
- {
- return GetDpiRatio(Application.Current.MainWindow);
- }
-
- public static double GetScreenHeight()
- {
- return SystemParameters.PrimaryScreenHeight * GetDpiRatio();
- }
-
- public static double GetScreenActualHeight()
- {
- return SystemParameters.PrimaryScreenHeight;
- }
-
- public static double GetScreenWidth()
- {
- return SystemParameters.PrimaryScreenWidth * GetDpiRatio();
- }
-
- public static double GetScreenActualWidth()
- {
- return SystemParameters.PrimaryScreenWidth;
- }
- }
以上是实现截图功能的核心代码,接下来添加快捷键截图功能,通过Ctrl+Alt+A快捷截图
5.引用WindowsApi,用于注册全局快捷键,这样即使主窗体不在前台显示也能使用快捷键截图
添加HotKey.cs
- public class HotKey
- {
-
- [DllImport("user32.dll", SetLastError = true)]
- public static extern bool RegisterHotKey(
- IntPtr hWnd, // handle to window
- int id, // hot key identifier
- KeyModifiers fsModifiers, // key-modifier options
- System.Windows.Forms.Keys vk // virtual-key code
- );
-
- [DllImport("user32.dll", SetLastError = true)]
- public static extern bool UnregisterHotKey(
- IntPtr hWnd, // handle to window
- int id // hot key identifier
- );
- [Flags]
- public enum KeyModifiers
- {
- None = 0,
- Alt = 1,
- Control = 2,
- Shift = 4,
- Windows = 8
- }
- }
6.在主窗体完成初始化时注册全局快捷键
- 【MainWindow.xaml.cs】
-
-
- protected override void OnSourceInitialized(EventArgs e)
- {
- base.OnSourceInitialized(e);
- this.myHandle = new WindowInteropHelper(this).Handle;
- //组合键
- ctrHotKey = (uint)(KeyModifiers.Alt | KeyModifiers.Control);
- //注册
- bool f = RegisterHotKey(this.myHandle, 100, (KeyModifiers)ctrHotKey, Keys.A);//这时热键为Alt+CTRL+A
- HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
- source.AddHook(WndProc);
- }
- //快捷键响应事件
- IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handle)
- {
- //Debug.WriteLine("hwnd:{0},msg:{1},wParam:{2},lParam{3}:,handle:{4}"
- // ,hwnd,msg,wParam,lParam,handle);
- string sid = wParam.ToString();
- switch (sid)
- {
- case "100":
- BTCut_Click(null, null);
- break;
- default:
- break;
- }
- return IntPtr.Zero;
- }
7.窗体程序退出时要注销掉全局快捷键
- 【MainWindow.xaml.cs】
-
-
- private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
- {
- UnregisterHotKey(this.myHandle, 100);//卸载快捷键
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。