zoukankan      html  css  js  c++  java
  • ScreenToGif 代码分析

    ScreenToGif项目由四个文件夹组成:

    1. Files 存放协议文件
    2. GifRecorder 存放gif编码器代码
    3. ScreenToGif 存放主代码
    4. Other 存放HooktestTranslator的代码

    问题1:GifRecorder 和ScreenToGif、Hooktest、Translator 下面都有了一个Properties,里面有个AssemblyInfo.cs是什么东西?

    .net工程的Properties文件夹下自动生成一个名为AssemblyInfo.cs的文件,一般情况下我们很少直接改动该文件。但我们实际上通过另一个形式操作该文件。那就是通过在鼠标右键点击项目的属性进入应用程序”->“程序集信息,然后修改信息。

    程序集指的是DLL或者EXE等可执行文件。

    问题2:启动界面分析

     

     

    <Window x:Class="ScreenToGif.Windows.Other.Startup"

            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

            xmlns:n="clr-namespace:ScreenToGif.Controls"

            xmlns:u="clr-namespace:ScreenToGif.Util"

            Title="{DynamicResource Title.StartUp}" Height="220" Width="500" Icon="/Resources/Logo.ico" WindowStartupLocation="CenterScreen"

            MinWidth="500" MinHeight="220" UseLayoutRounding="True" Loaded="Startup_OnLoaded">

     

        <Window.CommandBindings>

            <CommandBinding Command="u:Commands.NewRecording" CanExecute="Buttons_CanExecute" Executed="Recorder_Executed"/>

            <CommandBinding Command="u:Commands.NewWebcamRecording" CanExecute="Buttons_CanExecute" Executed="WebcamRecorder_Executed"/>

            <CommandBinding Command="u:Commands.NewBoardRecording" CanExecute="Buttons_CanExecute" Executed="Board_Executed"/>

            <CommandBinding Command="u:Commands.Editor" CanExecute="Buttons_CanExecute" Executed="Editor_Executed"/>

            <CommandBinding Command="u:Commands.Update" CanExecute="Update_CanExecute" Executed="Update_Executed"/>

            <CommandBinding Command="u:Commands.Options" CanExecute="Buttons_CanExecute" Executed="Options_Executed"/>

    <!--Command后面是命令的名字,实际执行的函数是executed里写的函数 其他控件必须指明command这个属性

    应用场景是菜单栏和工具栏的功能相同,我们要将其映射到同一个command。还有就是一个控件禁用后,相同功能的控件也要一起被禁用,这有CanExecute 来帮助同步,同时可用,或者同时不可用->

        </Window.CommandBindings>

     

        <Grid>

            <Grid.RowDefinitions>   <!--行定义-->

                <RowDefinition Height="45"/>

                <RowDefinition />

            </Grid.RowDefinitions>

     

            <Grid Grid.Row="0">

                <Grid.ColumnDefinitions>   <!--列定义-->

                    <ColumnDefinition/>

                    <ColumnDefinition Width="Auto"/>

                    <ColumnDefinition Width="Auto"/>

                    <ColumnDefinition Width="Auto"/>

                </Grid.ColumnDefinitions>

     

                <Label Grid.Column="0" Content="ScreenToGif" Margin="5" FontSize="18" Foreground="#FF251E46" Effect="{DynamicResource Shadow.Black.Small}"/>

     

                <!--<n:ImageButton Grid.Column="1" x:Name="BoardButton2" Text="Test" Content="{StaticResource Vector.Info}"

                                   Margin="5" Style="{StaticResource Style.Button.Horizontal}" Effect="{StaticResource Shadow.Foreground.Small}"

                                   Padding="3" MaxSize="25" Click="TestButton_OnClick" Visibility="Collapsed"/>-->

     

                <TextBlock Grid.Column="1" Name="UpdateTextBlock" VerticalAlignment="Center" Visibility="Hidden" Effect="{StaticResource Shadow.Black.Small}">

    <!--WPF Visibility的用法 Visible 元素在窗体中正常显示 Collaspsed 元素不显示,也不占用空间 Hidden 元素不显示,但是任然为它保留空间 -->

                    <Hyperlink Command="u:Commands.Update" ToolTip="{DynamicResource NewRelease.Tooltip}" Cursor="Hand">

                        <Run Name="UpdateRun" Text="{DynamicResource NewRelease}"/>

    <!--run指明一连串格式化的或者格式化的内联文本,类似html<span>-->

                    </Hyperlink>

                </TextBlock>

     

     

                <n:ImageButton Grid.Column="3" x:Name="OptionsButton" Text="{DynamicResource Options}" Content="{StaticResource Vector.Options}"

                               Margin="5" Style="{StaticResource Style.Button.Horizontal}" Effect="{StaticResource Shadow.Black.Small}"

                               Padding="2" MaxSize="25" Command="u:Commands.Options"/>

    <!--Effect是简单的像素处理 content属性显示图片  text 显示文本-->

            </Grid>

     

            <Grid Grid.Row="1">

                <Grid.ColumnDefinitions>

                    <ColumnDefinition/>

                    <ColumnDefinition/>

                    <ColumnDefinition/>

                    <ColumnDefinition/>

                </Grid.ColumnDefinitions>

     

                <n:ImageButton Grid.Column="0" x:Name="RecordButton" Text="{DynamicResource Recorder}" Margin="5,0,5,5"

                               Effect="{StaticResource Shadow.Black.Tiny}" MaxSize="36" Content="{StaticResource Vector.Record.New}"

                               Command="u:Commands.NewRecording" Style="{StaticResource Style.Button.Vertical.Border}" FontSize="13">

                    <n:ImageButton.ToolTip>

                        <n:HeaderedTooltip Header="{DynamicResource Recorder}" Text="{DynamicResource Tooltip.Recorder}"

                                                  MaxWidth="250" Placement="Bottom" HorizontalOffset="-5"/>

                    </n:ImageButton.ToolTip>

                </n:ImageButton>

     

                <n:ImageButton Grid.Column="1" x:Name="WebcamButton" Text="{DynamicResource Webcam}" Margin="5,0,5,5"

                               Effect="{StaticResource Shadow.Black.Tiny}" MaxSize="36" Content="{StaticResource Vector.Camera.New}"

                               Command="u:Commands.NewWebcamRecording" Style="{StaticResource Style.Button.Vertical.Border}" FontSize="13">

                    <n:ImageButton.ToolTip>

                        <n:HeaderedTooltip Header="{DynamicResource Webcam}" Text="{DynamicResource Tooltip.Webcam}" MaxWidth="250" Placement="Bottom" HorizontalOffset="-5"/>

                    </n:ImageButton.ToolTip>

                </n:ImageButton>

     

                <n:ImageButton Grid.Column="2" x:Name="BoardButton" Text="{DynamicResource Board}" Margin="5,0,5,5"

                               Effect="{StaticResource Shadow.Black.Tiny}" MaxSize="36" Content="{StaticResource Vector.Board.New}"

                               Command="u:Commands.NewBoardRecording" Style="{StaticResource Style.Button.Vertical.Border}" FontSize="13">

                    <n:ImageButton.ToolTip>

                        <n:HeaderedTooltip Header="{DynamicResource Board}" Text="{DynamicResource Tooltip.Board}" MaxWidth="250" Placement="Bottom" HorizontalOffset="-5"/>

                    </n:ImageButton.ToolTip>

                </n:ImageButton>

     

                <n:ImageButton Grid.Column="3" x:Name="EditorButton" Text="{DynamicResource Editor}" Margin="5,0,5,5"

                               Effect="{StaticResource Shadow.Black.Tiny}" MaxSize="35" Content="{StaticResource Vector.Editor}"

                               Command="u:Commands.Editor" Style="{StaticResource Style.Button.Vertical.Border}" FontSize="13">

                    <n:ImageButton.ToolTip>

                        <n:HeaderedTooltip Header="{DynamicResource Editor}" Text="{DynamicResource Tooltip.Editor}" MaxWidth="250" Placement="Bottom" HorizontalOffset="-5"/>   

                    </n:ImageButton.ToolTip><!---这有一个浮动提示->

     

     

                </n:ImageButton>

            </Grid>

        </Grid>

    </Window>

    问题3:使用的静态资源和动态资源是怎么个原理?

    静态资源指该资源只在程序载入内存时一次性使用,之后都不会改变。动态资源是相反的概念。

    资源的四个层级?

    1. 数据库中的资源 ,相当于仓库
    2. 资源文件中的资源,相当于旅行箱
    3. Wpf 对象资源,相当于背包
    4. 变量中的数据,相当于手里

    什么是wpf对象资源?

    使用window.Rescources标签下的ResourceDictionary标签夹住的资源

    <Window.Resources>

      <ResourceDictionary>  <!--这个ResourceDictionary标签可以省略-->

    <sys:String x:Key=”str”>

       我是一个资源

    </sys:String>

      </ResourceDictionary>

    </WIndow.Rescources>

    <TextBlock Text=”{StaticResource ResourceKey=str}”  <!--这一行的ResourceKey=可以不写-->

    这是在xaml中引用,如何在程序中引用呢?

    string text = (string) this.FindResource(“str”)//资源中的文件要自己来进行格式转换

    使用标签引用和程序中的FindResource引用会在当前控件的Resource属性中查找,如果找不到,就会找上一级的。

    如果得知就是引用当前的,可以使用string text = (string) this.Resources[“str”]

    将资源程序写到外部文件,如何在程序中引用?

    <window.Resources>

    <ResourceDictionary Source=”xxx.xaml”/>

    </window.Resources>

    静态资源和动态资源中的静态和动态不是描述资源的,描述控件行为的,也说明改资源项是否可以被外部改写(类似xml的改写),只载入一次,之后永远不变,还是可以动态的变化。

    对于动态资源可以使用this.Resoures[“res2”]=new TextBlock(){text=”我要改变了”} ,静态资源不理会对资源的重新赋值

    <window.Resources>

    <TextBlock x:Key=”res2” text=”我是一只鸡”/>

    </window.Resources>

    <Button  content=”{DynamicResources res2}”/>

    问题4:一个界面文件,是如何调用另外一个界面文件的?

    比如在ScreenToGif这个项目中,有个Windows文件夹,下面有个Other文件,里面有个ColorSelector.xaml,如何在其他界面文件中使用呢?

    步骤:

    1. 添加对该目录的引用using ScreenToGif.Windows.Other;,不然你需要写完整目录
    2. 书写代码

                var colorPicker = new ColorSelector(UserSettings.All.BoardColor) { Owner = this };

                var result = colorPicker.ShowDialog();

    问题5: style属性是什么东西?

    http://blog.csdn.net/aoshilang2249/article/details/45129365

    《深入浅出WPF》 深入浅出话模板

    问题6:录制屏幕界面分析

     

    <n:LightWindow x:Name="RecorderLightWindow" x:Class="ScreenToGif.Windows.Recorder"

                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

                   xmlns:n="clr-namespace:ScreenToGif.Controls"

                   xmlns:u="clr-namespace:ScreenToGif.Util"

                   xmlns:c="clr-namespace:ScreenToGif.Util.Converters"

                   Title="ScreenToGif" SnapsToDevicePixels="True" UseLayoutRounding="True" AllowsTransparency="True" WindowStyle="None"

                   Topmost="True" Icon="../Resources/Logo.ico" Child="{StaticResource Vector.Back}"

                   IsThin="{Binding RecorderThinMode, Source={x:Static u:UserSettings.All}}"

                   IsFullScreen="{Binding FullScreenMode, Source={x:Static u:UserSettings.All}}"

                   Width="{Binding Source={x:Static u:UserSettings.All}, Path=RecorderWidth, Mode=TwoWay}"

                   Height="{Binding Source={x:Static u:UserSettings.All}, Path=RecorderHeight, Mode=TwoWay}"

                   Left="{Binding Source={x:Static u:UserSettings.All}, Path=RecorderLeft, Mode=TwoWay}"

                   Top="{Binding Source={x:Static u:UserSettings.All}, Path=RecorderTop, Mode=TwoWay}"

                   FocusManager.FocusedElement="{Binding RelativeSource={x:Static RelativeSource.Self}, Mode=OneTime}"

                   Foreground="{Binding Source={x:Static u:UserSettings.All}, Path=RecorderForeground, Mode=TwoWay, Converter={StaticResource ColorToBrush}}"

                   Background="{Binding Source={x:Static u:UserSettings.All}, Path=RecorderBackground, Mode=TwoWay, Converter={StaticResource ColorToBrush}}"

                   SizeChanged="LightWindow_SizeChanged" Loaded="Recorder_Loaded" Closing="Window_Closing" LocationChanged="Window_LocationChanged">

        

        <Window.Resources>

            <Storyboard x:Key="ShowDiscardStoryboard">

                <BooleanAnimationUsingKeyFrames Storyboard.TargetName="DiscardButton" Storyboard.TargetProperty="IsHitTestVisible" Duration="0:0:0" >

                    <DiscreteBooleanKeyFrame Value="True" KeyTime="0:0:0"/>

                </BooleanAnimationUsingKeyFrames>

     

                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DiscardButton" Storyboard.TargetProperty="Visibility" Duration="0:0:0">

                    <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" KeyTime="0:0:0"/>

                </ObjectAnimationUsingKeyFrames>

     

                <DoubleAnimation Storyboard.TargetName="DiscardButton" Storyboard.TargetProperty="(Button.Opacity)" From="0" To="1" Duration="0:0:1">

                    <DoubleAnimation.EasingFunction>

                        <PowerEase Power="8" />

                    </DoubleAnimation.EasingFunction>

                </DoubleAnimation>

            </Storyboard>

     

            <Storyboard x:Key="HideDiscardStoryboard">

                <BooleanAnimationUsingKeyFrames Storyboard.TargetName="DiscardButton" Storyboard.TargetProperty="IsHitTestVisible" Duration="0:0:0" >

                    <DiscreteBooleanKeyFrame Value="False" KeyTime="0:0:0"/>

                </BooleanAnimationUsingKeyFrames>

     

                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DiscardButton" Storyboard.TargetProperty="Visibility" Duration="0:0:0">

                    <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" KeyTime="0:0:0"/>

                </ObjectAnimationUsingKeyFrames>

     

                <DoubleAnimation Storyboard.TargetName="DiscardButton" Storyboard.TargetProperty="(Button.Opacity)"

                                 From="{Binding ElementName=DiscardButton,Path=Opacity}" To="0" Duration="0:0:1">

                    <DoubleAnimation.EasingFunction>

                        <PowerEase Power="8" />

                    </DoubleAnimation.EasingFunction>

                </DoubleAnimation>

            </Storyboard>

     

            <c:StageToButtonString x:Key="StageToButtonStringConverter"/>

            <c:StageToCanvas x:Key="StageToCanvasConverter"/>

            <c:ShortcutKeys x:Key="ShortcutKeys"/>

            <c:InvertedBoolToVisibility x:Key="InvertedBoolToVisibility"/>

            <c:BoolOrToInvertedVisibility x:Key="BoolOrToInvertedVisibility"/>

            <c:IntToString x:Key="IntToStringConverter"/>

        </Window.Resources>

     

        <Window.CommandBindings><!--命令关联,命令前是否可以执行该命令,命令后要做什么-->

            <CommandBinding Command="u:Commands.Options" CanExecute="Options_CanExecute" Executed="Options_Executed"/>

            <CommandBinding Command="u:Commands.EnableSnapshot" CanExecute="EnableSnapshot_CanExecute" Executed="EnableSnapshot_Executed"/>

            <CommandBinding Command="u:Commands.EnableThinMode" CanExecute="EnableThinMode_CanExecute" Executed="EnableThinMode_Executed"/>

            <CommandBinding Command="u:Commands.EnableFullScreen" CanExecute="EnableFullScreen_CanExecute" Executed="EnableFullScreen_Executed"/>

            <CommandBinding Command="u:Commands.EnableSnapToWindow" CanExecute="SnapToWindow_CanExecute"/>

        </Window.CommandBindings>

     

        <Grid x:Name="OutterGrid" UseLayoutRounding="True">

            <Grid.RowDefinitions>

                <RowDefinition Height="*"/>

                <RowDefinition Height="31"/>

            </Grid.RowDefinitions>

            

            <!--Hollow part-->

            <Border BorderBrush="{Binding ElementName=RecorderLightWindow, Path=BorderBrush}" BorderThickness="{Binding ElementName=RecorderLightWindow, Path=BorderThickness}"/>

     

            <!--Command bar-->

            <Grid Grid.Row="1" x:Name="LowerGrid" Height="31" VerticalAlignment="Bottom" Background="{Binding ElementName=RecorderLightWindow, Path=Background}"

                  KeyboardNavigation.TabNavigation="Cycle" MouseLeftButtonDown="CommandGrid_MouseLeftButtonDown">

                <Grid.ColumnDefinitions>

                    <ColumnDefinition Width="Auto"/>

                    <ColumnDefinition/>

                </Grid.ColumnDefinitions>

     

                <Grid Grid.Column="0" Visibility="{Binding RecorderThinMode, Source={x:Static u:UserSettings.All}, Converter={StaticResource Bool2Visibility}}">

                    <Grid.RowDefinitions>

                        <RowDefinition/>

                        <RowDefinition/>

                    </Grid.RowDefinitions>

                    <Grid.ColumnDefinitions>

                        <ColumnDefinition Width="Auto"/>

                        <ColumnDefinition Width="Auto"/>

                    </Grid.ColumnDefinitions>

     

                    <n:ImageButton Grid.Row="0" Grid.Column="0" x:Name="BackButton" Content="{StaticResource Vector.Back}" Style="{StaticResource Style.Button.NoText}"

                                   ContentHeight="14" Padding="4,1" TabIndex="0" Click="BackButton_Click"/>

     

                    <n:ImageButton Grid.Row="1" Grid.Column="0" x:Name="CloseButton" Content="{StaticResource Vector.Close}" Style="{StaticResource Style.Button.NoText}"

                                   ContentHeight="10" Padding="4,1" TabIndex="1" Click="CloseButton_Click"/>

     

                    <TextBlock Grid.Row="0" Grid.Column="1" x:Name="CaptionText" Text="{Binding Title, ElementName=RecorderLightWindow}" FontFamily="Segoe UI" FontSize="12"

                               FontWeight="Regular" Margin="5,0,0,0" Foreground="#FF6F5252" Effect="{DynamicResource Shadow.Foreground.Small}"/>

     

                    <TextBlock Grid.Row="1" Grid.Column="1" x:Name="FrameCountTextBlock" Text="{Binding FrameCount, ElementName=RecorderLightWindow, Converter={StaticResource IntToStringConverter}}"

                               FontFamily="Segoe UI" FontSize="12" FontWeight="Regular" Margin="5,0,0,0" Foreground="#FF061E87" Effect="{DynamicResource Shadow.Foreground.Small}"/>

                </Grid>

     

                <StackPanel Grid.Column="1" x:Name="ControlStackPanel" Height="31" Orientation="Horizontal" HorizontalAlignment="Right"

                            ScrollViewer.VerticalScrollBarVisibility="Disabled">

     

                    <n:ImageButton x:Name="SnapButton" Content="{StaticResource Vector.Crosshair}" Margin="0" Style="{StaticResource Style.Button.NoText}"

                                   HorizontalContentAlignment="Center" Effect="{StaticResource Shadow.Foreground.Small}" ContentHeight="20" ContentWidth="20"

                                   Visibility="{Binding FullScreenMode, Source={x:Static u:UserSettings.All}, Converter={StaticResource InvertedBoolToVisibility}}"

                                   Command="u:Commands.EnableSnapToWindow" Padding="3" TabIndex="2" PreviewMouseDown="SnapButton_PreviewMouseDown">

                        <n:ImageButton.ToolTip>

                            <ToolTip HorizontalOffset="-5" Placement="Bottom" Content="{DynamicResource Recorder.SnapToWindow}"/>

                        </n:ImageButton.ToolTip>

                    </n:ImageButton>

     

                    <n:ImageButton x:Name="OptionsButton" Content="{StaticResource Vector.Options}" Margin="0" Style="{StaticResource Style.Button.NoText}"

                                   Effect="{StaticResource Shadow.Foreground.Small}" ContentHeight="20" ContentWidth="20" Command="u:Commands.Options" Padding="3" TabIndex="3">

                        <n:ImageButton.ToolTip>

                            <ToolTip HorizontalOffset="-5" Placement="Bottom" Content="{DynamicResource Options}"/>

                        </n:ImageButton.ToolTip>

                    </n:ImageButton>

     

                    <Separator Width="1" Margin="5,2"/>

     

                    <Viewbox Stretch="UniformToFill" ClipToBounds="True" Focusable="False">

                        <Viewbox.Visibility>

                            <MultiBinding Converter="{StaticResource BoolOrToInvertedVisibility}">

                                <Binding Path="RecorderThinMode" Source="{x:Static u:UserSettings.All}"/>

                                <Binding Path="SnapshotMode" Source="{x:Static u:UserSettings.All}"/>

                            </MultiBinding>

                        </Viewbox.Visibility>

                        

                        <Grid HorizontalAlignment="Center" VerticalAlignment="Center" FlowDirection="LeftToRight" Margin="-4">

                            <n:CircularProgressBar StrokeThickness="2" Percentage="100" SegmentColor="Gray" Radius="24" IsTabStop="False"/>

                            <n:CircularProgressBar StrokeThickness="22" Percentage="100" SegmentColor="#FFF0F1F1" Radius="10" IsTabStop="False"/>

     

                            <n:CircularProgressBar StrokeThickness="2" Value="{Binding ElementName=FpsIntegerUpDown, Path=Value, Mode=OneWay}"

                                                   IsInverted="True" Minimum="1" Maximum="60" SegmentColor="#FFE28A73" Radius="24" IsTabStop="False"/>

                            <n:CircularProgressBar StrokeThickness="22" Value="{Binding ElementName=FpsIntegerUpDown, Path=Value, Mode=OneWay}"

                                                   IsInverted="True" Minimum="1" Maximum="60" SegmentColor="#FFE28A73" Radius="10" IsTabStop="False"/>

                        </Grid>

     

                        <Viewbox.ToolTip>

                            <ToolTip HorizontalOffset="-5" Placement="Bottom" Content="{DynamicResource Recorder.FpsRange}"/>

                        </Viewbox.ToolTip>

                    </Viewbox>

     

                    <n:IntegerUpDown x:Name="FpsIntegerUpDown" Margin="1,3" StepValue="1" Minimum="1" Maximum="60" MinWidth="45" TabIndex="4"

                                     Value="{Binding Source={x:Static u:UserSettings.All}, Path=LatestFps, Mode=TwoWay}"

                                     Visibility="{Binding SnapshotMode, Source={x:Static u:UserSettings.All}, Converter={StaticResource InvertedBoolToVisibility}}">

                        <n:IntegerUpDown.ToolTip>

                            <ToolTip HorizontalOffset="-5" Placement="Bottom" Content="{DynamicResource Recorder.Fps}"/>

                        </n:IntegerUpDown.ToolTip>

                    </n:IntegerUpDown>

     

                    <Label Content="{StaticResource Recorder.Fps.Short}" FontSize="12" FontFamily="Segoe UI" Margin="1,0,0,0" VerticalContentAlignment="Center" Padding="0"

                           Foreground="{Binding ElementName=RecorderLightWindow, Path=Foreground}" Visibility="{Binding SnapshotMode, Source={x:Static u:UserSettings.All}, Converter={StaticResource InvertedBoolToVisibility}}"/>

     

                    <Separator Width="1" Margin="5,2" Visibility="{Binding SnapshotMode, Source={x:Static u:UserSettings.All}, Converter={StaticResource InvertedBoolToVisibility}}"/>

     

                    <!--<Viewbox Child="{StaticResource Vector.WidthHeight}" Stretch="UniformToFill" Margin="3,4" HorizontalAlignment="Right" FlowDirection="LeftToRight" SnapsToDevicePixels="True"

                                 Visibility="{Binding RecorderThinMode, Converter={StaticResource InvertedBoolToVisibility}, Source={x:Static u:UserSettings.All}}"/>-->

     

                    <n:IntegerBox x:Name="WidthIntegerBox" Value="{Binding Source={x:Static u:UserSettings.All}, Path=RecorderWidth, Mode=TwoWay}"

                                  Offset="{x:Static u:Constants.HorizontalOffset}" Minimum="100" Maximum="3000" TabIndex="6" Height="Auto" Padding="4,0" Margin="1,3"

                                  ToolTip="{DynamicResource Recorder.Width}" ToolTipService.Placement="Bottom" ToolTipService.HorizontalOffset="-5"

                                  Visibility="{Binding FullScreenMode, Source={x:Static u:UserSettings.All}, Converter={StaticResource InvertedBoolToVisibility}}"/>

     

                    <Label Content="×" FontSize="16" FontFamily="Segoe Script" Margin="1" VerticalContentAlignment="Center" Padding="0"

                           Foreground="{Binding ElementName=RecorderLightWindow, Path=Foreground}"

                           Visibility="{Binding FullScreenMode, Source={x:Static u:UserSettings.All}, Converter={StaticResource InvertedBoolToVisibility}}"/>

     

                    <n:IntegerBox x:Name="HeightIntegerBox" Value="{Binding Source={x:Static u:UserSettings.All}, Path=RecorderHeight, Mode=TwoWay}"

                                  Offset="{x:Static u:Constants.VerticalOffset}" Minimum="100" Maximum="3000" TabIndex="7" Height="Auto" Padding="4,0" Margin="1,3"

                                  ToolTip="{DynamicResource Recorder.Height}" ToolTipService.Placement="Bottom" ToolTipService.HorizontalOffset="-5"

                                  Visibility="{Binding FullScreenMode, Source={x:Static u:UserSettings.All}, Converter={StaticResource InvertedBoolToVisibility}}"/>

     

                    <Label Content="px" FontSize="12" FontFamily="Segoe UI" Margin="1,0,0,0" VerticalContentAlignment="Center" Padding="0"

                           Foreground="{Binding ElementName=RecorderLightWindow, Path=Foreground}"

                           Visibility="{Binding FullScreenMode, Source={x:Static u:UserSettings.All}, Converter={StaticResource InvertedBoolToVisibility}}"/>

     

                    <Separator Width="1" Margin="5,2" Visibility="{Binding FullScreenMode, Source={x:Static u:UserSettings.All}, Converter={StaticResource InvertedBoolToVisibility}}"/>

     

                    <n:ImageButton x:Name="DiscardButton" Text="{DynamicResource Recorder.Discard}" Content="{StaticResource Vector.Remove}" Visibility="Collapsed"

                                   Click="DiscardButton_Click" Style="{StaticResource Style.Button.Horizontal}"

                                   Foreground="{Binding ElementName=RecorderLightWindow, Path=Foreground}"

                                   UseLayoutRounding="True" MaxSize="16" ContentHeight="18" ContentWidth="18" TabIndex="8"

                                   MinWidth="{Binding RelativeSource={RelativeSource Mode=Self}, Path=ActualHeight}"

                                   KeyGesture="{Binding Converter={StaticResource ShortcutKeys}, ConverterParameter='3'}"/>

     

                    <!--ToolTip="{Binding Source={x:Static properties:Settings.Default}, Path=StartPauseKey, Converter={StaticResource KeysToStringConverter}}" ToolTipService.Placement="Bottom"-->

                    <n:ImageButton x:Name="RecordPauseButton" UseLayoutRounding="True" MaxSize="16" ContentHeight="18" ContentWidth="18" TabIndex="9"

                                   Text="{Binding Stage, ElementName=RecorderLightWindow, Converter={StaticResource StageToButtonStringConverter}, FallbackValue={StaticResource Recorder.Record}}"

                                   Content="{Binding Stage, ElementName=RecorderLightWindow, Converter={StaticResource StageToCanvasConverter}, FallbackValue={StaticResource Vector.Record}}"

                                   Click="RecordPauseButton_Click" Style="{StaticResource Style.Button.Horizontal}"

                                   Foreground="{Binding ElementName=RecorderLightWindow, Path=Foreground}"

                                   MinWidth="{Binding RelativeSource={RelativeSource Mode=Self}, Path=ActualHeight}"

                                   KeyGesture="{Binding Converter={StaticResource ShortcutKeys}, ConverterParameter='1'}">

                        <n:ImageButton.ContextMenu>

                            <ContextMenu>

                                <n:ImageMenuItem Header="{DynamicResource Recorder.RecordingOptions}" IsHitTestVisible="False" Image="{StaticResource Vector.Record}" MaxSize="16"/>

                                <Separator/>

                                <n:ImageMenuItem Header="{DynamicResource Recorder.Snapshot}" IsCheckable="True" Image="{StaticResource Vector.Camera.Add}" MaxSize="16"

                                                 IsChecked="{Binding SnapshotMode, Source={x:Static u:UserSettings.All}, Mode=TwoWay}" Command="u:Commands.EnableSnapshot"/>

     

                                <n:ImageMenuItem x:Name="ThinModeMenuItem" Header="{DynamicResource Recorder.ThinMode}" IsCheckable="True" Image="{StaticResource Vector.Application}" MaxSize="16"

                                                 IsChecked="{Binding RecorderThinMode, Source={x:Static u:UserSettings.All}, Mode=TwoWay}" Command="u:Commands.EnableThinMode"

                                                 Visibility="{Binding FullScreenMode, Source={x:Static u:UserSettings.All}, Converter={StaticResource InvertedBoolToVisibility}}"/>

     

                                <n:ImageMenuItem Header="{DynamicResource Recorder.Fullscreen}" IsCheckable="True" Image="{StaticResource Vector.WidthHeight}" MaxSize="16"

                                                 IsChecked="{Binding FullScreenMode, Source={x:Static u:UserSettings.All}, Mode=TwoWay}" Command="u:Commands.EnableFullScreen"/>

                            </ContextMenu>

                        </n:ImageButton.ContextMenu>

                    </n:ImageButton>

     

                    <n:ImageButton x:Name="StopButton" Text="{DynamicResource Recorder.Stop}" Content="{StaticResource Vector.Stop}"

                                   Click="StopButton_Click" Style="{StaticResource Style.Button.Horizontal}"

                                   Foreground="{Binding ElementName=RecorderLightWindow, Path=Foreground}"

                                   UseLayoutRounding="True" MaxSize="16" ContentHeight="18" ContentWidth="18" Margin="0" TabIndex="10"

                                   MinWidth="{Binding RelativeSource={RelativeSource Mode=Self}, Path=ActualHeight}"

                                   KeyGesture="{Binding Converter={StaticResource ShortcutKeys}, ConverterParameter='2'}"/>

                </StackPanel>

            </Grid>

        </Grid>

    </n:LightWindow>

    问题7:如果这个软件让你实现,你会怎么做?

    启动界面,是4个选项,录制桌面、录制摄像头、录制绘图、视频帧编辑器

    录制桌面、录制摄像头、录制绘图其实是一样的东西。

    无非是设置一个定时器,定时的采集图像放到硬盘中。这部分的代码在呢?

    C:UserslaiqunAppDataLocalTemp   C:UserslaiqunAppDataLocalTempScreenToGifRecording2018-02-03 14-18-53

     

                    <n:ImageButton x:Name="RecordPauseButton" UseLayoutRounding="True" MaxSize="16" ContentHeight="18" ContentWidth="18" TabIndex="9" 

                                   Text="{Binding Stage, ElementName=RecorderLightWindow, Converter={StaticResource StageToButtonStringConverter}, FallbackValue={StaticResource Recorder.Record}}" 

                                   Content="{Binding Stage, ElementName=RecorderLightWindow, Converter={StaticResource StageToCanvasConverter}, FallbackValue={StaticResource Vector.Record}}" 

                                   Click="RecordPauseButton_Click" Style="{StaticResource Style.Button.Horizontal}"

                                   Foreground="{Binding ElementName=RecorderLightWindow, Path=Foreground}" 

                                   MinWidth="{Binding RelativeSource={RelativeSource Mode=Self}, Path=ActualHeight}"

    录制按钮点击

            private void RecordPauseButton_Click(object sender, RoutedEventArgs e)

            {

                if (!UserSettings.All.SnapshotMode)

                    RecordPause();

                else

                    Snap();

            }

    RecordPause函数的实现:

            private async void RecordPause()

            {

                switch (Stage)  //Stage在哪儿改变?  

                {

                    case Stage.Stopped:  //一开始肯定是从stopped 状态开始的,启动录制后,这里会将stopped状态改变为recording,表示正在录制。

    录制其实在启动一个定时器,做各种记录性的操作。

    从UnregisterEvents这个函数可以看出蛛丝马迹      

      private void UnregisterEvents()

            {

                _capture.Tick -= Normal_Elapsed;

                _capture.Tick -= NormalAsync_Elapsed;

                _capture.Tick -= Cursor_Elapsed;

                _capture.Tick -= CursorAsync_Elapsed;

                _capture.Tick -= FullCursor_Elapsed;

                _capture.Tick -= Full_Elapsed;

            }

            private void Normal_Elapsed(object sender, EventArgs e)

            {

                //Actual position on the screen.  获取要录制的区域

                var lefttop = Dispatcher.Invoke(() =>

                {

                    var left = Math.Round((Math.Round(Left, MidpointRounding.AwayFromZero) + Constants.LeftOffset) * _scale);

                    var top = Math.Round((Math.Round(Top, MidpointRounding.AwayFromZero) + Constants.TopOffset) * _scale);

                    return new Point((int)left, (int)top);

                });

                //Take a screenshot of the area. 

                var bt = Native.Capture(_size, lefttop.X, lefttop.Y);

                if (bt == null || !IsLoaded)

                    return;

                var fileName = $"{Project.FullPath}{FrameCount}.png";

    //这里只是简单的更新一下图像文件信息,并没有实际创建图像文件

                Project.Frames.Add(new FrameInfo(fileName, FrameRate.GetMilliseconds(_snapDelay), new List<SimpleKeyGesture>(_keyList)));

                _keyList.Clear();

                //AddFrames创建图像文件

                ThreadPool.QueueUserWorkItem(delegate { AddFrames(fileName, new Bitmap(bt)); });//线程池

                FrameCount++;

            }

     

    1.       System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();//实例化 

    2.      myTimer.Tick += new EventHandler(函数名); //给timer挂起事件

    3.      myTimer.Enabled = true;//使timer可用

    4.       myTimer.Interval = n; //设置时间间隔,以毫秒为单位

    5.       myTimer.Stop(); //如果要暂停计时则使用Stop()方法

    6.       myTimer.Enabled = false;//若要停止使用timer,则使之不可用

     

    设置项界面

    是一个xml文件,用来读取和写入配置的。 程序的相关地方会读取这些配置,为了方便,最好把读取配置项的地方写在一起.这部分的代码在呢?UserSettings

    namespace ScreenToGif.Util

    {

        internal sealed class UserSettings : INotifyPropertyChanged

        {

            #region Variables

            private static ResourceDictionary _local;

            private static ResourceDictionary _appData;

            private static readonly ResourceDictionary Default;

            public event PropertyChangedEventHandler PropertyChanged;

            public static UserSettings All { get; } = new UserSettings();

    视频帧编辑器负责把录制的一帧帧的图像载入,创建对应的缩略图。这部分的代码在呢?

    我想在录制的时候顺势把鼠标和键盘录制进去,怎么实现?这部分的代码在呢?

    Recorder构造函数

                    _actHook = new UserActivityHook(true, true); //true for the mouse, true for the keyboard.

                    _actHook.KeyDown += KeyHookTarget;

                    _actHook.OnMouseActivity += MouseHookTarget;

     

  • 相关阅读:
    topcoder srm 445 div1
    topcoder srm 440 div1
    topcoder srm 435 div1
    topcoder srm 430 div1
    topcoder srm 400 div1
    topcoder srm 380 div1
    topcoder srm 370 div1
    topcoder srm 425 div1
    WKWebView强大的新特性
    Runtime那些事
  • 原文地址:https://www.cnblogs.com/laiqun/p/8412166.html
Copyright © 2011-2022 走看看