Commit 8af4571e SK

添加项目文件。

1 个父辈 e51d2214
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Costura.Fody.3.2.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.3.2.0\build\Costura.Fody.props')" />
<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>{2F0D362D-2A49-49C4-963D-99F958A616D7}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Acc.Demo</RootNamespace>
<AssemblyName>Demo</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</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>
<PropertyGroup>
<StartupObject>Acc.Demo.Program</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>disc_64px.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<SignManifests>false</SignManifests>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\AccImage\AccImage.csproj">
<Project>{2626350b-63da-416c-b72a-7fe7825c3711}</Project>
<Name>AccImage</Name>
</ProjectReference>
<ProjectReference Include="..\ImageBox\ImageBox.csproj">
<Project>{db03ed04-5e06-4feb-b891-0633448f24ec}</Project>
<Name>ImageBox</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="disc_64px.ico" />
<Content Include="FodyWeavers.xml">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Costura.Fody.3.2.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.3.2.0\build\Costura.Fody.props'))" />
<Error Condition="!Exists('..\packages\Fody.3.3.2\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.3.3.2\build\Fody.targets'))" />
</Target>
<Import Project="..\packages\Fody.3.3.2\build\Fody.targets" Condition="Exists('..\packages\Fody.3.3.2\build\Fody.targets')" />
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Costura>
<ExcludeAssemblies></ExcludeAssemblies>
</Costura>
</Weavers>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuild. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCompression" type="xs:boolean">
<xs:annotation>
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCleanup" type="xs:boolean">
<xs:annotation>
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification on the target assembly after all weavers have been finished.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
\ No newline at end of file

using Acc.Img;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Acc.Demo
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void OpenImage()
{
using (FileDialog dialog = new OpenFileDialog())
{
dialog.Filter = "图片 (*.raw,*.bmp;*.gif;*.jpeg;*.jpg;*.png)|*.raw;*.bmp;*.dib;*.rle;*.gif;*.jpg;*.png|RAW (*.raw)|*.raw|Bitmaps (*.bmp;*.dib;*.rle)|*.bmp;*.dib;*.rle|Graphics Interchange Format (*.gif)|*.gif|Joint Photographic Experts (*.jpg)|*.jpg|Portable Network Graphics (*.png)|*.png|All Files (*.*)|*.*";
dialog.DefaultExt = "png";
if (dialog.ShowDialog(this) == DialogResult.OK)
{
try
{
string imagePath = dialog.FileName;
labelImageName.Text = imagePath;
Image image = ImageUtil.ReadImage(imagePath);
orginalImage = image;
imageBox.Image = image;
imageBox.ZoomToFit();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void buttonOpen_Click(object sender, EventArgs e)
{
ClearStatusBar();
OpenImage();
}
Image orginalImage = null;
private void buttonCount_Click(object sender, EventArgs e)
{
Count();
}
private void buttonThesh_Click(object sender, EventArgs e)
{
int theshValue = -1;
if (!checkBoxAutoThresh.Checked)
{
theshValue = int.Parse(textBoxThesh.Text);
}
Image result = ImageUtil.Threshhold(orginalImage, theshValue);
imageBox.Image = result;
}
private void checkBoxAutoThresh_CheckedChanged(object sender, EventArgs e)
{
textBoxThesh.Enabled = !checkBoxAutoThresh.Checked;
}
private void 原图ToolStripMenuItem_Click(object sender, EventArgs e)
{
ClearStatusBar();
imageBox.Image = orginalImage;
}
private int markX = -1;
private int markY = -1;
private void imageBox_MouseDown(object sender, MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Right)
{
bool inImage = imageBox.IsPointInImage(e.Location);
System.Drawing.Point markPoint = imageBox.PointToImage(e.Location);
markX = markPoint.X;
markY = markPoint.Y;
元件特征ToolStripMenuItem.Enabled = inImage;
原图ToolStripMenuItem.Enabled = inImage;
contextMenuStrip.Show(this, e.Location);
}
}
private void Count()
{
ClearStatusBar();
int theshValue = -1;
if (!checkBoxAutoThresh.Checked)
{
theshValue = int.Parse(textBoxThesh.Text);
}
Task.Factory.StartNew(delegate {
//Image image = ImageUtil.FindCircle(orginalImage, theshValue, inv);
//imageBox.Image = image;
Stopwatch sw = new Stopwatch();
sw.Start();
int itemFeature = int.Parse(textBoxFeature.Text);
Image image = orginalImage;
int count = ImageUtil.CountItems(ref image, itemFeature, theshValue);
sw.Stop();
labelTime.Text = "耗时:" + sw.ElapsedMilliseconds + " ms";
labelCount.Text = "数量:" + count;
imageBox.Image = image;
});
}
private void ClearStatusBar()
{
labelFeature.Text = "";
labelCount.Text = "";
labelTime.Text = "";
}
private void 打开图片ToolStripMenuItem_Click(object sender, EventArgs e)
{
ClearStatusBar();
OpenImage();
}
private void 计数ToolStripMenuItem_Click(object sender, EventArgs e)
{
Count();
}
private void 元件特征ToolStripMenuItem_Click(object sender, EventArgs e)
{
ClearStatusBar();
int theshValue = -1;
if (!checkBoxAutoThresh.Checked)
{
theshValue = int.Parse(textBoxThesh.Text);
}
int feature = ImageUtil.GetItemFeature(orginalImage, markX, markY, theshValue);
labelFeature.Text = "特征值:" + feature + "";
textBoxFeature.Text = feature + "";
}
}
}
namespace Acc.Demo
{
partial class MainForm
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.imageBox = new Cyotek.Windows.Forms.ImageBox();
this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.打开图片ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.原图ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.元件特征ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.计数ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.buttonOpen = new System.Windows.Forms.Button();
this.buttonCount = new System.Windows.Forms.Button();
this.buttonThesh = new System.Windows.Forms.Button();
this.textBoxThesh = new System.Windows.Forms.TextBox();
this.checkBoxAutoThresh = new System.Windows.Forms.CheckBox();
this.panel1 = new System.Windows.Forms.Panel();
this.labelFeature = new System.Windows.Forms.Label();
this.labelImageName = new System.Windows.Forms.Label();
this.labelCount = new System.Windows.Forms.Label();
this.labelTime = new System.Windows.Forms.Label();
this.textBoxFeature = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.contextMenuStrip.SuspendLayout();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// imageBox
//
this.imageBox.AllowDrop = true;
this.imageBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.imageBox.Location = new System.Drawing.Point(12, 42);
this.imageBox.Name = "imageBox";
this.imageBox.Size = new System.Drawing.Size(614, 367);
this.imageBox.TabIndex = 0;
this.imageBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.imageBox_MouseDown);
//
// contextMenuStrip
//
this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.打开图片ToolStripMenuItem,
this.原图ToolStripMenuItem,
this.元件特征ToolStripMenuItem,
this.计数ToolStripMenuItem});
this.contextMenuStrip.Name = "contextMenuStrip";
this.contextMenuStrip.Size = new System.Drawing.Size(149, 92);
//
// 打开图片ToolStripMenuItem
//
this.打开图片ToolStripMenuItem.Name = "打开图片ToolStripMenuItem";
this.打开图片ToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.打开图片ToolStripMenuItem.Text = "打开图片";
this.打开图片ToolStripMenuItem.Click += new System.EventHandler(this.打开图片ToolStripMenuItem_Click);
//
// 原图ToolStripMenuItem
//
this.原图ToolStripMenuItem.Name = "原图ToolStripMenuItem";
this.原图ToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.原图ToolStripMenuItem.Text = "重新加载";
this.原图ToolStripMenuItem.Click += new System.EventHandler(this.原图ToolStripMenuItem_Click);
//
// 元件特征ToolStripMenuItem
//
this.元件特征ToolStripMenuItem.Name = "元件特征ToolStripMenuItem";
this.元件特征ToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.元件特征ToolStripMenuItem.Text = "获取元件特征";
this.元件特征ToolStripMenuItem.Click += new System.EventHandler(this.元件特征ToolStripMenuItem_Click);
//
// 计数ToolStripMenuItem
//
this.计数ToolStripMenuItem.Name = "计数ToolStripMenuItem";
this.计数ToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
this.计数ToolStripMenuItem.Text = "计数";
this.计数ToolStripMenuItem.Click += new System.EventHandler(this.计数ToolStripMenuItem_Click);
//
// buttonOpen
//
this.buttonOpen.Location = new System.Drawing.Point(13, 9);
this.buttonOpen.Name = "buttonOpen";
this.buttonOpen.Size = new System.Drawing.Size(75, 23);
this.buttonOpen.TabIndex = 1;
this.buttonOpen.Text = "打开";
this.buttonOpen.UseVisualStyleBackColor = true;
this.buttonOpen.Click += new System.EventHandler(this.buttonOpen_Click);
//
// buttonCount
//
this.buttonCount.Location = new System.Drawing.Point(105, 9);
this.buttonCount.Name = "buttonCount";
this.buttonCount.Size = new System.Drawing.Size(75, 23);
this.buttonCount.TabIndex = 2;
this.buttonCount.Text = "计数";
this.buttonCount.UseVisualStyleBackColor = true;
this.buttonCount.Click += new System.EventHandler(this.buttonCount_Click);
//
// buttonThesh
//
this.buttonThesh.Location = new System.Drawing.Point(375, 13);
this.buttonThesh.Name = "buttonThesh";
this.buttonThesh.Size = new System.Drawing.Size(75, 23);
this.buttonThesh.TabIndex = 3;
this.buttonThesh.Text = "二值化";
this.buttonThesh.UseVisualStyleBackColor = true;
this.buttonThesh.Click += new System.EventHandler(this.buttonThesh_Click);
//
// textBoxThesh
//
this.textBoxThesh.Location = new System.Drawing.Point(269, 13);
this.textBoxThesh.Name = "textBoxThesh";
this.textBoxThesh.Size = new System.Drawing.Size(46, 21);
this.textBoxThesh.TabIndex = 4;
this.textBoxThesh.Text = "30";
//
// checkBoxAutoThresh
//
this.checkBoxAutoThresh.AutoSize = true;
this.checkBoxAutoThresh.Location = new System.Drawing.Point(321, 17);
this.checkBoxAutoThresh.Name = "checkBoxAutoThresh";
this.checkBoxAutoThresh.Size = new System.Drawing.Size(48, 16);
this.checkBoxAutoThresh.TabIndex = 5;
this.checkBoxAutoThresh.Text = "自动";
this.checkBoxAutoThresh.UseVisualStyleBackColor = true;
this.checkBoxAutoThresh.CheckedChanged += new System.EventHandler(this.checkBoxAutoThresh_CheckedChanged);
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panel1.Controls.Add(this.labelFeature);
this.panel1.Controls.Add(this.labelImageName);
this.panel1.Controls.Add(this.labelCount);
this.panel1.Controls.Add(this.labelTime);
this.panel1.Location = new System.Drawing.Point(-1, 411);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(640, 23);
this.panel1.TabIndex = 7;
//
// labelFeature
//
this.labelFeature.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.labelFeature.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.labelFeature.Location = new System.Drawing.Point(105, 1);
this.labelFeature.Name = "labelFeature";
this.labelFeature.Size = new System.Drawing.Size(119, 22);
this.labelFeature.TabIndex = 3;
this.labelFeature.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// labelImageName
//
this.labelImageName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.labelImageName.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.labelImageName.Location = new System.Drawing.Point(223, 1);
this.labelImageName.Name = "labelImageName";
this.labelImageName.Size = new System.Drawing.Size(317, 22);
this.labelImageName.TabIndex = 2;
this.labelImageName.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// labelCount
//
this.labelCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.labelCount.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.labelCount.Location = new System.Drawing.Point(0, 1);
this.labelCount.Name = "labelCount";
this.labelCount.Size = new System.Drawing.Size(108, 22);
this.labelCount.TabIndex = 1;
this.labelCount.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// labelTime
//
this.labelTime.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.labelTime.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.labelTime.Location = new System.Drawing.Point(540, 1);
this.labelTime.Name = "labelTime";
this.labelTime.Size = new System.Drawing.Size(97, 22);
this.labelTime.TabIndex = 0;
this.labelTime.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// textBoxFeature
//
this.textBoxFeature.Location = new System.Drawing.Point(556, 16);
this.textBoxFeature.Name = "textBoxFeature";
this.textBoxFeature.Size = new System.Drawing.Size(46, 21);
this.textBoxFeature.TabIndex = 8;
this.textBoxFeature.Text = "200";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(473, 19);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(65, 12);
this.label1.TabIndex = 9;
this.label1.Text = "元件特征:";
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(638, 435);
this.Controls.Add(this.label1);
this.Controls.Add(this.textBoxFeature);
this.Controls.Add(this.panel1);
this.Controls.Add(this.checkBoxAutoThresh);
this.Controls.Add(this.textBoxThesh);
this.Controls.Add(this.buttonThesh);
this.Controls.Add(this.buttonCount);
this.Controls.Add(this.buttonOpen);
this.Controls.Add(this.imageBox);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "MainForm";
this.Text = "上海锐驰点料系统";
this.contextMenuStrip.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Cyotek.Windows.Forms.ImageBox imageBox;
private System.Windows.Forms.Button buttonOpen;
private System.Windows.Forms.Button buttonCount;
private System.Windows.Forms.Button buttonThesh;
private System.Windows.Forms.TextBox textBoxThesh;
private System.Windows.Forms.CheckBox checkBoxAutoThresh;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip;
private System.Windows.Forms.ToolStripMenuItem 原图ToolStripMenuItem;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label labelTime;
private System.Windows.Forms.Label labelCount;
private System.Windows.Forms.Label labelImageName;
private System.Windows.Forms.Label labelFeature;
private System.Windows.Forms.TextBox textBoxFeature;
private System.Windows.Forms.ToolStripMenuItem 元件特征ToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem 打开图片ToolStripMenuItem;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ToolStripMenuItem 计数ToolStripMenuItem;
}
}
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAABMLAAATCwAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABsLigAbC4oAGwuKABsLigAbC4oAGwuKBBsLigvbC4oYWwuKIlsLiiubC4ox2wu
KN1sLijjbC4o6mwuKOpsLijjbC4o3WwuKMdsLiiubC4oiWwuKGFsLigvbC4oEGwuKABsLigAbC4oAGwu
KABsLigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwuKABsLigAbC4oAGwuKABsLigRbC4oQWwuKIFsLii6bC4o5Gwu
KPVsLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij1bC4o5Gwu
KLpsLiiBbC4oQWwuKBFsLigAbC4oAGwuKABsLigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbC4oAGwuKABsLigAbC4oAWwuKCFsLihubC4owGwu
KPBsLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wu
KP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKPBsLijAbC4obmwuKCFsLigBbC4oAGwuKABsLigAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwuKABsLigAbC4oImwu
KH9sLijWbC4o/WwuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wu
KP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP1sLijWbC4of2wu
KCJsLigAbC4oAGwuKABsLigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwu
KABsLigQbC4oaWwuKNFsLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKPJsLijfbC4ov2wu
KKJsLiiJbC4of2wuKH9sLih9bC4of2wuKIxsLiiibC4ov2wuKOFsLijybC4o/2wuKP9sLij/bC4o/2wu
KP9sLij/bC4o/2wuKP9sLijRbC4oZ2wuKA9sLigAbC4oAGwuKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABsLigAbC4oAGwuKABsLig1bC4or2wuKPhsLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLijsbC4ovWwu
KH1sLihIbC4oIWwuKA9sLigGbC4oAGwuKABsLigAbC4oAGwuKABsLigAbC4oB2wuKBBsLigibC4oSGwu
KH1sLii9bC4o7GwuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKPhsLiiubC4oNWwuKABsLigAbC4oAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAGwuKABsLigAbC4oAGwuKAZsLihfbC4o22wuKP9sLij/bC4o/2wuKP9sLij/bC4o/Wwu
KNdsLiiGbC4oOmwuKBBsLigAbC4oAGwuKABsLigAbC4oAGwuKABsLigAAAAAAAAAAABsLigAbC4oAGwu
KABsLigAbC4oAGwuKABsLigAbC4oEGwuKDpsLiiJbC4o2GwuKP1sLij/bC4o/2wuKP9sLij/bC4o/2wu
KNtsLihfbC4oBmwuKABsLigAbC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwuKABsLigAbC4oAGwuKA5sLiiCbC4o8mwuKP9sLij/bC4o/2wu
KP9sLij/bC4o2GwuKHdsLigjbC4oAGwuKABsLigAbC4oAGwuKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwuKABsLigAbC4oAWwuKCNsLih3bC4o2Gwu
KP9sLij/bC4o/2wuKP9sLij/bC4o8mwuKIJsLigObC4oAGwuKABsLigAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwuKABsLigAbC4oAGwuKBRsLiiabC4o+mwu
KP9sLij/bC4o/2wuKP9sLijwbC4okmwuKCdsLigAbC4oAGgoJADx2rMA5sunAObLpwDmy6cA5sunAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbC4oAGwu
KABsLigAbC4oAGwuKCdsLiiSbC4o8GwuKP9sLij/bC4o/2wuKP9sLij6bC4ommwuKBRsLigAbC4oAGwu
KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwu
KBRsLiiebC4o/WwuKP9sLij/bC4o/2wuKP9sLijObC4oUWwuKAZsLigAZSQgAO3UrwDmy6cA5sunAObL
pxbmy6co5sunA+bLpwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAbC4oAGwuKABsLigAbC4oBmwuKFFsLijObC4o/2wuKP9sLij/bC4o/2wu
KP1sLiiebC4oFGwuKABsLigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABsLigAbC4oAGwuKA5sLiiabC4o/WwuKP9sLij/bC4o/2wuKP1sLiisbC4oKWwuKABrLScA////AObL
pwDmy6cA5sunJubLp3bmy6fL5sunwebLpxbmy6cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbC4oAGwuKABsLigAbC4oKWwu
KKxsLij9bC4o/2wuKP9sLij/bC4o/WwuKJpsLigObC4oAGwuKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABsLigAbC4oAGwuKAZsLiiCbC4o+mwuKP9sLij/bC4o/2wuKPhsLiiWbC4oFmwu
KABSDA0A6M6pAObLpwDmy6cY5sundubLp9jmy6f+5sun/+bLp/Pmy6dK5sunAMqQUADNl1oAzZdaAM2X
WgDNl1oAzZdaAM2XWgDNl1oAzZdaAM2XWgDNl1oAzZdaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABsLigAbC4oAGwuKABsLigWbC4olmwuKPhsLij/bC4o/2wuKP9sLij6bC4ogmwuKAZsLigAbC4oAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwuKABsLihfbC4o8mwuKP9sLij/bC4o/2wu
KPhsLiiKbC4oDGwuKAD/+MsA5sunAObLpwHmy6dH5sunwubLp/zmy6f/5sun/+bLp//my6f/5sunjOrT
sgHIjEkCzZdaE82XWibNl1o0zZdaQs2XWkLNl1o0zZdaJs2XWhTNl1oHzZdaAM2XWgDNl1oAzZdaAM2X
WgAAAAAAAAAAAAAAAAAAAAAAAAAAAGwuKABsLigAbC4oAGwuKAxsLiiKbC4o+GwuKP9sLij/bC4o/2wu
KPJsLihfbC4oAGwuKABsLigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbC4oAGwuKABsLig1bC4o22wu
KP9sLij/bC4o/2wuKP1sLiiWbC4oDGwuKACzinIA5sunAObLpwvmy6d05sun6ObLp//my6f/5sun/+bL
p//my6f/5sun/+bLp8zozqwVy5JTEM2XWrDNl1rnzZda682XWvDNl1rwzZda682XWubNl1rNzZdapM2X
Wm3Nl1oyzZdaCM2XWgDNl1oAzZdaAM2XWgAAAAAAAAAAAAAAAAAAAAAAbC4oAGwuKABsLigAbC4oDGwu
KJZsLij9bC4o/2wuKP9sLij/bC4o22wuKDVsLigAbC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAbC4oAGwu
KABsLigQbC4or2wuKP9sLij/bC4o/2wuKP9sLiisbC4oFmwuKACjdWEA5sunAObLpxTmy6eT5sun9+bL
p//my6f/5sun/+bLp//my6f/5sun/+bLp//my6fz5syoSbluHQXNl1qozZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r9zZda5s2XWqXNl1pNzZdaC82XWgDNl1oAzZdaAAAAAAAAAAAAAAAAAAAA
AAAAAAAAbC4oAGwuKABsLigWbC4orGwuKP9sLij/bC4o/2wuKP9sLiiubC4oD2wuKABsLigAAAAAAAAA
AAAAAAAAAAAAAGwuKABsLigAbC4oaWwuKPhsLij/bC4o/2wuKP9sLijObC4oKWwuKAD///AA5sunAObL
pxXmy6ee5sun/ebLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp4zCgTkAzZdaYs2X
WvrNl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda8s2XWqnNl1o1zZdaAM2X
WgDNl1oAAAAAAAAAAAAAAAAAAAAAAGwuKABsLigAbC4oAGwuKClsLijObC4o/2wuKP9sLij/bC4o+Gwu
KGdsLigAbC4oAAAAAAAAAAAAAAAAAGwuKABsLigAbC4oImwuKNFsLij/bC4o/2wuKP9sLijwbC4oUWwu
KABNBggA5sunAObLpwvmy6eV5sun/ebLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bL
p//my6fM6dCvFMyVVyTNl1rfzZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda382XWmvNl1oJzZdaAM2XWgDNl1oAAAAAAAAAAAAAAAAAbC4oAGwuKABsLigAbC4oUWwu
KPBsLij/bC4o/2wuKP9sLijRbC4oImwuKABsLigAAAAAAAAAAABsLigAbC4oAWwuKH9sLij/bC4o/2wu
KP9sLij/bC4okmwuKAZrLScA6M2pAObLpwPmy6d35sun9+bLp//my6f/5sun/+bLp//my6f/5sun/+bL
p//my6f/5sun/+bLp//my6f/5sun8+bMqEm0Yw0EzZdapc2XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r2zZdakM2XWhPNl1oAzZdaAAAAAAAAAAAAAAAAAAAA
AABsLigAbC4oAGwuKAZsLiiSbC4o/2wuKP9sLij/bC4o/2wuKH9sLigBbC4oAAAAAABsLigAbC4oAGwu
KCNsLijXbC4o/2wuKP9sLij/bC4o2GwuKCdsLigA////AObLpwDmy6dJ5sun6ubLp//my6f/5sun/+bL
p//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6eMwoE5AM2XWmLNl1r6zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv3Nl1qezZdaE82X
WgDNl1oAAAAAAAAAAAAAAAAAAAAAAGwuKABsLigAbC4oJ2wuKNhsLij/bC4o/2wuKP9sLijXbC4oI2wu
KABsLigAbC4oAGwuKABsLihvbC4o/WwuKP9sLij/bC4o/GwuKHdsLigAZCQgAObLpwDmy6cY5sunwubL
p//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sunzOnQ
rxTMlVckzZda382XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda/c2XWpDNl1oJzZdaAM2XWgAAAAAAAAAAAAAAAAAAAAAAbC4oAGwuKABsLih3bC4o/Gwu
KP9sLij/bC4o/WwuKG9sLigAbC4oAGwuKABsLigRbC4owGwuKP9sLij/bC4o/2wuKNZsLiggbC4oAOzT
rQDmy6cB5suneObLp/zmy6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bL
p//my6f/5sun/+bLp/Pmy6hKtWYRBM2XWqfNl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r2zZdaa82XWgDNl1oAzZdaAAAAAAAAAAAAAAAAAGwu
KABsLigAbC4oIGwuKNZsLij/bC4o/2wuKP9sLijAbC4oEWwuKABsLigAbC4oQWwuKPBsLij/bC4o/2wu
KP9sLiiGbC4oAWgoJADmy6cA5sunJubLp9jmy6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bL
p//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sunftKhaQDNl1o8zZdagM2XWn/Nl1qNzZdas82X
WuTNl1r+zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWt/Nl1o1zZdaAM2X
WgAAAAAAAAAAAAAAAAAAAAAAbC4oAGwuKAFsLiiGbC4o/2wuKP9sLij/bC4o8GwuKEFsLigAbC4oAGwu
KIFsLij/bC4o/2wuKP9sLijsbC4oOmwuKADx2rMA5sunAObLp3bmy6f+5sun/+bLp//my6f/5sun/+bL
p//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6fZ5sunfObLpyX58uEAzplcAM2X
WgDNl1oAzZdaAM2XWgvNl1oszZdaec2XWtjNl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r/zZdaqc2XWgvNl1oAzZdaAAAAAAAAAAAAAAAAAGwuKABsLigAbC4oOmwuKOxsLij/bC4o/2wu
KP9sLiiBbC4oAGwuKBBsLii6bC4o/2wuKP9sLij/bC4ovWwuKBBsLigA5sunAObLpxbmy6fL5sun/+bL
p//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp/rmy6ep5sunLObL
pwDmy6cA5sunAObLpwAAAAAAzZdaAM2XWgDNl1oAzZdaAM2XWgDNl1orzZdaps2XWvvNl1r/zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWvLNl1pOzZdaAM2XWgAAAAAAAAAAAAAAAAAAAAAAbC4oAGwu
KBBsLii9bC4o/2wuKP9sLij/bC4oumwuKBBsLigvbC4o5GwuKP9sLij/bC4o/2wuKH1sLigAbC4oAObL
pwDmy6co5sunwebLp/Pmy6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bL
p/rmy6eN5sunEubLpwDr0qwAYiEeAGwuKABsLigAbC4oAGwuKABsLigAbC4oAGUmJADSnV0AzZdaAM2X
WhHNl1qNzZda+82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZdaqM2XWgnNl1oAAAAAAAAA
AAAAAAAAAAAAAGwuKABsLigAbC4ofWwuKP9sLij/bC4o/2wuKORsLigvbC4oYWwuKPVsLij/bC4o/2wu
KPJsLihIbC4oAGwuKADmy6cA5sunA+bLpxbmy6dK5sunjObLp8zmy6fz5sun/+bLp//my6f/5sun/+bL
p//my6f/5sun/+bLp//my6ep5sunEubLpwCeb1wAbC4oAGwuKABsLigdbC4oT2wuKGZsLihmbC4oT2wu
KB1sLigAbC4oAKNpRADNl1oAzZdaEc2XWqbNl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
WubNl1oyzZdaAM2XWgAAAAAAAAAAAAAAAABsLigAbC4oAGwuKEhsLijybC4o/2wuKP9sLij1bC4oYWwu
KIlsLij/bC4o/2wuKP9sLijfbC4oIWwuKAAAAAAA5sunAObLpwDmy6cA5sunAOrTsgHozqwV5syoSebL
p4zmy6fM5sun8+bLp//my6f/5sun/+bLp//my6fY5sunLObLpwCeb1wAbC4oAGwuKA1sLihrbC4o0Gwu
KPVsLij7bC4o+2wuKPVsLijQbC4oa2wuKA1sLigAo2lEAM2XWgDNl1orzZda2M2XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r9zZdabc2XWgDNl1oAAAAAAAAAAAAAAAAAAAAAAGwuKABsLighbC4o32wu
KP9sLij/bC4o/2wuKIlsLiiubC4o/2wuKP9sLij/bC4ov2wuKA9sLigAAAAAAAAAAAAAAAAAAAAAAMqQ
UADIjEkCy5JTELluHQXCgTkA6dCvFObMqEnmy6eM5sunzObLp/Pmy6f/5suneebLpwDu1a8AbC4oAGwu
KA1sLiiQbC4o+WwuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKPlsLiiQbC4oDWwuKADTnl0AzZdaAM2X
WnnNl1r+zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWqTNl1oHzZdaAAAAAAAAAAAAAAAAAAAA
AABsLigAbC4oD2wuKL9sLij/bC4o/2wuKP9sLiiubC4ox2wuKP9sLij/bC4o/2wuKKJsLigGbC4oAAAA
AAAAAAAAAAAAAAAAAADNl1oAzZdaE82XWrDNl1qozZdaYsyVVyS0Yw0EwoE5AOnQrxTmy6hK5sunfubL
pyXmy6cAZSUhAGwuKABsLihvbC4o+WwuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o+Wwu
KG9sLigAZyglAM2XWgDNl1oszZda5M2XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1rNzZdaFM2X
WgAAAAAAAAAAAAAAAAAAAAAAbC4oAGwuKAZsLiiibC4o/2wuKP9sLij/bC4ox2wuKN1sLij/bC4o/2wu
KP9sLiiJbC4oAGwuKAAAAAAAAAAAAAAAAAAAAAAAzZdaAM2XWibNl1rnzZda/82XWvrNl1rfzZdapc2X
WmLMlVcktWYRBNKhaQD58uEA5sunAGwuKABsLigebC4o02wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wu
KP9sLij/bC4o/2wuKP9sLijTbC4oHmwuKADNl1oAzZdaC82XWrPNl1r/zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda5s2XWiXNl1oAAAAAAAAAAAAAAAAAAAAAAGwuKABsLigAbC4oiWwuKP9sLij/bC4o/2wu
KN1sLijjbC4o/2wuKP9sLij/bC4of2wuKABsLigAAAAAAAAAAAAAAAAAAAAAAM2XWgDNl1o1zZda7M2X
Wv/Nl1r/zZda/82XWv/Nl1r6zZda382XWqfNl1o8zplcAObLpwBsLigAbC4oUmwuKPZsLij/bC4o/2wu
KP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o9mwuKFJsLigAzZdaAM2XWgDNl1qKzZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWuzNl1o2zZdaAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwu
KH9sLij/bC4o/2wuKP9sLijjbC4o7WwuKP9sLij/bC4o/2wuKHtsLigAAAAAAAAAAAAAAAAAAAAAAAAA
AADNl1oAzZdaRM2XWvDNl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZdaf82XWgAAAAAAbC4oAGwu
KGxsLij+bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKPxsLihpbC4oAM2X
WgDNl1oAzZdaf82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1ryzZdaSc2XWgAAAAAAAAAAAAAA
AAAAAAAAAAAAAGwuKABsLih/bC4o/2wuKP9sLij/bC4o6WwuKOtsLij/bC4o/2wuKP9sLih6bC4oAAAA
AAAAAAAAAAAAAAAAAAAAAAAAzZdaAM2XWkTNl1rwzZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
Wn3Nl1oAzZdaAGwuKABsLihrbC4o/WwuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wu
KP9sLij8bC4oZ2wuKAAAAAAAzZdaAM2XWoDNl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda8s2X
WknNl1oAAAAAAAAAAAAAAAAAAAAAAAAAAABsLigAbC4ofWwuKP9sLij/bC4o/2wuKOdsLijjbC4o/2wu
KP9sLij/bC4of2wuKABsLigAAAAAAAAAAAAAAAAAAAAAAM2XWgDNl1o1zZda7M2XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1qKzZdaAM2XWgBsLigAbC4oUmwuKPZsLij/bC4o/2wuKP9sLij/bC4o/2wu
KP9sLij/bC4o/2wuKP9sLij/bC4o9mwuKFJsLigA5sunAM6ZXADNl1o8zZdap82XWt/Nl1r6zZda/82X
Wv/Nl1r/zZda/82XWuzNl1o2zZdaAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwuKH9sLij/bC4o/2wu
KP9sLijjbC4o3WwuKP9sLij/bC4o/2wuKIlsLigAbC4oAAAAAAAAAAAAAAAAAAAAAADNl1oAzZdaJs2X
WubNl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZdas82XWgvNl1oAbC4oAGwuKB5sLijTbC4o/2wu
KP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKNNsLigebC4oAObLpwDw4ccA0qFpALVm
EQTMlVckzZdaYs2XWqXNl1rfzZda+s2XWv/Nl1rnzZdaJc2XWgAAAAAAAAAAAAAAAAAAAAAAbC4oAGwu
KABsLiiJbC4o/2wuKP9sLij/bC4o3WwuKMdsLij/bC4o/2wuKP9sLiiibC4oBmwuKAAAAAAAAAAAAAAA
AAAAAAAAzZdaAM2XWhTNl1rNzZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWuTNl1oszZdaAGco
JQBsLigAbC4ob2wuKPlsLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKPlsLihvbC4oAGUk
IADmy6cA5sunJebLp3/my6hK6dCvFMKBOQC0Yw0EzJVXJM2XWmLNl1qozZdasM2XWhPNl1oAAAAAAAAA
AAAAAAAAAAAAAGwuKABsLigGbC4oomwuKP9sLij/bC4o/2wuKMdsLiiubC4o/2wuKP9sLij/bC4ov2wu
KA9sLigAAAAAAAAAAAAAAAAAAAAAAM2XWgDNl1oHzZdapM2XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r+zZdaec2XWgDTnl0AbC4oAGwuKA5sLiiVbC4o+WwuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wu
KPlsLiiVbC4oDmwuKADs060A5sunAObLp37my6f/5sun8+bLp8zmy6eM5syoSenQrxTCgTkAuW4dBcuS
UxDIjEkCypBQAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oEGwuKL9sLij/bC4o/2wuKP9sLiiubC4oiWwu
KP9sLij/bC4o/2wuKN9sLighbC4oAAAAAAAAAAAAAAAAAAAAAADNl1oAzZdaAM2XWm3Nl1r9zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWtjNl1orzZdaAKJoRABsLigAbC4oDmwuKG9sLijTbC4o9mwu
KPxsLij8bC4o9mwuKNNsLihvbC4oDmwuKACfcF0A5sunAObLpyzmy6fZ5sun/+bLp//my6f/5sun/+bL
p/Pmy6fM5sunjObMqEnozqwV6tOyAebLpwDmy6cA5sunAObLpwAAAAAAbC4oAGwuKCJsLijhbC4o/2wu
KP9sLij/bC4oiWwuKGFsLij1bC4o/2wuKP9sLijybC4oSGwuKABsLigAAAAAAAAAAAAAAAAAzZdaAM2X
WgDNl1oyzZda5s2XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZdaps2XWhHNl1oAk1g8AGwu
KABsLigAbC4oHmwuKFJsLihnbC4oZ2wuKFJsLigebC4oAGwuKACfcF0A5sunAObLpxLmy6ep5sun/+bL
p//my6f/5sun/+bLp//my6f/5sun/+bLp//my6fz5sunzObLp4zmy6dK5sunFubLpwPmy6cAbC4oAGwu
KABsLihIbC4o8mwuKP9sLij/bC4o9WwuKGFsLigvbC4o5GwuKP9sLij/bC4o/2wuKH1sLigAbC4oAAAA
AAAAAAAAAAAAAAAAAADNl1oAzZdaCM2XWqXNl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
WvvNl1qNzZdaEs2XWgDTnV0AZyglAGwuKABsLigAbC4oAGwuKABsLigAbC4oAGQjHwDr0q0A5sunAObL
pxLmy6eS5sun++bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun8+bL
p8Hmy6co5sunAGwuKABsLigAbC4ofWwuKP9sLij/bC4o/2wuKORsLigvbC4oEGwuKLpsLij/bC4o/2wu
KP9sLii9bC4oEGwuKAAAAAAAAAAAAAAAAAAAAAAAzZdaAM2XWgDNl1pNzZda8s2XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r/zZda+s2XWqnNl1oszZdaAM2XWgDNl1oAzZdaAM2XWgAAAAAA5sunAObL
pwDmy6cA5sunAObLpyzmy6ep5sun++bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bL
p//my6f/5sun/+bLp//my6fL5sunFubLpwBsLigAbC4oEGwuKL1sLij/bC4o/2wuKP9sLii6bC4oEGwu
KABsLiiBbC4o/2wuKP9sLij/bC4o7GwuKDpsLigAbC4oAAAAAAAAAAAAAAAAAM2XWgDNl1oAzZdaC82X
WqnNl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda2M2XWnnNl1oszZdaC82X
WgDNl1oAzZdaAM6ZXADw4ccA5sunJebLp4Dmy6fa5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bL
p//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f+5sundubLpwDz27QAbC4oAGwuKDpsLijsbC4o/2wu
KP9sLij/bC4ogWwuKABsLigAbC4oQWwuKPBsLij/bC4o/2wuKP9sLiiGbC4oAWwuKAAAAAAAAAAAAAAA
AAAAAAAAzZdaAM2XWgDNl1o1zZda382XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r+zZda5M2XWrPNl1qKzZdaf82XWoDNl1o80qFpAObLp3/my6f/5sun/+bLp//my6f/5sun/+bL
p//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun2ObLpybmy6cAaCkkAGwu
KAFsLiiJbC4o/2wuKP9sLij/bC4o8GwuKEFsLigAbC4oAGwuKBFsLijAbC4o/2wuKP9sLij/bC4o1mwu
KCBsLigAbC4oAAAAAAAAAAAAAAAAAM2XWgDNl1oAzZdaAM2XWmvNl1r2zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZdap7VmEQTmy6hK5sun8+bL
p//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/ObL
p3jmy6cB7NOtAGwuKABsLigjbC4o2GwuKP9sLij/bC4o/2wuKMBsLigRbC4oAGwuKABsLigAbC4obmwu
KP1sLij/bC4o/2wuKPxsLih3bC4oAGwuKAAAAAAAAAAAAAAAAAAAAAAAzZdaAM2XWgDNl1oJzZdakM2X
Wv3Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
Wt/MlVck6dCvFObLp8zmy6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bL
p//my6f/5sun/+bLp8Lmy6cY5sunAGQkIABsLigAbC4od2wuKP1sLij/bC4o/2wuKP1sLihubC4oAGwu
KABsLigAbC4oAGwuKCFsLijWbC4o/2wuKP9sLij/bC4o2GwuKCdsLigAbC4oAAAAAAAAAAAAAAAAAAAA
AADNl1oAzZdaAM2XWhPNl1qezZda/c2XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r6zZdaYsKBOQDmy6eM5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bL
p//my6f/5sun/+bLp//my6f/5sun/+bLp+rmy6dJ5sunAP///wBsLigAbC4oJ2wuKNhsLij/bC4o/2wu
KP9sLijWbC4oIWwuKABsLigAAAAAAGwuKABsLigBbC4of2wuKP9sLij/bC4o/2wuKP9sLiiSbC4oBmwu
KABsLigAAAAAAAAAAAAAAAAAAAAAAM2XWgDNl1oAzZdaE82XWpDNl1r2zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWqW0Yw0E5syoSebLp/Pmy6f/5sun/+bL
p//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp/fmy6d35sunA+jNqQBrLScAbC4oBmwu
KJJsLij/bC4o/2wuKP9sLij/bC4of2wuKAFsLigAAAAAAAAAAABsLigAbC4oAGwuKCJsLijRbC4o/2wu
KP9sLij/bC4o8GwuKFFsLigAbC4oAGwuKAAAAAAAAAAAAAAAAADNl1oAzZdaAM2XWgDNl1oJzZdaa82X
Wt/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1rfzJVXJOnQ
rxTmy6fM5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bLp/3my6eV5sunC+bL
pwBNBggAbC4oAGwuKFFsLijwbC4o/2wuKP9sLij/bC4o0WwuKCJsLigAbC4oAAAAAAAAAAAAAAAAAGwu
KABsLigAbC4oZ2wuKPhsLij/bC4o/2wuKP9sLijObC4oKWwuKABsLigAbC4oAAAAAAAAAAAAAAAAAAAA
AADNl1oAzZdaAM2XWgDNl1o1zZdaqc2XWvLNl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1r/zZda/82X
Wv/Nl1r/zZda+s2XWmLCgTkA5sunjObLp//my6f/5sun/+bLp//my6f/5sun/+bLp//my6f/5sun/+bL
p/3my6ee5sunFebLpwD///AAbC4oAGwuKClsLijObC4o/2wuKP9sLij/bC4o+GwuKGdsLigAbC4oAAAA
AAAAAAAAAAAAAAAAAABsLigAbC4oAGwuKA9sLiiubC4o/2wuKP9sLij/bC4o/2wuKKxsLigWbC4oAGwu
KAAAAAAAAAAAAAAAAAAAAAAAAAAAAM2XWgDNl1oAzZdaAM2XWgvNl1pOzZdaqM2XWubNl1r9zZda/82X
Wv/Nl1r/zZda/82XWv/Nl1r/zZda/82XWv/Nl1qouW4dBebMqEnmy6fz5sun/+bLp//my6f/5sun/+bL
p//my6f/5sun/+bLp/fmy6eT5sunFObLpwCjdWEAbC4oAGwuKBZsLiisbC4o/2wuKP9sLij/bC4o/2wu
KK5sLigPbC4oAGwuKAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwuKABsLigAbC4oNWwuKNtsLij/bC4o/2wu
KP9sLij9bC4olmwuKAxsLigAbC4oAGwuKAAAAAAAAAAAAAAAAAAAAAAAzZdaAM2XWgDNl1oAzZdaAM2X
WgnNl1oyzZdabc2XWqTNl1rNzZda5s2XWuzNl1ryzZda8c2XWuzNl1rnzZdasMuSUxDozqwV5sunzObL
p//my6f/5sun/+bLp//my6f/5sun/+bLp+rmy6d35sunC+bLpwCzinIAbC4oAGwuKAxsLiiWbC4o/Wwu
KP9sLij/bC4o/2wuKNtsLig1bC4oAGwuKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwu
KABsLihfbC4o8mwuKP9sLij/bC4o/2wuKPhsLiiKbC4oDGwuKABsLigAbC4oAAAAAAAAAAAAAAAAAAAA
AAAAAAAAzZdaAM2XWgDNl1oAzZdaAM2XWgDNl1oHzZdaFM2XWiXNl1o2zZdaSc2XWkfNl1o2zZdaJs2X
WhPIjEkC6tOyAebLp4zmy6f/5sun/+bLp//my6f/5sun/ObLp8Lmy6dJ5sunA+bLpwD/+MsAbC4oAGwu
KAxsLiiKbC4o+GwuKP9sLij/bC4o/2wuKPJsLihfbC4oAGwuKABsLigAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAGwuKABsLigAbC4oBmwuKIJsLij6bC4o/2wuKP9sLij/bC4o+GwuKJZsLigWbC4oAGwu
KABsLigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM2XWgDNl1oAzZdaAM2XWgDNl1oAzZdaAM2X
WgDNl1oAzZdaAM2XWgDNl1oAypBQAObLpwDmy6dK5sun8+bLp//my6f+5sun2ObLp3jmy6cY5sunAOjN
qQBNBggAbC4oAGwuKBZsLiiWbC4o+GwuKP9sLij/bC4o/2wuKPpsLiiCbC4oBmwuKABsLigAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbC4oAGwuKABsLigObC4ommwuKP1sLij/bC4o/2wu
KP9sLij9bC4orGwuKClsLigAbC4oAGwuKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADmy6cA5sunFubLp8Hmy6fL5sundubL
pybmy6cB5sunAP///wBrLScAbC4oAGwuKClsLiisbC4o/WwuKP9sLij/bC4o/2wuKP1sLiiabC4oDmwu
KABsLigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwu
KBRsLiiebC4o/WwuKP9sLij/bC4o/2wuKP9sLijObC4oUWwuKAZsLigAbC4oAGwuKAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5sunAObL
pwPmy6co5sunFubLpwDmy6cA7dSuAGUlIQBsLigAbC4oBmwuKFFsLijObC4o/2wuKP9sLij/bC4o/2wu
KP1sLiiebC4oFGwuKABsLigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAbC4oAGwuKABsLigAbC4oFGwuKJpsLij6bC4o/2wuKP9sLij/bC4o/2wuKPBsLiiSbC4oJ2wu
KABsLigAbC4oAGwuKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAObLpwDmy6cA5sunAObLpwDz27QAaCkkAGwuKABsLigBbC4oKGwuKJJsLijwbC4o/2wu
KP9sLij/bC4o/2wuKPpsLiiabC4oFGwuKABsLigAbC4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwuKABsLigObC4ogmwuKPJsLij/bC4o/2wu
KP9sLij/bC4o/2wuKNhsLih3bC4oI2wuKAFsLigAbC4oAGwuKABsLigAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbC4oAGwuKABsLigAbC4oAGwuKAFsLigjbC4oemwu
KNlsLij/bC4o/2wuKP9sLij/bC4o/2wuKPJsLiiCbC4oDmwuKABsLigAbC4oAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwuKABsLigAbC4oAGwu
KAZsLihfbC4o22wuKP9sLij/bC4o/2wuKP9sLij/bC4o/WwuKNhsLiiJbC4oOmwuKBBsLigAbC4oAGwu
KABsLigAbC4oAGwuKABsLigAAAAAAAAAAABsLigAbC4oAGwuKABsLigAbC4oAGwuKABsLigAbC4oEGwu
KDxsLiiKbC4o12wuKP1sLij/bC4o/2wuKP9sLij/bC4o/2wuKNtsLihfbC4oBmwuKABsLigAbC4oAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAGwuKABsLigAbC4oAGwuKDVsLiiubC4o+GwuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wu
KOxsLii9bC4of2wuKEhsLigibC4oEGwuKAdsLigAbC4oAGwuKABsLigAbC4oAGwuKABsLigHbC4oEGwu
KCJsLihIbC4of2wuKL1sLijtbC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o+GwuKK5sLig1bC4oAGwu
KABsLigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbC4oAGwuKABsLigAbC4oD2wuKGdsLijRbC4o/2wu
KP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLijybC4o4WwuKL9sLiiibC4ojGwuKH9sLiiAbC4ogGwu
KH9sLiiMbC4oomwuKL9sLijhbC4o8mwuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o0Wwu
KGdsLigPbC4oAGwuKABsLigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwu
KABsLigAbC4oImwuKH9sLijXbC4o/WwuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wu
KP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wu
KP1sLijWbC4of2wuKCJsLigAbC4oAGwuKABsLigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABsLigAbC4oAGwuKABsLigBbC4oI2wuKG9sLijAbC4o8GwuKP9sLij/bC4o/2wu
KP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wu
KP9sLij/bC4o8GwuKMBsLihubC4oIWwuKAFsLigAbC4oAGwuKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsLigAbC4oAGwuKABsLigAbC4oEWwu
KEFsLiiBbC4oumwuKORsLij1bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wuKP9sLij/bC4o/2wu
KP9sLij/bC4o9WwuKORsLii6bC4ogWwuKEFsLigRbC4oAGwuKABsLigAbC4oAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABsLigAbC4oAGwuKABsLigAbC4oAGwuKBBsLigvbC4oYWwuKIlsLiiubC4ox2wuKN1sLijjbC4o6mwu
KOpsLijjbC4o3WwuKMdsLiiubC4oiWwuKGFsLigvbC4oEGwuKABsLigAbC4oAGwuKABsLigAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA///AAAAD/////wAAAAD////8AAAAAD////AAAAAAD///4AAAAAAH///AAAAAAAP//wAAAYAA
AP/+AAA//AAAf/wAAB//gAA//AAAH//gAD/4AAAf//gAH/AAAAAB/AAP4AAAAAA+AAfgAAAAAA8AB8AA
AAAAB8ADwAAAAAADwAOAAAAAAADgAYAAAAAAAPABAAAAAAAAeAAAAAAAAAA8AAAAAAAAABwAAAAAAAAA
HgAAAAAAAAAOAAAAAAEAAA8AAAAAAAAADwAAAAAAAAAHAAEAAAAAAAeAAeAAAAAAB4AB4AAAAAAHgAHg
AAAAAAeAAeAAAAAAB4AD4AEAAAAHwAPgAAAAgAfAAeAAAAAAB4AB4AAAAAAHgAHgAAAAAAeAAeAAAAAA
B4AB4AAAAAAAgADgAAAAAAAAAPAAAAAAAAAA8AAAgAAAAABwAAAAAAAAAHgAAAAAAAAAOAAAAAAAAAA8
AAAAAAAAAB4AAAAAAACADwAAAAAAAYAHAAAAAAABwAPAAAAAAAPAA+AAAAAAA+AA8AAAAAAH4AB8AAAA
AAfwAD+AAAAAD/gAH//4AAAf/AAH//gAAD/8AAH/+AAAP/4AAD/8AAB//wAAAYAAAP//wAAAAAAD///g
AAAAAAf///AAAAAAD////AAAAAA/////AAAAAP/////AAAAD//8=
</value>
</data>
</root>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Acc.Demo
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Control.CheckForIllegalCrossThreadCalls = false;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("锐驰点料Demo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Acc Feeder Counter")]
[assembly: AssemblyCopyright("Copyright Acctronics© 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("2f0d362d-2a49-49c4-963d-99f958a616d7")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Acc.Demo.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.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 (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Acc.Demo.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;
}
}
}
}
<?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>
\ No newline at end of file
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Acc.Demo.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.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;
}
}
}
}
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
此文件类型无法预览
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Costura.Fody" version="3.2.0" targetFramework="net40" />
<package id="Fody" version="3.3.2" targetFramework="net40" developmentDependency="true" />
</packages>
\ No newline at end of file

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27703.2035
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "Demo\Demo.csproj", "{2F0D362D-2A49-49C4-963D-99F958A616D7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AccImage", "..\AccImage\AccImage.csproj", "{2626350B-63DA-416C-B72A-7FE7825C3711}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageBox", "ImageBox\ImageBox.csproj", "{DB03ED04-5E06-4FEB-B891-0633448F24EC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2F0D362D-2A49-49C4-963D-99F958A616D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F0D362D-2A49-49C4-963D-99F958A616D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F0D362D-2A49-49C4-963D-99F958A616D7}.Debug|x64.ActiveCfg = Debug|Any CPU
{2F0D362D-2A49-49C4-963D-99F958A616D7}.Debug|x64.Build.0 = Debug|Any CPU
{2F0D362D-2A49-49C4-963D-99F958A616D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F0D362D-2A49-49C4-963D-99F958A616D7}.Release|Any CPU.Build.0 = Release|Any CPU
{2F0D362D-2A49-49C4-963D-99F958A616D7}.Release|x64.ActiveCfg = Release|Any CPU
{2F0D362D-2A49-49C4-963D-99F958A616D7}.Release|x64.Build.0 = Release|Any CPU
{2626350B-63DA-416C-B72A-7FE7825C3711}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2626350B-63DA-416C-B72A-7FE7825C3711}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2626350B-63DA-416C-B72A-7FE7825C3711}.Debug|x64.ActiveCfg = Debug|x64
{2626350B-63DA-416C-B72A-7FE7825C3711}.Debug|x64.Build.0 = Debug|x64
{2626350B-63DA-416C-B72A-7FE7825C3711}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2626350B-63DA-416C-B72A-7FE7825C3711}.Release|Any CPU.Build.0 = Release|Any CPU
{2626350B-63DA-416C-B72A-7FE7825C3711}.Release|x64.ActiveCfg = Release|x64
{2626350B-63DA-416C-B72A-7FE7825C3711}.Release|x64.Build.0 = Release|x64
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Debug|x64.ActiveCfg = Debug|Any CPU
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Debug|x64.Build.0 = Debug|Any CPU
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Release|Any CPU.Build.0 = Release|Any CPU
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Release|x64.ActiveCfg = Release|Any CPU
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AE0B833E-EEE6-4719-952C-7233EA17EC3D}
EndGlobalSection
EndGlobal
此文件类型无法预览
此文件的差异太大,无法显示。
<?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>{DB03ED04-5E06-4FEB-B891-0633448F24EC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ImageBox</RootNamespace>
<AssemblyName>ImageBox</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ImageBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ImageBoxActionSources.cs" />
<Compile Include="ImageBoxBorderStyle.cs" />
<Compile Include="ImageBoxCancelEventArgs.cs" />
<Compile Include="ImageBoxGridDisplayMode.cs" />
<Compile Include="ImageBoxGridScale.cs" />
<Compile Include="ImageBoxNativeMethods.cs" />
<Compile Include="ImageBoxSelectionMode.cs" />
<Compile Include="ImageBoxSizeMode.cs" />
<Compile Include="ImageBoxZoomActions.cs" />
<Compile Include="ImageBoxZoomEventArgs.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ScrollControl.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ScrollProperties.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="VirtualScrollableControl.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ZoomLevelCollection.cs" />
<Compile Include="ZoomLevelCollectionConverter.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="ImageBox.bmp" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
using System;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Specifies the source of an action being performed.
/// </summary>
[Flags]
public enum ImageBoxActionSources
{
/// <summary>
/// Unknown source.
/// </summary>
Unknown = 0,
/// <summary>
/// A user initialized the action.
/// </summary>
User = 1
}
}
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Specifies the border styles of an image
/// </summary>
public enum ImageBoxBorderStyle
{
/// <summary>
/// No border.
/// </summary>
None,
/// <summary>
/// A fixed, single-line border.
/// </summary>
FixedSingle,
/// <summary>
/// A fixed, single-line border with a solid drop shadow.
/// </summary>
FixedSingleDropShadow,
/// <summary>
/// A fixed, single-line border with a soft outer glow.
/// </summary>
FixedSingleGlowShadow
}
}
using System.ComponentModel;
using System.Drawing;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Provides data for a cancelable event.
/// </summary>
public class ImageBoxCancelEventArgs : CancelEventArgs
{
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ImageBoxCancelEventArgs"/> class.
/// </summary>
/// <param name="location">The location of the action being performed.</param>
public ImageBoxCancelEventArgs(Point location)
: this()
{
this.Location = location;
}
#endregion
#region Protected Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ImageBoxCancelEventArgs"/> class.
/// </summary>
protected ImageBoxCancelEventArgs()
{ }
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the location of the action being performed.
/// </summary>
/// <value>The location of the action being performed.</value>
public Point Location { get; protected set; }
#endregion
}
}
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Specifies the display styles for the background texture grid
/// </summary>
public enum ImageBoxGridDisplayMode
{
/// <summary>
/// No background.
/// </summary>
None,
/// <summary>
/// Background is displayed in the control's client area.
/// </summary>
Client,
/// <summary>
/// Background is displayed only in the image region.
/// </summary>
Image
}
}
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Specifies the size of the background texture grid.
/// </summary>
public enum ImageBoxGridScale
{
/// <summary>
/// Displays a solid color
/// </summary>
None,
/// <summary>
/// Half of the default size.
/// </summary>
Tiny,
/// <summary>
/// Default size.
/// </summary>
Small,
/// <summary>
/// 50% increase of default size.
/// </summary>
Medium,
/// <summary>
/// 100% increase of default size.
/// </summary>
Large
}
}
using System;
using System.Runtime.InteropServices;
// ReSharper disable NotAccessedField.Global
// ReSharper disable InconsistentNaming
// ReSharper disable FieldCanBeMadeReadOnly.Global
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable PartialTypeWithSinglePart
internal partial class NativeMethods // partial for when linking this file into other assemblies
// ReSharper restore PartialTypeWithSinglePart
// ReSharper restore ClassNeverInstantiated.Global
{
#region Enums
[Flags]
public enum SIF
{
SIF_RANGE = 0x0001,
SIF_PAGE = 0x0002,
SIF_POS = 0x0004,
SIF_DISABLENOSCROLL = 0x0008,
SIF_TRACKPOS = 0x0010,
SIF_ALL = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS
}
#endregion
#region Constants
public const int GWL_STYLE = (-16);
public const int SB_BOTH = 3;
public const int SB_BOTTOM = 7;
public const int SB_CTL = 2;
public const int SB_ENDSCROLL = 8;
public const int SB_HORZ = 0;
public const int SB_LEFT = 6;
public const int SB_LINEDOWN = 1;
public const int SB_LINELEFT = 0;
public const int SB_LINERIGHT = 1;
public const int SB_LINEUP = 0;
public const int SB_PAGEDOWN = 3;
public const int SB_PAGELEFT = 2;
public const int SB_PAGERIGHT = 3;
public const int SB_PAGEUP = 2;
public const int SB_RIGHT = 7;
public const int SB_THUMBPOSITION = 4;
public const int SB_THUMBTRACK = 5;
public const int SB_TOP = 6;
public const int SB_VERT = 1;
public const int WM_HSCROLL = 0x00000114;
public const int WM_VSCROLL = 0x00000115;
public const int WS_BORDER = 0x00800000;
public const int WS_EX_CLIENTEDGE = 0x200;
public const int WS_HSCROLL = 0x00100000;
public const int WS_VSCROLL = 0x00200000;
#endregion
#region Private Constructors
private NativeMethods()
{ }
#endregion
#region Class Members
[DllImport("user32.dll", SetLastError = true)]
public static extern int GetScrollInfo(IntPtr hwnd, int bar, [MarshalAs(UnmanagedType.LPStruct)] SCROLLINFO scrollInfo);
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
public static extern int SetScrollInfo(IntPtr hwnd, int bar, [MarshalAs(UnmanagedType.LPStruct)] SCROLLINFO scrollInfo, bool redraw);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hwnd, int index, UInt32 newLong);
#endregion
#region Nested Types
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class SCROLLINFO
{
public int cbSize;
public SIF fMask;
public int nMin;
public int nMax;
public int nPage;
public int nPos;
public int nTrackPos;
public SCROLLINFO()
{
cbSize = Marshal.SizeOf(this);
nPage = 0;
nMin = 0;
nMax = 0;
nPos = 0;
nTrackPos = 0;
fMask = 0;
}
}
#endregion
}
// ReSharper restore NotAccessedField.Global
// ReSharper restore FieldCanBeMadeReadOnly.Global
// ReSharper restore InconsistentNaming
}
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Specifies the selection mode.
/// </summary>
public enum ImageBoxSelectionMode
{
/// <summary>
/// No selection.
/// </summary>
None,
/// <summary>
/// Rectangle selection.
/// </summary>
Rectangle,
/// <summary>
/// Zoom selection.
/// </summary>
Zoom
}
}
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Determines the sizing mode of an image hosted in an <see cref="ImageBox" /> control.
/// </summary>
public enum ImageBoxSizeMode
{
/// <summary>
/// The image is disiplayed according to current zoom and scroll properties.
/// </summary>
Normal,
/// <summary>
/// The image is stretched to fill the client area of the control.
/// </summary>
Stretch,
/// <summary>
/// The image is stretched to fill as much of the client area of the control as possible, whilst retaining the same aspect ratio for the width and height.
/// </summary>
Fit
}
}
using System;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Describes the zoom action occuring
/// </summary>
[Flags]
public enum ImageBoxZoomActions
{
/// <summary>
/// No action.
/// </summary>
None = 0,
/// <summary>
/// The control is increasing the zoom.
/// </summary>
ZoomIn = 1,
/// <summary>
/// The control is decreasing the zoom.
/// </summary>
ZoomOut = 2,
/// <summary>
/// The control zoom was reset.
/// </summary>
ActualSize = 4
}
}
using System;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Contains event data for the <see cref="ImageBox.ZoomChanged"/> event.
/// </summary>
public class ImageBoxZoomEventArgs : EventArgs
{
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ImageBoxZoomEventArgs"/> class.
/// </summary>
/// <param name="actions">The zoom operation being performed.</param>
/// <param name="source">The source of the operation.</param>
/// <param name="oldZoom">The old zoom level.</param>
/// <param name="newZoom">The new zoom level.</param>
public ImageBoxZoomEventArgs(ImageBoxZoomActions actions, ImageBoxActionSources source, int oldZoom, int newZoom)
: this()
{
this.Actions = actions;
this.Source = source;
this.OldZoom = oldZoom;
this.NewZoom = newZoom;
}
#endregion
#region Protected Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ImageBoxZoomEventArgs"/> class.
/// </summary>
protected ImageBoxZoomEventArgs()
{ }
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the actions that occured.
/// </summary>
/// <value>The zoom operation.</value>
public ImageBoxZoomActions Actions { get; protected set; }
/// <summary>
/// Gets or sets the new zoom level.
/// </summary>
/// <value>The new zoom level.</value>
public int NewZoom { get; protected set; }
/// <summary>
/// Gets or sets the old zoom level.
/// </summary>
/// <value>The old zoom level.</value>
public int OldZoom { get; protected set; }
/// <summary>
/// Gets or sets the source of the operation..
/// </summary>
/// <value>The source.</value>
public ImageBoxActionSources Source { get; protected set; }
#endregion
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("ImageBox")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ImageBox")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("db03ed04-5e06-4feb-b891-0633448f24ec")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
#if USEWIN32PINVOKELIB
using Cyotek.Win32;
#endif
// Original ScrollControl code by Scott Crawford (http://sukiware.com/)
namespace Cyotek.Windows.Forms
{
/// <summary>
/// Defines a base class for controls that support scrolling behavior.
/// </summary>
[ToolboxItem(false)]
public partial class ScrollControl : Control
{
#region Instance Fields
private bool _alwaysShowHScroll;
private bool _alwaysShowVScroll;
private BorderStyle _borderStyle;
private Size _pageSize;
private Size _scrollSize;
private Size _stepSize;
#endregion
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ScrollControl" /> class.
/// </summary>
public ScrollControl()
{
// ReSharper disable DoNotCallOverridableMethodsInConstructor
this.BorderStyle = BorderStyle.Fixed3D;
this.ScrollSize = Size.Empty;
this.PageSize = Size.Empty;
this.StepSize = new Size(10, 10);
this.HorizontalScroll = new HScrollProperties(this);
this.VerticalScroll = new VScrollProperties(this);
// ReSharper restore DoNotCallOverridableMethodsInConstructor
}
#endregion
#region Events
/// <summary>
/// Occurs when the BorderStyle property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler BorderStyleChanged;
/// <summary>
/// Occurs when the mouse wheel moves while the control has focus.
/// </summary>
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
[Category("Mouse")]
public new event MouseEventHandler MouseWheel;
/// <summary>
/// Occurs when the PageSize property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler PageSizeChanged;
/// <summary>
/// Occurs when the user or code scrolls through the client area.
/// </summary>
[Category("Action")]
public event ScrollEventHandler Scroll;
/// <summary>
/// Occurs when the ScrollSize property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler ScrollSizeChanged;
/// <summary>
/// Occurs when the StepSize property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler StepSizeChanged;
#endregion
#region Overridden Properties
/// <summary>
/// Gets the required creation parameters when the control handle is created.
/// </summary>
/// <value>The create params.</value>
/// <returns>
/// A <see cref="T:System.Windows.Forms.CreateParams" /> that contains the required creation parameters when the handle to the control is created.
/// </returns>
protected override CreateParams CreateParams
{
get
{
CreateParams createParams;
createParams = base.CreateParams;
switch (_borderStyle)
{
case BorderStyle.FixedSingle:
createParams.Style |= NativeMethods.WS_BORDER;
break;
case BorderStyle.Fixed3D:
createParams.ExStyle |= NativeMethods.WS_EX_CLIENTEDGE;
break;
}
return createParams;
}
}
#endregion
#region Overridden Methods
/// <summary>
/// Raises the <see cref="System.Windows.Forms.Control.EnabledChanged" /> event.
/// </summary>
/// <param name="e">
/// An <see cref="T:System.EventArgs" /> that contains the event data.
/// </param>
protected override void OnEnabledChanged(EventArgs e)
{
base.OnEnabledChanged(e);
this.UpdateScrollbars();
}
/// <summary>
/// Raises the <see cref="System.Windows.Forms.Control.MouseDown" /> event.
/// </summary>
/// <param name="e">
/// A <see cref="T:System.Windows.Forms.MouseEventArgs" /> that contains the event data.
/// </param>
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (!this.Focused)
{
this.Focus();
}
}
/// <summary>
/// Raises the <see cref="System.Windows.Forms.Control.MouseWheel" /> event.
/// </summary>
/// <param name="e">
/// A <see cref="T:System.Windows.Forms.MouseEventArgs" /> that contains the event data.
/// </param>
protected override void OnMouseWheel(MouseEventArgs e)
{
MouseEventHandler handler;
if (this.WheelScrollsControl)
{
int x;
int y;
int delta;
x = this.HorizontalScroll.Value;
y = this.VerticalScroll.Value;
// TODO: Find if we are hovering over a horizontal scrollbar and scroll that instead of the default vertical.
if (this.VerticalScroll.Visible && this.VerticalScroll.Enabled)
{
if (ModifierKeys == Keys.Control)
{
delta = this.VerticalScroll.LargeChange;
}
else
{
delta = SystemInformation.MouseWheelScrollLines * this.VerticalScroll.SmallChange;
}
y += (e.Delta > 0) ? -delta : delta;
}
else if (this.HorizontalScroll.Visible && this.HorizontalScroll.Enabled)
{
if (ModifierKeys == Keys.Control)
{
delta = this.HorizontalScroll.LargeChange;
}
else
{
delta = SystemInformation.MouseWheelScrollLines * this.HorizontalScroll.SmallChange;
}
x += (e.Delta > 0) ? -delta : delta;
}
this.ScrollTo(x, y);
}
handler = this.MouseWheel;
if (handler != null)
{
handler(this, e);
}
base.OnMouseWheel(e);
}
/// <summary>
/// Processes Windows messages.
/// </summary>
/// <param name="msg">
/// The Windows <see cref="T:System.Windows.Forms.Message" /> to process.
/// </param>
[DebuggerStepThrough]
protected override void WndProc(ref Message msg)
{
switch (msg.Msg)
{
case NativeMethods.WM_HSCROLL:
case NativeMethods.WM_VSCROLL:
this.WmScroll(ref msg);
break;
default:
base.WndProc(ref msg);
break;
}
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets a value indicating whether the horizontal scrollbar should always be displayed, even when not required.
/// </summary>
/// <value>
/// <c>true</c> if the horizontal scrollbar should always be displayed; otherwise, <c>false</c>.
/// </value>
[Category("Layout")]
[DefaultValue(false)]
public bool AlwaysShowHScroll
{
get { return _alwaysShowHScroll; }
set
{
if (_alwaysShowHScroll != value)
{
_alwaysShowHScroll = value;
if (value)
{
NativeMethods.SCROLLINFO scrollInfo;
scrollInfo = new NativeMethods.SCROLLINFO();
scrollInfo.fMask = NativeMethods.SIF.SIF_RANGE | NativeMethods.SIF.SIF_DISABLENOSCROLL;
scrollInfo.nMin = 0;
scrollInfo.nMax = 0;
scrollInfo.nPage = 1;
this.SetScrollInfo(ScrollOrientation.HorizontalScroll, scrollInfo, false);
this.Invalidate();
}
else
{
this.UpdateHorizontalScrollbar();
}
}
}
}
/// <summary>
/// Gets or sets a value indicating whether the vertical scrollbar should always be displayed, even when not required.
/// </summary>
/// <value>
/// <c>true</c> if the vertical scrollbar should always be displayed; otherwise, <c>false</c>.
/// </value>
[Category("Layout")]
[DefaultValue(false)]
public bool AlwaysShowVScroll
{
get { return _alwaysShowVScroll; }
set
{
bool shown = VScroll;
_alwaysShowVScroll = value;
if (_alwaysShowVScroll != shown)
{
if (_alwaysShowVScroll)
{
NativeMethods.SCROLLINFO scrollInfo;
scrollInfo = new NativeMethods.SCROLLINFO();
scrollInfo.fMask = NativeMethods.SIF.SIF_RANGE | NativeMethods.SIF.SIF_DISABLENOSCROLL;
scrollInfo.nMin = 0;
scrollInfo.nMax = 0;
scrollInfo.nPage = 1;
this.SetScrollInfo(ScrollOrientation.VerticalScroll, scrollInfo, false);
this.Invalidate();
}
else
{
this.UpdateVerticalScrollbar();
}
}
}
}
/// <summary>
/// Gets or sets the border style.
/// </summary>
/// <value>The border style.</value>
[Category("Appearance")]
[DefaultValue(typeof(BorderStyle), "Fixed3D")]
public virtual BorderStyle BorderStyle
{
get { return _borderStyle; }
set
{
if (this.BorderStyle != value)
{
_borderStyle = value;
this.OnBorderStyleChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets the horizontal scrollbar properties.
/// </summary>
/// <value>The horizontal scrollbar properties.</value>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
public HScrollProperties HorizontalScroll { get; protected set; }
/// <summary>
/// Gets or sets the size of the scroll pages.
/// </summary>
/// <value>The size of the page.</value>
/// <exception cref="System.ArgumentOutOfRangeException"></exception>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual Size PageSize
{
get { return _pageSize; }
set
{
if (value.Width < 0)
{
throw new ArgumentOutOfRangeException("value", "Width must be a positive integer.");
}
if (value.Height < 0)
{
throw new ArgumentOutOfRangeException("value", "Height must be a positive integer.");
}
if (this.PageSize != value)
{
_pageSize = value;
this.OnPageSizeChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets or sets the size of the scroll area.
/// </summary>
/// <value>The size of the scroll.</value>
/// <exception cref="System.ArgumentOutOfRangeException"></exception>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual Size ScrollSize
{
get { return _scrollSize; }
set
{
if (value.Width < 0)
{
throw new ArgumentOutOfRangeException("value", "Width must be a positive integer.");
}
if (value.Height < 0)
{
throw new ArgumentOutOfRangeException("value", "Height must be a positive integer.");
}
if (this.ScrollSize != value)
{
_scrollSize = value;
this.OnScrollSizeChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets or sets the size of scrollbar stepping.
/// </summary>
/// <value>The size of the step.</value>
/// <exception cref="System.ArgumentOutOfRangeException"></exception>
[Category("Layout")]
[DefaultValue(typeof(Size), "10, 10")]
public virtual Size StepSize
{
get { return _stepSize; }
set
{
if (value.Width < 0)
{
throw new ArgumentOutOfRangeException("value", "Width must be a positive integer.");
}
if (value.Height < 0)
{
throw new ArgumentOutOfRangeException("value", "Height must be a positive integer.");
}
if (this.StepSize != value)
{
_stepSize = value;
this.OnStepSizeChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets the vertical scrollbar properties.
/// </summary>
/// <value>The vertical scrollbar properties.</value>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
public VScrollProperties VerticalScroll { get; protected set; }
#endregion
#region Protected Properties
/// <summary>
/// Gets or sets a value indicating whether the horizontal scrollbar is displayed
/// </summary>
/// <value>
/// <c>true</c> if the horizontal scrollbar is displayed; otherwise, <c>false</c>.
/// </value>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
protected bool HScroll
{
get { return (NativeMethods.GetWindowLong(this.Handle, NativeMethods.GWL_STYLE) & NativeMethods.WS_HSCROLL) == NativeMethods.WS_HSCROLL; }
set
{
uint longValue = NativeMethods.GetWindowLong(this.Handle, NativeMethods.GWL_STYLE);
if (value)
{
longValue |= NativeMethods.WS_HSCROLL;
}
else
{
unchecked
{
longValue &= (uint)~NativeMethods.WS_HSCROLL;
}
}
NativeMethods.SetWindowLong(this.Handle, NativeMethods.GWL_STYLE, longValue);
}
}
/// <summary>
/// Gets or sets a value indicating whether the vertical scrollbar is displayed
/// </summary>
/// <value>
/// <c>true</c> if the vertical scrollbar is displayed; otherwise, <c>false</c>.
/// </value>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
protected bool VScroll
{
get { return (NativeMethods.GetWindowLong(this.Handle, NativeMethods.GWL_STYLE) & NativeMethods.WS_VSCROLL) == NativeMethods.WS_VSCROLL; }
set
{
uint longValue = NativeMethods.GetWindowLong(this.Handle, NativeMethods.GWL_STYLE);
if (value)
{
longValue |= NativeMethods.WS_VSCROLL;
}
else
{
unchecked
{
longValue &= (uint)~NativeMethods.WS_VSCROLL;
}
}
NativeMethods.SetWindowLong(this.Handle, NativeMethods.GWL_STYLE, longValue);
}
}
/// <summary>
/// Gets or sets a value indicating whether the control is scrolled when the mouse wheel is spun
/// </summary>
/// <value>
/// <c>true</c> if the mouse wheel scrolls the control; otherwise, <c>false</c>.
/// </value>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
protected bool WheelScrollsControl { get; set; }
#endregion
#region Public Members
/// <summary>
/// Scrolls both scrollbars to the given values
/// </summary>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
public void ScrollTo(int x, int y)
{
this.ScrollTo(ScrollOrientation.HorizontalScroll, x);
this.ScrollTo(ScrollOrientation.VerticalScroll, y);
}
#endregion
#region Protected Members
/// <summary>
/// Gets the type of scrollbar event.
/// </summary>
/// <param name="wParam">The wparam value from a window proc.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentException"></exception>
protected ScrollEventType GetEventType(IntPtr wParam)
{
switch (wParam.ToInt32() & 0xFFFF)
{
case NativeMethods.SB_BOTTOM:
return ScrollEventType.Last;
case NativeMethods.SB_ENDSCROLL:
return ScrollEventType.EndScroll;
case NativeMethods.SB_LINEDOWN:
return ScrollEventType.SmallIncrement;
case NativeMethods.SB_LINEUP:
return ScrollEventType.SmallDecrement;
case NativeMethods.SB_PAGEDOWN:
return ScrollEventType.LargeIncrement;
case NativeMethods.SB_PAGEUP:
return ScrollEventType.LargeDecrement;
case NativeMethods.SB_THUMBPOSITION:
return ScrollEventType.ThumbPosition;
case NativeMethods.SB_THUMBTRACK:
return ScrollEventType.ThumbTrack;
case NativeMethods.SB_TOP:
return ScrollEventType.First;
default:
throw new ArgumentException(string.Format("{0} isn't a valid scroll event type.", wParam), "wparam");
}
}
/// <summary>
/// Raises the <see cref="BorderStyleChanged" /> event.
/// </summary>
/// <param name="e">
/// The <see cref="EventArgs" /> instance containing the event data.
/// </param>
protected virtual void OnBorderStyleChanged(EventArgs e)
{
EventHandler handler;
base.UpdateStyles();
handler = this.BorderStyleChanged;
if (handler != null)
{
handler(this, e);
}
}
/// <summary>
/// Raises the <see cref="PageSizeChanged" /> event.
/// </summary>
/// <param name="e">
/// The <see cref="EventArgs" /> instance containing the event data.
/// </param>
protected virtual void OnPageSizeChanged(EventArgs e)
{
EventHandler handler;
this.UpdateScrollbars();
handler = this.PageSizeChanged;
if (handler != null)
{
handler(this, e);
}
}
/// <summary>
/// Raises the <see cref="Scroll" /> event.
/// </summary>
/// <param name="e">
/// The <see cref="ScrollEventArgs" /> instance containing the event data.
/// </param>
protected virtual void OnScroll(ScrollEventArgs e)
{
ScrollEventHandler handler;
this.UpdateHorizontalScroll();
this.UpdateVerticalScroll();
handler = this.Scroll;
if (handler != null)
{
handler(this, e);
}
}
/// <summary>
/// Raises the <see cref="ScrollSizeChanged" /> event.
/// </summary>
/// <param name="e">
/// The <see cref="EventArgs" /> instance containing the event data.
/// </param>
protected virtual void OnScrollSizeChanged(EventArgs e)
{
EventHandler handler;
this.UpdateScrollbars();
handler = this.ScrollSizeChanged;
if (handler != null)
{
handler(this, e);
}
}
/// <summary>
/// Raises the <see cref="StepSizeChanged" /> event.
/// </summary>
/// <param name="e">
/// The <see cref="EventArgs" /> instance containing the event data.
/// </param>
protected virtual void OnStepSizeChanged(EventArgs e)
{
EventHandler handler;
handler = this.StepSizeChanged;
if (handler != null)
{
handler(this, e);
}
}
/// <summary>
/// Set the given scrollbar's tracking position to the specified value
/// </summary>
/// <param name="scrollbar">The scrollbar.</param>
/// <param name="value">The value.</param>
protected virtual void ScrollTo(ScrollOrientation scrollbar, int value)
{
NativeMethods.SCROLLINFO oldInfo;
oldInfo = this.GetScrollInfo(scrollbar);
if (value > ((oldInfo.nMax - oldInfo.nMin) + 1) - oldInfo.nPage)
{
value = ((oldInfo.nMax - oldInfo.nMin) + 1) - oldInfo.nPage;
}
if (value < oldInfo.nMin)
{
value = oldInfo.nMin;
}
if (oldInfo.nPos != value)
{
NativeMethods.SCROLLINFO scrollInfo;
scrollInfo = new NativeMethods.SCROLLINFO();
scrollInfo.fMask = NativeMethods.SIF.SIF_POS;
scrollInfo.nPos = value;
this.SetScrollInfo(scrollbar, scrollInfo, true);
this.OnScroll(new ScrollEventArgs(ScrollEventType.ThumbPosition, oldInfo.nPos, value, scrollbar));
}
}
/// <summary>
/// Updates the properties of the horizontal scrollbar.
/// </summary>
protected virtual void UpdateHorizontalScroll()
{
NativeMethods.SCROLLINFO scrollInfo;
scrollInfo = this.GetScrollInfo(ScrollOrientation.HorizontalScroll);
this.HorizontalScroll.Enabled = this.Enabled;
this.HorizontalScroll.LargeChange = scrollInfo.nPage;
this.HorizontalScroll.Maximum = scrollInfo.nMax;
this.HorizontalScroll.Minimum = scrollInfo.nMin;
this.HorizontalScroll.SmallChange = this.StepSize.Width;
this.HorizontalScroll.Value = scrollInfo.nPos;
this.HorizontalScroll.Visible = true;
}
/// <summary>
/// Updates the horizontal scrollbar.
/// </summary>
protected virtual void UpdateHorizontalScrollbar()
{
NativeMethods.SCROLLINFO scrollInfo;
int scrollWidth;
int pageWidth;
scrollWidth = this.ScrollSize.Width - 1;
pageWidth = this.PageSize.Width;
if (scrollWidth < 1)
{
scrollWidth = 0;
pageWidth = 1;
}
scrollInfo = new NativeMethods.SCROLLINFO();
scrollInfo.fMask = NativeMethods.SIF.SIF_PAGE | NativeMethods.SIF.SIF_RANGE;
if (this.AlwaysShowHScroll || !this.Enabled)
{
scrollInfo.fMask |= NativeMethods.SIF.SIF_DISABLENOSCROLL;
}
scrollInfo.nMin = 0;
scrollInfo.nMax = scrollWidth;
scrollInfo.nPage = pageWidth;
this.SetScrollInfo(ScrollOrientation.HorizontalScroll, scrollInfo, true);
}
/// <summary>
/// Updates the scrollbars.
/// </summary>
protected void UpdateScrollbars()
{
this.UpdateHorizontalScrollbar();
this.UpdateVerticalScrollbar();
}
/// <summary>
/// Updates the properties of the vertical scrollbar.
/// </summary>
protected virtual void UpdateVerticalScroll()
{
NativeMethods.SCROLLINFO scrollInfo;
scrollInfo = this.GetScrollInfo(ScrollOrientation.VerticalScroll);
this.VerticalScroll.Enabled = this.Enabled;
this.VerticalScroll.LargeChange = scrollInfo.nPage;
this.VerticalScroll.Maximum = scrollInfo.nMax;
this.VerticalScroll.Minimum = scrollInfo.nMin;
this.VerticalScroll.SmallChange = this.StepSize.Height;
this.VerticalScroll.Value = scrollInfo.nPos;
this.VerticalScroll.Visible = true;
}
/// <summary>
/// Updates the vertical scrollbar.
/// </summary>
protected virtual void UpdateVerticalScrollbar()
{
NativeMethods.SCROLLINFO scrollInfo;
int scrollHeight;
int pageHeight;
scrollHeight = this.ScrollSize.Height - 1;
pageHeight = this.PageSize.Height;
if (scrollHeight < 1)
{
scrollHeight = 0;
pageHeight = 1;
}
scrollInfo = new NativeMethods.SCROLLINFO();
scrollInfo.fMask = NativeMethods.SIF.SIF_PAGE | NativeMethods.SIF.SIF_RANGE;
if (AlwaysShowVScroll)
{
scrollInfo.fMask |= NativeMethods.SIF.SIF_DISABLENOSCROLL;
}
scrollInfo.nMin = 0;
scrollInfo.nMax = scrollHeight;
scrollInfo.nPage = pageHeight;
this.SetScrollInfo(ScrollOrientation.VerticalScroll, scrollInfo, true);
}
/// <summary>
/// Processes the WM_HSCROLL and WM_VSCROLL Windows messages.
/// </summary>
/// <param name="msg">
/// The Windows <see cref="T:System.Windows.Forms.Message" /> to process.
/// </param>
protected virtual void WmScroll(ref Message msg)
{
ScrollOrientation scrollbar;
int oldValue;
int newValue;
ScrollEventType eventType;
eventType = this.GetEventType(msg.WParam);
scrollbar = msg.Msg == NativeMethods.WM_HSCROLL ? ScrollOrientation.HorizontalScroll : ScrollOrientation.VerticalScroll;
if (eventType != ScrollEventType.EndScroll)
{
int step;
NativeMethods.SCROLLINFO scrollInfo;
step = scrollbar == ScrollOrientation.HorizontalScroll ? this.StepSize.Width : this.StepSize.Height;
scrollInfo = this.GetScrollInfo(scrollbar);
scrollInfo.fMask = NativeMethods.SIF.SIF_POS;
oldValue = scrollInfo.nPos;
switch (eventType)
{
case ScrollEventType.ThumbPosition:
case ScrollEventType.ThumbTrack:
scrollInfo.nPos = scrollInfo.nTrackPos;
break;
case ScrollEventType.SmallDecrement:
scrollInfo.nPos = oldValue - step;
break;
case ScrollEventType.SmallIncrement:
scrollInfo.nPos = oldValue + step;
break;
case ScrollEventType.LargeDecrement:
scrollInfo.nPos = oldValue - scrollInfo.nPage;
break;
case ScrollEventType.LargeIncrement:
scrollInfo.nPos = oldValue + scrollInfo.nPage;
break;
case ScrollEventType.First:
scrollInfo.nPos = scrollInfo.nMin;
break;
case ScrollEventType.Last:
scrollInfo.nPos = scrollInfo.nMax;
break;
default:
Debug.Assert(false, string.Format("Unknown scroll event type {0}", eventType));
break;
}
if (scrollInfo.nPos > ((scrollInfo.nMax - scrollInfo.nMin) + 1) - scrollInfo.nPage)
{
scrollInfo.nPos = ((scrollInfo.nMax - scrollInfo.nMin) + 1) - scrollInfo.nPage;
}
if (scrollInfo.nPos < scrollInfo.nMin)
{
scrollInfo.nPos = scrollInfo.nMin;
}
newValue = scrollInfo.nPos;
this.SetScrollInfo(scrollbar, scrollInfo, true);
}
else
{
oldValue = 0;
newValue = 0;
}
this.OnScroll(new ScrollEventArgs(eventType, oldValue, newValue, scrollbar));
}
#endregion
#region Private Members
/// <summary>
/// Gets scrollbar properties
/// </summary>
/// <param name="scrollbar">The bar.</param>
/// <returns></returns>
private NativeMethods.SCROLLINFO GetScrollInfo(ScrollOrientation scrollbar)
{
NativeMethods.SCROLLINFO info;
info = new NativeMethods.SCROLLINFO();
info.fMask = NativeMethods.SIF.SIF_ALL;
NativeMethods.GetScrollInfo(this.Handle, (int)scrollbar, info);
return info;
}
/// <summary>
/// Sets scrollbar properties.
/// </summary>
/// <param name="scrollbar">The scrollbar.</param>
/// <param name="scrollInfo">The scrollbar properties.</param>
/// <param name="refresh">
/// if set to <c>true</c> the scrollbar will be repainted.
/// </param>
/// <returns></returns>
// ReSharper disable UnusedMethodReturnValue.Local
private int SetScrollInfo(ScrollOrientation scrollbar, NativeMethods.SCROLLINFO scrollInfo, bool refresh) // ReSharper restore UnusedMethodReturnValue.Local
{
return NativeMethods.SetScrollInfo(this.Handle, (int)scrollbar, scrollInfo, refresh);
}
#endregion
}
}
using System.ComponentModel;
// Original ScrollControl code by Scott Crawford (http://sukiware.com/)
namespace Cyotek.Windows.Forms
{
partial class ScrollControl
{
#region Nested Types
/// <summary>
/// Provides basic properties for the horizontal scroll bar in a <see cref="ScrollControl"/>.
/// </summary>
public class HScrollProperties : ScrollProperties
{
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ScrollProperties" /> class.
/// </summary>
/// <param name="container">The <see cref="ScrollControl" /> whose scrolling properties this object describes.</param>
public HScrollProperties(ScrollControl container)
: base(container)
{ }
#endregion
}
/// <summary>
/// Encapsulates properties related to scrolling.
/// </summary>
public abstract class ScrollProperties
{
#region Instance Fields
private readonly ScrollControl _container;
#endregion
#region Protected Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ScrollProperties"/> class.
/// </summary>
/// <param name="container">The <see cref="ScrollControl"/> whose scrolling properties this object describes.</param>
protected ScrollProperties(ScrollControl container)
{
//System.Windows.Forms.ScrollProperties
_container = container;
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets whether the scroll bar can be used on the container.
/// </summary>
/// <value><c>true</c> if the scroll bar can be used; otherwise, <c>false</c>.</value>
[DefaultValue(true)]
public bool Enabled { get; set; }
/// <summary>
/// Gets or sets the distance to move a scroll bar in response to a large scroll command.
/// </summary>
/// <value>An <see cref="int"/> describing how far, in pixels, to move the scroll bar in response to a large change.</value>
[DefaultValue(10)]
public int LargeChange { get; set; }
/// <summary>
/// Gets or sets the upper limit of the scrollable range.
/// </summary>
/// <value>An <see cref="int"/> representing the maximum range of the scroll bar.</value>
[DefaultValue(100)]
public int Maximum { get; set; }
/// <summary>
/// Gets or sets the lower limit of the scrollable range.
/// </summary>
/// <value>An <see cref="int"/> representing the lower range of the scroll bar.</value>
[DefaultValue(0)]
public int Minimum { get; set; }
/// <summary>
/// Gets the control to which this scroll information applies.
/// </summary>
/// <value>A <see cref="ScrollControl"/>.</value>
public ScrollControl ParentControl
{
get { return _container; }
}
/// <summary>
/// Gets or sets the distance to move a scroll bar in response to a small scroll command.
/// </summary>
/// <value>An <see cref="int"/> representing how far, in pixels, to move the scroll bar.</value>
[DefaultValue(1)]
public int SmallChange { get; set; }
/// <summary>
/// Gets or sets a numeric value that represents the current position of the scroll bar box.
/// </summary>
/// <value>An <see cref="int"/> representing the position of the scroll bar box, in pixels. </value>
[Bindable(true)]
[DefaultValue(0)]
public int Value { get; set; }
/// <summary>
/// Gets or sets whether the scroll bar can be seen by the user.
/// </summary>
/// <value><c>true</c> if it can be seen; otherwise, <c>false</c>.</value>
[DefaultValue(false)]
public bool Visible { get; set; }
#endregion
}
/// <summary>
/// Provides basic properties for the vertical scroll bar in a <see cref="ScrollControl"/>.
/// </summary>
public class VScrollProperties : ScrollProperties
{
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ScrollProperties" /> class.
/// </summary>
/// <param name="container">The <see cref="ScrollControl" /> whose scrolling properties this object describes.</param>
public VScrollProperties(ScrollControl container)
: base(container)
{ }
#endregion
}
#endregion
}
}
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
// Original VirtualScrollableControl code by Scott Crawford (http://sukiware.com/)
namespace Cyotek.Windows.Forms
{
/// <summary>
/// Defines a base class for controls that support auto-scrolling behavior.
/// </summary>
[ToolboxItem(false)]
public class VirtualScrollableControl : ScrollControl
{
#region Instance Fields
private bool _autoScroll;
private Size _autoScrollMargin;
private Size _autoScrollMinSize;
private Point _autoScrollPosition;
#endregion
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="VirtualScrollableControl" /> class.
/// </summary>
public VirtualScrollableControl()
{
this.AutoScrollMargin = Size.Empty;
this.AutoScrollMinSize = Size.Empty;
this.AutoScrollPosition = Point.Empty;
this.AutoScroll = true;
base.SetStyle(ControlStyles.ContainerControl, true);
}
#endregion
#region Events
/// <summary>
/// Occurs when the AutoScroll property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler AutoScrollChanged;
/// <summary>
/// Occurs when the AutoScrollMargin property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler AutoScrollMarginChanged;
/// <summary>
/// Occurs when the AutoScrollMinSize property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler AutoScrollMinSizeChanged;
/// <summary>
/// Occurs when the AutoScrollPosition property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler AutoScrollPositionChanged;
#endregion
#region Overridden Methods
/// <summary>
/// Raises the <see cref="System.Windows.Forms.Control.Resize" /> event.
/// </summary>
/// <param name="e">
/// An <see cref="T:System.EventArgs" /> that contains the event data.
/// </param>
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.AdjustScrollbars();
if (this.AutoScroll && !this.AutoScrollPosition.IsEmpty)
{
int xOffset;
int yOffset;
Rectangle scrollArea;
scrollArea = this.ScrollArea;
xOffset = scrollArea.Right - this.DisplayRectangle.Right;
yOffset = scrollArea.Bottom - this.DisplayRectangle.Bottom;
if (this.AutoScrollPosition.Y < 0 && yOffset < 0)
{
yOffset = Math.Max(yOffset, this.AutoScrollPosition.Y);
}
else
{
yOffset = 0;
}
if (this.AutoScrollPosition.X < 0 && xOffset < 0)
{
xOffset = Math.Max(xOffset, this.AutoScrollPosition.X);
}
else
{
xOffset = 0;
}
this.ScrollByOffset(new Size(xOffset, yOffset));
}
}
/// <summary>
/// Raises the <see cref="ScrollControl.Scroll" /> event.
/// </summary>
/// <param name="e">
/// The <see cref="ScrollEventArgs" /> instance containing the event data.
/// </param>
protected override void OnScroll(ScrollEventArgs e)
{
if (e.Type != ScrollEventType.EndScroll)
{
switch (e.ScrollOrientation)
{
case ScrollOrientation.HorizontalScroll:
this.ScrollByOffset(new Size(e.NewValue + this.AutoScrollPosition.X, 0));
break;
case ScrollOrientation.VerticalScroll:
this.ScrollByOffset(new Size(0, e.NewValue + this.AutoScrollPosition.Y));
break;
}
}
base.OnScroll(e);
}
/// <summary>
/// Raises the <see cref="System.Windows.Forms.Control.VisibleChanged" /> event.
/// </summary>
/// <param name="e">
/// An <see cref="T:System.EventArgs" /> that contains the event data.
/// </param>
protected override void OnVisibleChanged(EventArgs e)
{
if (base.Visible)
{
base.PerformLayout();
}
base.OnVisibleChanged(e);
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets a value indicating whether the container enables the user to scroll to any controls placed outside of its visible boundaries.
/// </summary>
/// <value>
/// <c>true</c> if the container enables auto-scrolling; otherwise, <c>false</c>.
/// </value>
[Category("Layout")]
[DefaultValue(true)]
public virtual bool AutoScroll
{
get { return _autoScroll; }
set
{
if (this.AutoScroll != value)
{
_autoScroll = value;
this.OnAutoScrollChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets or sets the size of the auto-scroll margin.
/// </summary>
/// <value>
/// A <see cref="T:System.Drawing.Size" /> that represents the height and width of the auto-scroll margin in pixels.
/// </value>
/// <exception cref="System.ArgumentOutOfRangeException"></exception>
[Category("Layout")]
[DefaultValue(typeof(Size), "0, 0")]
public virtual Size AutoScrollMargin
{
get { return _autoScrollMargin; }
set
{
if (value.Width < 0)
{
throw new ArgumentOutOfRangeException("value", "Width must be a positive integer.");
}
else if (value.Height < 0)
{
throw new ArgumentOutOfRangeException("value", "Height must be a positive integer.");
}
if (this.AutoScrollMargin != value)
{
_autoScrollMargin = value;
this.OnAutoScrollMarginChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets or sets the minimum size of the auto-scroll.
/// </summary>
/// <value>
/// A <see cref="T:System.Drawing.Size" /> that determines the minimum size of the virtual area through which the user can scroll.
/// </value>
[Category("Layout")]
[DefaultValue(typeof(Size), "0, 0")]
public virtual Size AutoScrollMinSize
{
get { return _autoScrollMinSize; }
set
{
if (this.AutoScrollMinSize != value)
{
_autoScrollMinSize = value;
this.OnAutoScrollMinSizeChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets or sets the location of the auto-scroll position.
/// </summary>
/// <value>
/// A <see cref="T:System.Drawing.Point" /> that represents the auto-scroll position in pixels.
/// </value>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual Point AutoScrollPosition
{
get { return _autoScrollPosition; }
set
{
Point translated;
translated = this.AdjustPositionToSize(new Point(-value.X, -value.Y));
if (this.AutoScrollPosition != translated)
{
this.ScrollByOffset(new Size(_autoScrollPosition.X - translated.X, _autoScrollPosition.Y - translated.Y));
_autoScrollPosition = translated;
this.OnAutoScrollPositionChanged(EventArgs.Empty);
}
}
}
#endregion
#region Protected Properties
/// <summary>
/// Total area of all visible controls which are scrolled with this container
/// </summary>
protected Rectangle ScrollArea
{
get
{
Rectangle area;
area = Rectangle.Empty;
foreach (Control child in Controls)
{
if (child.Visible)
{
area = Rectangle.Union(child.Bounds, area);
}
}
return Rectangle.Union(area, new Rectangle(_autoScrollPosition, _autoScrollMinSize));
}
}
/// <summary>
/// Gets the view port rectangle.
/// </summary>
/// <value>The view port rectangle.</value>
protected Rectangle ViewPortRectangle
{
get { return new Rectangle(-_autoScrollPosition.X, -_autoScrollPosition.Y, this.DisplayRectangle.Width, this.DisplayRectangle.Height); }
}
#endregion
#region Public Members
/// <summary>
/// Scrolls the specified child control into view on an auto-scroll enabled control.
/// </summary>
/// <param name="activeControl">The child control to scroll into view.</param>
public void ScrollControlIntoView(Control activeControl)
{
if (activeControl.Visible && AutoScroll && (HorizontalScroll.Visible || VerticalScroll.Visible))
{
Point position;
position = this.AdjustPositionToSize(new Point(this.AutoScrollPosition.X + activeControl.Left, this.AutoScrollPosition.Y + activeControl.Top));
if (position.X != this.AutoScrollPosition.X || position.Y != this.AutoScrollPosition.Y)
{
this.ScrollByOffset(new Size(this.AutoScrollPosition.X - position.X, this.AutoScrollPosition.Y - position.Y));
}
}
}
#endregion
#region Protected Members
/// <summary>
/// Adjusts the given Point according to the scroll size
/// </summary>
/// <param name="position">The position.</param>
/// <returns></returns>
protected Point AdjustPositionToSize(Point position)
{
int x;
int y;
x = position.X;
y = position.Y;
if (x < -(this.AutoScrollMinSize.Width - this.ClientRectangle.Width))
{
x = -(this.AutoScrollMinSize.Width - this.ClientRectangle.Width);
}
if (y < -(this.AutoScrollMinSize.Height - this.ClientRectangle.Height))
{
y = -(this.AutoScrollMinSize.Height - base.ClientRectangle.Height);
}
if (x > 0)
{
x = 0;
}
if (y > 0)
{
y = 0;
}
return new Point(x, y);
}
/// <summary>
/// Raises the <see cref="AutoScrollChanged" /> event.
/// </summary>
/// <param name="e">
/// The <see cref="EventArgs" /> instance containing the event data.
/// </param>
protected virtual void OnAutoScrollChanged(EventArgs e)
{
EventHandler handler;
handler = this.AutoScrollChanged;
if (handler != null)
{
handler(this, e);
}
}
/// <summary>
/// Raises the <see cref="AutoScrollMarginChanged" /> event.
/// </summary>
/// <param name="e">
/// The <see cref="EventArgs" /> instance containing the event data.
/// </param>
protected virtual void OnAutoScrollMarginChanged(EventArgs e)
{
EventHandler handler;
handler = this.AutoScrollMarginChanged;
if (handler != null)
{
handler(this, e);
}
}
/// <summary>
/// Raises the <see cref="AutoScrollMinSizeChanged" /> event.
/// </summary>
/// <param name="e">
/// The <see cref="EventArgs" /> instance containing the event data.
/// </param>
protected virtual void OnAutoScrollMinSizeChanged(EventArgs e)
{
EventHandler handler;
this.AutoScrollPosition = this.AdjustPositionToSize(this.AutoScrollPosition);
this.AdjustScrollbars();
handler = this.AutoScrollMinSizeChanged;
if (handler != null)
{
handler(this, e);
}
}
/// <summary>
/// Raises the <see cref="AutoScrollPositionChanged" /> event.
/// </summary>
/// <param name="e">
/// The <see cref="EventArgs" /> instance containing the event data.
/// </param>
protected virtual void OnAutoScrollPositionChanged(EventArgs e)
{
EventHandler handler;
handler = this.AutoScrollPositionChanged;
if (handler != null)
{
handler(this, e);
}
}
#endregion
#region Private Members
/// <summary>
/// Adjusts the scrollbars.
/// </summary>
private void AdjustScrollbars()
{
Rectangle clientRectangle;
Size scrollSize;
Size pageSize;
int horzAddition;
int vertAddition;
bool horizontalScrollVisible;
bool verticalScrollVisible;
clientRectangle = this.ClientRectangle;
scrollSize = new Size();
pageSize = new Size();
horzAddition = 0;
vertAddition = 0;
horizontalScrollVisible = false;
verticalScrollVisible = false;
if (this.AutoScroll && (this.AutoScrollMinSize.Height > clientRectangle.Height || this.AutoScrollMinSize.Width > clientRectangle.Width))
{
int i;
for (i = 0; i < 2; i++)
{
if (this.AutoScrollMinSize.Width > (clientRectangle.Width - vertAddition))
{
horizontalScrollVisible = true;
horzAddition = SystemInformation.VerticalScrollBarWidth;
}
if (this.AutoScrollMinSize.Height > (clientRectangle.Height - horzAddition))
{
verticalScrollVisible = true;
vertAddition = SystemInformation.HorizontalScrollBarHeight;
}
}
}
if (verticalScrollVisible)
{
scrollSize.Height = this.AutoScrollMinSize.Height;
if (clientRectangle.Height > horzAddition)
{
pageSize.Height = clientRectangle.Height - horzAddition;
}
}
if (horizontalScrollVisible)
{
scrollSize.Width = this.AutoScrollMinSize.Width;
if (clientRectangle.Width > vertAddition)
{
pageSize.Width = clientRectangle.Width - vertAddition;
}
}
this.ScrollSize = scrollSize;
this.PageSize = pageSize;
}
/// <summary>
/// Scrolls child controls by the given offset
/// </summary>
/// <param name="offset">The offset.</param>
private void ScrollByOffset(Size offset)
{
if (!offset.IsEmpty)
{
this.SuspendLayout();
foreach (Control child in Controls)
{
child.Location -= offset;
}
_autoScrollPosition = new Point(_autoScrollPosition.X - offset.Width, _autoScrollPosition.Y - offset.Height);
this.ScrollTo(-_autoScrollPosition.X, -_autoScrollPosition.Y);
this.ResumeLayout();
this.Invalidate();
}
}
#endregion
};
} ;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Cyotek.Windows.Forms
{
/// <summary>
/// Represents available levels of zoom in an <see cref="ImageBox"/> control
/// </summary>
public class ZoomLevelCollection : IList<int>
{
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ZoomLevelCollection"/> class.
/// </summary>
public ZoomLevelCollection()
{
this.List = new SortedList<int, int>();
}
/// <summary>
/// Initializes a new instance of the <see cref="ZoomLevelCollection"/> class.
/// </summary>
/// <param name="collection">The default values to populate the collection with.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the <c>collection</c> parameter is null</exception>
public ZoomLevelCollection(IEnumerable<int> collection)
: this()
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
this.AddRange(collection);
}
#endregion
#region Class Properties
/// <summary>
/// Returns the default zoom levels
/// </summary>
public static ZoomLevelCollection Default
{
get
{
return new ZoomLevelCollection(new[]
{
7, 10, 15, 20, 25, 30, 50, 70, 100, 150, 200, 300, 400, 500, 600, 700, 800, 1200, 1600
});
}
}
#endregion
#region Public Properties
/// <summary>
/// Gets the number of elements contained in the <see cref="ZoomLevelCollection" />.
/// </summary>
/// <returns>
/// The number of elements contained in the <see cref="ZoomLevelCollection" />.
/// </returns>
public int Count
{
get { return this.List.Count; }
}
/// <summary>
/// Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only.
/// </summary>
/// <value><c>true</c> if this instance is read only; otherwise, <c>false</c>.</value>
/// <returns>true if the <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only; otherwise, false.
/// </returns>
public bool IsReadOnly
{
get { return false; }
}
/// <summary>
/// Gets or sets the zoom level at the specified index.
/// </summary>
/// <param name="index">The index.</param>
public int this[int index]
{
get { return this.List.Values[index]; }
set
{
this.List.RemoveAt(index);
this.Add(value);
}
}
#endregion
#region Protected Properties
/// <summary>
/// Gets or sets the backing list.
/// </summary>
protected SortedList<int, int> List { get; set; }
#endregion
#region Public Members
/// <summary>
/// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
/// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
public void Add(int item)
{
this.List.Add(item, item);
}
/// <summary>
/// Adds a range of items to the <see cref="ZoomLevelCollection"/>.
/// </summary>
/// <param name="collection">The items to add to the collection.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the <c>collection</c> parameter is null.</exception>
public void AddRange(IEnumerable<int> collection)
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
foreach (int value in collection)
{
this.Add(value);
}
}
/// <summary>
/// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
public void Clear()
{
this.List.Clear();
}
/// <summary>
/// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1" /> contains a specific value.
/// </summary>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
/// <returns>true if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false.</returns>
public bool Contains(int item)
{
return this.List.ContainsKey(item);
}
/// <summary>
/// Copies a range of elements this collection into a destination <see cref="Array"/>.
/// </summary>
/// <param name="array">The <see cref="Array"/> that receives the data.</param>
/// <param name="arrayIndex">A 64-bit integer that represents the index in the <see cref="Array"/> at which storing begins.</param>
public void CopyTo(int[] array, int arrayIndex)
{
for (int i = 0; i < this.Count; i++)
{
array[arrayIndex + i] = this.List.Values[i];
}
}
/// <summary>
/// Finds the index of a zoom level matching or nearest to the specified value.
/// </summary>
/// <param name="zoomLevel">The zoom level.</param>
public int FindNearest(int zoomLevel)
{
int nearestValue = this.List.Values[0];
int nearestDifference = Math.Abs(nearestValue - zoomLevel);
for (int i = 1; i < this.Count; i++)
{
int value = this.List.Values[i];
int difference = Math.Abs(value - zoomLevel);
if (difference < nearestDifference)
{
nearestValue = value;
nearestDifference = difference;
}
}
return nearestValue;
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.</returns>
public IEnumerator<int> GetEnumerator()
{
return this.List.Values.GetEnumerator();
}
/// <summary>
/// Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1" />.
/// </summary>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1" />.</param>
/// <returns>The index of <paramref name="item" /> if found in the list; otherwise, -1.</returns>
public int IndexOf(int item)
{
return this.List.IndexOfKey(item);
}
/// <summary>
/// Not implemented.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="item">The item.</param>
/// <exception cref="System.NotImplementedException">Not implemented</exception>
public void Insert(int index, int item)
{
throw new NotImplementedException();
}
/// <summary>
/// Returns the next increased zoom level for the given current zoom.
/// </summary>
/// <param name="zoomLevel">The current zoom level.</param>
/// <returns>The next matching increased zoom level for the given current zoom if applicable, otherwise the nearest zoom.</returns>
public int NextZoom(int zoomLevel)
{
int index;
index = this.IndexOf(this.FindNearest(zoomLevel));
if (index < this.Count - 1)
{
index++;
}
return this[index];
}
/// <summary>
/// Returns the next decreased zoom level for the given current zoom.
/// </summary>
/// <param name="zoomLevel">The current zoom level.</param>
/// <returns>The next matching decreased zoom level for the given current zoom if applicable, otherwise the nearest zoom.</returns>
public int PreviousZoom(int zoomLevel)
{
int index;
index = this.IndexOf(this.FindNearest(zoomLevel));
if (index > 0)
{
index--;
}
return this[index];
}
/// <summary>
/// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
/// <returns>true if <paramref name="item" /> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false. This method also returns false if <paramref name="item" /> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1" />.</returns>
public bool Remove(int item)
{
return this.List.Remove(item);
}
/// <summary>
/// Removes the element at the specified index of the <see cref="ZoomLevelCollection"/>.
/// </summary>
/// <param name="index">The zero-based index of the element to remove.</param>
public void RemoveAt(int index)
{
this.List.RemoveAt(index);
}
/// <summary>
/// Copies the elements of the <see cref="ZoomLevelCollection"/> to a new array.
/// </summary>
/// <returns>An array containing copies of the elements of the <see cref="ZoomLevelCollection"/>.</returns>
public int[] ToArray()
{
int[] results;
results = new int[this.Count];
this.CopyTo(results, 0);
return results;
}
#endregion
#region IList<int> Members
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>An <see cref="ZoomLevelCollection" /> object that can be used to iterate through the collection.</returns>
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms
{
public class ZoomLevelCollectionConverter
: TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
string data;
ZoomLevelCollection result;
data = value as string;
if (!string.IsNullOrEmpty(data))
{
char separator;
string[] items;
TypeConverter converter;
if (culture == null)
culture = CultureInfo.CurrentCulture;
result = new ZoomLevelCollection();
separator = culture.TextInfo.ListSeparator[0];
items = data.Split(separator);
converter = TypeDescriptor.GetConverter(typeof(int));
foreach (string item in items)
result.Add((int)converter.ConvertFromString(context, culture, item));
}
else
result = null;
return result;
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
object result;
if (destinationType == null)
throw new ArgumentNullException("destinationType");
if (value is ZoomLevelCollection)
{
if (destinationType == typeof(string))
{
ZoomLevelCollection collection;
StringBuilder data;
string separator;
TypeConverter converter;
collection = (ZoomLevelCollection)value;
if (culture == null)
culture = CultureInfo.CurrentCulture;
separator = culture.TextInfo.ListSeparator + " ";
converter = TypeDescriptor.GetConverter(typeof(int));
data = new StringBuilder();
foreach (int item in collection)
{
if (data.Length != 0)
data.Append(separator);
data.Append(converter.ConvertToString(context, culture, item));
}
result = data.ToString();
}
else if (destinationType == typeof(InstanceDescriptor))
{
ZoomLevelCollection collection;
ConstructorInfo constructor;
collection = (ZoomLevelCollection)value;
constructor = typeof(ZoomLevelCollection).GetConstructor(new Type[] { typeof(IList<int>) });
result = new InstanceDescriptor(constructor, new object[] { collection.ToArray() });
}
else
result = null;
}
else
result = null;
if (result == null)
result = base.ConvertTo(context, culture, value, destinationType);
return result;
}
}
}
此文件太大,无法显示。
此文件太大,无法显示。
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<dllmap dll="OpenCvSharpExtern" target="libOpenCvSharpExtern.so" />
</configuration>
\ No newline at end of file
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!