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;

     

  • 相关阅读:
    jquery弹窗居中-类似alert()
    php explode时间分割
    php+mysql+jquery日历签到
    php查找字符串中第一个非0的位置截取
    SQL Server Data Tool 嘹解(了解)一下 SSDT -摘自网络
    Headless MSBuild Support for SSDT (*.sqlproj) Projects [利用msbuild自动化部署 .sqlproj]- 摘自网络
    SSDT – Error SQL70001 This statement is not recognized in this context-摘自网络
    Web Services and C# Enums -摘自网络
    Excel中VBA 连接 数据库 方法- 摘自网络
    解决 Provider 'System.Data.SqlServerCe.3.5' not installed. -摘自网络
  • 原文地址:https://www.cnblogs.com/laiqun/p/8412166.html
Copyright © 2011-2022 走看看