Classes
Class | Description | |
---|---|---|
DataInfo | データ情報 | |
DataObject<(Of <(<'TYPE>)>)> | データオブジェクト | |
ParserEventArgs | 画像処理イベント引数クラス | |
ParserInfo | 画像処理アプリケーション構成情報 | |
ParserNode | 画像処理ノード (基本クラス) | |
ParserNodeFolder | 画像処理ノード (フォルダ) ※WIL-Builder プラグイン対応 | |
ParserNodeUnit | 画像処理ノード (基本ユニット) ※WIL-Builder プラグイン対応 | |
ParserProperty | 画像処理処理ノードのプロパティ | |
ParserThread | 画像処理アプリケーションスレッド | |
SharedData | 共有データ |
Interfaces
Interface | Description | |
---|---|---|
IAuxCamera | カメラ初期化パラメータインターフェース | |
IAuxDio | デジタル入出力インターフェース | |
IAuxGrabber | イメージグラバーインターフェース | |
IAuxSerialPort | シリアル通信インターフェース | |
IAuxTcpClient | TCP/IP 通信クライアントインターフェース | |
IAuxTcpServer | TCP/IP 通信サーバーインターフェース | |
IAuxUdpClient | UDP 通信クライアントインターフェース | |
IDataObject<(Of <(<'TYPE>)>)> | データインターフェース | |
IParserEntryPoint | プラグインエントリポイントインターフェース | |
IParserNodeFeatures | 実装する機能の説明を取得するインターフェース | |
IParserNodeIndexer | データ配列指標を持つノードのインターフェース | |
IParserNodeInstance | インスタンスを保有するノードのインターフェース | |
IParserNodeMode | 処理モードを持つノードのインターフェース | |
IParserNodePropertyDialog | プロパティダイアログを持つノードのインターフェース | |
IParserNodeRemarks | ノードと入出力の説明を取得するインターフェース | |
IParserNodeScope | スコープを持つノードのインターフェース | |
IParserNodeStatisticsCtrl | 統計コントロールを持つノードのインターフェース | |
IParserNodeVisibleLevel | ノードの描画処理の可視属性のインターフェース | |
IParserPropertyDenyDisposing | ノード入出力プロパティの解放の拒否インターフェース | |
IStatisticsCtrl | 統計コントロールインターフェース |
Delegates
Delegate | Description | |
---|---|---|
ParserEventHandler | 画像処理完了イベントのデリゲート |
Enumerations
Enumeration | Description | |
---|---|---|
EventReason | イベント発生理由 | |
IndexMode | データ指標モード | |
SavingLevel | 保存レベル | |
VisibleLevel | 可視レベル |
Remarks
このネームスペースには、画像処理アプリケーションを容易に開発するためのフレームワークを集約しています。
トピック:
構成:
画像処理アプリケーションをモデル化すると下記の3つの要素で構成されます。
- ユーザーインターフェース
- 外部機器の実装部分
- 画像処理の実装部分
主要なクラスは以下の3つ(橙色の矩形)です。
下図はクラス間の依存関係を示します。矢印が依存方向です。
クラス | 概要 |
---|---|
ParserThread |
画像処理スレッドです。 後述の画像処理ノードを周期処理するために使用します。 ユーザーが .NET Framework の BackgroundWorker を使用して 周期処理をする事とほぼ等価ですが、 周期処理の実行回数の管理など、僅かにコーディングの手間を省けます。 |
ParserInfo |
外部機器の構成情報を管理するクラスです。 このクラスは XML ファイルから構成情報を読み込み各デバイスの初期化を行います。 内部には各デバイスのコントローラを監視するスレッドを保有しており、 デバイスの状態変化(例:取り込み完了、割り込み発生、データ受信等)をイベントによって ユーザーアプリケーションに通知する仕組みになっています。 通常、構成情報の復元やデバイスの初期化/監視処理をユーザーアプリケーションに実装するには 膨大なコーディングを必要としますので、このクラスを使用する事でコード量を低減することができます。 現在のところ、イメージグラバー・デジタル入出力・シリアル通信・TCP/IP通信・UDP通信に対応しています。 関連: FVIL.Imaging, FVIL.IO, FVIL.Ports, FVIL.Net |
ParserNode |
画像処理を実装する為の基本クラスです。 本ライブラリでは、画像処理ノードと呼称しています。 ユーザーはこのクラスの派生クラスを作成し 独自の画像処理を実装することで本フレームワークで動作させることができます。 派生クラスのひな型は WIL-Builder (評価アプリケーション) のソースコード生成機能を 使用すると容易に作成することができます。 |
コンポーネント図 (ParserThread):
下図は ParserThread の構造を示します。
- Setup/Dispose によってスレッドの初期化/解放が行えます。
- Start/Stop/Abort でスレッドの開始/停止/中断が行えます。
- スレッド実行中は、画像処理ノードを繰り返し実行します。
コンポーネント図 (ParserInfo):
下図は ParserInfo の構造を示します。
- Load/Save によって外部機器の構成情報の読み込みと保存が行えます。
- Setup/Dispose で内部のデバイスコントローラの初期化と解放が行えます。
- インターフェースを介して内部のデバイスコントローラを操作できます。
関連:
IAuxCamera
IAuxGrabber
IAuxDio
IAuxSerialPort
IAuxTcpServer
IAuxTcpClient
IAuxUdpClient
Examples
サンプルコード:
具体的な実装方法を示します。
目次:
1. プロジェクトの準備
本プロジェクトは、3つのソースコード(Program.cs, MainForm.cs, ParserNodeUser.cs)で構成されます。
(参照設定については、ここでは省略します。チュートリアルを参考にしてください。)
また、実行時には、構成情報を保存した ParserInfo.xml を使用します。
本例では、ParserInfo.xml と ParserNodeUser.cs を WIL-Builder で下図(1-b, 1-c)のように構築して生成しています。
図1-a) プロジェクト:
図1-b) WIL-Builder - Data タブ:
ParserInfo.xml は、下図 で設定した外部機器構成を保存したものです。
ここでは、イメージグラバー・デジタル入出力・シリアル通信のみを接続しています。
このファイルは、WIL-Builder の File メニューの『 Save Configuration 』で生成できます。
図1-c) WIL-Builder - Task タブ:
ParserNodeUser.cs は 下図 で構築した画像処理ワークフローをソースコードに変換したものです。
このファイルは、WIL-Builder の File メニューの『 Save Source Code 』で生成できます。
2. ParserNodeUser (画像処理)
下記は WIL-Builder のソースコード生成機能で出力した画像処理フローです。 (※ Execute メソッド以外のメソッドは本例では使用しないので削除しています。) カメラから画像を1枚取り込んで QR コード認識し、デコードした文字列をシリアル通信で送信しています。 この例で使用している外部機器はイメージグラバーとシリアル通信だけですが、 デジタル入出力を使用する場合は他の外部機器と同様に ParserInfo をインターフェースにキャストすることで操作できます。 外部機器のインターフェースは、IAux プレフィックスが付加されたものです。 イメージグラバーの場合は IAuxGrabber、 シリアル通信の場合は IAuxSerialPort、 デジタル入出力の場合は IAuxDio インターフェースを使用します。
C# | Copy |
---|---|
namespace FVIL.Parser { using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Reflection; using System.ComponentModel; using System.Windows.Forms; using System.Runtime.Serialization; using System.Security.Permissions; using System.Globalization; using fvalgcli; [System.SerializableAttribute()] [System.ComponentModel.TypeConverterAttribute(typeof(System.ComponentModel.ExpandableObjectConverter))] public partial class ParserNodeUser : FVIL.Parser.ParserNodeUnit { /// <summary> /// コンストラクタ. /// </summary> public ParserNodeUser() { } /// <summary> /// コンストラクタ. /// </summary> protected ParserNodeUser(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } /// <summary> /// 実行 (1回分の画像処理を記述します。ParserThread から繰り返し呼ばれます。) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public override void Execute(object sender, System.EventArgs e) { FVIL.Data.CFviImage target1_out0 = new FVIL.Data.CFviImage(640, 480, FVIL.ImageType.RGB32, 1); FVIL.Data.CFviImage target2_out0 = new FVIL.Data.CFviImage(640, 480, FVIL.ImageType.UC8, 1); FVIL.QR.CFviQRResult target3_out0 = new FVIL.QR.CFviQRResult(); FVIL.QR.CFviQRData target4_out0 = new FVIL.QR.CFviQRData(); FVIL.Data.CFviPoint target4_out1 = new FVIL.Data.CFviPoint(279.59361580612148, 345.94194954668984); int target4_out2 = 29; string target4_out3 = "http://m.jtad.jp/w/?s=50220585091739"; double target4_out4 = 4.203502996971773; int target4_out5 = 4; int target4_out6 = 430; int target4_out7 = 4; // 画像取り込み (同期)#1 FVIL.Imaging.GrabberThread target1 = ((FVIL.Parser.IAuxGrabber)(ParserInfo)).Threads[0]; ((FVIL.Imaging.IGrabImageSync)(target1)).Grab(target1_out0); // 濃淡化#1 FVIL.Conversion.CFviGrayScale target2 = new FVIL.Conversion.CFviGrayScale(); target2.SrcImages[0] = target1_out0; target2.DstImages[0] = target2_out0; target2.CoefficientBlue = 0.114; target2.CoefficientGreen = 0.587; target2.CoefficientRed = 0.299; target2_out0.Depth = 8; target2.Execute(); // QRコード認識#1 FVIL.QR.CFviQR target3 = new FVIL.QR.CFviQR(); target3.SrcImages[0] = target2_out0; target3.Result = target3_out0; target3.Param.BinThreshold = 128; target3.Param.BinMethod = FVIL.QR.BinMethod.Average; target3.Param.EffortLevel = FVIL.QR.EffortLevel.Maximum; target3.Param.MinVar = 1000; target3.Param.WindowSize = 11; target3.Execute(); // QRコードデータ#1 target4_out0.CopyFrom(target3_out0[0]); target4_out1 = target4_out0.Center; target4_out2 = target4_out0.Size; target4_out3 = target4_out0.Text; target4_out4 = target4_out0.MinCellWidth; target4_out5 = target4_out0.ApptsCount; target4_out6 = target4_out0.CellOnesCount; target4_out7 = target4_out0.DelimitingPtsCount; // シリアル通信 (送信)#1 System.IO.Ports.SerialPort target5 = ((FVIL.Parser.IAuxSerialPort)(ParserInfo)).Ports[0]; target5.WriteLine(target4_out3.ToString()); } } } |
Visual Basic | Copy |
---|---|
Imports System.Collections.Generic Imports System.Text Imports System.Drawing Imports System.Reflection Imports System.ComponentModel Imports System.Windows.Forms Imports System.Runtime.Serialization Imports System.Security.Permissions Imports System.Globalization Imports fvalgcli Imports FVIL.Parser <System.SerializableAttribute()> _ <System.ComponentModel.TypeConverterAttribute(GetType(System.ComponentModel.ExpandableObjectConverter))> _ Partial Public Class ParserNodeUser Inherits FVIL.Parser.ParserNodeUnit ''' <summary> ''' コンストラクタ ''' </summary> Public Sub New() End Sub ''' <summary> ''' コンストラクタ ''' </summary> Protected Sub New(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext) MyBase.New(info, context) End Sub ''' <summary> ''' 実行(1回分の画像処理を記述します。ParserThread から繰り返し呼ばれます。) ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Public Overrides Sub Execute(ByVal sender As Object, ByVal e As System.EventArgs) Dim target1_out0 As New FVIL.Data.CFviImage(640, 480, FVIL.ImageType.RGB32, 1) Dim target2_out0 As New FVIL.Data.CFviImage(640, 480, FVIL.ImageType.UC8, 1) Dim target3_out0 As New FVIL.QR.CFviQRResult() Dim target4_out0 As New FVIL.QR.CFviQRData() Dim target4_out1 As New FVIL.Data.CFviPoint(279.593615806121, 345.94194954669) Dim target4_out2 As Integer = 29 Dim target4_out3 As String = "http://m.jtad.jp/w/?s=50220585091739" Dim target4_out4 As Double = 4.20350299697177 Dim target4_out5 As Integer = 4 Dim target4_out6 As Integer = 430 Dim target4_out7 As Integer = 4 ' 画像取り込み (同期)#1 Dim target1 As FVIL.Imaging.GrabberThread = DirectCast(ParserInfo, FVIL.Parser.IAuxGrabber).Threads(0) DirectCast(target1, FVIL.Imaging.IGrabImageSync).Grab(target1_out0) ' 濃淡化#1 Dim target2 As New FVIL.Conversion.CFviGrayScale() target2.SrcImages(0) = target1_out0 target2.DstImages(0) = target2_out0 target2.CoefficientBlue = 0.114 target2.CoefficientGreen = 0.587 target2.CoefficientRed = 0.299 target2_out0.Depth = 8 target2.Execute() ' QRコード認識#1 Dim target3 As New FVIL.QR.CFviQR() target3.SrcImages(0) = target2_out0 target3.Result = target3_out0 target3.Param.BinThreshold = 128 target3.Param.BinMethod = FVIL.QR.BinMethod.Average target3.Param.EffortLevel = FVIL.QR.EffortLevel.Maximum target3.Param.MinVar = 1000 target3.Param.WindowSize = 11 target3.Execute() ' QRコードデータ#1 target4_out0.CopyFrom(target3_out0(0)) target4_out1 = target4_out0.Center target4_out2 = target4_out0.Size target4_out3 = target4_out0.Text target4_out4 = target4_out0.MinCellWidth target4_out5 = target4_out0.ApptsCount target4_out6 = target4_out0.CellOnesCount target4_out7 = target4_out0.DelimitingPtsCount ' シリアル通信 (送信)#1 Dim target5 As System.IO.Ports.SerialPort = DirectCast(ParserInfo, FVIL.Parser.IAuxSerialPort).Ports(0) target5.WriteLine(target4_out3.ToString()) End Sub End Class |
3. Program (初期化)
- 構成情報の初期化:
Load メソッドで ParserInfo.xml を読み込み、Setup メソッドで初期化しています。 (※ParserInfo.xml の生成は、WIL-Builder を使用してください。生成された XML は下記を参照ください。) この時、XML の内容に従って各デバイスのオープンを行い、デバイスコントローラの監視スレッドを起動します。 - 画像処理スレッドの初期化:
Setup メソッドで初期化しています。この時点でスレッドが待機状態になります。 この他、ParserInfo/ParserNode プロパティにインスタンスを設定する必要があります。 このスレッドは、ParserInfo/ParserNode プロパティを介してデバイスの操作や 画像処理ノードの開始/停止を行います。 - 画像処理ノードの初期化:
Setup メソッドで初期化しています。(※注:本例では SetupOverlay を省略しています。) この他、ParserInfo プロパティにインスタンスを設定する必要があります。 画像処理ノードに実装した処理でデバイスの操作を行うために必要です。
C# | Copy |
---|---|
using System; using System.Collections.Generic; using System.Windows.Forms; namespace SampleCode { static class Program { /// <summary> /// アプリケーションのメイン エントリ ポイントです. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // ライブラリの初期化. FVIL._SetUp.InitVisionLibrary(); FVIL._SetUp.AppPath = System.IO.Directory.GetCurrentDirectory(); try { // 構成情報の初期化. string config_file = "ParserInfo.xml"; if (System.IO.File.Exists(config_file)) Defs.ParserInfo.Load(config_file); Defs.ParserInfo.Setup(); // 画像処理スレッドの初期化. Defs.ParserThread.Setup(); Defs.ParserThread.ParserInfo = Defs.ParserInfo; Defs.ParserThread.ParserNode = Defs.ParserNode; // 画像処理ノードの初期化. Defs.ParserNode.Setup(); Defs.ParserNode.ParserInfo = Defs.ParserInfo; MainForm form = new MainForm(); Application.Run(form); } finally { // 解放. Defs.ParserThread.Dispose(); Defs.ParserInfo.Dispose(); Defs.ParserNode.Dispose(); } } } static class Defs { /// <summary> /// 画像処理スレッド. /// </summary> static public FVIL.Parser.ParserThread ParserThread = new FVIL.Parser.ParserThread(); /// <summary> /// 画像処理ノード. /// </summary> static public FVIL.Parser.ParserNodeUser ParserNode = new FVIL.Parser.ParserNodeUser(); /// <summary> /// 画像処理アプリケーション構成情報. /// </summary> static public FVIL.Parser.ParserInfo ParserInfo = new FVIL.Parser.ParserInfo(); } } |
Visual Basic | Copy |
---|---|
Imports System.Collections.Generic Imports System.Windows.Forms NotInheritable Class Program Private Sub New() End Sub ''' <summary> ''' アプリケーションのメイン エントリ ポイントです。 ''' </summary> <STAThread> _ Friend Shared Sub Main() Application.EnableVisualStyles() Application.SetCompatibleTextRenderingDefault(False) ' ライブラリの初期化. FVIL._SetUp.InitVisionLibrary() FVIL._SetUp.AppPath = System.IO.Directory.GetCurrentDirectory() Try ' 構成情報の初期化. Dim config_file As String = "ParserInfo.xml" If System.IO.File.Exists(config_file) Then Defs.ParserInfo.Load(config_file) End If Defs.ParserInfo.Setup() ' 画像処理スレッドの初期化. Defs.ParserThread.Setup() Defs.ParserThread.ParserInfo = Defs.ParserInfo Defs.ParserThread.ParserNode = Defs.ParserNode ' 画像処理ノードの初期化. Defs.ParserNode.Setup() Defs.ParserNode.ParserInfo = Defs.ParserInfo Dim form As New MainForm() Application.Run(form) Finally ' 解放. Defs.ParserThread.Dispose() Defs.ParserInfo.Dispose() Defs.ParserNode.Dispose() End Try End Sub End Class NotInheritable Class Defs Private Sub New() End Sub ''' <summary> ''' 画像処理スレッド ''' </summary> Public Shared ParserThread As New FVIL.Parser.ParserThread() ''' <summary> ''' 画像処理ノード ''' </summary> Public Shared ParserNode As New FVIL.Parser.ParserNodeUser() ''' <summary> ''' 画像処理アプリケーション構成情報 ''' </summary> Public Shared ParserInfo As New FVIL.Parser.ParserInfo() End Class |
ParserInfo.xml
Xml | Copy |
---|---|
<?xml version="1.0" encoding="utf-8"?> <ParserInfo> <Description /> <Passcode /> <IsAuto>false</IsAuto> <IsFullscreen>false</IsFullscreen> <IsMaintenance>false</IsMaintenance> <ImageSavingDir>images</ImageSavingDir> <ImageSavingLevel>Error</ImageSavingLevel> <ImageSavingMax>30</ImageSavingMax> <DataInfos /> <CameraParams /> <GrabberInfos> <GrabberInfo> <ConfigFile>C:\FAST\WIL\3.0.0\CameraFiles\DS\DS_USB0.xml</ConfigFile> <BufferNum>2</BufferNum> <PluginAssembly /> <PluginClassName /> <SimulatorFile /> <SimulatorFileMode>Normal</SimulatorFileMode> <SimulatorOption>Auto</SimulatorOption> <Commands /> </GrabberInfo> </GrabberInfos> <DioInfos> <DioInfo> <Kind>II320</Kind> <DeviceID>0</DeviceID> <PluginAssembly /> <PluginClassName /> <SimulatorOption>Auto</SimulatorOption> <Commands> <string>InterruptEdge=Rise</string> </Commands> <BitAssignDI /> <BitAssignDO /> </DioInfo> </DioInfos> <SerialPortInfos> <SerialPortInfo> <PortName>COM11</PortName> <BaudRate>9600</BaudRate> <Parity>None</Parity> <DataBits>8</DataBits> <StopBits>One</StopBits> <Handshake>None</Handshake> <NewLine>CR</NewLine> <ReadBufferSize>4096</ReadBufferSize> <ReadTimeout>500</ReadTimeout> <ReceivedBytesThreshold>1</ReceivedBytesThreshold> <WriteBufferSize>2048</WriteBufferSize> <WriteTimeout>500</WriteTimeout> <DtrEnable>false</DtrEnable> <RtsEnable>false</RtsEnable> </SerialPortInfo> </SerialPortInfos> <TcpServerInfos /> <TcpClientInfos /> <UdpClientInfos /> </ParserInfo> |
4. MainForm
下記はメインフォームのアウトラインです。
コード中に記載するコメントの (1)~(4) の部分の実装内容については
後述の 4-1~4-4 をご参照ください。
C# | Copy |
---|---|
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace SampleCode { /// <summary> /// 画像処理アプリケーションメインフォーム. /// </summary> public partial class MainForm : Form { /// <summary> /// コンストラクタ. /// </summary> public MainForm() { InitializeComponent(); } /// <summary> /// フォームロード時の初期化処理. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainForm_Load(object sender, EventArgs e) { // (1) 画像処理スレッド関連.(イベントハンドラ登録) // (2) イメージグラバー関連.(イベントハンドラ登録) timerUpdateUI.Enabled = true; } /// <summary> /// フォームが閉じられるときの解放処理. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { timerUpdateUI.Enabled = false; } /// <summary> /// 定期的な表示更新処理. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timerUpdateUI_Tick(object sender, EventArgs e) { // (1) 画像処理スレッド関連.(表示更新) // (2) イメージグラバー関連.(表示更新) // (3) デジタル入出力関連.(表示更新) // (4) シリアル通信関連.(表示更新) // (2) イメージグラバー関連.(取り込み完了イベント) // (1) 画像処理スレッド関連.(完了イベント) } // (1) 画像処理スレッド関連. // (2) イメージグラバー関連. // (3) デジタル入出力関連. // (4) シリアル通信関連. } } |
Visual Basic | Copy |
---|---|
Imports System.Collections.Generic Imports System.ComponentModel Imports System.Data Imports System.Drawing Imports System.Text Imports System.Windows.Forms ''' <summary> ''' 画像処理アプリケーションメインフォーム ''' </summary> Public Partial Class MainForm Inherits Form ''' <summary> ''' コンストラクタ ''' </summary> Public Sub New() InitializeComponent() End Sub ''' <summary> ''' フォームロード時の初期化処理 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub MainForm_Load(sender As Object, e As EventArgs) '' (1) 画像処理スレッド関連.(イベントハンドラ登録) '' (2) イメージグラバー関連.(イベントハンドラ登録) timerUpdateUI.Enabled = True End Sub ''' <summary> ''' フォームが閉じられるときの解放処理 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub MainForm_FormClosing(sender As Object, e As FormClosingEventArgs) timerUpdateUI.Enabled = False End Sub ''' <summary> ''' 定期的な表示更新処理 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub timerUpdateUI_Tick(sender As Object, e As EventArgs) '' (1) 画像処理スレッド関連.(表示更新) '' (2) イメージグラバー関連.(表示更新) '' (3) デジタル入出力関連.(表示更新) '' (4) シリアル通信関連.(表示更新) '' (2) イメージグラバー関連.(取り込み完了イベント) '' (1) 画像処理スレッド関連.(完了イベント) End Sub '' (1) 画像処理スレッド関連. '' (2) イメージグラバー関連. '' (3) デジタル入出力関連. '' (4) シリアル通信関連. End Class |
4-1. MainForm (画像処理スレッド)
下記のソースコードには、画像処理スレッド(ParserThread)に関連する処理のみ抜粋しています。
MainForm_Load ではイベントハンドラを登録しています。
このハンドラはスレッド実行中に画像処理が完了するたびにコールバックされます。
toolThreadStart_Click/toolThreadAbort_Click では、スレッドの開始/停止/中断を行っています。
これらはツールストリップボタンのイベントに関連づけられたハンドラです。
timerUpdateUI_Tick では、ツールストリップボタンの有効/無効やチェックの ON/OFF を行っています。
また、画像処理スレッドの完了イベントを監視して処理結果をステータスストリップに表示しています。
表示処理はプライマリスレッド(ウィンドウハンドルを所有しているスレッド)のタイミングで行う必要があることに注意してください。
別スレッドから直接フォームにアクセスすることはできません。
この例ではタイマーコンポーネントを使用することでプライマリスレッドのタイミングで処理する方法を使用しています。
一般的には、Invoke メソッドを使用します。
その場合は、ParserThread_Notify に表示処理を実装することになります。
Invoke メソッドについては MSDN Library をご参照ください。
MSDN Library:
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.invoke(v=vs.80).aspx
C# | Copy |
---|---|
namespace SampleCode { public partial class MainForm : Form { public MainForm() { InitializeComponent(); } /// <summary> /// フォームロード時の初期化処理. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainForm_Load(object sender, EventArgs e) { #region 画像処理スレッド関連. Defs.ParserThread.Notify += ParserThread_Notify; #endregion } /// <summary> /// 定期的な表示更新処理. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timerUpdateUI_Tick(object sender, EventArgs e) { #region 画像処理スレッド関連. { toolThreadStart.Enabled = (Defs.ParserThread != null); toolThreadStart.Checked = (Defs.ParserThread != null && Defs.ParserThread.IsBusy); toolThreadAbort.Enabled = (Defs.ParserThread != null && Defs.ParserThread.IsBusy); } #endregion #region 画像処理スレッド関連.(完了イベント) if (ParserEventArgs != null) { statusTimeStamp.Text = string.Format( "{0:00}:{1:00}:{2:00}", ParserEventArgs.TimeStamp.Hour, ParserEventArgs.TimeStamp.Minute, ParserEventArgs.TimeStamp.Second); statusProcessTime.Text = string.Format( "{0:0.000} ms", ParserEventArgs.ProcessTime); if (ParserEventArgs.Exception == null) statusMessage.Text = ParserEventArgs.Message; else statusMessage.Text = ParserEventArgs.Exception.Message; if (Defs.ParserNode != null) { Defs.ParserNode.ChangeVisibleLevel(FVIL.Parser.VisibleLevel.Enable); Defs.ParserNode.Draw(ImageView); } ParserEventArgs = null; } #endregion } /// <summary> /// 画像処理スレッドの開始と停止. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void toolThreadStart_Click(object sender, EventArgs e) { if (Defs.ParserThread == null) return; if (Defs.ParserThread.IsBusy == false) Defs.ParserThread.Start(); else Defs.ParserThread.Stop(); } /// <summary> /// 画像処理スレッドの中断. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void toolThreadAbort_Click(object sender, EventArgs e) { if (Defs.ParserThread == null) return; Defs.ParserThread.Abort(); } /// <summary> /// 画像処理完了通知イベント. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ParserThread_Notify(object sender, FVIL.Parser.ParserEventArgs e) { ParserEventArgs = e; } /// <summary> /// 画像処理完了通知イベント引数. /// </summary> private FVIL.Parser.ParserEventArgs ParserEventArgs = null; } } |
Visual Basic | Copy |
---|---|
Imports System.Collections.Generic Imports System.ComponentModel Imports System.Data Imports System.Drawing Imports System.Text Imports System.Windows.Forms ''' <summary> ''' 画像処理アプリケーションメインフォーム ''' </summary> Public Partial Class MainForm Inherits Form ''' <summary> ''' コンストラクタ ''' </summary> Public Sub New() InitializeComponent() End Sub ''' <summary> ''' フォームロード時の初期化処理 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub MainForm_Load(sender As Object, e As EventArgs) '#Region "画像処理スレッド関連." AddHandler Defs.ParserThread.Notify, AddressOf ParserThread_Notify '#End Region End Sub ''' <summary> ''' フォームが閉じられるときの解放処理 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub MainForm_FormClosing(sender As Object, e As FormClosingEventArgs) timerUpdateUI.Enabled = False End Sub ''' <summary> ''' 定期的な表示更新処理 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub timerUpdateUI_Tick(sender As Object, e As EventArgs) '#Region "画像処理スレッド関連." If True Then toolThreadStart.Enabled = (Defs.ParserThread IsNot Nothing) toolThreadStart.Checked = (Defs.ParserThread IsNot Nothing AndAlso Defs.ParserThread.IsBusy) toolThreadAbort.Enabled = (Defs.ParserThread IsNot Nothing AndAlso Defs.ParserThread.IsBusy) End If '#End Region '#Region "画像処理スレッド関連.(完了イベント)" If ParserEventArgs IsNot Nothing Then statusTimeStamp.Text = String.Format("{0:00}:{1:00}:{2:00}", ParserEventArgs.TimeStamp.Hour, ParserEventArgs.TimeStamp.Minute, ParserEventArgs.TimeStamp.Second) statusProcessTime.Text = String.Format("{0:0.000} ms", ParserEventArgs.ProcessTime) If ParserEventArgs.Exception Is Nothing Then statusMessage.Text = ParserEventArgs.Message Else statusMessage.Text = ParserEventArgs.Exception.Message End If If Defs.ParserNode IsNot Nothing Then Defs.ParserNode.ChangeVisibleLevel(FVIL.Parser.VisibleLevel.Enable) Defs.ParserNode.Draw(ImageView) End If ParserEventArgs = Nothing End If '#End Region End Sub ''' <summary> ''' 画像処理スレッドの開始と停止 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub toolThreadStart_Click(sender As Object, e As EventArgs) If Defs.ParserThread Is Nothing Then Return End If If Defs.ParserThread.IsBusy = False Then Defs.ParserThread.Start() Else Defs.ParserThread.[Stop]() End If End Sub ''' <summary> ''' 画像処理スレッドの中断 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub toolThreadAbort_Click(sender As Object, e As EventArgs) If Defs.ParserThread Is Nothing Then Return End If Defs.ParserThread.Abort() End Sub ''' <summary> ''' 画像処理完了通知イベント ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub ParserThread_Notify(sender As Object, e As FVIL.Parser.ParserEventArgs) ParserEventArgs = e End Sub ''' <summary> ''' 画像処理完了通知イベント引数 ''' </summary> Private ParserEventArgs As FVIL.Parser.ParserEventArgs = Nothing End Class |
4-2. MainForm (イメージグラバー)
下記のソースコードには、イメージグラバーに関連する処理のみ抜粋しています。
イメージグラバーを操作するには
ParserInfo を
IAuxGrabber にキャストして
Threads プロパティから
GrabberThread を抽出します。
この例では処理の簡略化の為、配列の 0 番目の要素からのみ抽出しています。
MainForm_Load ではイベントハンドラを登録しています。
このハンドラは画像取り込みが完了するたびにコールバックされます。
toolGrabberStart_Click では、スレッドの開始/中断を行っています。
toolGrabberFocusing_Click では、焦点調整フォームをポップアップ表示しています。
これらはツールストリップボタンのイベントに関連づけられたハンドラです。
timerUpdateUI_Tick では、ツールストリップボタンの有効/無効やチェックの ON/OFF を行っています。
また、イメージグラバースレッドの画像取り込み完了イベントを監視して取り込み画像を画像ビューに表示しています。
表示処理はプライマリスレッド(ウィンドウハンドルを所有しているスレッド)のタイミングで行う必要があることに注意してください。
別スレッドから直接フォームにアクセスすることはできません。
この例ではタイマーコンポーネントを使用することでプライマリスレッドのタイミングで処理する方法を使用しています。
一般的には、Invoke メソッドを使用します。
その場合は、GrabberThread_FrameValid に表示処理を実装することになります。
Invoke メソッドについては MSDN Library をご参照ください。
MSDN Library:
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.invoke(v=vs.80).aspx
C# | Copy |
---|---|
namespace SampleCode { public partial class MainForm : Form { /// <summary> /// フォームロード時の初期化処理. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainForm_Load(object sender, EventArgs e) { #region イメージグラバー関連. // (注) この例ではコードの簡素化の為に1つ目のグラバーのみ使用しています. { FVIL.Parser.IAuxGrabber grabber = (FVIL.Parser.IAuxGrabber)Defs.ParserInfo; if (grabber.Threads.Length > 0 && grabber.Threads[0] != null) grabber.Threads[0].FrameValid += GrabberThread_FrameValid; } #endregion } /// <summary> /// 定期的な表示更新処理. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timerUpdateUI_Tick(object sender, EventArgs e) { #region イメージグラバー関連. { FVIL.Parser.IAuxGrabber grabber = (FVIL.Parser.IAuxGrabber)Defs.ParserInfo; bool grabber_enable = (grabber.Threads.Length > 0 && grabber.Threads[0] != null); toolGrabberStart.Enabled = grabber_enable; toolGrabberStart.Checked = (grabber_enable && grabber.Threads[0].IsBusy); toolGrabberFocusing.Enabled = (grabber_enable && GrabberFocusingForm == null); } #endregion #region イメージグラバー関連.(取り込み完了イベント) if (GrabberEventArgs != null) { if (GrabberEventArgs.Exception == null && GrabberEventArgs.Images.Length > 0 && GrabberEventArgs.Images[0] != null) { ImageView.Image = GrabberEventArgs.Images[0]; ImageView.Refresh(); } GrabberEventArgs = null; } #endregion } /// <summary> /// イメージグラバーの開始・停止. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void toolGrabberStart_Click(object sender, EventArgs e) { FVIL.Parser.IAuxGrabber grabber = (FVIL.Parser.IAuxGrabber)Defs.ParserInfo; if (grabber.Threads.Length == 0) return; if (grabber.Threads[0] == null) return; try { FVIL.Imaging.GrabberThread thread = grabber.Threads[0]; if (thread.IsBusy == false) thread.Start(); else thread.Abort(); } catch (System.Exception ex) { MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// <summary> /// 焦点調整フォームの表示. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void toolGrabberFocusing_Click(object sender, EventArgs e) { FVIL.Parser.IAuxGrabber grabber = (FVIL.Parser.IAuxGrabber)Defs.ParserInfo; if (grabber.Threads.Length == 0) return; if (grabber.Threads[0] == null) return; try { FVIL.Imaging.GrabberThread thread = grabber.Threads[0]; GrabberFocusingForm = thread.CreateFocusingDialog(); GrabberFocusingForm.FormClosed += GrabberFocusingForm_FormClosed; GrabberFocusingForm.Show(); } catch (System.Exception ex) { MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// <summary> /// 焦点調整フォーム. /// </summary> private Form GrabberFocusingForm = null; /// <summary> /// 焦点調整フォームが閉じたとき. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void GrabberFocusingForm_FormClosed(object sender, EventArgs e) { GrabberFocusingForm = null; } /// <summary> /// イメージグラバーの取り込み完了通知イベント. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void GrabberThread_FrameValid(object sender, FVIL.Imaging.GrabberEventArgs e) { GrabberEventArgs = e; } /// <summary> /// イメージグラバーの取り込み完了通知イベント引数. /// </summary> private FVIL.Imaging.GrabberEventArgs GrabberEventArgs = null; } } |
Visual Basic | Copy |
---|---|
Imports System.Collections.Generic Imports System.ComponentModel Imports System.Data Imports System.Drawing Imports System.Text Imports System.Windows.Forms ''' <summary> ''' 画像処理アプリケーションメインフォーム ''' </summary> Public Partial Class MainForm Inherits Form ''' <summary> ''' フォームロード時の初期化処理 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub MainForm_Load(sender As Object, e As EventArgs) '#Region "イメージグラバー関連." ' (注) この例ではコードの簡素化の為に1つ目のグラバーのみ使用しています. If True Then Dim grabber As FVIL.Parser.IAuxGrabber = DirectCast(Defs.ParserInfo, FVIL.Parser.IAuxGrabber) If grabber.Threads.Length > 0 AndAlso grabber.Threads(0) IsNot Nothing Then AddHandler grabber.Threads(0).FrameValid, AddressOf GrabberThread_FrameValid End If End If '#End Region End Sub ''' <summary> ''' 定期的な表示更新処理 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub timerUpdateUI_Tick(sender As Object, e As EventArgs) '#Region "イメージグラバー関連." If True Then Dim grabber As FVIL.Parser.IAuxGrabber = DirectCast(Defs.ParserInfo, FVIL.Parser.IAuxGrabber) Dim grabber_enable As Boolean = (grabber.Threads.Length > 0 AndAlso grabber.Threads(0) IsNot Nothing) toolGrabberStart.Enabled = grabber_enable toolGrabberStart.Checked = (grabber_enable AndAlso grabber.Threads(0).IsBusy) toolGrabberFocusing.Enabled = (grabber_enable AndAlso GrabberFocusingForm Is Nothing) End If '#End Region '#Region "イメージグラバー関連.(取り込み完了イベント)" If GrabberEventArgs IsNot Nothing Then If GrabberEventArgs.Exception Is Nothing AndAlso GrabberEventArgs.Images.Length > 0 AndAlso GrabberEventArgs.Images(0) IsNot Nothing Then ImageView.Image = GrabberEventArgs.Images(0) ImageView.Refresh() End If GrabberEventArgs = Nothing End If '#End Region End Sub ''' <summary> ''' イメージグラバーの開始・停止 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub toolGrabberStart_Click(sender As Object, e As EventArgs) Dim grabber As FVIL.Parser.IAuxGrabber = DirectCast(Defs.ParserInfo, FVIL.Parser.IAuxGrabber) If grabber.Threads.Length = 0 Then Return End If If grabber.Threads(0) Is Nothing Then Return End If Try Dim thread As FVIL.Imaging.GrabberThread = grabber.Threads(0) If thread.IsBusy = False Then thread.Start() Else thread.Abort() End If Catch ex As System.Exception MessageBox.Show(Me, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.[Error]) End Try End Sub ''' <summary> ''' 焦点調整フォームの表示 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub toolGrabberFocusing_Click(sender As Object, e As EventArgs) Dim grabber As FVIL.Parser.IAuxGrabber = DirectCast(Defs.ParserInfo, FVIL.Parser.IAuxGrabber) If grabber.Threads.Length = 0 Then Return End If If grabber.Threads(0) Is Nothing Then Return End If Try Dim thread As FVIL.Imaging.GrabberThread = grabber.Threads(0) GrabberFocusingForm = thread.CreateFocusingDialog() AddHandler GrabberFocusingForm.FormClosed, AddressOf GrabberFocusingForm_FormClosed GrabberFocusingForm.Show() Catch ex As System.Exception MessageBox.Show(Me, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.[Error]) End Try End Sub ''' <summary> ''' 焦点調整フォーム ''' </summary> Private GrabberFocusingForm As Form = Nothing ''' <summary> ''' 焦点調整フォームが閉じたとき ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub GrabberFocusingForm_FormClosed(sender As Object, e As EventArgs) GrabberFocusingForm = Nothing End Sub #End Region #Region "イメージグラバー関連.(イベントハンドラ)" ''' <summary> ''' イメージグラバーの取り込み完了通知イベント ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub GrabberThread_FrameValid(sender As Object, e As FVIL.Imaging.GrabberEventArgs) GrabberEventArgs = e End Sub ''' <summary> ''' イメージグラバーの取り込み完了通知イベント引数 ''' </summary> Private GrabberEventArgs As FVIL.Imaging.GrabberEventArgs = Nothing End Class |
4-3. MainForm (デジタル入出力)
下記のソースコードには、デジタル入出力デバイスに関連する処理のみ抜粋しています。
デジタル入出力デバイスを操作するには
ParserInfo を
IAuxDio にキャストして
Threads プロパティから
DioThread を抽出します。
この例では処理の簡略化の為、配列の 0 番目の要素からのみ抽出しています。
toolDioMonitor_Click では、デジタル入出力テストフォームをポップアップ表示しています。
これはツールストリップボタンのイベントに関連づけられたハンドラです。
timerUpdateUI_Tick では、ツールストリップボタンの有効/無効やチェックの ON/OFF を行っています。
C# | Copy |
---|---|
namespace SampleCode { public partial class MainForm : Form { /// <summary> /// 定期的な表示更新処理. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timerUpdateUI_Tick(object sender, EventArgs e) { #region デジタル入出力関連. { FVIL.Parser.IAuxDio dio = (FVIL.Parser.IAuxDio)Defs.ParserInfo; bool dio_enable = (dio.Threads.Length > 0 && dio.Threads[0] != null); toolDioMonitor.Enabled = (dio_enable && DioMonitorForm == null); } #endregion } /// <summary> /// デジタル入出力モニタの表示. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void toolDioMonitor_Click(object sender, EventArgs e) { FVIL.Parser.IAuxDio dio = (FVIL.Parser.IAuxDio)Defs.ParserInfo; if (dio.Threads.Length == 0) return; if (dio.Threads[0] == null) return; try { FVIL.IO.DioThread thread = dio.Threads[0]; DioMonitorForm = thread.CreateTestDialog(); DioMonitorForm.FormClosed += DioMonitorForm_FormClosed; DioMonitorForm.Show(); } catch (System.Exception ex) { MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// <summary> /// デジタル入出力モニタ. /// </summary> private Form DioMonitorForm = null; /// <summary> /// デジタル入出力モニタが閉じたとき. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void DioMonitorForm_FormClosed(object sender, EventArgs e) { DioMonitorForm = null; } } } |
Visual Basic | Copy |
---|---|
Imports System.Collections.Generic Imports System.ComponentModel Imports System.Data Imports System.Drawing Imports System.Text Imports System.Windows.Forms ''' <summary> ''' 画像処理アプリケーションメインフォーム ''' </summary> Public Partial Class MainForm Inherits Form ''' <summary> ''' 定期的な表示更新処理 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub timerUpdateUI_Tick(sender As Object, e As EventArgs) '#Region "デジタル入出力関連." If True Then Dim dio As FVIL.Parser.IAuxDio = DirectCast(Defs.ParserInfo, FVIL.Parser.IAuxDio) Dim dio_enable As Boolean = (dio.Threads.Length > 0 AndAlso dio.Threads(0) IsNot Nothing) toolDioMonitor.Enabled = (dio_enable AndAlso DioMonitorForm Is Nothing) End If '#End Region End Sub ''' <summary> ''' デジタル入出力モニタの表示 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub toolDioMonitor_Click(sender As Object, e As EventArgs) Dim dio As FVIL.Parser.IAuxDio = DirectCast(Defs.ParserInfo, FVIL.Parser.IAuxDio) If dio.Threads.Length = 0 Then Return End If If dio.Threads(0) Is Nothing Then Return End If Try Dim thread As FVIL.IO.DioThread = dio.Threads(0) DioMonitorForm = thread.CreateTestDialog() AddHandler DioMonitorForm.FormClosed, AddressOf DioMonitorForm_FormClosed DioMonitorForm.Show() Catch ex As System.Exception MessageBox.Show(Me, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.[Error]) End Try End Sub ''' <summary> ''' デジタル入出力モニタ ''' </summary> Private DioMonitorForm As Form = Nothing ''' <summary> ''' デジタル入出力モニタが閉じたとき ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub DioMonitorForm_FormClosed(sender As Object, e As EventArgs) DioMonitorForm = Nothing End Sub End Class |
4-4. MainForm (シリアル通信)
下記のソースコードには、シリアル通信ポートに関連する処理のみ抜粋しています。
シリアル通信ポートを操作するには
ParserInfo を
IAuxSerialPort にキャストして
Ports プロパティから
System.IO.Ports.SerialPort を抽出します。
この例では処理の簡略化の為、配列の 0 番目の要素からのみ抽出しています。
toolSerialPort_Click では、シリアル通信プロパティフォームをポップアップ表示しています。
これはツールストリップボタンのイベントに関連づけられたハンドラです。
timerUpdateUI_Tick では、ツールストリップボタンの有効/無効やチェックの ON/OFF を行っています。
C# | Copy |
---|---|
namespace SampleCode { public partial class MainForm : Form { /// <summary> /// 定期的な表示更新処理. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timerUpdateUI_Tick(object sender, EventArgs e) { #region シリアル通信関連. { FVIL.Parser.IAuxSerialPort com = (FVIL.Parser.IAuxSerialPort)Defs.ParserInfo; bool com_enable = (com.Ports.Length > 0 && com.Ports[0] != null); toolSerialPort.Enabled = (com_enable && SerialPortForm == null); } #endregion } /// <summary> /// シリアル通信フォームの表示. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void toolSerialPort_Click(object sender, EventArgs e) { FVIL.Parser.IAuxSerialPort com = (FVIL.Parser.IAuxSerialPort)Defs.ParserInfo; if (com == null) return; if (com.Ports.Length == 0) return; if (com.Ports[0] == null) return; try { System.IO.Ports.SerialPort port = com.Ports[0]; SerialPortForm = FVIL.Ports.SerialPortTool.CreatePropertyDialog(port); SerialPortForm.FormClosed += SerialPortForm_FormClosed; SerialPortForm.Show(); } catch (System.Exception ex) { MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// <summary> /// シリアル通信フォーム. /// </summary> private Form SerialPortForm = null; /// <summary> /// シリアル通信フォームが閉じたとき. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SerialPortForm_FormClosed(object sender, EventArgs e) { SerialPortForm = null; } } } |
Visual Basic | Copy |
---|---|
Imports System.Collections.Generic Imports System.ComponentModel Imports System.Data Imports System.Drawing Imports System.Text Imports System.Windows.Forms ''' <summary> ''' 画像処理アプリケーションメインフォーム ''' </summary> Public Partial Class MainForm Inherits Form ''' <summary> ''' 定期的な表示更新処理 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub timerUpdateUI_Tick(sender As Object, e As EventArgs) '#Region "シリアル通信関連." If True Then Dim com As FVIL.Parser.IAuxSerialPort = DirectCast(Defs.ParserInfo, FVIL.Parser.IAuxSerialPort) Dim com_enable As Boolean = (com.Ports.Length > 0 AndAlso com.Ports(0) IsNot Nothing) toolSerialPort.Enabled = (com_enable AndAlso SerialPortForm Is Nothing) End If '#End Region End Sub ''' <summary> ''' シリアル通信フォームの表示 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub toolSerialPort_Click(sender As Object, e As EventArgs) Dim com As FVIL.Parser.IAuxSerialPort = DirectCast(Defs.ParserInfo, FVIL.Parser.IAuxSerialPort) If com Is Nothing Then Return End If If com.Ports.Length = 0 Then Return End If If com.Ports(0) Is Nothing Then Return End If Try Dim port As System.IO.Ports.SerialPort = com.Ports(0) SerialPortForm = FVIL.Ports.SerialPortTool.CreatePropertyDialog(port) AddHandler SerialPortForm.FormClosed, AddressOf SerialPortForm_FormClosed SerialPortForm.Show() Catch ex As System.Exception MessageBox.Show(Me, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.[Error]) End Try End Sub ''' <summary> ''' シリアル通信フォーム ''' </summary> Private SerialPortForm As Form = Nothing ''' <summary> ''' シリアル通信フォームが閉じたとき ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub SerialPortForm_FormClosed(sender As Object, e As EventArgs) SerialPortForm = Nothing End Sub End Class |
E. スクリーンショット
図 1 が今回作成したメインフォームです。
ツールストリップの左側にある緑の三角ボタンや四角ボタンで画像処理スレッドの開始/停止/中断を行います。
その他のボタンは接続しているデバイスの操作を行うものです。
ツールストリップボタンを押すと 図 2,3,4 に示すフォームをポップアップ表示します。
これらのフォームは本ライブラリに組み込まれたものです。
図1) メインフォーム:
図2) 焦点調整フォーム:
図3) デジタル入出力テストフォーム:
図4) シリアル通信プロパティフォーム: