Click here to Skip to main content
15,885,811 members
Articles / Desktop Programming / MFC

The SBJ MVC Framework - The Design View, Responding to Model Change

Rate me:
Please Sign up or sign in to vote.
4.87/5 (22 votes)
19 Mar 2009CPOL13 min read 80.5K   2.4K   51  
A Model-View-Controller Framework that integrates with the MFC Doc/View architecture.
//------------------------------------------------------------------------------
// $Workfile: ModelController.h $
// $Header: /SbjDev/SbjCore/ModelController.h 4     11/24/08 10:33a Steve $
//
//	Copyright � 2008 SbjCat
// All rights reserved.
//
//
// *** Authors ***
//	 Steve Johnson
//
// $Revision: 4 $
//
//-----------------------------------------------------------------------------

#pragma once

#include "ControlledCmdTargetT.h"
#include "ModelTypeDefs.h"
#include "ModelDataTypes.h"

namespace SbjCore
{
	namespace Mvc
	{
		namespace Model
		{
			struct ControllerImpl;

			class AFX_EXT_CLASS Controller : public CmdTargetController
			{
				typedef CmdTargetController t_Base;

				DECLARE_DYNAMIC(Controller)
			public:
				Controller();
				virtual ~Controller();
				
			public:
				/*
				The abstract Model::Controller defines a static value of 
				0xFFFFFFFF for the root item of any Model. Concrete
				implementations are free to use any unique identification
				scheme for individual ModelItems.
				*/
				static HANDLE GetItemRoot();

			public:
				/*
				The Model::Controller provides UndoRedo services for all 
				abstract methods. The MessageHandlers that actually handle
				the ID_EDIT_UNDO and ID_EDIT_REDO messages, can access the
				UndoRedoMgr class through this call.
				*/
				SbjCore::UndoRedo::Manager* GetUndoRedoMgr() const;
				
				/*
				Retrieves the collection of currently selected ModelItems.
				*/
				int GetSelectedItems(ItemHandles& selItems) const;
				/*
				Initializes the collection of currently selected ModelItems.
				*/
				void SetSelectedItems(const ItemHandles& selItems);
				/*
				Clears the collection of currently selected ModelItems.
				*/
				void ClearSelectedItems();

			public:
				/*
				Calls the abstract private method OnCreateItem which is 
				implemented in a concrete derived Model class.
				*/
				HANDLE CreateItem(LPCTSTR lpszItemType);
				
				/*
				Calls the abstract private method OnInsertChild which is 
				implemented in a concrete derived Model class. The action
				of inserting the child can optionally be added to the UndoRedo
				management provided by the Model::Controller.
				*/
				bool InsertChild(
					const HANDLE hChild,
					const HANDLE hParent,
					const HANDLE hAfter = NULL,
					bool bAddToUndoRedo = true);

				/*
				Calls the abstract private method OnRemoveChild which is 
				implemented in a concrete derived Model class.   The action
				of inserting the child can optionally be added to the UndoRedo
				management provided by the Model::Controller.
				*/
				bool RemoveChild(
					const HANDLE hChild,
					bool bAddToUndoRedo = true);

				/*
				Calls the abstract private method OnGetItemAttrValue which is 
				implemented in a concrete derived Model class.
				*/
				_variant_t GetItemAttrValue(
					const HANDLE hItem, 
					const CString& sAttrName) const;

				/*
				Calls the abstract private method OnSetItemAttrValue which is 
				implemented in a concrete derived Model class.  The action
				of inserting the child can optionally be added to the UndoRedo
				management provided by the Model::Controller.
				*/
				bool SetItemAttrValue(
					const HANDLE hItem, 
					const CString& sAttrName, 
					const _variant_t& val,
					bool bAddToUndoRedo = false, 
					bool bFireEvents = false);

				/*
				Calls the abstract private method OnAssureUniqueItemAttrValue
				which is implemented in a concrete derived Model class.
				*/
				CString AssureUniqueItemAttrValue(
					const HANDLE hItem, 
					const CString& sAttrName, 
					const _variant_t& val) const;

				/*
				Calls the private method OnCookAttrName which by default takes
				a camelCase attribute name and capitalizes the first letter and
				splits the name at successive capitals by inserting a space. 
				Derivative Models are free to override this behavior.
				*/
				CString CookAttrName(const CString& sAttrName) const;

				/*
				Calls the abstract private method OnGetItemTypeName
				which is implemented in a concrete derived Model class.
				*/
				CString GetItemTypeName(HANDLE hItem) const;
				
				/*
				Calls the abstract private method OnGetParentItem
				which is implemented in a concrete derived Model class.
				*/
				HANDLE GetParentItem(const HANDLE hItem) const;

				/*
				Calls the abstract private method OnGetItemChildern
				which is implemented in a concrete derived Model class.
				*/
				int GetItemChildren(HANDLE hItem, SbjCore::Mvc::Model::ItemHandles& items) const; // NULL hItem returns root

				/*
				Calls the abstract private method OnGetItemAttrNames
				which is implemented in a concrete derived Model class.
				*/
				int GetItemAttrNames(HANDLE hItem, SbjCore::Mvc::Model::ItemAttrNames& attrNames) const;
				
				/*
				Calls the abstract private method OnGetItemAttrName
				which is implemented in a concrete derived Model class.
				*/
				CString GetItemAttrName(HANDLE hItem, int nAttrIndex) const;

			private:				
				/*
				By default takes a camelCase attribute name and capitalizes 
				the first letter and splits the name at successive capitals 
				by inserting a space. Derivative Models are free to override 
				this behavior.
				*/
				virtual CString OnCookAttrName(const CString& sAttrName) const;

			private:
				/*
				Implemented in concrete Model derivations to create a ModelItem
				of the lpszItemType named Model type and return a unique HANDLE 
				to it.
				*/
				virtual HANDLE OnCreateItem(LPCTSTR lpszItemType) = 0;

				/*
				Implemented in concrete Model derivations to Insert a ModelItem
				as a child if the hParent Item. Optionally the Item can be
				inserted after the hAfter Item. 
				*/
				virtual bool OnInsertChild(
					const HANDLE hChild,
					const HANDLE hParent,
					const HANDLE hAfter) = 0;

				/*
				Implemented in concrete Model derivations to Remove a ModelItem
				from the Model. 
				*/
				virtual bool OnRemoveChild(
					const HANDLE hChild) = 0;

				/*
				Implemented in concrete Model derivations to retrieve the value
				of a ModelItem attribute by name.
				*/
				virtual _variant_t OnGetItemAttrValue(
					const HANDLE hItem, 
					const CString& sAttrName) const = 0;

				/*
				Implemented in concrete Model derivations to set the value
				of a ModelItem attribute by name.
				*/
				virtual bool OnSetItemAttrValue(
					const HANDLE hItem, 
					const CString& sAttrName, 
					const _variant_t& val) = 0;

				/*
				Implemented in concrete Model derivations to assure that the
				attribute value is unique among attributes of sibling ModelItems.
				*/
				virtual CString OnAssureUniqueItemAttrValue(
					const HANDLE hItem, 
					const CString& sAttrName, 
					const _variant_t& val) const = 0;

				/*
				Implemented in concrete Model derivations to retrieve the ModelItem
				type name.
				*/
				virtual CString OnGetItemTypeName(HANDLE hItem) const = 0;
				
				/*
				Implemented in concrete Model derivations to retrieve the ModelItem
				parent.
				*/
				virtual HANDLE OnGetParentItem(const HANDLE hItem) const = 0;

				/*
				Implemented in concrete Model derivations to retrieve the children of 
				the ModelItem.
				*/
				virtual int OnGetItemChildren(HANDLE hItem, SbjCore::Mvc::Model::ItemHandles& items) const = 0;

				/*
				Implemented in concrete Model derivations to retrieve the names of all attributes of 
				the ModelItem.
				*/
				virtual int OnGetItemAttrNames(HANDLE hItem, SbjCore::Mvc::Model::ItemAttrNames& attrNames) const = 0;

			private:
				struct ControllerImpl* const m_pImpl;
			};

			/*
			Returns the Controller for the currently active Model.
			*/
			AFX_EXT_API Controller* GetCurController();
		}
	}
}

//*** Modification History ***
// $Log: /SbjDev/SbjCore/ModelController.h $
// 
// 4     11/24/08 10:33a Steve
// Final changes before MVCChapt1 v2.0.1
// 
// 3     11/12/08 2:22p Steve
// Finished Generalization of Model  v2.0.1
// 
// 2     10/28/08 11:41a Steve
// 
// 1     10/28/08 11:12a Steve
// 
// 2     10/26/08 9:19a Steve
// 
// 1     10/24/08 9:03a Steve

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
SBJ
United States United States
Real name is Steve Johnson. Programming since 1979. Started on a Heathkit Micro with a DEC LSI-11 and UCSD Pascal. Moved to PCs & DOS as soon as Turbo Pascal became available. Did some Assembly, ISR, TSR etc. All this while working for a Manufacturing Co. for 8 years. Had my own solo Co. doing barcode labeling software for 4 years (terrible business man, all I wanted to do was code). Since then working for various software companies. Moved to Windows around the time of 3.1 with Borland C then C++. Then on to VC++ and MFC, and just about anything I could get my hands on or had to learn for my job, and been at it ever since. Of course recently I've been playing with .NET, ASP, C#, WPF etc.

Comments and Discussions