CEで全画面表示(3)
FactoryとRTTIもどきを実装するために、以下のようなマクロを用意しています。
// ファクトリーベース class CPageFactoryBase { public: virtual CAbstractPage* CreateInstance(CWnd* pParent) = 0; }; // ファクトリーテンプレート template <class T> class CPageFactory : public CPageFactoryBase { public: virtual CAbstractPage* CreateInstance(CWnd* pParent) { return( new T( pParent ) ); } };
// メタ情報ベース class CPageInfoBase { public: CPageInfoBase(UINT nDialogID) : m_nDialogID( nDialogID ) { } protected: UINT m_nDialogID; public: UINT GetDialogId() { return( m_nDialogID ); } virtual CPageFactoryBase* GetFactory() = 0; }; // メタ情報テンプレート template <class T> class CPageInfo : public CPageInfoBase { public: CPageInfo(UINT nPageID) : CPageInfoBase( nPageID ) { } public: virtual CPageFactoryBase* GetFactory() { return( &m_factory ); } protected: CPageFactory< T > m_factory; };
// メタ情報取得 #define PAGE_INTO( class_name ) \ ((CPageInfoBase*)(&class_name::m_pageinfo)) \ // メタ情報宣言 #define DECLARE_PAGEINFO( class_name ) \ public: \ friend class CPageFactory<class_name>; \ public: \ static const CPageInfo<class_name> m_pageinfo; \ public: \ virtual CPageInfoBase* GetPageInfo() { return( PAGE_INTO( class_name ) ); } \ // メタ情報実装 #define IMPLEMENT_PAGEINFO( class_name ) \ const CPageInfo<class_name> class_name::m_pageinfo = CPageInfo<class_name>( class_name##::IDD ); \
ヘッダファイルにDECLARE_PAGEINFO、ソースファイルにIMPLEMENT_PAGEINFOを定義することにより、クラスのstaticメンバとしてメタ情報CPageInfoBaseが定義されます。
CPageInfoBaseにはFactoryとRTTI代わりのIDが定義されるため、これを用いてフレームワーク内でリフレクションもどきが実現できるようになります。
フレームワークのコントローラーには、画面IDと型情報としてCPageInfoBase*(PAGE_INTO(クラス名))を渡すわけですね。
同じ様なしかけをどこかで見たな…っというわけで、つまりMFCのDECLARE_DYNAMIC、IMPLEMENT_DYNAMIC、RUNTIME_CLASSのパクリなわけです(・∀・)