WPF開發者QQ群
此群已滿340500857?,請加新群458041663
?? ??? 由于微信群人數太多入群請添加小編微信號
?yanjinhuawechat 或 W_Feng_aiQ?邀請入群
?需備注WPF開發者?
?接著上一篇,兼容屏幕縮放問題。
01
—
代碼如下
一、創建ScreenCut.xaml代碼如下。
<ResourceDictionary?xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:controls="clr-namespace:WPFDevelopers.Controls"><ResourceDictionary.MergedDictionaries><ResourceDictionary?Source="Basic/ControlBasic.xaml"/><ResourceDictionary?Source="ButtonsStyles.xaml"/></ResourceDictionary.MergedDictionaries><Style?x:Key="RectangleStyle"?TargetType="{x:Type?Rectangle}"><Setter?Property="Fill"?Value="{DynamicResource?BlackSolidColorBrush}"/><Setter?Property="Opacity"?Value=".5"/></Style><Style?TargetType="{x:Type?controls:ScreenCut}"?BasedOn="{StaticResource?ControlBasicStyle}"><Setter?Property="WindowState"?Value="Maximized"/><Setter?Property="WindowStyle"?Value="None"/><Setter?Property="Template"><Setter.Value><ControlTemplate?TargetType="{x:Type?controls:ScreenCut}"><Canvas?x:Name="PART_Canvas"Width="{Binding?Source={x:Static?SystemParameters.PrimaryScreenWidth}}"Height="{Binding?Source={x:Static?SystemParameters.PrimaryScreenHeight}}"><Rectangle?x:Name="PART_RectangleLeft"?Style="{DynamicResource?RectangleStyle}"/><Rectangle?x:Name="PART_RectangleTop"?Style="{DynamicResource?RectangleStyle}"/><Rectangle?x:Name="PART_RectangleRight"?Style="{DynamicResource?RectangleStyle}"/><Rectangle?x:Name="PART_RectangleBottom"?Style="{DynamicResource?RectangleStyle}"/><Border?x:Name="PART_Border"?BorderBrush="{DynamicResource?PrimaryNormalSolidColorBrush}"?BorderThickness="1"?Background="Transparent"?Cursor="SizeAll"/><WrapPanel?x:Name="PART_WrapPanel"?Visibility="Hidden"?Panel.ZIndex="99"Height="38"?Background="{DynamicResource?WhiteSolidColorBrush}"VerticalAlignment="Center"><Button?x:Name="PART_ButtonSave"?Style="{DynamicResource?PathButton}"ToolTip="保存"?Margin="10,0,0,0"><Button.Content><Path?Fill="{DynamicResource?InfoPressedSolidColorBrush}"?Width="18"?Height="18"?Stretch="Fill"?Data="{StaticResource?PathSave}"/></Button.Content></Button><Button?x:Name="PART_ButtonCancel"?Style="{DynamicResource?PathButton}"ToolTip="取消"><Button.Content><Path?Fill="{DynamicResource?DangerPressedSolidColorBrush}"?Width="14"?Height="14"?Stretch="Fill"?Data="{StaticResource?PathCancel}"/></Button.Content></Button><Button?x:Name="PART_ButtonComplete"??Style="{DynamicResource?PathButton}"ToolTip="完成"?Margin="0,0,10,0"><Button.Content><Path?Fill="{DynamicResource?SuccessPressedSolidColorBrush}"??Width="20"?Height="15"?Stretch="Fill"?Data="{StaticResource?PathComplete}"/></Button.Content></Button></WrapPanel></Canvas></ControlTemplate></Setter.Value></Setter></Style>
</ResourceDictionary>
二、創建ScreenCut.cs代碼如下。
using?Microsoft.Win32;
using?System;
using?System.Windows;
using?System.Windows.Controls;
using?System.Windows.Input;
using?System.Windows.Interop;
using?System.Windows.Media;
using?System.Windows.Media.Imaging;
using?System.Windows.Shapes;
using?WPFDevelopers.Helpers;namespace?WPFDevelopers.Controls
{[TemplatePart(Name?=?CanvasTemplateName,?Type?=?typeof(Canvas))][TemplatePart(Name?=?RectangleLeftTemplateName,?Type?=?typeof(Rectangle))][TemplatePart(Name?=?RectangleTopTemplateName,?Type?=?typeof(Rectangle))][TemplatePart(Name?=?RectangleRightTemplateName,?Type?=?typeof(Rectangle))][TemplatePart(Name?=?RectangleBottomTemplateName,?Type?=?typeof(Rectangle))][TemplatePart(Name?=?BorderTemplateName,?Type?=?typeof(Border))][TemplatePart(Name?=?WrapPanelTemplateName,?Type?=?typeof(WrapPanel))][TemplatePart(Name?=?ButtonSaveTemplateName,?Type?=?typeof(Button))][TemplatePart(Name?=?ButtonCancelTemplateName,?Type?=?typeof(Button))][TemplatePart(Name?=?ButtonCompleteTemplateName,?Type?=?typeof(Button))]public?class?ScreenCut?:?Window{private?const?string?CanvasTemplateName?=?"PART_Canvas";private?const?string?RectangleLeftTemplateName?=?"PART_RectangleLeft";private?const?string?RectangleTopTemplateName?=?"PART_RectangleTop";private?const?string?RectangleRightTemplateName?=?"PART_RectangleRight";private?const?string?RectangleBottomTemplateName?=?"PART_RectangleBottom";private?const?string?BorderTemplateName?=?"PART_Border";private?const?string?WrapPanelTemplateName?=?"PART_WrapPanel";private?const?string?ButtonSaveTemplateName?=?"PART_ButtonSave";private?const?string?ButtonCancelTemplateName?=?"PART_ButtonCancel";private?const?string?ButtonCompleteTemplateName?=?"PART_ButtonComplete";private?Canvas?_canvas;private?Rectangle?_rectangleLeft,?_rectangleTop,?_rectangleRight,?_rectangleBottom;private?Border?_border;private?WrapPanel?_wrapPanel;private?Button?_buttonSave,?_buttonCancel,?_buttonComplete;private?Rect?rect;private?Point?pointStart,?pointEnd;private?bool?isMouseUp?=?false;private?Win32ApiHelper.DeskTopSize?size;static?ScreenCut(){DefaultStyleKeyProperty.OverrideMetadata(typeof(ScreenCut),?new?FrameworkPropertyMetadata(typeof(ScreenCut)));}public?override?void?OnApplyTemplate(){base.OnApplyTemplate();_canvas?=?GetTemplateChild(CanvasTemplateName)?as?Canvas;_rectangleLeft?=?GetTemplateChild(RectangleLeftTemplateName)?as?Rectangle;_rectangleTop?=?GetTemplateChild(RectangleTopTemplateName)?as?Rectangle;_rectangleRight?=?GetTemplateChild(RectangleRightTemplateName)?as?Rectangle;_rectangleBottom?=?GetTemplateChild(RectangleBottomTemplateName)?as?Rectangle;_border?=?GetTemplateChild(BorderTemplateName)?as?Border;_wrapPanel?=?GetTemplateChild(WrapPanelTemplateName)?as?WrapPanel;_buttonSave?=?GetTemplateChild(ButtonSaveTemplateName)?as?Button;if?(_buttonSave?!=?null)_buttonSave.Click?+=?_buttonSave_Click;_buttonCancel?=?GetTemplateChild(ButtonCancelTemplateName)?as?Button;if?(_buttonCancel?!=?null)_buttonCancel.Click?+=?_buttonCancel_Click;_buttonComplete?=?GetTemplateChild(ButtonCompleteTemplateName)?as?Button;if?(_buttonComplete?!=?null)_buttonComplete.Click?+=?_buttonComplete_Click;_canvas.Background?=?new?ImageBrush(Capture());_rectangleLeft.Width?=?_canvas.Width;_rectangleLeft.Height?=?_canvas.Height;}private?void?_buttonSave_Click(object?sender,?RoutedEventArgs?e){SaveFileDialog?dlg?=?new?SaveFileDialog();dlg.FileName?=?$"WPFDevelopers{DateTime.Now.ToString("yyyyMMddHHmmss")}.jpg";dlg.DefaultExt?=?".jpg";dlg.Filter?=?"image?file|*.jpg";if?(dlg.ShowDialog()?==?true){BitmapEncoder?pngEncoder?=?new?PngBitmapEncoder();pngEncoder.Frames.Add(BitmapFrame.Create(CutBitmap()));using?(var?fs?=?System.IO.File.OpenWrite(dlg.FileName)){pngEncoder.Save(fs);fs.Dispose();fs.Close();}}Close();}private?void?_buttonComplete_Click(object?sender,?RoutedEventArgs?e){Clipboard.SetImage(CutBitmap());Close();}CroppedBitmap?CutBitmap(){_border.Visibility?=?Visibility.Collapsed;_rectangleLeft.Visibility?=?Visibility.Collapsed;_rectangleTop.Visibility?=?Visibility.Collapsed;_rectangleRight.Visibility?=?Visibility.Collapsed;_rectangleBottom.Visibility?=?Visibility.Collapsed;var?renderTargetBitmap?=?new?RenderTargetBitmap((int)_canvas.Width,(int)_canvas.Height,?96d,?96d,?System.Windows.Media.PixelFormats.Default);renderTargetBitmap.Render(_canvas);return?new?CroppedBitmap(renderTargetBitmap,?new?Int32Rect((int)rect.X,?(int)rect.Y,?(int)rect.Width,?(int)rect.Height));}private?void?_buttonCancel_Click(object?sender,?RoutedEventArgs?e){Close();}protected?override?void?OnPreviewKeyDown(KeyEventArgs?e){if?(e.Key?==?Key.Escape)Close();}protected?override?void?OnPreviewMouseLeftButtonDown(MouseButtonEventArgs?e){pointStart?=?e.GetPosition(_canvas);if?(!isMouseUp){_wrapPanel.Visibility?=?Visibility.Hidden;pointEnd?=?pointStart;rect?=?new?Rect(pointStart,?pointEnd);}}protected?override?void?OnPreviewMouseMove(MouseEventArgs?e){if?(e.LeftButton?==?MouseButtonState.Pressed){var?current?=?e.GetPosition(_canvas);if?(!isMouseUp){MoveAllRectangle(current);}else{if?(current?!=?pointStart){var?vector?=?Point.Subtract(current,?pointStart);var?left?=?Canvas.GetLeft(_border)?+?vector.X;var?top?=?Canvas.GetTop(_border)?+?vector.Y;if?(left?<=?0)left?=?0;if?(top?<=?0)top?=?0;if?(left?+?_border.Width?>=?_canvas.ActualWidth)left?=?_canvas.ActualWidth?-?_border.ActualWidth;if?(top?+?_border.Height?>=?_canvas.ActualHeight)top?=?_canvas.ActualHeight?-?_border.ActualHeight;pointStart?=?current;Canvas.SetLeft(_border,?left);Canvas.SetTop(_border,?top);rect?=?new?Rect(new?Point(left,?top),?new?Point(left?+?_border.Width,?top?+?_border.Height));_rectangleLeft.Width?=?left?<=?0???0?:?left?>=?_canvas.ActualWidth???_canvas.ActualWidth?:?left;_rectangleLeft.Height?=?_canvas.ActualHeight;Canvas.SetLeft(_rectangleTop,?_rectangleLeft.Width);_rectangleTop.Height?=?top?<=?0???0?:?top?>=?_canvas.ActualHeight???_canvas.ActualHeight?:?top;Canvas.SetLeft(_rectangleRight,?left?+?_border.Width);var?wRight?=?_canvas.ActualWidth?-?(_border.Width?+?_rectangleLeft.Width);_rectangleRight.Width?=?wRight?<=?0???0?:?wRight;_rectangleRight.Height?=?_canvas.ActualHeight;Canvas.SetLeft(_rectangleBottom,?_rectangleLeft.Width);Canvas.SetTop(_rectangleBottom,?top?+?_border.Height);_rectangleBottom.Width?=?_border.Width;var?hBottom?=?_canvas.ActualHeight?-?(top?+?_border.Height);_rectangleBottom.Height?=?hBottom?<=?0???0?:?hBottom;}}}}protected?override?void?OnPreviewMouseLeftButtonUp(MouseButtonEventArgs?e){_wrapPanel.Visibility?=?Visibility.Visible;Canvas.SetLeft(_wrapPanel,?rect.X?+?rect.Width?-?_wrapPanel.ActualWidth);var?y?=?Canvas.GetTop(_border)?+?_border.ActualHeight?+?_wrapPanel.ActualHeight;if?(y?>?_canvas.ActualHeight)y?=?Canvas.GetTop(_border)?-?_wrapPanel.ActualHeight?-?4;elsey?=?Canvas.GetTop(_border)?+?_border.ActualHeight?+?4;Canvas.SetTop(_wrapPanel,?y);isMouseUp?=?true;}void?MoveAllRectangle(Point?current){pointEnd?=?current;rect?=?new?Rect(pointStart,?pointEnd);_rectangleLeft.Width?=?rect.X;_rectangleLeft.Height?=?_canvas.Height;Canvas.SetLeft(_rectangleTop,?_rectangleLeft.Width);_rectangleTop.Width?=?rect.Width;double?h?=?0.0;if?(current.Y?<?pointStart.Y)h?=?current.Y;elseh?=?current.Y?-?rect.Height;_rectangleTop.Height?=?h;Canvas.SetLeft(_rectangleRight,?_rectangleLeft.Width?+?rect.Width);_rectangleRight.Width?=?_canvas.Width?-?(rect.Width?+?_rectangleLeft.Width);_rectangleRight.Height?=?_canvas.Height;Canvas.SetLeft(_rectangleBottom,?_rectangleLeft.Width);Canvas.SetTop(_rectangleBottom,?rect.Height?+?_rectangleTop.Height);_rectangleBottom.Width?=?rect.Width;_rectangleBottom.Height?=?_canvas.Height?-?(rect.Height?+?_rectangleTop.Height);_border.Height?=?rect.Height;_border.Width?=?rect.Width;Canvas.SetLeft(_border,?rect.X);Canvas.SetTop(_border,?rect.Y);}BitmapSource?Capture(){IntPtr?hBitmap;IntPtr?hDC?=?Win32ApiHelper.GetDC(Win32ApiHelper.GetDesktopWindow());IntPtr?hMemDC?=?Win32ApiHelper.CreateCompatibleDC(hDC);size.cx?=?Win32ApiHelper.GetSystemMetrics(0);size.cy?=?Win32ApiHelper.GetSystemMetrics(1);hBitmap?=?Win32ApiHelper.CreateCompatibleBitmap(hDC,?size.cx,?size.cy);if?(hBitmap?!=?IntPtr.Zero){IntPtr?hOld?=?(IntPtr)Win32ApiHelper.SelectObject(hMemDC,?hBitmap);Win32ApiHelper.BitBlt(hMemDC,?0,?0,?size.cx,?size.cy,?hDC,?0,?0,?Win32ApiHelper.TernaryRasterOperations.SRCCOPY);Win32ApiHelper.SelectObject(hMemDC,?hOld);Win32ApiHelper.DeleteDC(hMemDC);Win32ApiHelper.ReleaseDC(Win32ApiHelper.GetDesktopWindow(),?hDC);var?bsource?=?Imaging.CreateBitmapSourceFromHBitmap(hBitmap,?IntPtr.Zero,?Int32Rect.Empty,?BitmapSizeOptions.FromEmptyOptions());Win32ApiHelper.DeleteObject(hBitmap);GC.Collect();return?bsource;}return?null;}}
}
三、新建WINAPI DLL Imports.cs代碼如下。
#region?WINAPI?DLL?Imports[DllImport("gdi32.dll",?ExactSpelling?=?true,?PreserveSig?=?true,?SetLastError?=?true)]public?static?extern?IntPtr?SelectObject(IntPtr?hdc,?IntPtr?hgdiobj);[DllImport("gdi32.dll")]public?static?extern?IntPtr?CreateCompatibleBitmap(IntPtr?hdc,?int?nWidth,?int?nHeight);[DllImport("gdi32.dll",?SetLastError?=?true)]public?static?extern?IntPtr?CreateCompatibleDC(IntPtr?hdc);[DllImport("gdi32.dll")]public?static?extern?bool?DeleteObject(IntPtr?hObject);[DllImport("gdi32.dll")]public?static?extern?IntPtr?CreateBitmap(int?nWidth,?int?nHeight,?uint?cPlanes,?uint?cBitsPerPel,?IntPtr?lpvBits);[DllImport("user32.dll")]public?static?extern?IntPtr?GetDC(IntPtr?hWnd);[DllImport("user32.dll")]public?static?extern?int?ReleaseDC(IntPtr?hWnd,?IntPtr?hDC);[DllImport("gdi32.dll",?EntryPoint?=?"DeleteDC")]public?static?extern?IntPtr?DeleteDC(IntPtr?hDc);public?const?int?SM_CXSCREEN?=?0;public?const?int?SM_CYSCREEN?=?1;[DllImport("user32.dll",?EntryPoint?=?"GetDesktopWindow")]public?static?extern?IntPtr?GetDesktopWindow();[DllImport("user32.dll",?EntryPoint?=?"GetSystemMetrics")]public?static?extern?int?GetSystemMetrics(int?abc);[DllImport("user32.dll",?EntryPoint?=?"GetWindowDC")]public?static?extern?IntPtr?GetWindowDC(Int32?ptr);public?struct?DeskTopSize{public?int?cx;public?int?cy;}public?enum?TernaryRasterOperations?:?uint{///?<summary>dest?=?source</summary>SRCCOPY?=?0x00CC0020,///?<summary>dest?=?source?OR?dest</summary>SRCPAINT?=?0x00EE0086,///?<summary>dest?=?source?AND?dest</summary>SRCAND?=?0x008800C6,///?<summary>dest?=?source?XOR?dest</summary>SRCINVERT?=?0x00660046,///?<summary>dest?=?source?AND?(NOT?dest)</summary>SRCERASE?=?0x00440328,///?<summary>dest?=?(NOT?source)</summary>NOTSRCCOPY?=?0x00330008,///?<summary>dest?=?(NOT?src)?AND?(NOT?dest)</summary>NOTSRCERASE?=?0x001100A6,///?<summary>dest?=?(source?AND?pattern)</summary>MERGECOPY?=?0x00C000CA,///?<summary>dest?=?(NOT?source)?OR?dest</summary>MERGEPAINT?=?0x00BB0226,///?<summary>dest?=?pattern</summary>PATCOPY?=?0x00F00021,///?<summary>dest?=?DPSnoo</summary>PATPAINT?=?0x00FB0A09,///?<summary>dest?=?pattern?XOR?dest</summary>PATINVERT?=?0x005A0049,///?<summary>dest?=?(NOT?dest)</summary>DSTINVERT?=?0x00550009,///?<summary>dest?=?BLACK</summary>BLACKNESS?=?0x00000042,///?<summary>dest?=?WHITE</summary>WHITENESS?=?0x00FF0062}[DllImport("gdi32.dll")]public?static?extern?bool?BitBlt(IntPtr?hdc,?int?nXDest,?int?nYDest,?int?nWidth,?int?nHeight,?IntPtr?hdcSrc,?int?nXSrc,?int?nYSrc,?TernaryRasterOperations?dwRop);#endregion}
四、新建ScreenCutExample.xaml.cs代碼如下。
var?screenCut?=?new?ScreenCut();screenCut.ShowDialog();//screenCut.Show();
02
—
效果預覽
鳴謝素材提供者 - 吳鋒
源碼地址如下
Github:https://github.com/WPFDevelopersOrg
Gitee:https://gitee.com/WPFDevelopersOrg
WPF開發者QQ群:?340500857?|?458041663
Github:https://github.com/WPFDevelopersOrg
出處:https://www.cnblogs.com/yanjinhua
版權:本作品采用「署名-非商業性使用-相同方式共享 4.0 國際」許可協議進行許可。
轉載請著名作者 出處 https://github.com/WPFDevelopersOrg
掃一掃關注我們,
更多知識早知道!
點擊閱讀原文可跳轉至源代碼
                            總結
                            
                                以上是生活随笔為你收集整理的WPF 实现截屏控件之移动(二)(仿微信)的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。