Răsfoiți Sursa

20250709 WPF 第一版界面

向羽 孟 9 luni în urmă
părinte
comite
0931b84e2f
34 a modificat fișierele cu 1068 adăugiri și 56 ștergeri
  1. 6 0
      CCDCount.sln
  2. 6 0
      CCDCountWpf/App.config
  3. 9 0
      CCDCountWpf/App.xaml
  4. 17 0
      CCDCountWpf/App.xaml.cs
  5. 148 0
      CCDCountWpf/CCDCountWpf.csproj
  6. BIN
      CCDCountWpf/FromImage/test.bmp
  7. BIN
      CCDCountWpf/FromImage/中断.png
  8. BIN
      CCDCountWpf/FromImage/中断_白.png
  9. BIN
      CCDCountWpf/FromImage/数据.png
  10. BIN
      CCDCountWpf/FromImage/数据_白.png
  11. BIN
      CCDCountWpf/FromImage/相机小.png
  12. BIN
      CCDCountWpf/FromImage/相机小_白.png
  13. BIN
      CCDCountWpf/FromImage/设置.png
  14. BIN
      CCDCountWpf/FromImage/设置_白.png
  15. BIN
      CCDCountWpf/FromImage/运行.png
  16. BIN
      CCDCountWpf/FromImage/运行_白.png
  17. BIN
      CCDCountWpf/FromImage/退出.png
  18. BIN
      CCDCountWpf/FromImage/退出_白.png
  19. 38 0
      CCDCountWpf/MainWindow.xaml
  20. 122 0
      CCDCountWpf/MainWindow.xaml.cs
  21. 52 0
      CCDCountWpf/Properties/AssemblyInfo.cs
  22. 71 0
      CCDCountWpf/Properties/Resources.Designer.cs
  23. 117 0
      CCDCountWpf/Properties/Resources.resx
  24. 30 0
      CCDCountWpf/Properties/Settings.Designer.cs
  25. 7 0
      CCDCountWpf/Properties/Settings.settings
  26. 97 0
      CCDCountWpf/WpfPage/MainPage.xaml
  27. 168 0
      CCDCountWpf/WpfPage/MainPage.xaml.cs
  28. 1 0
      TestWork.DLL/CCDCount.DLL.csproj
  29. 95 25
      TestWork.DLL/MainThreadClass.cs
  30. 28 12
      TestWork.DLL/ShuLiClass.cs
  31. 40 0
      TestWork.DLL/Tools/SystemMonitorClass.cs
  32. 1 0
      TestWork.MODEL/CCDCount.MODEL.csproj
  33. 15 0
      TestWork.MODEL/ConfigModel/SaveConfigModel.cs
  34. 0 19
      TestWork/Forms/MainForm.cs

+ 6 - 0
CCDCount.sln

@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCDCount.DLL", "TestWork.DL
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCDCount.MODEL", "TestWork.MODEL\CCDCount.MODEL.csproj", "{C230B744-CABC-4B34-80BB-2CEE55A8B2B9}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCDCountWpf", "CCDCountWpf\CCDCountWpf.csproj", "{DCCBE504-5801-442E-A406-4A7099D46553}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -27,6 +29,10 @@ Global
 		{C230B744-CABC-4B34-80BB-2CEE55A8B2B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{C230B744-CABC-4B34-80BB-2CEE55A8B2B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{C230B744-CABC-4B34-80BB-2CEE55A8B2B9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DCCBE504-5801-442E-A406-4A7099D46553}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DCCBE504-5801-442E-A406-4A7099D46553}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DCCBE504-5801-442E-A406-4A7099D46553}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DCCBE504-5801-442E-A406-4A7099D46553}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 6 - 0
CCDCountWpf/App.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
+    </startup>
+</configuration>

+ 9 - 0
CCDCountWpf/App.xaml

@@ -0,0 +1,9 @@
+<Application x:Class="CCDCountWpf.App"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:local="clr-namespace:CCDCountWpf"
+             StartupUri="MainWindow.xaml">
+    <Application.Resources>
+         
+    </Application.Resources>
+</Application>

+ 17 - 0
CCDCountWpf/App.xaml.cs

@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace CCDCountWpf
+{
+    /// <summary>
+    /// App.xaml 的交互逻辑
+    /// </summary>
+    public partial class App : Application
+    {
+    }
+}

+ 148 - 0
CCDCountWpf/CCDCountWpf.csproj

@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{DCCBE504-5801-442E-A406-4A7099D46553}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>CCDCountWpf</RootNamespace>
+    <AssemblyName>CCDCountWpf</AssemblyName>
+    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>x64</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="MvCameraControl.Net, Version=4.3.2.2, Culture=neutral, PublicKeyToken=a3c7c5e3a730cd12, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\TestWork.DLL\DLL\MvCameraControl.Net.dll</HintPath>
+    </Reference>
+    <Reference Include="MvFGCtrlC.Net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=52fddfb3f94be800, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\TestWork.DLL\DLL\MvFGCtrlC.Net.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xaml">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="WindowsBase" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+  </ItemGroup>
+  <ItemGroup>
+    <ApplicationDefinition Include="App.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </ApplicationDefinition>
+    <Page Include="WpfPage\MainPage.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="MainWindow.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Compile Include="App.xaml.cs">
+      <DependentUpon>App.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="WpfPage\MainPage.xaml.cs">
+      <DependentUpon>MainPage.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="MainWindow.xaml.cs">
+      <DependentUpon>MainWindow.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\数据_白.png" />
+    <Resource Include="FromImage\相机小_白.png" />
+    <Resource Include="FromImage\设置_白.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\数据.png" />
+    <Resource Include="FromImage\相机小.png" />
+    <Resource Include="FromImage\设置.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\退出_白.png" />
+    <Resource Include="FromImage\退出.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\中断_白.png" />
+    <Resource Include="FromImage\中断.png" />
+    <Resource Include="FromImage\运行_白.png" />
+    <Resource Include="FromImage\运行.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="FromImage\test.bmp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\TestWork.DLL\CCDCount.DLL.csproj">
+      <Project>{e7f2647e-07d6-41f2-81fd-fa32da6d2526}</Project>
+      <Name>CCDCount.DLL</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\TestWork.MODEL\CCDCount.MODEL.csproj">
+      <Project>{c230b744-cabc-4b34-80bb-2cee55a8b2b9}</Project>
+      <Name>CCDCount.MODEL</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

BIN
CCDCountWpf/FromImage/test.bmp


BIN
CCDCountWpf/FromImage/中断.png


BIN
CCDCountWpf/FromImage/中断_白.png


BIN
CCDCountWpf/FromImage/数据.png


BIN
CCDCountWpf/FromImage/数据_白.png


BIN
CCDCountWpf/FromImage/相机小.png


BIN
CCDCountWpf/FromImage/相机小_白.png


BIN
CCDCountWpf/FromImage/设置.png


BIN
CCDCountWpf/FromImage/设置_白.png


BIN
CCDCountWpf/FromImage/运行.png


BIN
CCDCountWpf/FromImage/运行_白.png


BIN
CCDCountWpf/FromImage/退出.png


BIN
CCDCountWpf/FromImage/退出_白.png


+ 38 - 0
CCDCountWpf/MainWindow.xaml

@@ -0,0 +1,38 @@
+<Window x:Class="CCDCountWpf.MainWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:CCDCountWpf"
+        mc:Ignorable="d"
+        Title="MainWindow" Height="557" Width="820" MinWidth="900" MinHeight="600" Closing="Window_Closing">
+    <Grid Background="#FF00A0FB">
+        <Grid x:Name="HeardGrid" Height="60" VerticalAlignment="Top">
+            <Button x:Name="ExitBtn" HorizontalAlignment="Left" Height="60" Width="60" Click="ExitBtn_Click" Background="{x:Null}">
+                <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                    <Image  Source="/FromImage/退出.png" Width="28" Height="28" />
+                    <TextBlock Text="系统退出" FontSize="10" FontWeight="Bold" Margin="0,8,0,0" HorizontalAlignment="Center" />
+                </StackPanel>
+            </Button>
+            <Button x:Name="MainPageBtn" HorizontalAlignment="Left" Height="60" Width="60" Margin="60,0,0,0" Background="{x:Null}" Click="MainPageBtn_Click">
+                <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                    <Image  Source="/FromImage/相机小.png" Width="32" Height="32" />
+                    <TextBlock Text="主界面" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" />
+                </StackPanel>
+            </Button>
+            <Button HorizontalAlignment="Left" Height="60" Width="60" Margin="120,0,0,0" Background="{x:Null}">
+                <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                    <Image  Source="/FromImage/设置.png" Width="32" Height="32" />
+                    <TextBlock Text="设置界面" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" />
+                </StackPanel>
+            </Button>
+            <Button x:Name="RnIdentifyBtn" HorizontalAlignment="Left" Height="60" Width="60" Margin="180,0,0,0" Background="{x:Null}" Click="RnIdentifyBtn_Click">
+                <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                    <Image  Source="/FromImage/运行.png" Width="32" Height="32" />
+                    <TextBlock Text="开始运行" FontSize="10" FontWeight="Bold" Margin="0,5,0,0" HorizontalAlignment="Center" />
+                </StackPanel>
+            </Button>
+        </Grid>
+        <Frame x:Name="ShowFrame" Margin="0,60,0,0"/>
+    </Grid>
+</Window>

+ 122 - 0
CCDCountWpf/MainWindow.xaml.cs

@@ -0,0 +1,122 @@
+using CCDCount.DLL;
+using CCDCount.DLL.Tools;
+using CCDCount.MODEL.ConfigModel;
+using LogClass;
+using MvCameraControl;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Windows;
+
+namespace CCDCountWpf
+{
+    public static class MessageBus
+    {
+        public static MainThreadClass mainThreadClass = null;
+    }
+    /// <summary>
+    /// MainWindow.xaml 的交互逻辑
+    /// </summary>
+    public partial class MainWindow : Window
+    {
+        #region 变量与实例
+        Uri ShowUri = null;
+        public ModbusTcpClient modbusTcpClient = new ModbusTcpClient();
+        SaveConfigModel Config = null;
+        #endregion
+
+        #region 窗体事件
+        /// <summary>
+        /// 主窗体构造函数
+        /// </summary>
+        public MainWindow()
+        {
+            InitializeComponent();
+            //modbusTcpClient.Connect("192.168.1.88");
+            modbusTcpClient.Connect("127.0.0.1");
+            if (File.Exists(".\\Config\\CCDCountConfig.xml"))
+            {
+                Config = XmlStorage.DeserializeFromXml<SaveConfigModel>(".\\Config\\CCDCountConfig.xml");
+            }
+            SDKSystem.Initialize();
+            MainPageBtn_Click(null, null);
+        }
+
+        
+        /// <summary>
+        /// 退出按钮点击事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void ExitBtn_Click(object sender, RoutedEventArgs e)
+        {
+            this.Close();
+        }
+
+        /// <summary>
+        /// 主界面按钮点击事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void MainPageBtn_Click(object sender, RoutedEventArgs e)
+        {
+            ShowUri = new Uri("WpfPage\\MainPage.xaml", UriKind.Relative);
+            ShowFrame.Navigate(ShowUri);
+        }
+
+        /// <summary>
+        /// 开始运行按钮点击事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void RnIdentifyBtn_Click(object sender, RoutedEventArgs e)
+        {
+            RunCameraIdentify();
+        }
+
+        /// <summary>
+        /// 窗体关闭事件
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
+        {
+            SDKSystem.Finalize();
+            if (MessageBus.mainThreadClass != null) MessageBus.mainThreadClass.StopMianThread();
+            Environment.Exit(0);
+        }
+        #endregion
+
+        #region 私有方法
+        /// <summary>
+        /// 启动相机识别
+        /// </summary>
+        private void RunCameraIdentify()
+        {
+            if (Config == null)
+            {
+                MessageBox.Show("尚未添加相机,请前往配置页面配置相机");
+                return;
+            }
+            MessageBus.mainThreadClass = new MainThreadClass(Config.ShuLiConfigClass, Config.CameraConfig);
+            //判断是否添加线程
+            if (!MessageBus.mainThreadClass.IsOpenLoadThread)
+                return;
+            MessageBus.mainThreadClass.SetModbusClient(modbusTcpClient);
+            //启动单相机实例的全部线程
+            if (!MessageBus.mainThreadClass.StartMianThread(Config.CameraConfig))
+            {
+                LOG.error(MessageBus.mainThreadClass.ThisCameraDevice + "_" + MessageBus.mainThreadClass.ThisCameraSN + "启动失败");
+                MessageBox.Show(MessageBus.mainThreadClass.ThisCameraDevice + "_" + MessageBus.mainThreadClass.ThisCameraSN + "启动失败");
+                return;
+            }
+        }
+        #endregion
+
+
+
+
+
+    }
+}

+ 52 - 0
CCDCountWpf/Properties/AssemblyInfo.cs

@@ -0,0 +1,52 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("CCDCountWpf")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CCDCountWpf")]
+[assembly: AssemblyCopyright("Copyright ©  2025")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+//若要开始生成可本地化的应用程序,请设置
+//.csproj 文件中的 <UICulture>CultureYouAreCodingWith</UICulture>
+//在 <PropertyGroup> 中。例如,如果你使用的是美国英语。
+//使用的是美国英语,请将 <UICulture> 设置为 en-US。  然后取消
+//对以下 NeutralResourceLanguage 特性的注释。  更新
+//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+    ResourceDictionaryLocation.None, //主题特定资源词典所处位置
+                                     //(未在页面中找到资源时使用,
+                                     //或应用程序资源字典中找到时使用)
+    ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
+                                              //(未在页面中找到资源时使用,
+                                              //、应用程序或任何主题专用资源字典中找到时使用)
+)]
+
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 71 - 0
CCDCountWpf/Properties/Resources.Designer.cs

@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本: 4.0.30319.42000
+//
+//     对此文件的更改可能导致不正确的行为,如果
+//     重新生成代码,则所做更改将丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace CCDCountWpf.Properties
+{
+
+
+    /// <summary>
+    ///   强类型资源类,用于查找本地化字符串等。
+    /// </summary>
+    // 此类是由 StronglyTypedResourceBuilder
+    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+    // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+    // (以 /str 作为命令选项),或重新生成 VS 项目。
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources
+    {
+
+        private static global::System.Resources.ResourceManager resourceMan;
+
+        private static global::System.Globalization.CultureInfo resourceCulture;
+
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources()
+        {
+        }
+
+        /// <summary>
+        ///   返回此类使用的缓存 ResourceManager 实例。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager
+        {
+            get
+            {
+                if ((resourceMan == null))
+                {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CCDCountWpf.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+
+        /// <summary>
+        ///   重写当前线程的 CurrentUICulture 属性,对
+        ///   使用此强类型资源类的所有资源查找执行重写。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture
+        {
+            get
+            {
+                return resourceCulture;
+            }
+            set
+            {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 117 - 0
CCDCountWpf/Properties/Resources.resx

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 30 - 0
CCDCountWpf/Properties/Settings.Designer.cs

@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace CCDCountWpf.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

+ 7 - 0
CCDCountWpf/Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

+ 97 - 0
CCDCountWpf/WpfPage/MainPage.xaml

@@ -0,0 +1,97 @@
+<Page x:Class="CCDCountWpf.WpfPage.MainPage"
+      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+      xmlns:local="clr-namespace:CCDCountWpf.WpfPage"
+      mc:Ignorable="d"
+      Title="MainPage" Height="503" Width="876" Loaded="Page_Loaded">
+
+    <Grid>
+        <Image x:Name="ShowBox" Height="160" VerticalAlignment="Top" OpacityMask="Black" />
+        <Grid Margin="0,160,0,60">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="*"/>
+                <ColumnDefinition Width="*"/>
+            </Grid.ColumnDefinitions>
+
+            <Border Grid.Column="0" 
+                    Background="#7F808080" 
+                    CornerRadius="8"
+                    BorderBrush="Gray"
+                    BorderThickness="1"
+                    Margin="15,10,15,0" Height="160" VerticalAlignment="Top">
+
+                <StackPanel Orientation="Horizontal">
+                    <StackPanel Orientation="Vertical">
+                        <Label  Content="当前总粒数:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                        <Label  Content="当前合格数:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                        <Label  Content="当前不合格数:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                    </StackPanel>
+                    <StackPanel Orientation="Vertical">
+                        <TextBox x:Name="AllActiveNumTbx" HorizontalAlignment="Left" Margin="0,15,0,0"  TextWrapping="Wrap" Width="120" FontWeight="Bold" FontSize="20" IsReadOnly="True" Background="{x:Null}"/>
+                        <TextBox x:Name="AllOkNumTbx" HorizontalAlignment="Left" Margin="0,17,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" FontWeight="Bold" FontSize="20" IsReadOnly="True" Background="{x:Null}"/>
+                        <TextBox x:Name="AllNgNumTbx"  HorizontalAlignment="Left" Margin="0,17,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" FontWeight="Bold" FontSize="20" IsReadOnly="True" Background="{x:Null}"/>
+                    </StackPanel>
+                    <StackPanel Orientation="Vertical">
+                        <Label x:Name="CamRunStaticLab" Content="未运行" HorizontalAlignment="Right" Margin="10,5,10,0" VerticalAlignment="Top" Background="{x:Null}" FontSize="25" Foreground="Red" FontWeight="Bold"/>
+                        <Button x:Name="DataClear" Content="清零" BorderThickness="1" HorizontalAlignment="Left" Margin="10,50,10,0" VerticalAlignment="Top" Width="80" Height="40" Background="#FF1709AF" FontWeight="Bold" FontSize="20" Foreground="White" Click="DataClear_Click">
+                            <Button.Template>
+                                <ControlTemplate TargetType="Button">
+                                    <Border CornerRadius="5" 
+                                            Background="{TemplateBinding Background}"
+                                            BorderBrush="{TemplateBinding BorderBrush}"
+                                            BorderThickness="{TemplateBinding BorderThickness}">
+                                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                                    </Border>
+                                </ControlTemplate>
+                            </Button.Template>
+                        </Button>
+                    </StackPanel>
+                </StackPanel>
+                <!-- 卡片内容 -->
+            </Border>
+
+            <Border Grid.Column="0" 
+                    Background="#7F808080" 
+                    CornerRadius="8"
+                    BorderBrush="Gray"
+                    BorderThickness="1"
+                    Margin="15,180,15,0" Height="60" VerticalAlignment="Top">
+                <StackPanel Orientation="Horizontal">
+                    <StackPanel Orientation="Vertical">
+                        <Label  Content="计数速度:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="20"/>
+                    </StackPanel>
+                    <StackPanel Orientation="Vertical" Margin="40,0,0,0" >
+                        <TextBox x:Name="ShuLiSpeedTbx" HorizontalAlignment="Left" Margin="0,15,0,0"  TextWrapping="Wrap" Width="120" FontWeight="Bold" FontSize="20" IsReadOnly="True" Background="{x:Null}"/>
+                    </StackPanel>
+                    <StackPanel Orientation="Vertical" Margin="10,0,0,0" >
+                        <Label Content="粒/秒" FontWeight="Bold" FontSize="20" Margin="0,10,0,0" />
+                    </StackPanel>
+                </StackPanel>
+            </Border>
+
+            <Border Grid.Column="1" 
+                    Background="#7F808080" 
+                    CornerRadius="8"
+                    BorderBrush="Gray"
+                    BorderThickness="1"
+                    Margin="15,10,15,0" Height="250" VerticalAlignment="Top">
+                <Label Content="控制按钮预留区域" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="30"/>
+            </Border>
+        </Grid>
+        <Grid VerticalAlignment="Bottom" Height="50" Margin="0,0,0,5">
+            <Border Grid.Column="0" 
+                    Background="#7F808080" 
+                    CornerRadius="8"
+                    BorderBrush="Gray"
+                    BorderThickness="1"
+                    Margin="10,0,10,0" VerticalAlignment="Bottom" Height="50">
+                <StackPanel Orientation="Horizontal">
+                    <Label x:Name="CPUMonitorLab" HorizontalAlignment="Left" VerticalAlignment="Top" Height="40" Margin="30,8,0,0" Width="120" FontSize="18" FontWeight="Bold"></Label>
+                    <Label x:Name="RamMonitorLab" HorizontalAlignment="Left" VerticalAlignment="Top" Height="40" Margin="30,8,0,0" Width="180" FontSize="18" FontWeight="Bold"></Label>
+                </StackPanel>
+            </Border>
+        </Grid>
+    </Grid>
+</Page>

+ 168 - 0
CCDCountWpf/WpfPage/MainPage.xaml.cs

@@ -0,0 +1,168 @@
+
+using LogClass;
+using MvCameraControl;
+using System;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Interop;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using static System.Net.Mime.MediaTypeNames;
+
+namespace CCDCountWpf.WpfPage
+{
+    /// <summary>
+    /// MainPage.xaml 的交互逻辑
+    /// </summary>
+    public partial class MainPage : Page
+    {
+        #region 变量与实例
+        bool IsShow = false;
+        SystemMonitor monitor = new SystemMonitor();
+        #endregion
+        public MainPage()
+        {
+            InitializeComponent();
+            StartUpdataShowDataThread();
+        }
+
+        /// <summary>
+        ///  启动更新显示数据线程
+        /// </summary>
+        private void StartUpdataShowDataThread()
+        {
+            IsShow = true;
+            Bitmap image = null;
+            const int targetMsPerFrame = 100; // 20FPS=50ms
+            Stopwatch renderSW = new Stopwatch();
+            Task.Run(() =>
+            {
+                while (IsShow)
+                {
+                    UpdataShuLiShowData();
+                    UpdateMonitorMessage();
+                    renderSW.Restart();
+                    if (MessageBus.mainThreadClass == null)
+                    {
+                        LOG.log(string.Format("{0}:当前加载相机空", "IdentifyCameraForm-StartShowImageThread"));
+                        Thread.Sleep(100);
+                        continue;
+                    }
+                    if (MessageBus.mainThreadClass.HistoryActiveNum > 0)
+                    {
+                        MessageBus.mainThreadClass.GetShowImage(800, out image);
+                    }
+                    else
+                    {
+                        MessageBus.mainThreadClass.GetNullShowImage(4096, 800, out image);
+                        Thread.Sleep(100);
+                        LOG.log(string.Format("{0}-{1}号相机线程启动异常", "IdentifyCameraForm-StartShowImageThread:", MessageBus.mainThreadClass.ThisCamerNo));
+                    }
+                    if (image == null)
+                    {
+                        LOG.log(string.Format("{0}:获取图片失败", "IdentifyCameraForm-StartShowImageThread"));
+                        continue;
+                    }
+                    System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
+                    {
+                        var bitmapImage = ConvertToBitmapImage(image);
+                        ShowBox.Source = bitmapImage;
+                    }));
+                    //进行精准20帧控制
+                    int elapsed = (int)renderSW.ElapsedMilliseconds;
+                    if (elapsed < targetMsPerFrame)
+                    {
+                        Thread.Sleep(targetMsPerFrame - elapsed);
+                    }
+                    Thread.Sleep(50);
+                }
+            });
+        }
+
+        /// <summary>
+        ///  停止更新显示数据线程
+        /// </summary>
+        private void StopUpdataShowDataThread()
+        {
+            IsShow = false;
+        }
+
+
+        /// <summary>
+        /// 更新数粒显示数据
+        /// </summary>
+        private void UpdataShuLiShowData()
+        {
+            if (MessageBus.mainThreadClass == null) return;
+            if (MessageBus.mainThreadClass.ShuLiState)
+            {
+                System.Windows.Application.Current.Dispatcher.Invoke(() =>
+                {
+
+                    CamRunStaticLab.Foreground = MessageBus.mainThreadClass.CameraRunStatic == true ? System.Windows.Media.Brushes.Green : System.Windows.Media.Brushes.Red;
+                    CamRunStaticLab.Content = MessageBus.mainThreadClass.CameraRunStatic == true ? "运行中" : "未运行";
+                });
+            }
+            else
+            {
+                System.Windows.Application.Current.Dispatcher.Invoke(() =>
+                {
+
+                    CamRunStaticLab.Foreground = System.Windows.Media.Brushes.Yellow;
+                    CamRunStaticLab.Content = "视野遮挡";
+                });
+            }
+            System.Windows.Application.Current.Dispatcher.Invoke(() =>
+            {
+                AllActiveNumTbx.Text = MessageBus.mainThreadClass.HistoryActiveNum.ToString();
+                AllOkNumTbx.Text = MessageBus.mainThreadClass.NgHistoryNum.ToString();
+                AllNgNumTbx.Text = MessageBus.mainThreadClass.OkHistoryNum.ToString();
+                ShuLiSpeedTbx.Text = MessageBus.mainThreadClass.GetOneSecondActiveNum().ToString();
+            });
+        }
+
+        /// <summary>
+        /// 更新监控信息
+        /// </summary>
+        private void UpdateMonitorMessage()
+        {
+            System.Windows.Application.Current.Dispatcher.Invoke(() =>
+            {
+                RamMonitorLab.Content = $"可用内存: {monitor.GetAvailableMemory()}MB";
+                CPUMonitorLab.Content = $"CPU: {monitor.GetCpuUsage().ToString("0.00")}%";
+            });
+        }
+
+        // Bitmap 转 BitmapImage 的辅助方法
+        private BitmapImage ConvertToBitmapImage(Bitmap bitmap)
+        {
+            using (MemoryStream memory = new MemoryStream())
+            {
+                bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
+                memory.Position = 0;
+                var bitmapImage = new BitmapImage();
+                bitmapImage.BeginInit();
+                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
+                bitmapImage.StreamSource = memory;
+                bitmapImage.EndInit();
+                return bitmapImage;
+            }
+        }
+
+        private void DataClear_Click(object sender, RoutedEventArgs e)
+        {
+            MessageBus.mainThreadClass.ClearHistoryActive();
+        }
+
+        private void Page_Loaded(object sender, RoutedEventArgs e)
+        {
+            this.Width = double.NaN; // 等效于 Auto
+            this.Height = double.NaN;
+        }
+    }
+}

+ 1 - 0
TestWork.DLL/CCDCount.DLL.csproj

@@ -88,6 +88,7 @@
     <Compile Include="Delta\EtherCAT_DLL.cs" />
     <Compile Include="Delta\EtherCAT_DLL_Err.cs" />
     <Compile Include="Tools\ModbusClass.cs" />
+    <Compile Include="Tools\SystemMonitorClass.cs" />
     <Compile Include="Tools\XMLFileClass.cs" />
     <Compile Include="ZhengYunDong\Zmcaux.cs" />
     <Compile Include="ZhengYunDong\ZmcauxClass.cs" />

+ 95 - 25
TestWork.DLL/MainThreadClass.cs

@@ -28,8 +28,6 @@ namespace CCDCount.DLL
         public string ThisCameraSN = string.Empty;
         public string ThisCamerName = string.Empty;
         public int ThisCamerNo = -1;
-        //留给主界面的回调函数
-        public event EventHandler<ActiveObjectEventArgsClass> WorkerToFrom;
 
         public bool CameraStatic { get { return _CameraStatic; } }
         private bool _CameraStatic = false;
@@ -63,10 +61,15 @@ namespace CCDCount.DLL
         /// </summary>
         private bool _ShuLiState = true;
         public bool ShuLiState { get { return _ShuLiState; } }
+
+        private bool IsDebug = false;
         #endregion
 
         #region 公共方法
-
+        /// <summary>
+        /// 设置ModbusTcpClient
+        /// </summary>
+        /// <param name="modbusTcpClient"></param>
         public void SetModbusClient(ModbusTcpClient modbusTcpClient)
         {
             this.modbusTcpClient = modbusTcpClient;
@@ -81,6 +84,11 @@ namespace CCDCount.DLL
             }
         }
 
+        /// <summary>
+        /// 初始化构造方法
+        /// </summary>
+        /// <param name="configClass"></param>
+        /// <param name="CameraConfig"></param>
         public MainThreadClass(ShuLiConfigClass configClass,CameraConfig CameraConfig)
         {
             // 数粒配置文件地址
@@ -101,6 +109,7 @@ namespace CCDCount.DLL
             ThisCameraDevice =  CameraConfig.DeviceName;
             ThisCamerNo = CameraConfig.CamerNo;
         }
+
         /// <summary>
         /// 开始主线程
         /// </summary>
@@ -167,6 +176,7 @@ namespace CCDCount.DLL
             result = true;
             return result;
         }
+
         /// <summary>
         /// 停止主线程
         /// </summary>
@@ -182,6 +192,11 @@ namespace CCDCount.DLL
             StopSendBottLogicMessageThread();
         }
 
+        /// <summary>
+        /// 重加载相机
+        /// </summary>
+        /// <param name="CameraSN"></param>
+        /// <returns></returns>
         public bool ReLoadCamera(string CameraSN)
         { 
             bool result = false;
@@ -197,6 +212,9 @@ namespace CCDCount.DLL
              
         }
 
+        /// <summary>
+        /// 释放相机资源
+        /// </summary>
         public void DisposeCamera()
         {
             cameraClass.StopCamera();
@@ -204,6 +222,7 @@ namespace CCDCount.DLL
             ThisCamerName = string.Empty;
             ThisCameraDevice = string.Empty;
         }
+
         /// <summary>
         /// 获取显示用的图片数据
         /// </summary>
@@ -222,18 +241,54 @@ namespace CCDCount.DLL
             List<ActiveObjectClass> Data = shuLiClass.GetHistoryActive().Where(o => o.LastSeenLine > NewActive.LastSeenLine - ImageHeight).ToList();
             Data.ForEach(o => o.RowsData.ForEach(p => RowsShowList.Add(p)));
             Bitmap BitmapImage = new Bitmap(NewActive.ImageWidth, ImageHeight);
-            Graphics g = Graphics.FromImage(BitmapImage);
-            Pen redPen = new Pen(Color.Red, 1);
-            List<RowStartEndCol> ShowList = RowsShowList.Where(o => o.RowsCol > NewActive.LastSeenLine - BitmapImage.Height).ToList();
-            RowsShowList.Where(o => o.RowsCol < NewActive.LastSeenLine - BitmapImage.Height).ToList().ForEach(o => RowsShowList.Remove(o));
-            RowsShowList.Clear();
-            ShowList.ForEach(o => g.DrawLine(redPen, new Point(o.StartCol, (int)(NewActive.LastSeenLine - o.RowsCol)), new Point(o.EndCol, (int)(NewActive.LastSeenLine - o.RowsCol))));
-            ShowList.Clear();
+            using (Graphics g = Graphics.FromImage(BitmapImage))
+            {
+                g.Clear(Color.White);
+                using (Pen BlackPan = new Pen(Color.Black, 4))
+                {
+                    for (int i = 0; i < shuLiClass.ChannelsRoi.Count - 1; i++)
+                    {
+                        g.DrawLine(BlackPan, new Point(shuLiClass.ChannelsRoi[i], 0), new Point(shuLiClass.ChannelsRoi[i], BitmapImage.Height));
+                    }
+                }
+                using (Pen redPen = new Pen(Color.Red, 1))
+                {
+                    List<RowStartEndCol> ShowList = RowsShowList.Where(o => o.RowsCol > NewActive.LastSeenLine - BitmapImage.Height).ToList();
+                    RowsShowList.Where(o => o.RowsCol < NewActive.LastSeenLine - BitmapImage.Height).ToList().ForEach(o => RowsShowList.Remove(o));
+                    RowsShowList.Clear();
+                    ShowList.ForEach(o => g.DrawLine(redPen, new Point(o.StartCol, (int)(NewActive.LastSeenLine - o.RowsCol)), new Point(o.EndCol, (int)(NewActive.LastSeenLine - o.RowsCol))));
+                    ShowList.Clear();
+                }
+            }
             ImageData = BitmapImage.Clone() as Bitmap;
             BitmapImage.Dispose();
             //GC.Collect();
         }
 
+        /// <summary>
+        /// 获取无数据的图片
+        /// </summary>
+        /// <param name="ImageWidth"></param>
+        /// <param name="ImageHeight"></param>
+        /// <param name="ImageData"></param>
+        public void GetNullShowImage(int ImageWidth, int ImageHeight, out Bitmap ImageData)
+        {
+            Bitmap BitmapImage = new Bitmap(ImageWidth, ImageHeight);
+            using (Graphics g = Graphics.FromImage(BitmapImage))
+            {
+                g.Clear(Color.White);
+                using (Pen BlackPan = new Pen(Color.Black, 4))
+                {
+                    for (int i = 0; i < shuLiClass.ChannelsRoi.Count - 1; i++)
+                    {
+                        g.DrawLine(BlackPan, new Point(shuLiClass.ChannelsRoi[i], 0), new Point(shuLiClass.ChannelsRoi[i], BitmapImage.Height));
+                    }
+                }
+            }
+            ImageData = BitmapImage.Clone() as Bitmap;
+            BitmapImage.Dispose();
+        }
+
         /// <summary>
         /// 获取此刻的Config数据
         /// </summary>
@@ -265,6 +320,7 @@ namespace CCDCount.DLL
                 //新建一个相机配置
                 CameraConfig = new CameraConfig();
         }
+
         /// <summary>
         /// 保存所有Config
         /// </summary>
@@ -285,9 +341,28 @@ namespace CCDCount.DLL
             return result;
         }
 
-        public void Dispose()
+        /// <summary>
+        /// 清除历史数据
+        /// </summary>
+        /// <returns></returns>
+        public bool ClearHistoryActive()
         {
-            //MechanicalControl.Dispose();
+            bool result = false;
+            if(shuLiClass != null)
+                result = shuLiClass.ClearHistoryActive();
+            return result;
+        }
+
+        /// <summary>
+        /// 获取过去一秒内颗粒数量
+        /// </summary>
+        /// <returns></returns>
+        public int GetOneSecondActiveNum()
+        {
+            int result = 0;
+            if(shuLiClass != null)
+                result = shuLiClass.GetHistoryActive().Where(o=>o.EndCheckTime>DateTime.Now-TimeSpan.FromSeconds(1)).Count();
+            return result;
         }
         #endregion
 
@@ -344,16 +419,6 @@ namespace CCDCount.DLL
             }
         }
 
-
-        /// <summary>
-        /// 对外通知事件
-        /// </summary>
-        private void OnOneGrain(List<ActiveObjectClass> activeObject)
-        {
-            ActiveObjectEventArgsClass activeObjectEventArgs = new ActiveObjectEventArgsClass(activeObject);
-            // 触发事件
-            WorkerToFrom?.Invoke(this, activeObjectEventArgs);
-        }
         #endregion
 
         #region 线程方法
@@ -404,6 +469,11 @@ namespace CCDCount.DLL
                     GC.Collect();
                     stopwatch.Restart();
                 }
+                //Debug模式,不进行图像处理
+                if (IsDebug)
+                {
+                    continue;
+                }
                 //Thread.Sleep(5);
                 bool result = cameraClass.GetOnceImage(out IFramedata);
                 if (result)
@@ -471,7 +541,7 @@ namespace CCDCount.DLL
             Stopwatch sw = Stopwatch.StartNew();
             while (IsSend)
             {
-                LOG.log("进入线程", 6);
+                //LOG.log("进入线程", 6);
                 sw.Restart();
                 sendMessage = new ushort();
                 //读取装瓶状态
@@ -501,9 +571,9 @@ namespace CCDCount.DLL
                         modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 100, value: sendMessage);
                         modbusTcpClient.WriteCoilsRegister(slaveId: 1, CoilsAddress: 11, values: true);
                     }
+                    sw.Stop();
+                    LOG.log(string.Format("sendMessage[1]:{0},此次写值耗时:{1}", sendMessage, sw.Elapsed), 6);
                 }
-                sw.Stop();
-                LOG.log(string.Format("离开线程写入值:sendMessage[1]:{0},此次写值耗时:{1}", sendMessage, sw.Elapsed), 6);
                 Thread.Sleep(1);
             }
         }

+ 28 - 12
TestWork.DLL/ShuLiClass.cs

@@ -26,7 +26,8 @@ namespace CCDCount.DLL
         private bool IsIdentify = false; //线程是否开始识别的标志
         private long currentLine = 0; //行数记录
         private ShuLiConfigClass shuLiConfig = null;// 数粒参数配置文件
-        private List<int> ChannelsRoi = new List<int>();
+        public List<int> ChannelsRoi{get{ return _ChannelsRoi; }}
+        private List<int> _ChannelsRoi = new List<int>();
         private int ChannelWidth = 0;//每个区域的宽度
         private int IdentifyImageWidth = -1;
         private static readonly object _lockObj = new object(); // 专用锁对象\
@@ -63,6 +64,7 @@ namespace CCDCount.DLL
                     PandingCode = 2
                 };
             }
+            InitChannel();
         }
 
         /// <summary>
@@ -116,14 +118,6 @@ namespace CCDCount.DLL
                 return historyActiveObjects.Count();
         }
 
-        /// <summary>
-        /// 清除缓存的内存的中的历史数据
-        /// </summary>
-        public void ClearHistoryActive()
-        {
-            historyActiveObjects.Clear();
-        }
-
         /// <summary>
         /// 获取历史数据中,正常数据数量
         /// </summary>
@@ -144,6 +138,19 @@ namespace CCDCount.DLL
                 return historyActiveObjects.Where(o=>o.StateCode != 0).Count();
         }
 
+        /// <summary>
+        /// 清除历史数据
+        /// </summary>
+        /// <returns></returns>
+        public bool ClearHistoryActive()
+        {
+            lock (_lockObj)
+            {
+                historyActiveObjects.Clear();
+                return true;
+            }
+        }
+
         /// <summary>
         /// 开启识别
         /// </summary>
@@ -221,7 +228,8 @@ namespace CCDCount.DLL
         /// <param name="ImageWidth"></param>
         public void InitChannel()
         {
-            shuLiConfig.ImageWidth = IdentifyImageWidth;
+            _ChannelsRoi.Clear();
+            shuLiConfig.ImageWidth = IdentifyImageWidth==-1? shuLiConfig.ImageWidth: IdentifyImageWidth;
             if (shuLiConfig.Channel > 0)
             {
                 if (shuLiConfig.IsIdentifyRoiOpen)
@@ -234,7 +242,7 @@ namespace CCDCount.DLL
                 }
                 for (int i = 0; i < shuLiConfig.Channel; i++)
                 {
-                    ChannelsRoi.Add(ChannelWidth + i * ChannelWidth);
+                    _ChannelsRoi.Add(ChannelWidth + i * ChannelWidth);
                 }
             }
         }
@@ -249,6 +257,14 @@ namespace CCDCount.DLL
 
             return result;
         }
+
+        public int GetConfigImageWidth()
+        {
+            int result = -1;
+            if(shuLiConfig != null)
+                result = shuLiConfig.ImageWidth;
+            return result;
+        }
         #endregion
 
         #region 私有方法
@@ -556,7 +572,7 @@ namespace CCDCount.DLL
             }
             else
             {
-                result = ChannelsRoi[StartChannel] - activeObject.MinStartCol > activeObject.MaxEndCol - ChannelsRoi[StartChannel]? StartChannel: EndChannel;
+                result = _ChannelsRoi[StartChannel] - activeObject.MinStartCol > activeObject.MaxEndCol - _ChannelsRoi[StartChannel]? StartChannel: EndChannel;
             }
             return result;
         }

+ 40 - 0
TestWork.DLL/Tools/SystemMonitorClass.cs

@@ -0,0 +1,40 @@
+using System;
+using System.Diagnostics;
+using System.Threading;
+
+public class SystemMonitor
+{
+    private readonly PerformanceCounter _cpuCounter;
+    private readonly PerformanceCounter _ramCounter;
+    Stopwatch stopwatch = Stopwatch.StartNew();
+    private float HisCPUCounter = 0;
+
+    public SystemMonitor()
+    {
+        _cpuCounter = new PerformanceCounter(
+            "Processor", "% Processor Time", "_Total");
+
+        _ramCounter = new PerformanceCounter(
+            "Memory", "Available MBytes");
+    }
+
+    public float GetCpuUsage()
+    {
+        stopwatch.Stop();
+        if (stopwatch.ElapsedMilliseconds > 1000)
+        {
+            stopwatch.Restart();
+            HisCPUCounter = _cpuCounter.NextValue();
+        }
+        else
+        {
+            stopwatch.Start();
+        }
+        return HisCPUCounter;
+    }
+
+    public float GetAvailableMemory()
+    {
+        return _ramCounter.NextValue();
+    }
+}

+ 1 - 0
TestWork.MODEL/CCDCount.MODEL.csproj

@@ -45,6 +45,7 @@
     <Compile Include="CameraClass\CameraImageSizeClass.cs" />
     <Compile Include="CameraClass\CameraInfoClass.cs" />
     <Compile Include="ConfigModel\CamerasConfig.cs" />
+    <Compile Include="ConfigModel\SaveConfigModel.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ShuLiClass\ActiveObjectClass.cs" />
     <Compile Include="ShuLiClass\ActiveObjectEventArgsClass.cs" />

+ 15 - 0
TestWork.MODEL/ConfigModel/SaveConfigModel.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CCDCount.MODEL.ConfigModel
+{
+    public class SaveConfigModel
+    {
+        public ShuLiConfigClass ShuLiConfigClass { get; set; }
+
+        public CameraConfig CameraConfig { get; set; }
+    }
+}

+ 0 - 19
TestWork/Forms/MainForm.cs

@@ -221,7 +221,6 @@ namespace CCDCount.Forms
                     MessageBox.Show(LsMainThread[i].ThisCameraDevice + "_" + LsMainThread[i].ThisCameraSN + "启动失败");
                     return;
                 }
-                LsMainThread[i].WorkerToFrom +=  Worker_MianThreadToFrom;
             }
         }
 
@@ -237,23 +236,5 @@ namespace CCDCount.Forms
         }
 
         #endregion
-
-        #region  主界面回调事件
-        /// <summary>
-        /// 通知主界面回调的事件
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void Worker_MianThreadToFrom(object sender, ActiveObjectEventArgsClass e)
-        {
-            // 事件处理逻辑
-            Console.WriteLine("结果已通知到主界面!");
-
-
-            
-            //此处进行与下位机的交互(将通道数给下位机控制程序)
-            //float getvalue = 0;
-        }
-        #endregion
     }
 }