////////////////////////////////////////////////////////////////////////////////
//
//	　このクラスは継承して使用するテンプレートクラスである。
//	　CEditのような基本コントロールクラスの代わりとして継承する。
//	　TBaseとして継承すべきだったコントロールクラスを指定する。
//	　例えば、CMwlmfcEditExクラスと言う新規クラスを作成し、
//	　CEditの代わりとして本クラスを使用する場合は、以下のようにする。
//
//		class CMwlmfcEditEx : public CEdit
//								↓
//		class CMwlmfcEditEx : public CMfcExtSingleData<CEdit>
//
//	　・継承先のBEGIN/END_MESSAGE_MAP内にて ON_WM_DROPFILES()、ON_WM_DESTROY() を
//		定義しておく必要がある。なお、これの代わりとして MESD_MESSAGE_MAPS
//		マクロを使用することが出来る。
//		（ただし、ClassWizardはこのマクロを認識してくれないので注意が必要・・・）
//
//	　・operator = はC++仕様上継承する事が出来ない。よって継承先にて operator =
//		を再定義する必要がある。なお、これの代わりとして MESD_OPERATOR_EQ
//		マクロを使用することが出来る。
//
////////////////////////////////////////////////////////////////////////////////

#ifndef __MfcExtSingleData_H__
#define __MfcExtSingleData_H__

/*#define MESD_MESSAGE_MAPS(CLASS_NAME,BASE_CLASS)	\
	BEGIN_MESSAGE_MAP(CLASS_NAME, BASE_CLASS)	\
		ON_WM_DROPFILES()	\
		ON_WM_DESTROY()	\
	END_MESSAGE_MAP()
*/

namespace mwlmfc{

#define MESD_MESSAGE_MAPS	\
	ON_WM_DROPFILES()	\
	ON_WM_DESTROY()

/*#define ON_MESD_MESSAGE_MAPS()	\
	ON_WM_DROPFILES()	\
	ON_WM_DESTROY()*/

#define MESD_OPERATOR_EQ	operator =(const char* s){ operator_eq(s); }

//	クラス宣言
template <typename TBase> class CMfcExtSingleData : public TBase
//template <typename TBase> class CMfcExtSingleData : public virtual TBase, virtual CWnd
{
private:
	CString m_cstrData;

protected:
	//	ファイルドロップ
	void OnDropFiles(HDROP hDropInfo)
	{
		int nFileCount = DragQueryFile( hDropInfo, 0xffffffff, NULL,0 );
		if ( nFileCount > 1 ){
			MessageBox( "1つ以上のオブジェクトをドラッグ&ドロップすることはできません。" );
		}
		else
		{
			char szFile[1024];
			if ( DragQueryFile( hDropInfo, 0, szFile, sizeof(szFile) ) >= sizeof(szFile) )
			{
				MessageBox( "ま、まさかそんな長いファイルパスが来るとは…！？(残念ながら1023文字までしか対応してない)" );
			}
			else
			{
				//SetWindowText( szFile );
				VirtualSetWindowText( szFile );
			}
		}
		
		TBase::OnDropFiles(hDropInfo);
	}

	//	CDialog::DoModalが終わると呼ばれてしまうらしい
	void OnDestroy(){
		//	ちょいと待った！CStringにとってくるぞ
		GetWindowText( m_cstrData );

		TBase::OnDestroy();
	}

	//	仮想関数（継承先で挙動を変更可能）
	virtual void VirtualSetWindowText( const char* szText ){
		CWnd::SetWindowText( szText );
	}

public:
	//	コンストラクタ・デストラクタ
	CMfcExtSingleData(){}
	virtual ~CMfcExtSingleData(){}

	//	オペレータオーバーロード
	operator LPCTSTR(){
		if ( m_hWnd != NULL )
			GetWindowText( m_cstrData );
		return m_cstrData;
	}
	//operator =( const char* szText ){ <-- operator =は継承不可（´・ω・`）なC++の仕様
	//	継承側でoperator =を実装し、内部で以下のメソッドを呼び出す事！
	const char* operator_eq( const char* szText ){
		if ( m_hWnd != NULL )
			VirtualSetWindowText( szText );
			//SetWindowText( szText );
		return szText;
	}
};

//typedef CMfcExtSingleData<TBase> CMfcWindowTextEx<TBase>;
#define CMfcWindowTextEx CMfcExtSingleData


////////////////////////////////////////////////////////////

template <typename T, typename TREF=T> class CGenericControlBase
{
protected:
	//std::vector<T> m_cenericList;
	std::map<int,T> m_cenericList;
	int m_indexCounter;
	
public:
	CGenericControlBase(){
		m_indexCounter = 0;
	}
	
	int AddGeneric(TREF val){
		m_indexCounter++;
		m_cenericList[m_indexCounter] = val;
		return m_indexCounter;
	}
	T& GetGenericByIndex(int index){
		std::map<int,T>::iterator it = m_cenericList.find(index);
		if ( it == m_cenericList.end() )
			throw string("GetGenericByIndex: failed index");

		return it->second;
	}
};

}//namespace mwlmfc

#endif//__MfcExtSingleData_H__
