/*
First author tiritomato 2013.

mqsdx is distributed under the GNU Lesser General Public License 3.0(LGPLv3).

support blog (Japanese only)
http://d.hatena.ne.jp/tiri_tomato/
*/

#ifdef __cplusplus_cli
#include "../MQCLI.hpp"

namespace MQCLI {

	Lock::Lock( System::Object^ pObject ) : m_pObject( pObject ) {
		System::Threading::Monitor::Enter( m_pObject );
	}

	Lock::~Lock() {
		System::Threading::Monitor::Exit( m_pObject );
	}

	System::String^ String::Repeat(System::String^ src, int ct) {
		if ( ct == 0 ) return System::String::Empty;
		if ( (src == nullptr) || (ct<0) ) return nullptr;
		System::Text::StringBuilder^ sb = gcnew System::Text::StringBuilder(src->Length * ct);
		for ( int i = 0; i < ct; i++ ) sb->Append( src );
		return sb->ToString();
	}

	void RecursiveExceptionPrintElement(String::IndentBuilder^ src, System::String^ name, System::String^ value, int indentDepth ) {
		if ( value == nullptr ) value = "Nothing";
		src->AppendLine( System::String::Format("{0}:{1}{2}", name,
			value->Contains(System::Environment::NewLine) ? System::Environment::NewLine : System::String::Empty, value ), indentDepth );
	}

	void RecursiveExceptionPrint( String::IndentBuilder^ src, System::Exception^ ex, int indentDepth ) {
		if ( (src==nullptr) || (ex==nullptr) ) return;
		System::Type^ t = ex->GetType();
		RecursiveExceptionPrintElement(src, "TypeName", t->Name, indentDepth);
		RecursiveExceptionPrintElement(src, "TypeFullName", t->FullName, indentDepth);
		RecursiveExceptionPrintElement(src, "Message", ex->Message, indentDepth);
		if ( ex->InnerException == nullptr ) 
			src->AppendLine("InnerException:Nothing", indentDepth);
		else {
			src->AppendLine("InnerException:", indentDepth);
			RecursiveExceptionPrint(src,ex->InnerException,indentDepth+1);
		}
		RecursiveExceptionPrintElement(src,"Source", ex->Source, indentDepth);
		RecursiveExceptionPrintElement(src,"StackTrace", ex->StackTrace, indentDepth);
	}

	System::String^ String::FromException(System::Exception^ ex, System::String^ indentUnit, int indentDepth ) {
		IndentBuilder^ ret = gcnew String::IndentBuilder(indentUnit);
		RecursiveExceptionPrint(ret,ex,System::Math::Max(0,indentDepth));
		return ret->ToString();
	}
	
	bool PluginMainHolder::Regist( IBasePlugin^ pluginBody ) {
		Lock lock(m_lock);
		if ( m_pluginMain == nullptr && pluginBody != nullptr && pluginBody->basePlugin != NULL ) {
			m_pluginMain = pluginBody;
			return true;
		}
		return false;
	}

	MQBasePlugin* PluginMainHolder::pluginMain::get() {
		Lock lock(m_lock);
		if ( m_pluginMain == nullptr ) return NULL;
		return m_pluginMain->basePlugin;
	}
	
	BOOL PluginMainHolder::Activate(MQDocument doc, BOOL flag) {
		IActivate^ iPlugin = dynamic_cast<IActivate^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->Activate(doc,flag);
		return FALSE;
	}
	bool PluginMainHolder::ExecuteCallback(MQDocument doc, void *option) {
		IExecuteCallback^ iPlugin = dynamic_cast<IExecuteCallback^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->ExecuteCallback(doc, option);
		return CommandPluginDefault().ExecuteCallback(doc, option);
	}
	void PluginMainHolder::Exit() {
		IExit^ iPlugin = dynamic_cast<IExit^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->Exit();
	}
	BOOL PluginMainHolder::Initialize() {
		IInitialize^ iPlugin = dynamic_cast<IInitialize^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->Initialize();
		return FALSE;
	}
	BOOL PluginMainHolder::IsActivated(MQDocument doc) {
		IIsActivated^ iPlugin = dynamic_cast<IIsActivated^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->IsActivated(doc);
		return CommandPluginDefault().IsActivated(doc);
	}
	void PluginMainHolder::OnMinimize(MQDocument doc, BOOL flag) {
		IOnMinimize^ iPlugin = dynamic_cast<IOnMinimize^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnMinimize(doc, flag);
	}
	int PluginMainHolder::OnReceiveUserMessage(MQDocument doc, DWORD src_product, DWORD src_id, const char *description, void *message) {
		IOnReceiveUserMessage^ iPlugin = dynamic_cast<IOnReceiveUserMessage^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnReceiveUserMessage(doc,src_product,src_id,description,message);
		return CommandPluginDefault().OnReceiveUserMessage(doc,src_product,src_id,description,message);
	}
	void PluginMainHolder::OnDraw(MQDocument doc, MQScene scene, int width, int height) {
		IOnDraw^ iPlugin = dynamic_cast<IOnDraw^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnDraw(doc, scene, width, height);
	}
	void PluginMainHolder::OnNewDocument(MQDocument doc, const char *filename, MQStationPlugin::NEW_DOCUMENT_PARAM& param) {
		IOnNewDocument^ iPlugin = dynamic_cast<IOnNewDocument^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnNewDocument(doc, filename, param);
	}
	void PluginMainHolder::OnEndDocument(MQDocument doc) {
		IOnEndDocument^ iPlugin = dynamic_cast<IOnEndDocument^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnEndDocument(doc);
	}
	void PluginMainHolder::OnSaveDocument(MQDocument doc, const char *filename, MQStationPlugin::SAVE_DOCUMENT_PARAM& param) {
		IOnSaveDocument^ iPlugin = dynamic_cast<IOnSaveDocument^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnSaveDocument(doc, filename, param);
	}
	BOOL PluginMainHolder::OnUndo(MQDocument doc, int undo_state) {
		IOnUndo^ iPlugin = dynamic_cast<IOnUndo^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnUndo(doc, undo_state);
		return CommandPluginDefault().OnUndo(doc, undo_state);
	}
	BOOL PluginMainHolder::OnRedo(MQDocument doc, int redo_state) {
		IOnRedo^ iPlugin = dynamic_cast<IOnRedo^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnRedo(doc, redo_state);
		return CommandPluginDefault().OnRedo(doc, redo_state);
	}
	void PluginMainHolder::OnUpdateUndo(MQDocument doc, int undo_state, int undo_size) {
		IOnUpdateUndo^ iPlugin = dynamic_cast<IOnUpdateUndo^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnUpdateUndo(doc, undo_state, undo_size);
	}
	void PluginMainHolder::OnObjectModified(MQDocument doc) {
		IOnObjectModified^ iPlugin = dynamic_cast<IOnObjectModified^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnObjectModified(doc);
	}
	void PluginMainHolder::OnObjectSelected(MQDocument doc) {
		IOnObjectSelected^ iPlugin = dynamic_cast<IOnObjectSelected^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnObjectSelected(doc);
	}
	void PluginMainHolder::OnUpdateObjectList(MQDocument doc) {
		IOnUpdateObjectList^ iPlugin = dynamic_cast<IOnUpdateObjectList^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnUpdateObjectList(doc);
	}
	void PluginMainHolder::OnMaterialModified(MQDocument doc) {
		IOnMaterialModified^ iPlugin = dynamic_cast<IOnMaterialModified^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnMaterialModified(doc);
	}
	void PluginMainHolder::OnUpdateMaterialList(MQDocument doc) {
		IOnUpdateMaterialList^ iPlugin = dynamic_cast<IOnUpdateMaterialList^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnUpdateMaterialList(doc);
	}
	void PluginMainHolder::OnUpdateScene(MQDocument doc, MQScene scene) {
		IOnUpdateScene^ iPlugin = dynamic_cast<IOnUpdateScene^>(m_pluginMain);
		if ( iPlugin != nullptr ) iPlugin->OnUpdateScene(doc, scene);
	}
	BOOL PluginMainHolder::OnLeftButtonDown(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnLeftButtonDown^ iPlugin = dynamic_cast<IOnLeftButtonDown^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnLeftButtonDown(doc, scene, state);
		return CommandPluginDefault().OnLeftButtonDown(doc, scene, state);
	}
	BOOL PluginMainHolder::OnLeftButtonMove(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnLeftButtonMove^ iPlugin = dynamic_cast<IOnLeftButtonMove^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnLeftButtonMove(doc, scene, state);
		return CommandPluginDefault().OnLeftButtonMove(doc, scene, state);
	}
	BOOL PluginMainHolder::OnLeftButtonUp(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnLeftButtonUp^ iPlugin = dynamic_cast<IOnLeftButtonUp^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnLeftButtonUp(doc, scene, state);
		return CommandPluginDefault().OnLeftButtonUp(doc, scene, state);
	}
	BOOL PluginMainHolder::OnMiddleButtonDown(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnMiddleButtonDown^ iPlugin = dynamic_cast<IOnMiddleButtonDown^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnMiddleButtonDown(doc, scene, state);
		return CommandPluginDefault().OnMiddleButtonDown(doc, scene, state);
	}
	BOOL PluginMainHolder::OnMiddleButtonMove(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnMiddleButtonMove^ iPlugin = dynamic_cast<IOnMiddleButtonMove^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnMiddleButtonMove(doc, scene, state);
		return CommandPluginDefault().OnMiddleButtonMove(doc, scene, state);
	}
	BOOL PluginMainHolder::OnMiddleButtonUp(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnMiddleButtonUp^ iPlugin = dynamic_cast<IOnMiddleButtonUp^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnMiddleButtonUp(doc, scene, state);
		return CommandPluginDefault().OnMiddleButtonUp(doc, scene, state);
	}
	BOOL PluginMainHolder::OnRightButtonDown(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnRightButtonDown^ iPlugin = dynamic_cast<IOnRightButtonDown^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnRightButtonDown(doc, scene, state);
		return CommandPluginDefault().OnRightButtonDown(doc, scene, state);
	}
	BOOL PluginMainHolder::OnRightButtonMove(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnRightButtonMove^ iPlugin = dynamic_cast<IOnRightButtonMove^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnRightButtonMove(doc, scene, state);
		return CommandPluginDefault().OnRightButtonMove(doc, scene, state);
	}
	BOOL PluginMainHolder::OnRightButtonUp(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnRightButtonUp^ iPlugin = dynamic_cast<IOnRightButtonUp^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnRightButtonUp(doc, scene, state);
		return CommandPluginDefault().OnRightButtonUp(doc, scene, state);
	}
	BOOL PluginMainHolder::OnMouseMove(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnMouseMove^ iPlugin = dynamic_cast<IOnMouseMove^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnMouseMove(doc, scene, state);
		return CommandPluginDefault().OnMouseMove(doc, scene, state);
	}
	BOOL PluginMainHolder::OnMouseWheel(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnMouseWheel^ iPlugin = dynamic_cast<IOnMouseWheel^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnMouseWheel(doc, scene, state);
		return CommandPluginDefault().OnMouseWheel(doc, scene, state);
	}
	BOOL PluginMainHolder::OnKeyDown(MQDocument doc, MQScene scene, int key, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnKeyDown^ iPlugin = dynamic_cast<IOnKeyDown^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnKeyDown(doc, scene, key, state);
		return CommandPluginDefault().OnKeyDown(doc, scene, key, state);
	}
	BOOL PluginMainHolder::OnKeyUp(MQDocument doc, MQScene scene, int key, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		IOnKeyUp^ iPlugin = dynamic_cast<IOnKeyUp^>(m_pluginMain);
		if ( iPlugin != nullptr ) return iPlugin->OnKeyUp(doc, scene, key, state);
		return CommandPluginDefault().OnKeyUp(doc, scene, key, state);
	}
	/// @endcond

	bool StationPluginsInterfacedBase::ExecuteCallback(MQDocument doc, void *option) {
		return CommandPluginDefault().ExecuteCallback(doc, option);
	}
	BOOL StationPluginsInterfacedBase::IsActivated(MQDocument doc) {
		return CommandPluginDefault().IsActivated(doc);
	}
	void StationPluginsInterfacedBase::OnMinimize(MQDocument doc, BOOL flag) {
		CommandPluginDefault().OnMinimize(doc, flag);
	}
	int StationPluginsInterfacedBase::OnReceiveUserMessage(MQDocument doc, DWORD src_product, DWORD src_id, const char *description, void *message) {
		return CommandPluginDefault().OnReceiveUserMessage(doc, src_product, src_id, description, message);
	}
	void StationPluginsInterfacedBase::OnDraw(MQDocument doc, MQScene scene, int width, int height) {
		CommandPluginDefault().OnDraw(doc, scene, width, height);
	}
	void StationPluginsInterfacedBase::OnNewDocument(MQDocument doc, const char *filename, MQStationPlugin::NEW_DOCUMENT_PARAM& param) {
		CommandPluginDefault().OnNewDocument(doc, filename, param);
	}
	void StationPluginsInterfacedBase::OnEndDocument(MQDocument doc) {
		CommandPluginDefault().OnEndDocument(doc);
	}
	void StationPluginsInterfacedBase::OnSaveDocument(MQDocument doc, const char *filename, MQStationPlugin::SAVE_DOCUMENT_PARAM& param) {
		CommandPluginDefault().OnSaveDocument(doc, filename, param);
	}
	BOOL StationPluginsInterfacedBase::OnUndo(MQDocument doc, int undo_state) {
		return CommandPluginDefault().OnUndo(doc, undo_state);
	}
	BOOL StationPluginsInterfacedBase::OnRedo(MQDocument doc, int redo_state) {
		return CommandPluginDefault().OnRedo(doc, redo_state);
	}
	void StationPluginsInterfacedBase::OnUpdateUndo(MQDocument doc, int undo_state, int undo_size) {
		CommandPluginDefault().OnUpdateUndo(doc, undo_state, undo_size);
	}
	void StationPluginsInterfacedBase::OnObjectModified(MQDocument doc) {
		CommandPluginDefault().OnObjectModified(doc);
	}
	void StationPluginsInterfacedBase::OnObjectSelected(MQDocument doc) {
		CommandPluginDefault().OnObjectSelected(doc);
	}
	void StationPluginsInterfacedBase::OnUpdateObjectList(MQDocument doc) {
		CommandPluginDefault().OnUpdateObjectList(doc);
	}
	void StationPluginsInterfacedBase::OnMaterialModified(MQDocument doc) {
		CommandPluginDefault().OnMaterialModified(doc);
	}
	void StationPluginsInterfacedBase::OnUpdateMaterialList(MQDocument doc) {
		CommandPluginDefault().OnUpdateMaterialList(doc);
	}
	void StationPluginsInterfacedBase::OnUpdateScene(MQDocument doc, MQScene scene) {
		CommandPluginDefault().OnUpdateScene(doc, scene);
	}
	int StationPluginsInterfacedBase::SendUserMessage(MQDocument doc, DWORD target_product, DWORD target_id, const char *description, void *param) {
		if ( basePlugin == NULL ) return 0;
		return basePlugin->SendUserMessage(doc,target_product,target_id,description,param);
	}
	void StationPluginsInterfacedBase::WindowClose() {
		MQStationPlugin* plugin = dynamic_cast<MQStationPlugin*>(basePlugin);
		if ( plugin != NULL ) plugin->WindowClose();
		else ::MessageBox(0,0,0,0);
	}
	void StationPluginsInterfacedBase::BeginCallback(void* option) {
		MQStationPlugin* plugin = dynamic_cast<MQStationPlugin*>(basePlugin);
		if ( plugin != NULL ) plugin->BeginCallback(option);
	}
	void StationPluginsInterfacedBase::GetPlugInID(DWORD *Product, DWORD *ID) {
		MQBasePlugin* plugin = basePlugin;
		if ( plugin != NULL ) return plugin->GetPlugInID(Product,ID);
	}
	DWORD StationPluginsInterfacedBase::ProductID::get() {
		DWORD ProductID = -1, PluginID = -1;
		GetPlugInID(&ProductID, &PluginID);
		return ProductID;
	}
	DWORD StationPluginsInterfacedBase::PluginID::get() {
		DWORD ProductID = -1, PluginID = -1;
		GetPlugInID(&ProductID, &PluginID);
		return PluginID;
	}
	const char* StationPluginsInterfacedBase::GetPlugInName() {
		MQBasePlugin* plugin = basePlugin;
		if ( plugin != NULL ) return plugin->GetPlugInName();
		return NULL;
	}
	int StationPluginsInterfacedBase::GetPlugInType() {
		MQBasePlugin* plugin = basePlugin;
		if ( plugin != NULL ) return plugin->GetPlugInType();
		return 0;
	}
	const char* StationPluginsInterfacedBase::EnumString() {
		MQStationPlugin* plugin = dynamic_cast<MQStationPlugin*>(basePlugin);
		if ( plugin != NULL ) plugin->EnumString();
		return NULL;
	}

	BOOL CommandPluginsInterfacedBase::OnLeftButtonDown(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnLeftButtonDown(doc, scene, state);
	}
	BOOL CommandPluginsInterfacedBase::OnLeftButtonMove(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnLeftButtonMove(doc, scene, state);
	}
	BOOL CommandPluginsInterfacedBase::OnLeftButtonUp(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnLeftButtonUp(doc, scene, state);
	}
	BOOL CommandPluginsInterfacedBase::OnMiddleButtonDown(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnMiddleButtonDown(doc, scene, state);
	}
	BOOL CommandPluginsInterfacedBase::OnMiddleButtonMove(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnMiddleButtonMove(doc, scene, state);
	}
	BOOL CommandPluginsInterfacedBase::OnMiddleButtonUp(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnMiddleButtonUp(doc, scene, state);
	}
	BOOL CommandPluginsInterfacedBase::OnRightButtonDown(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnRightButtonDown(doc, scene, state);
	}
	BOOL CommandPluginsInterfacedBase::OnRightButtonMove(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnRightButtonMove(doc, scene, state);
	}
	BOOL CommandPluginsInterfacedBase::OnRightButtonUp(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnRightButtonUp(doc, scene, state);
	}
	BOOL CommandPluginsInterfacedBase::OnMouseMove(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnMouseMove(doc, scene, state);
	}
	BOOL CommandPluginsInterfacedBase::OnMouseWheel(MQDocument doc, MQScene scene, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnMouseWheel(doc, scene, state);
	}
	BOOL CommandPluginsInterfacedBase::OnKeyDown(MQDocument doc, MQScene scene, int key, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnKeyDown(doc, scene, key, state);
	}
	BOOL CommandPluginsInterfacedBase::OnKeyUp(MQDocument doc, MQScene scene, int key, MQCommandPlugin::MOUSE_BUTTON_STATE& state) {
		return CommandPluginDefault().OnKeyUp(doc, scene, key, state);
	}
	
/*! @brief MQCLIライブラリの初期化
@return Initializeは有効なインスタンスが設定された一回目だけ成功しtrueを返します。nullptrや二度目のInitializeは失敗してfalseを返します。
@details MQCLI::StationPluginを継承したクラスは一度だけそのプラグインクラスの継承インスタンスを確保し、以下のサンプルのように MQCLI::Initialize() に渡してください。
@code
#include "MQx/MQCLI.hpp"

public ref class CustomPlugin : MQCLI::StationPlugin {
public:
	CustomPlugin() : StationPlugin( "tiritomato", "Sample Copyright(C) 2013, tiritomato.", "SampleButton" ) {}
	virtual BOOL Activate(MQDocument doc, BOOL flag) override {
		if ( flag == TRUE ) ::MessageBox( MQ_GetWindowHandle(), "Activate!", NULL, 0 );
		return flag;
	}
};

static bool initialResult = MQCLI::Initialize( gcnew CustomPlugin() );
@endcode
このサンプルではコマンドプラグインのActivate()メソッドをオーバーライドして、コマンドボタンを選択した時にメッセージボックスを表示します。
@ref MQCLIの使い方 "プロジェクト設定"
に問題なければ、この数行のコンパイルは成功し、そのままプラグインDLLのインストールとテストが実行できるはずです。
*/
	bool Initialize( MQCLI::StationPlugin^ pluginBody ) { return PluginMainHolder::Regist( pluginBody ); }
	
/*! @brief MQCLIライブラリの初期化
@return Initializeは有効なインスタンスが設定された一回目だけ成功しtrueを返します。nullptrや二度目のInitializeは失敗してfalseを返します。
@details MQCLI::CommandPluginを継承したクラスは一度だけそのプラグインクラスの継承インスタンスを確保し、以下のサンプルのように MQCLI::Initialize() に渡してください。
@code
#include "MQx/MQCLI.hpp"

public ref class CustomPlugin : MQCLI::CommandPlugin {
public:
	CustomPlugin() : CommandPlugin( "tiritomato", "Sample Copyright(C) 2013, tiritomato.", "SampleButton" ) {}
	virtual BOOL Activate(MQDocument doc, BOOL flag) override {
		if ( flag == TRUE ) ::MessageBox( MQ_GetWindowHandle(), "Activate!", NULL, 0 );
		return flag;
	}
};

static bool initialResult = MQCLI::Initialize( gcnew CustomPlugin() );
@endcode
このサンプルではコマンドプラグインのActivate()メソッドをオーバーライドして、コマンドボタンを選択した時にメッセージボックスを表示します。
@ref MQCLIの使い方 "プロジェクト設定"
に問題なければ、この数行のコンパイルは成功し、そのままプラグインDLLのインストールとテストが実行できるはずです。
*/
	bool Initialize( MQCLI::CommandPlugin^ pluginBody ) { return PluginMainHolder::Regist( pluginBody ); }
}

/*!
	@brief DLLエントリーポイント
	@attention
		アンマネージド／マネージド混合アプリにおいてDLLMain中にマネージドコードを実行するとロックする危険があるため、DllMainでは何もしないで下さい。
		代わりに、グローバル変数の初期化ロジックで対応する事を検討してください。
*/
#pragma unmanaged
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

#pragma managed
MQBasePlugin *GetPluginClass() {
	return MQCLI::PluginMainHolder::pluginMain;
}

#endif