using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing.Design;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Windows.Forms;
using GeoLibrary;
using GeoLibrary.Design;
using GeoLibrary.Interfaces;
using GeoLibrary.Delegates;
using GeoLibrary.Properties;
namespace GeoLibrary.Components
{
///
/// イベント監視コンポーネントクラス
///
///
///
#if !DEBUG
[DebuggerStepThrough()]
#endif
[Designer(typeof(GuardianComponentDesigner))]
[ProvideProperty("EventList", typeof(Component))]
[ResourceDescription("CTL_DSC_SEASER")]
public class Guardian
: Component, IExtenderProvider
{
///
/// コンポーネント別のイベントリストホルダを保持します
///
private Dictionary
///
/// ログ用ディレクトリ情報オブジェクトを保持します
///
private LogDirectoryInfo m_logDirectoryInfo;
///
/// ログ用ディレクトリ情報オブジェクト設定済フラグを保持します
///
private bool m_setDirectoryFlg;
///
/// コンポーネントプールを保持します
///
private List
///
/// 同期用オブジェクト
///
private object m_lockObject;
///
/// デザイナオブジェクト用プロパティ
/// コンポーネント別のイベントリストホルダを取得設定します
/// デザイン時のみのプロパティ
///
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Dictionary
{
set
{
// セットはデザイン時のみです
if (!this.DesignMode)
{
throw new InvalidOperationException(Resources.ERR_MES_INVALID_OPE);
}
// 引数をチェック
else if (value == null)
{
throw new NullReferenceException(Resources.ERR_MES_ARG_NULL);
}
this.m_eventDictionary = value;
}
get
{
return this.m_eventDictionary;
}
}
///
/// デザイナ用メソッド
/// ログ用ディレクトリの変更を検知するために必要です
///
///
private bool ShouldSerializeLogDirectory()
{
return true;
}
///
/// デザイナ用メソッド
/// ログ用ディレクトリを初期化するために必要です
///
private void ResetLogDirectory()
{
this.m_logDirectoryInfo = new LogDirectoryInfo();
}
///
/// ログ用ディレクトリを設定します
///
///
[Category(Grobal.C_CATEGORY)]
[ResourceDescription("PRO_DSC_LOGDIRECTORYINFO")]
[TypeConverter(typeof(LogDirectoryInfoTypeConverter))]
public LogDirectoryInfo LogDirectory
{
set
{
// 引数をチェック
if (value == null)
{
value = new LogDirectoryInfo();
}
this.m_logDirectoryInfo = value;
// デザインモードならここまで
if (this.DesignMode)
{
return;
}
// クリティカルセクション
lock (this.m_lockObject)
{
// フラグをセット
this.m_setDirectoryFlg = true;
// コンポーネントプールをチェック
if (this.m_componetPool != null)
{
foreach (Component component in this.m_componetPool)
{
this.CoreTask(component);
}
}
// コンポーネントプールを削除
this.m_componetPool = null;
}
}
get
{
return this.m_logDirectoryInfo;
}
}
///
/// デザイナ用メソッド
/// コンポーネント別のイベントリストホルダの変更を検知するために必要です
///
///
private bool ShouldSerializeEventList(Component a_component)
{
try
{
if (this.GetEventList(a_component).AddedEventList.Count == 0)
{
return false;
}
return true;
}
catch
{
return true;
}
}
///
/// コンポーネント別のイベントリストホルダを取得します
///
/// コンポーネント
///
[Category(Grobal.C_CATEGORY)]
[Editor(typeof(EventListHolderValueEditor), typeof(UITypeEditor))]
[ResourceDescription("PRO_DSC_EVENTLISTHOLDER")]
[TypeConverter(typeof(EventListHolderTypeConverter))]
public EventListHolder GetEventList(Component component)
{
// 引数をチェック
if (component == null)
{
throw new NullReferenceException("component が null 参照です");
}
// コンポーネントに対するイベントリストオブジェクトを保持していなければ
if (!this.m_eventDictionary.ContainsKey(component))
{
// 新規に生成する
EventListHolder holder = new EventListHolder();
// 生成したリストホルダにイベントリストを追加
holder.EventList.InsertRange(0, component.GetType().GetEvents());
// ディクショナリに追加
this.m_eventDictionary.Add(component, holder);
}
// 値を返す
return this.m_eventDictionary[component];
}
///
/// コンポーネント別のイベントリストホルダを設定します
///
/// コンポーネント
/// イベントリストホルダ
[Category(Grobal.C_CATEGORY)]
[Editor(typeof(EventListHolderValueEditor), typeof(UITypeEditor))]
[ResourceDescription("PRO_DSC_EVENTLISTHOLDER")]
[TypeConverter(typeof(EventListHolderTypeConverter))]
public void SetEventList(Component component, EventListHolder listHolder)
{
// 引数をチェック
if (component == null)
{
throw new NullReferenceException("component が null 参照です");
}
// コンポーネントに対するイベントリストオブジェクトを保持していなければ
if (!this.m_eventDictionary.ContainsKey(component))
{
// 新規に生成する
this.m_eventDictionary.Add(component, null);
}
// 値をセット
this.m_eventDictionary[component] = listHolder;
// デザインモード、もしくはイベントリストホルダがnull参照ならここまでで終了
if (this.DesignMode || listHolder == null)
{
return;
}
// クリティカルセクション
lock (this.m_lockObject)
{
// ログ用ディレクトリがセットされていれば
if (this.m_setDirectoryFlg)
{
// ハンドラの生成を行う
this.CoreTask(component);
}
// セットされていなければコンポーネントプールに追加
else
{
if (this.m_componetPool == null)
{
this.m_componetPool = new List
}
this.m_componetPool.Add(component);
}
}
}
///
/// コンストラクタ
///
public Guardian()
: base()
{
this.m_eventDictionary = new Dictionary
this.m_logDirectoryInfo = new LogDirectoryInfo();
this.m_setDirectoryFlg = false;
this.m_componetPool = null;
this.m_lockObject = new object();
}
///
/// コンストラクタ
///
/// コンテナ
public Guardian(IContainer container)
: this()
{
container.Add(this);
}
///
/// コアタスク
/// 動的ハンドラを生成します
///
///
private void CoreTask(Component component)
{
try
{
// コンポーネントごとに指定されたイベントを全てフックします
if (this.m_eventDictionary.ContainsKey(component))
{
Type type;
MethodInfo addMethod;
// 全イベントのハンドラを動的に生成
List
foreach (EventInfo eventInfo in eventList)
{
try
{
type = eventInfo.EventHandlerType;
if (!GrobalHandlerDictionary.Contains(type, eventInfo.Name))
{
GrobalHandlerDictionary.CreateDynamicHandler(type, eventInfo.Name, this.m_logDirectoryInfo);
}
addMethod = eventInfo.GetAddMethod();
addMethod.Invoke(component, new Object[] { GrobalHandlerDictionary.GetDynamicHandler(type, eventInfo.Name) });
}
catch
{
Grobal.GrobalErrorHandler("Guardian.CoreTask¥r¥n予期せぬ例外", 1, 1);
}
}
}
}
catch
{
Grobal.GrobalErrorHandler("Guardian.CoreTask¥r¥n予期せぬ例外", 1, 1);
}
}
///
/// IExtenderProviderインターフェイス実装
/// コンポーネントに対して拡張プロパティを実装するかどうかの値を取得します
///
/// 対象コンポーネント
///
/// true : 実装する
/// false : 実装しない
///
public virtual bool CanExtend(object extendee)
{
if (extendee is Guardian)
{
return false;
}
return true;
}
}
}