ScreenToGif 代碼分析

ScreenToGif項目由四個文件夾組成:html

  1. Files 存放協議文件
  2. GifRecorder 存放gif編碼器代碼
  3. ScreenToGif 存放主代碼
  4. Other 存放HooktestTranslator的代碼

問題1:GifRecorder 和ScreenToGif、Hooktest、Translator 下面都有了一個Properties,裏面有個AssemblyInfo.cs是什麼東西?

.net工程的Properties文件夾下自動生成一個名爲AssemblyInfo.cs的文件,通常狀況下咱們不多直接改動該文件。但咱們實際上經過另外一個形式操做該文件。那就是經過在鼠標右鍵點擊項目的屬性進入應用程序」->「程序集信息,而後修改信息。數據庫

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

問題2:啓動界面分析

 

 

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

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

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

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

        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">this

 

    <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:\Users\laiqun\AppData\Local\Temp\   C:\Users\laiqun\AppData\Local\Temp\ScreenToGif\Recording\2018-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;

相關文章
相關標籤/搜索