共通ファイル(common)
概要
ICImagingControlをインストール時にサンプルのフォルダ内にcommonが投函されてます。ここではcommonファイルの使い方・役割について説明します。
サンプルプログラム
Software | IC Imaging Control 3.5, Visual Studio™ 2019 |
---|---|
サンプル(C#) | common.zip |
サンプルツールの外観
ファイル名 | 外観 | 対象のプロパティ |
---|---|---|
IControlBase | なし | インターフェースのため、なし |
AbsValSlider | VCDAbsoluteValueProperty | |
PushButton | VCDButtonProperty | |
RangeSlider | VCDRangeProperty | |
StringCombo | VCDMapStringsProperty | |
Switch | VCDSwitchProperty |
CommonにあるサンプルはVCDプロパティの各インターフェースに使えるように、複数のWindowsフォームに共通する要素を基本フォームにまとめています。
このサンプルでは、VCDプロパティ:プロパティダイアログ画面のカスタマイズ編のVCDProprtyiesDlgで使用するための下記のフォーム(ファイル)が含まれています。
csファイル | Windowsフォームを含むソース・ファイル |
---|---|
Designer.csファイル | Windowsフォームのデザイン部分を定義するソース・ファイル |
resxファイル | Windowsフォームのリソース(文字列などのデータ)が保存されているファイル |
IControlBase、AbsValSlider、PushButton、RangeSlider、StringCombo、Switchの6種類のフォームがあります。
各フォームでは、基本フォームを継承するだけでテキストボックスなどの共通する要素を再利用できるようになります。
下記では基本フォームを継承する方法について説明します。
これらの継承したコントロールの再利用の方法については下記をご覧ください。
VCDプロパティ:プロパティダイアログ画面のカスタマイズ編
IC Imaging Control_Ver3.5(C#/VB.NET) サンプルプログラム
IControlBase
internal interface IControlBase
{
void UpdateControl();
}
internal interface IControlSlider
{
void ScrollUpdate();
}
公開インターフェイスに追加をする(DLLでは非公開)メンバーを定義しています。
こうすることでライブラリを汎用的に使用することができます。
AbsValSlider(VCDAbsoluteValuePropertyの制御)
public partial class AbsValSlider : UserControl , IControlBase, IControlSlider
{
public AbsValSlider( TIS.Imaging.VCDAbsoluteValueProperty itf )
{
_prop_itf = itf;
InitializeComponent();
Slider.Minimum = 0;
Slider.Maximum = 100;
UpdateControl();
}
// スライダーを制御するインターフェース
private TIS.Imaging.VCDAbsoluteValueProperty _prop_itf;
// 更新していることを示すフラグ
private bool _updating;
// コントロールがユーザーによって変更されたことを示すフラグで
// これによって、コントロールを更新する必要がなくなります
private bool _selfClicked;
// 同じアイテムのインターフェースに接続されたスライダーのコレクション
// このスライダーを変更する場合は、これらのスライダーを更新する必要があります
private System.Collections.ArrayList _sisterSliders;
private void trackBar1_Scroll(object sender, EventArgs e)
{
try
{
// スクロールイベントが発火した場合にのみ、プロパティを変更します
if (!_updating)
{
// スライダーの位置に応じて新しい絶対値を取得します
// 新しい値をインターフェースに設定します
if (!_prop_itf.ReadOnly)
{
_prop_itf.Value = GetAbsVal();
}
// 絶対値の粒度がわからず、実際に設定されている値がプロパティに割り当てた値と異なるため
// VCDAbsoluteValuePropertyから新しい値を読み戻します
ScrollUpdate();
// 接続されている可能性のあるスライダーがわかっている場合は、それらを更新します
_selfClicked = true;
if (!(_sisterSliders == null))
{
foreach (IControlSlider sld in _sisterSliders)
{
sld.ScrollUpdate();
}
}
_selfClicked = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void AbsValSlider_Load(object sender, EventArgs e)
{
_updating = false;
_selfClicked = false;
}
// この関数は、現在の絶対値に基づいてスライダーの必要な位置を計算します
private int GetSliderPos()
{
double rmin = 0;
double rmax = 0;
double absval = 0;
double rangelen = 0;
double p = 0;
// インターフェイスからプロパティデータを取得します
rmin = _prop_itf.RangeMin;
rmax = _prop_itf.RangeMax;
absval = _prop_itf.Value;
// プロパティの寸法関数に応じて計算を行います
if (_prop_itf.DimFunction == TIS.Imaging.AbsDimFunction.eAbsDimFunc_Log)
{
rangelen = System.Math.Log(rmax) - System.Math.Log(rmin);
p = 100 / rangelen * (System.Math.Log(absval) - System.Math.Log(rmin));
}
else // AbsValItf.DimFunction = AbsDimFunction.eAbsDimFunc_Linear
{
rangelen = rmax - rmin;
p = 100 / rangelen * (absval - rmin);
}
// 整数にまるめます
return (int)System.Math.Round(p, 0);
}
// この関数は、スライダーの位置に基づいて現在の絶対値を計算します
private double GetAbsVal()
{
double rmin = 0;
double rmax = 0;
double rangelen = 0;
double value = 0;
// インターフェイスからプロパティデータを取得します
rmin = _prop_itf.RangeMin;
rmax = _prop_itf.RangeMax;
// プロパティの寸法関数に応じて計算を行います
if (_prop_itf.DimFunction == TIS.Imaging.AbsDimFunction.eAbsDimFunc_Log)
{
rangelen = System.Math.Log(rmax) - System.Math.Log(rmin);
value = System.Math.Exp(System.Math.Log(rmin) + rangelen / 100 * Slider.Value);
}
else // AbsValItf.DimFunction = AbsDimFunction.eAbsDimFunc_Linear
{
rangelen = rmax - rmin;
value = rmin + rangelen / 100 * Slider.Value;
}
// 範囲外の場合は値を修正してください
if (value > rmax)
{
value = rmax;
}
if (value < rmin)
{
value = rmin;
}
return value;
}
public void UpdateControl()
{
_updating = true;
// プロパティが利用可能かどうかを確認します
if (_prop_itf.Available)
{
// スライダーを有効にする
Slider.Enabled = true;
ScrollUpdate();
}
else
{
// スライダーを無効にする
Slider.Enabled = false;
// テキストボックスを無効にする
ValueText.Text = "";
ValueText.Enabled = false;
}
_updating = false;
}
public void ScrollUpdate()
{
// このイベントがこのコントロールによって発火された場合は更新しないでください
if (_selfClicked)
{
return;
}
// プロパティが利用できない場合は更新しないでください
if (!_prop_itf.Available)
{
return;
}
_updating = true;
// 現在の値のテキスト表現をテキストボックスに割り当てます
ValueText.Text = _prop_itf.Value.ToString();
if (!ValueText.Enabled)
{
ValueText.Enabled = true;
}
// Set the slider position
Slider.Value = GetSliderPos();
_updating = false;
}
public void setSisterSliders(System.Collections.ArrayList sliders)
{
_sisterSliders = sliders;
}
private void AbsValSlider_Layout(object sender, System.Windows.Forms.LayoutEventArgs e)
{
if (_prop_itf == null)
{
return;
}
// テキストボックスの適切な幅を推定するために
// テキストボックスの長さを決めます
int lenmin = 0;
int lenmid = 0;
int lenmax = 0;
System.Drawing.Graphics g = this.CreateGraphics();
lenmin = (int)g.MeasureString(_prop_itf.RangeMin.ToString(), this.Font).Width;
double valmid = _prop_itf.RangeMax - _prop_itf.RangeMin / 2;
lenmid = (int)g.MeasureString(valmid.ToString(), this.Font).Width;
lenmax = (int)g.MeasureString(_prop_itf.RangeMax.ToString(), this.Font).Width;
g.Dispose();
int textlen = 0;
textlen = lenmin;
if (lenmid > textlen)
{
textlen = lenmid;
}
if (lenmax > textlen)
{
textlen = lenmax;
}
// スライダーとテキストボックスのサイズを変更します
Slider.Width = Width - (textlen + 20);
Slider.Height = Height;
ValueText.Height = Height;
ValueText.Left = Width - (textlen + 20);
ValueText.Width = textlen + 20;
}
}
上記のフォームは下記のゲインのような数値設定に利用されます。
例:Gain(VCD Property Inspectorのアプリケーションの画面)
ゲインなどの設定できるプロパティはMin(最小値)、Max(最大値)、Value(浮動小数点数)の三種類となっておりますので、それらの値に対してスライダーの割り当てやテキストボックスの配置、位置調整を行うことで利用できます。
PushButton(VCDButtonPropertyの制御)
public partial class PushButton : UserControl, IControlBase
{
public PushButton( TIS.Imaging.VCDButtonProperty itf )
{
InitializeComponent();
PushItf = itf;
button1.Text = itf.Parent.Name;
UpdateControl();
}
// このボタンが制御するインターフェース
public TIS.Imaging.VCDButtonProperty PushItf;
// 同じアイテムのインターフェースに接続されたコントロールのコレクション
// このボタンを押すと、これらのコントロールを更新する必要があります
public System.Collections.ArrayList sisterControls;
private void button1_Click(object sender, EventArgs e)
{
try
{
// インターフェイスに通知します
PushItf.Push();
// 同じアイテムのコントロールについて知っている場合は、それらを更新します
if (!(sisterControls == null))
{
foreach (IControlBase ctl in sisterControls)
{
ctl.UpdateControl();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button1_Resize(object sender, EventArgs e)
{
// ボタンはユーザーコントロール全体を埋めます
button1.Width = Width;
button1.Height = Height;
}
public void UpdateControl()
{
// ボタンのプロパティが使用可能かどうかを確認します
button1.Enabled = PushItf.Available;
}
public void setSisterControls(System.Collections.ArrayList controls)
{
sisterControls = controls;
}
}
上記のフォームは下記のホワイトバランスの自動設定(ワンプッシュ)ような設定に利用されます。
例:WhiteBalance(VCD Property Inspectorのアプリケーションの画面)
ワンプッシュでできるプロパティはPushメソッドのみですので、ボタンクリックのイベントにPushメソッドを入れ込んだり、ボタンの有効化・無効化を定義することで利用できます。
RangeSlider(VCDRangePropertyの制御)
public partial class RangeSlider : UserControl, IControlBase, IControlSlider
{
public RangeSlider( TIS.Imaging.VCDRangeProperty itf )
{
InitializeComponent();
_rangeProperty = itf;
InitialUpdate();
UpdateControl();
}
// このスライダーが制御するインターフェース
private TIS.Imaging.VCDRangeProperty _rangeProperty;
// 同じアイテムのインターフェースに接続されたスライダーのコレクションです
// このスライダーを変更する場合は、これらのスライダーを更新する必要があります
private System.Collections.ArrayList _sisterSliders;
private void Slider_Scroll(object sender, EventArgs e)
{
try
{
// ぷろぱてぃに新しい値を割り当てます
if (!_rangeProperty.ReadOnly)
{
_rangeProperty.Value = Slider.Value * _rangeProperty.Delta;
}
// テキストボックスの更新
ValueText.Text = _rangeProperty.Value.ToString();
// 接続されているスライダーがわかっている場合は、更新します
if (!(_sisterSliders == null))
{
foreach (IControlSlider sld in _sisterSliders)
{
if (!(sld == this))
{
sld.ScrollUpdate();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void UpdateControl()
{
// プロパティが利用可能かどうかを確認します
if (_rangeProperty.Available)
{
// スライダーとテキストボックスを有効にする
Slider.Enabled = true;
ValueText.Enabled = true;
// スライダーの位置を調整
ScrollUpdate();
}
else
{
// スライダーを無効にする
Slider.Enabled = false;
// テキストボックスを無効にする
ValueText.Text = "";
ValueText.Enabled = false;
}
}
private void InitialUpdate()
{
// スライダーの範囲を初期化する
int min = _rangeProperty.RangeMin / _rangeProperty.Delta;
int max = _rangeProperty.RangeMax / _rangeProperty.Delta;
Slider.TickFrequency = 1;
if (max - min > 50)
{
Slider.TickFrequency = 10;
}
if (max - min > 500)
{
Slider.TickFrequency = 100;
}
Slider.Minimum = min;
Slider.Maximum = max;
if (min == max)
{
Slider.Enabled = false;
}
}
public void ScrollUpdate()
{
if (!_rangeProperty.Available) return;
// 新しいスライダーの位置を計算します
int pos = _rangeProperty.Value / _rangeProperty.Delta;
if (pos < Slider.Minimum || pos > Slider.Maximum )
{
Slider.Enabled = false;
}
else
{
Slider.Value = pos;
}
ValueText.Text = pos.ToString();
}
public void setSisterSliders(System.Collections.ArrayList sliders)
{
_sisterSliders = sliders;
}
private void RangeSlider_Layout(object sender, System.Windows.Forms.LayoutEventArgs e)
{
// スライダーとテキストボックスの位置を調整する
Slider.Width = Width * 80 / 100;
Slider.Height = Height;
ValueText.Height = Height;
ValueText.Left = Width * 80 / 100;
ValueText.Width = Width * 20 / 100;
}
}
上記のフォームは下記のシャープネスような範囲設定に利用されます。
例:Shapness(VCD Property Inspectorのアプリケーションの画面)
シャープネスなどの設定できるプロパティはMin(最小値)、Max(最大値)、Value(整数値)の三種類となっておりますので、それらの値に対してスライダーの割り当てやテキストボックスの配置、位置調整を行うことで利用できます。
AbsValSliderとほぼ仕様上変わりませんが、AbsoluteValueでは浮動小数点数を扱う値も制御できる一方、Rangeでは整数値しか制御できません。
StringCombo(VCDMapStringsPropertyの制御)
public partial class StringCombo : UserControl, IControlBase
{
public StringCombo( TIS.Imaging.VCDMapStringsProperty itf )
{
InitializeComponent();
_prop_itf = itf;
InitialUpdate();
UpdateControl();
}
// コンボボックスのインターフェース
private TIS.Imaging.VCDMapStringsProperty _prop_itf;
// スライダーへの変更を無視するための更新フラグ
private bool _updating;
// 同じアイテムのインターフェースに接続されたスライダーのコレクション
// コンボボックスが変更された場合、これらのスライダーを更新する必要があります
private System.Collections.ArrayList _sisterSliders;
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
// クリックイベントがはっかしたときにだけプロパティを変更します
if (!_updating)
{
// 文字列を割り当てます
if (!_prop_itf.ReadOnly)
{
_prop_itf.String = Combo.Text;
}
// 接続されているスライダーがわかっている場合は、更新します
if (!(_sisterSliders == null))
{
foreach (IControlBase ctl in _sisterSliders)
{
ctl.UpdateControl();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void UpdateControl()
{
_updating = true;
// プロパティが利用可能かどうかを確認します
Combo.Enabled = _prop_itf.Available;
// 現在の文字列を更新します。
ScrollUpdate();
_updating = false;
}
private void InitialUpdate()
{
// コンボボックスに使用可能な文字列を入力します
Combo.Items.Clear();
foreach (string s in _prop_itf.Strings)
{
Combo.Items.Add(s);
}
}
public void ScrollUpdate()
{
_updating = true;
// 新しい位置を算出します
Combo.SelectedIndex = _prop_itf.Value - _prop_itf.RangeMin;
_updating = false;
}
private void StringCombo_Resize(object eventSender, System.EventArgs eventArgs)
{
Combo.Width = Width;
}
public void setSisterSliders(System.Collections.ArrayList sliders)
{
_sisterSliders = sliders;
}
}
上記のフォームは下記のホワイトバランスのモード繰り替え設定に利用されます。
例:WhiteBalance(VCD Property Inspectorのアプリケーションの画面)
ホワイトバランスのGray worldなどの利用できるモードをリスト化して、それをコンボボックスと連携することで利用することができます。
Switch(VCDSwitchPropertyの制御)
public partial class Switch : UserControl, IControlBase
{
public Switch( TIS.Imaging.VCDSwitchProperty itf )
{
InitializeComponent();
_switchItf = itf;
Check.Text = itf.Parent.Name;
UpdateControl();
}
// スイッチコントロールのインターフェース
public TIS.Imaging.VCDSwitchProperty _switchItf;
public bool updating;
// 同じアイテムのインターフェースに接続されたコントロールのコレクション
// このボタンをクリックすると、これらのコントロールを更新する必要があります
public System.Collections.ArrayList sisterControls;
private void checkBox1_CheckStateChanged(object sender, EventArgs e)
{
try
{
// クリックイベントが発火した時にだけプロパティを変更します。
if (updating)
{
return;
}
if (!_switchItf.ReadOnly)
{
// プロパティに新しい値を割り当てます
_switchItf.Switch = Check.Checked;
}
// 同じアイテムのコントロールについて知っている場合は、それらを更新します
if (!(sisterControls == null))
{
foreach (IControlBase chk in sisterControls)
{
chk.UpdateControl();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Switch_Resize(object sender, EventArgs e)
{
// ボタンはユーザーコントロール全体を埋めます
Check.Width = Width;
Check.Height = Height;
}
public void UpdateControl()
{
updating = true;
Check.Enabled = _switchItf.Available;
Check.Checked = _switchItf.Switch;
updating = false;
}
public void setSisterControls(System.Collections.ArrayList ctrls)
{
sisterControls = ctrls;
}
}
上記のフォームは下記のホワイトバランスの自動設定ようなON/OFF設定に利用されます。
例:WhiteBalance(VCD Property Inspectorのアプリケーションの画面)
自動設定ようなON/OFFのプロパティはON/OFF切り替えるためのSwitchプロパティのみですので、Switchプロパティをチェックボックスと紐づけることで利用できます。
AbsValSliderの制御方法
// コントロールはコレクションに入れられ、スイッチをチェックした後の迅速な更新を可能にします
private System.Collections.ArrayList currentSisterControls;
// アイテムのスライダーは別のコレクションに入れられ、
// 接続されているスライダーをさらに高速に更新できるようになります
private System.Collections.ArrayList currentSisterSliders;
// こグローバル更新イベントのすべてのコントロールのコレクションです
private readonly System.Collections.ArrayList allControls = new System.Collections.ArrayList();
private void CreateAbsValSlider(TIS.Imaging.VCDAbsoluteValueProperty itf, int left, int top, int width, int height)
{
// AbsValSliderコントロールを生成する
AbsValSlider Slider = new AbsValSlider( itf );
Slider.Name = "absvalslider" + allControls.Count;
currentFrame.Controls.Add(Slider);
Slider.SetBounds(left, top, width, height);
// currentSisterControlsにコントロールを追加します
currentSisterControls.Add(Slider);
// currentSisterSlidersにコントロールを追加します
currentSisterSliders.Add(Slider);
// currentSisterSlidersをコントロールにセットする
Slider.setSisterSliders(currentSisterSliders);
// すべてのコントロールのグローバルリストに追加します
allControls.Add(Slider);
}
実際にAbsValSliderを使用するとなると上記のようなコーディングとなります。
AbsValSliderクラスをインスタンス化してコントロールグループにスライダーを入れ込むことでゲインや露光時間のための個々のコントローラを用意しなくても、上記の方法によって一括で制御可能となります。
その他、継承したコントロールの再利用の方法については、下記をご覧ください。
VCDプロパティ:プロパティダイアログ画面のカスタマイズ編
IC Imaging Control_Ver3.5(C#/VB.NET) サンプルプログラム