加入專案檔案。

This commit is contained in:
JEFF 2025-01-18 14:03:40 +08:00
parent 550e6cfc2b
commit 261eddd350
13 changed files with 1222 additions and 0 deletions

25
WindowsFormsApp1.sln Normal file
View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.34916.146
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormsApp1", "WindowsFormsApp1\WindowsFormsApp1.csproj", "{9126E2B4-E759-4070-BEC2-E81E8E3DC6AA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9126E2B4-E759-4070-BEC2-E81E8E3DC6AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9126E2B4-E759-4070-BEC2-E81E8E3DC6AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9126E2B4-E759-4070-BEC2-E81E8E3DC6AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9126E2B4-E759-4070-BEC2-E81E8E3DC6AA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9F9BD2E3-07E9-4EBE-AAD0-7D84442D1888}
EndGlobalSection
EndGlobal

View File

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

299
WindowsFormsApp1/Basler.cs Normal file
View File

@ -0,0 +1,299 @@
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Basler.Pylon;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
namespace WindowsFormsApp1
{
public class Basler
{
private readonly Form1 form;
public Basler(Form1 form)
{
this.form = form;
}
//連接相機各數
public int CameraNumber = CameraFinder.Enumerate().Count;
// 共享的鎖
private readonly object lockObject = new object();
//委託+事件=回調函數,用於傳遞相機抓取的圖像
public delegate void CameraImage(Bitmap bmp, int cameraIndex);
public event CameraImage CameraImageEvent;
//委託+事件=回調函數,用於傳遞相機抓取的圖像
//public delegate void CameraImage1(Bitmap bmp1);
//public event CameraImage1 CameraImageEvent1;
// 創建一個列表來儲存所有的相機
List<Camera> allCameras = new List<Camera>();
//Basler裡將相機採集到的圖像轉換成位圖
PixelDataConverter pxConvert = new PixelDataConverter();
//控制相機採集圖片的過程!
public bool Graber;
public bool freed;
public bool trigger;
//第一步初始化相機 所用的cameras里的事件然后绑定自己寫好的事件
public void CameraInit()
{
// 獲取所有可用相機的列表
List<ICameraInfo> allCameraInfos = CameraFinder.Enumerate();
// 創建一個字典來儲存每個相機的識別碼和相機物件
Dictionary<string, Camera> cameras = new Dictionary<string, Camera>();
foreach (ICameraInfo cameraInfo in allCameraInfos)
{
// 創建一個新的相機物件
Camera camera0 = new Camera(cameraInfo);
// 獲取相機的識別碼
string id = camera0.CameraInfo[CameraInfoKey.SerialNumber];
Console.WriteLine(id);
// 將相機物件儲存到字典中
cameras[id] = camera0;
}
Graber = true;
freed = true;
//相當於初始化了一下相機的動態鏈庫 可以調用Camera裡面的東西
// 清空 allCameras 列表
allCameras.Clear();
// 將字典中的所有相機添加到列表中
foreach (string id in cameras.Keys)
{
allCameras.Add(cameras[id]);
}
// 為每個相機設定事件處理程序
for (int i = 0; i < allCameras.Count; i++)
{
//自由連接模式
//當連接到像機自動適應此配置
//打开後添加到Basler.Pylon.ICamera中。
allCameras[i].CameraOpened += Configuration.AcquireContinuous;
//抓取开始事件
allCameras[i].StreamGrabber.GrabStarted += StreamGrabber_GrabStarted;
//抓取圖片事件
//allCameras[i].StreamGrabber.ImageGrabbed += (sender, e) => StreamGrabber_ImageGrabbed(sender, e, i);
//打开相機
allCameras[i].Open();
}
}
/// <summary>
/// 斷開連接
/// </summary>
public void Close()
{
for (int i = 0; i < allCameras.Count; i++)
{
//停止連接
allCameras[i].StreamGrabber.Stop();
}
//釋放相機資源
DestroyCamera();
}
/// <summary>
/// 擷取圖片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
// 創建一個Bitmap類型的陣列來存儲影像
private readonly Bitmap[] images;
// 定義一個可以存放 IGrabResult 物件的陣列
private readonly IGrabResult[] grabResults;
private void StreamGrabber_ImageGrabbed(object sender, ImageGrabbedEventArgs e, int cameraIndex)
{
lock (lockObject)
{
IGrabResult grabResult = e.GrabResult;
if (grabResult.IsValid && Graber)
{
//委托就用到了!
CameraImageEvent(GrabResult2Bmp(grabResult), cameraIndex);
}
}
}
//private void StreamGrabber_ImageGrabbed1(object sender, ImageGrabbedEventArgs e)
//{
// lock (lockObject)
// {
// IGrabResult grabResult1 = e.GrabResult;
// if (grabResult1.IsValid && Graber)
// {
// // 將 IGrabResult 物件存入陣列
// grabResults[1] = grabResult1;
// // 在需要時轉換為 Bitmap 物件
// images[1] = GrabResult2Bmp(grabResults[1]);
// //委托就用到了!
// CameraImageEvent1(images[1]);
// }
// }
//}
/// <summary>
/// 開始擷取
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StreamGrabber_GrabStarted(object sender, EventArgs e)
{
Graber = true;
}
/// <summary>
/// 釋放相機
/// </summary>
public void DestroyCamera()
{
if (freed == true)
{
for (int i = 0; i < allCameras.Count; i++)
{
allCameras[i].Close();
allCameras[i].Dispose();
}
freed = false;
Graber = false;
trigger = false;
MessageBox.Show("相機已斷開連接");
}
else
{
return;
}
}
/// <summary>
/// 將相機圖相轉成Bitmap
/// </summary>
/// <param name="grabResult"></param>
/// <returns></returns>
Bitmap GrabResult2Bmp(IGrabResult grabResult)
{
// PixelFormat format:新的像素格式 System.Drawing.Bitmap。 这必须指定一个值,开头 Format。(参1:图宽参2:图高参3:像素格式)
Bitmap b = new Bitmap(grabResult.Width, grabResult.Height, PixelFormat.Format32bppArgb);
//BitmapData:指定位图像的属性
BitmapData bitmapData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, b.PixelFormat);
//PixelType.BGRA8packed:抓取结果返回像素类型,由图像处理支持类使用
pxConvert.OutputPixelFormat = PixelType.BGRA8packed;
IntPtr bmpIntpr = bitmapData.Scan0;
pxConvert.Convert(bmpIntpr, bitmapData.Stride * b.Height, grabResult);
b.UnlockBits(bitmapData);
return b;
}
public void judge(int i)
{
if (trigger == false)
{
trigger = true;
allCameras[i].StreamGrabber.ImageGrabbed += (sender, e) => StreamGrabber_ImageGrabbed(sender, e, i);
}
else
{
return;
}
}
public void OneShot(int i)
{
judge(i);
if (Graber == true)
{
if (i<CameraNumber)
{
//PLCamera:所有可用于basler摄像机设备dByStre的参数名称列表 SingleFrame启用单帧采集模式。
allCameras[i].Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.SingleFrame);
allCameras[i].StreamGrabber.Start(1, GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);
}
else
{
MessageBox.Show("請確保連接相機數量!!");
}
}
else
{
MessageBox.Show("請連接相機!!");
}
}
public void KeepShot(int i)
{
judge(i);
if (i == 0)
{
form.button3.Enabled = true;
}
else if (i == 1)
{
form.button7.Enabled = true;
}
if (Graber == true)
{
if (i < CameraNumber)
{
//Continuous啟用連續採集模式。
allCameras[i].Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous);
//camera.StreamGrabber.Start(GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);
lock (lockObject)
{
//GrabStrategy.OneByOne:默認抓取策略
//GrabLoop.ProvidedByStreamGrabber:定義額外線呈的使用
allCameras[i].StreamGrabber.Start(GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);
}
}
else
{
MessageBox.Show("請確保連接相機數量!!");
}
}
else
{
MessageBox.Show("請連接相機!!");
}
}
public void Stop(int i)
{
if (allCameras != null)
{
if (i < CameraNumber)
{
//擷取停止
allCameras[i].StreamGrabber.Stop();
}
else
{
MessageBox.Show("請確保連接相機數量!!");
}
}
else
{
MessageBox.Show("該相機已停止擷取");
}
}
}
}

261
WindowsFormsApp1/Form1.Designer.cs generated Normal file
View File

@ -0,0 +1,261 @@
namespace WindowsFormsApp1
{
partial class Form1
{
/// <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 Form
/// <summary>
/// 此為設計工具支援所需的方法 - 請勿使用程式碼編輯器修改
/// 這個方法的內容。
/// </summary>
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button();
this.button1 = new System.Windows.Forms.Button();
this.button5 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.textBox1 = new System.Windows.Forms.TextBox();
this.pictureBox2 = new System.Windows.Forms.PictureBox();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.button6 = new System.Windows.Forms.Button();
this.button7 = new System.Windows.Forms.Button();
this.button8 = new System.Windows.Forms.Button();
this.pictureBox3 = new System.Windows.Forms.PictureBox();
this.pictureBox4 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Location = new System.Drawing.Point(257, 139);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(405, 297);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox1.TabIndex = 1;
this.pictureBox1.TabStop = false;
//
// button2
//
this.button2.Location = new System.Drawing.Point(334, 101);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(103, 32);
this.button2.TabIndex = 2;
this.button2.Text = "拍一張照";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.Enabled = false;
this.button3.Location = new System.Drawing.Point(566, 101);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(104, 30);
this.button3.TabIndex = 3;
this.button3.Text = "停止";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// button4
//
this.button4.Location = new System.Drawing.Point(447, 101);
this.button4.Name = "button4";
this.button4.Size = new System.Drawing.Size(113, 30);
this.button4.TabIndex = 4;
this.button4.Text = "連續拍";
this.button4.UseVisualStyleBackColor = true;
this.button4.Click += new System.EventHandler(this.button4_Click);
//
// button1
//
this.button1.Location = new System.Drawing.Point(230, 15);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(98, 47);
this.button1.TabIndex = 5;
this.button1.Text = "斷開連接";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button5
//
this.button5.Location = new System.Drawing.Point(12, 12);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(98, 50);
this.button5.TabIndex = 6;
this.button5.Text = "相機連接";
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.button5_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(117, 15);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(65, 12);
this.label1.TabIndex = 7;
this.label1.Text = "相機連接數";
//
// textBox1
//
this.textBox1.Enabled = false;
this.textBox1.Location = new System.Drawing.Point(116, 40);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 22);
this.textBox1.TabIndex = 8;
//
// pictureBox2
//
this.pictureBox2.Location = new System.Drawing.Point(697, 139);
this.pictureBox2.Name = "pictureBox2";
this.pictureBox2.Size = new System.Drawing.Size(405, 297);
this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox2.TabIndex = 9;
this.pictureBox2.TabStop = false;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("標楷體", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(136)));
this.label2.Location = new System.Drawing.Point(232, 101);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(96, 27);
this.label2.TabIndex = 10;
this.label2.Text = "相機一";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("標楷體", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(136)));
this.label3.Location = new System.Drawing.Point(692, 103);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(96, 27);
this.label3.TabIndex = 11;
this.label3.Text = "相機二";
//
// button6
//
this.button6.Location = new System.Drawing.Point(907, 101);
this.button6.Name = "button6";
this.button6.Size = new System.Drawing.Size(115, 23);
this.button6.TabIndex = 14;
this.button6.Text = "連續拍";
this.button6.UseVisualStyleBackColor = true;
this.button6.Click += new System.EventHandler(this.button6_Click);
//
// button7
//
this.button7.Enabled = false;
this.button7.Location = new System.Drawing.Point(1026, 101);
this.button7.Name = "button7";
this.button7.Size = new System.Drawing.Size(106, 23);
this.button7.TabIndex = 13;
this.button7.Text = "停止";
this.button7.UseVisualStyleBackColor = true;
this.button7.Click += new System.EventHandler(this.button7_Click);
//
// button8
//
this.button8.Location = new System.Drawing.Point(794, 101);
this.button8.Name = "button8";
this.button8.Size = new System.Drawing.Size(105, 25);
this.button8.TabIndex = 12;
this.button8.Text = "拍一張照";
this.button8.UseVisualStyleBackColor = true;
this.button8.Click += new System.EventHandler(this.button8_Click);
//
// pictureBox3
//
this.pictureBox3.Location = new System.Drawing.Point(257, 442);
this.pictureBox3.Name = "pictureBox3";
this.pictureBox3.Size = new System.Drawing.Size(405, 297);
this.pictureBox3.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox3.TabIndex = 15;
this.pictureBox3.TabStop = false;
//
// pictureBox4
//
this.pictureBox4.Location = new System.Drawing.Point(697, 442);
this.pictureBox4.Name = "pictureBox4";
this.pictureBox4.Size = new System.Drawing.Size(405, 297);
this.pictureBox4.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox4.TabIndex = 16;
this.pictureBox4.TabStop = false;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1137, 756);
this.Controls.Add(this.pictureBox4);
this.Controls.Add(this.pictureBox3);
this.Controls.Add(this.button6);
this.Controls.Add(this.button7);
this.Controls.Add(this.button8);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.pictureBox2);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.label1);
this.Controls.Add(this.button5);
this.Controls.Add(this.button1);
this.Controls.Add(this.button4);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.pictureBox1);
this.Name = "Form1";
this.Text = "Form1";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed);
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Button button2;
public System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button4;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.PictureBox pictureBox2;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button button6;
public System.Windows.Forms.Button button7;
private System.Windows.Forms.Button button8;
private System.Windows.Forms.PictureBox pictureBox3;
private System.Windows.Forms.PictureBox pictureBox4;
}
}

140
WindowsFormsApp1/Form1.cs Normal file
View File

@ -0,0 +1,140 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Basler.Pylon;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
//public class DoubleBufferedPictureBox : PictureBox
//{
// public DoubleBufferedPictureBox()
// {
// this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
// this.UpdateStyles();
// }
//}
private readonly Basler Basler;
// 定義一個 PictureBox 的列表
public List<PictureBox> pictureBoxes;
public Form1()
{
InitializeComponent();
//// 使用自定義的PictureBox類
//DoubleBufferedPictureBox pictureBox1 = new DoubleBufferedPictureBox();
//DoubleBufferedPictureBox pictureBox2 = new DoubleBufferedPictureBox();
Basler = new Basler(this);
Basler.CameraImageEvent += Camera_CameraImageEvent;
//Basler.CameraImageEvent1 += Camera_CameraImageEvent1;
// 在構造函數中初始化 pictureBoxes 列表
pictureBoxes = new List<PictureBox> { pictureBox1, pictureBox2 /*, 其他 PictureBox 控件 */ };
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button5_Click(object sender, EventArgs e)
{
textBox1.Text = Basler.CameraNumber.ToString();
//如果连接相机个数大于0的话 初始化之前写的CameraInit();
if (Basler.CameraNumber > 0)
{
Basler.CameraInit();
}
else
{
MessageBox.Show("未連接到相機");
Unable();
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
Basler.DestroyCamera();
pictureBox1.Image?.Dispose();
pictureBox2.Image?.Dispose();
}
void Unable()
{
this.button1.Enabled = false;
this.button2.Enabled = false;
this.button3.Enabled = false;
this.button4.Enabled = false;
}
private void Camera_CameraImageEvent(Bitmap bmp, int cameraIndex)
{
// 確保 cameraIndex 不超出範圍
if (cameraIndex >= 0 && cameraIndex < pictureBoxes.Count)
{
// 根據 cameraIndex 決定要更新哪個 pictureBox
PictureBox pictureBoxToUpdate = pictureBoxes[cameraIndex];
//使用委托进行跨线程交互 防止线程卡死状态在Invoke前面加一个Begin
pictureBoxToUpdate.BeginInvoke(new MethodInvoker(delegate
{
Bitmap old = pictureBoxToUpdate.Image as Bitmap;
pictureBoxToUpdate.Image = bmp;
if (old != null)
old.Dispose();
}));
}
else
{
Console.WriteLine($"無效的相機索引:{cameraIndex}");
}
}
private void button2_Click(object sender, EventArgs e)
{
Basler.OneShot(0);
}
private void button8_Click(object sender, EventArgs e)
{
Basler.OneShot(1);
}
private void button3_Click(object sender, EventArgs e)
{
Basler.Stop(0);
button3.Enabled = false;
button4.Enabled = true;
button2.Enabled = true;
}
private void button7_Click(object sender, EventArgs e)
{
Basler.Stop(1);
button7.Enabled = false;
button6.Enabled = true;
button8.Enabled = true;
}
private void button4_Click(object sender, EventArgs e)
{
Basler.KeepShot(0);
button4.Enabled = false;
button2.Enabled = false;
}
private void button6_Click(object sender, EventArgs e)
{
Basler.KeepShot(1);
button6.Enabled = false;
button8.Enabled = false;
}
private void button1_Click(object sender, EventArgs e)
{
Basler.Close();
}
}
}

120
WindowsFormsApp1/Form1.resx Normal file
View File

@ -0,0 +1,120 @@
<?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>
</root>

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
internal static class Program
{
/// <summary>
/// 應用程式的主要進入點。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 組件的一般資訊是由下列的屬性集控制。
// 變更這些屬性的值即可修改組件的相關
// 資訊。
[assembly: AssemblyTitle("WindowsFormsApp1")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WindowsFormsApp1")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 將 ComVisible 設為 false 可對 COM 元件隱藏
// 組件中的類型。若必須從 COM 存取此組件中的類型,
// 的類型,請在該類型上將 ComVisible 屬性設定為 true。
[assembly: ComVisible(false)]
// 下列 GUID 為專案公開 (Expose) 至 COM 時所要使用的 typelib ID
[assembly: Guid("9126e2b4-e759-4070-bec2-e81e8e3dc6aa")]
// 組件的版本資訊由下列四個值所組成:
//
// 主要版本
// 次要版本
// 組建編號
// 修訂編號
//
// 您可以指定所有的值,也可以使用 '*' 將組建和修訂編號
// 設為預設,如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 這段程式碼是由工具產生的。
// 執行階段版本:4.0.30319.42000
//
// 變更這個檔案可能會導致不正確的行為,而且如果已重新產生
// 程式碼,則會遺失變更。
// </auto-generated>
//------------------------------------------------------------------------------
namespace WindowsFormsApp1.Properties
{
/// <summary>
/// 用於查詢當地語系化字串等的強類型資源類別
/// </summary>
// 這個類別是自動產生的,是利用 StronglyTypedResourceBuilder
// 類別透過 ResGen 或 Visual Studio 這類工具產生。
// 若要加入或移除成員,請編輯您的 .ResX 檔,然後重新執行 ResGen
// (利用 /str 選項),或重建您的 VS 專案。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// 傳回這個類別使用的快取的 ResourceManager 執行個體。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WindowsFormsApp1.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;
}
}
}
}

View File

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

View File

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

View File

@ -0,0 +1,7 @@
<?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>

View File

@ -0,0 +1,88 @@
<?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>{9126E2B4-E759-4070-BEC2-E81E8E3DC6AA}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>WindowsFormsApp1</RootNamespace>
<AssemblyName>WindowsFormsApp1</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Basler.Pylon, Version=1.2.0.0, Culture=neutral, PublicKeyToken=e389355f398382ab, processorArchitecture=AMD64">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\Windows\Microsoft.NET\assembly\GAC_64\Basler.Pylon\v4.0_1.2.0.0__e389355f398382ab\Basler.Pylon.dll</HintPath>
</Reference>
<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="Basler.cs" />
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.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>
</Compile>
<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>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>