QQ截图看起来很简单,但实际做起来比较复杂。下面先看看完成后的效果图,后续再详细说明开发历程!
与QQ原生截图还是挺像的吧。整个开发断断续续历时一周左右,期间更换了三种不同思路,重构了2次代码才最终有上图展示效果。
废话不说了,开始讲代码。
第一种方案(有坑):
参考地址:https://www.cnblogs.com/lonelyxmas/p/10754115.html
Demo下载:https://download.csdn.net/download/asciil/12473318
原理描述:
截图其实一个透明Windows窗体覆盖在最顶层,其中用InkCanvas画布存储截图时的屏幕图片。鼠标在其上按下左键拖动时,首先画矩形(也就是截图区域高亮部分),其次设置四周蒙层部分大小及位置(分为上下左右四部分,以Rectangle元素实现)。
原理听起来其实很简单,但实际上会有问题。请看下面效果图
看到了吗,在拖动过程中鼠标处会有白色线条出现。这个现象产生的原因是由于Win10 DPI缩放引起的,通过找资料没有发现到比较好的解决办法,所以放弃此思路。(但就在我写博客时,Windows1909版本更新了,然后我发现同样的代码居然没有这个现象了)
贴上主要部分代码:
-
样式文件(ScreenshotWindowStyle.xaml)
<Style x:Key="MaskCanvasStyle" TargetType="Rectangle"> <Setter Property="IsHitTestVisible" Value="False"/> <Setter Property="Fill" Value="#40000000"/> <Setter Property="HorizontalAlignment" Value="Left"/> <Setter Property="VerticalAlignment" Value="Top"/> </Style> <Style x:Key="SnapAreaStyle" TargetType="Border"> <Setter Property="IsHitTestVisible" Value="False"/> <Setter Property="BorderThickness" Value="4"/> <Setter Property="BorderBrush" Value="DodgerBlue"/> <Setter Property="Background" Value="Transparent"/> <Setter Property="HorizontalAlignment" Value="Left"/> <Setter Property="VerticalAlignment" Value="Top"/> <Style.Triggers> <DataTrigger Binding="{Binding IsShowTargetArea,RelativeSource={RelativeSource AncestorType=local:ScreenshotWindow}}" Value="True"> <Setter Property="IsHitTestVisible" Value="True"/> <Setter Property="BorderThickness" Value="1"/> </DataTrigger> </Style.Triggers> </Style> <Style x:Key="HotspotStyle" TargetType="Rectangle"> <Setter Property="Height" Value="5"/> <Setter Property="Width" Value="5"/> <Setter Property="Fill" Value="DodgerBlue"/> <Setter Property="HorizontalAlignment" Value="Left"/> <Setter Property="VerticalAlignment" Value="Top"/> <Setter Property="Visibility" Value="Collapsed"/> <Style.Triggers> <Trigger Property="local:ToolTipAttachProperty.Placement" Value="LeftTop"> <Setter Property="Margin" Value="-3, -3, 0, 0"/> <Setter Property="HorizontalAlignment" Value="Left"/> <Setter Property="VerticalAlignment" Value="Top"/> </Trigger> <Trigger Property="local:ToolTipAttachProperty.Placement" Value="TopCenter"> <Setter Property="Margin" Value="0, -3, 0, 0"/> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="VerticalAlignment" Value="Top"/> </Trigger> <Trigger Property="local:ToolTipAttachProperty.Placement" Value="RightTop"> <Setter Property="Margin" Value="0, -3, -3, 0"/> <Setter Property="HorizontalAlignment" Value="Right"/> <Setter Property="VerticalAlignment" Value="Top"/> </Trigger> <Trigger Property="local:ToolTipAttachProperty.Placement" Value="RightCenter"> <Setter Property="Margin" Value="0, 0, -3, 0"/> <Setter Property="HorizontalAlignment" Value="Right"/> <Setter Property="VerticalAlignment" Value="Center"/> </Trigger> <Trigger Property="local:ToolTipAttachProperty.Placement" Value="RightBottom"> <Setter Property="Margin" Value="0, 0, -3, -3"/> <Setter Property="HorizontalAlignment" Value="Right"/> <Setter Property="VerticalAlignment" Value="Bottom"/> </Trigger> <Trigger Property="local:ToolTipAttachProperty.Placement" Value="BottomCenter"> <Setter Property="Margin" Value="0, 0, 0, -3"/> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="VerticalAlignment" Value="Bottom"/> </Trigger> <Trigger Property="local:ToolTipAttachProperty.Placement" Value="LeftBottom"> <Setter Property="Margin" Value="-3, 0, 0, -3"/> <Setter Property="HorizontalAlignment" Value="Left"/> <Setter Property="VerticalAlignment" Value="Bottom"/> </Trigger> <Trigger Property="local:ToolTipAttachProperty.Placement" Value="LeftCenter"> <Setter Property="Margin" Value="-3, 0, 0, 0"/> <Setter Property="HorizontalAlignment" Value="Left"/> <Setter Property="VerticalAlignment" Value="Center"/> </Trigger> <DataTrigger Binding="{Binding IsShowTargetArea,RelativeSource={RelativeSource AncestorType=local:ScreenshotWindow}}" Value="True"> <Setter Property="Visibility" Value="Visible"/> </DataTrigger> </Style.Triggers> </Style> <Style TargetType="{x:Type local:ScreenshotWindow}"> <Setter Property="UseLayoutRounding" Value="True"/> <Setter Property="WindowStyle" Value="None"/> <Setter Property="WindowState" Value="Maximized"/> <Setter Property="Topmost" Value="True"/> <Setter Property="ResizeMode" Value="NoResize"/> <Setter Property="Background" Value="Transparen