Click here to Skip to main content
15,896,207 members
Articles / Mobile Apps

The StateWizard VC++ Add-in and Engine with Source Code

Rate me:
Please Sign up or sign in to vote.
4.73/5 (24 votes)
26 Mar 2009CPOL12 min read 190.9K   2.8K   132  
A cross-platform state-oriented application framework and a ClassWizard-like round-trip UML dynamic modeling/development tool that runs in popular IDEs. Aims at providing concurrent, distributed, and real-time application development tools for Win32/Linux
/**********************************************************************
UML StateWizard provides its software under the LGPL License and 
zlib/libpng License for open source projects.

Email us at info@intelliwizard.com for any information, suggestions and 
feature requestions.

Home Page: http://www.intelliwizard.com
*************************************************************************/

// AddEventDlg.cpp : implementation file
// Add evnet handler.

#include "stdafx.h"
#include "StateTree.h"
#include "AddEventDlg.h"
#include ".\addeventdlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAddEventDlg dialog


//CAddEventDlg::CAddEventDlg(IApplication * pApp, CWnd* pParent /*=NULL*/)
CAddEventDlg::CAddEventDlg(CWnd* pParent /*=NULL*/)
: CDialog(CAddEventDlg::IDD, pParent)
{
//	m_pApplication = pApp;
	//{{AFX_DATA_INIT(CAddEventDlg)
	m_eventHdlName = _T("");
	m_transitionStateName = _T("");
	m_eventID = _T("");
	//}}AFX_DATA_INIT
}


void CAddEventDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAddEventDlg)
	DDX_Control(pDX, IDC_TRANSITION_STATE_NAME_BOX, m_stateListBox);
	DDX_Text(pDX, IDC_EVENT_HANDLER_EDIT, m_eventHdlName);
	DDX_CBString(pDX, IDC_TRANSITION_STATE_NAME_BOX, m_transitionStateName);
	DDX_CBString(pDX, IDC_EVENT_ID_BOX, m_eventID);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CAddEventDlg, CDialog)
	//{{AFX_MSG_MAP(CAddEventDlg)
	ON_BN_CLICKED(IDC_INTERNAL_TRANSITION_RADIO, OnInternalTransationButton)
	ON_BN_CLICKED(IDC_TRANSITION_RADIO, OnTransactionStateButton)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_ACTION_CHECK, OnActionCheck)
	ON_CBN_EDITCHANGE(IDC_EVENT_ID_BOX, OnEditchangeEventIdBox)
	ON_CBN_SELCHANGE(IDC_EVENT_ID_BOX, OnSelchangeEventIdBox)
	ON_CBN_SELCHANGE(IDC_TRANSITION_STATE_NAME_BOX, OnSelchangeTransitionStateNameBox)
	//}}AFX_MSG_MAP
	ON_WM_HELPINFO()
END_MESSAGE_MAP()


/*	lack this message ON_WM_HELPINFO() */

/////////////////////////////////////////////////////////////////////////////
// CAddEventDlg message handlers
////////////////////////////////////////////////////////////////////////////
// DESCRIPTION: Initialize the AddEventDlg
// INPUT: None
// OUTPUT: None
// Note: 
////////////////////////////////////////////////////////////////////////////
BOOL CAddEventDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();

	CString sServiceHdrPath = m_pStateTree->m_EventIdFilePath;
	//!!! Update Interface
	BSTR bstrServiceHdrPath = _com_util::ConvertStringToBSTR(sServiceHdrPath.GetBuffer());
	m_pStateTree->Fire_TestOpenedDocIsModified(bstrServiceHdrPath,VARIANT_FALSE);
	sServiceHdrPath.ReleaseBuffer();

	if (sServiceHdrPath == "" || m_pStateTree->data.isOpenedDocModified==FALSE) // No any modification on event id header file.
		;
	else
	{
		// Update the event id list.
		m_pStateTree->m_EventIdList.RemoveAll();
		//!!! Update Interface
		//!!! From CString to BSTR & From CStringArray to a pointer VARIANT
		bstrServiceHdrPath=_com_util::ConvertStringToBSTR(sServiceHdrPath.GetBuffer());
		CComVariant pEventIdList;
		pEventIdList.puintVal=reinterpret_cast<UINT*>(&m_pStateTree->m_EventIdList);
		m_pStateTree->Fire_GetEventIdList(bstrServiceHdrPath,pEventIdList);
		m_pStateTree->data.Convert2StringArray(m_pStateTree->m_EventIdList, m_pStateTree->data.eventIdList);
		sServiceHdrPath.ReleaseBuffer();
	}

	// Delete every other item from the combo box.
	CComboBox* pEventIdBox = ((CComboBox*)GetDlgItem(IDC_EVENT_ID_BOX));
	for (int i=0;i < pEventIdBox->GetCount();i++)
	{
		pEventIdBox->DeleteString( i );
	}

	int nEventNum;
	int nSize = (int)m_pStateTree->m_EventIdList.GetSize();
	((CComboBox*)GetDlgItem(IDC_EVENT_ID_BOX))->Clear();
	for (nEventNum = 0; nEventNum < nSize; nEventNum++)
		pEventIdBox->InsertString(-1, (LPCTSTR)(m_pStateTree->m_EventIdList.GetAt(nEventNum)));

	// Set check on check box for action editor
	((CButton*)GetDlgItem(IDC_ACTION_CHECK))->SetCheck(1);

	// TODO: Add extra initialization here
	((CComboBox*)GetDlgItem(IDC_TRANSITION_STATE_NAME_BOX))->EnableWindow(FALSE);
	((CButton*)GetDlgItem(IDC_INTERNAL_TRANSITION_RADIO))->SetCheck(1);
	// ((CButton*)GetDlgItem(IDOK))->EnableWindow(FALSE);
	UpdateOKBtnStatus();
	m_bIsInternalTransition = TRUE;

	// Get current state name
	HTREEITEM hSelector;
	HTREEITEM hCurState;
	HTREEITEM hApp;

	hSelector = m_pStateTree->tree.GetSelectedItem();
	if (m_bIsEditEvent)
		hCurState = m_pStateTree->tree.GetParentItem(hSelector);
	else
		hCurState = hSelector;

	if (m_pStateTree->tree.GetItemData(hCurState) & STATE_TREE_APPLICATION_MASK)
	{
		CString sAppName;

		sAppName = m_pStateTree->tree.GetItemText(hCurState);

		((CStatic*)GetDlgItem(IDC_STATIC_CUR_STATE))->SetWindowText(sAppName);	
	}
	else if (m_pStateTree->tree.GetItemData(hCurState) & STATE_TREE_STATE_MASK)
	{
		CString sStateName;

		sStateName = m_pStateTree->tree.GetItemText(hCurState);
		if (m_pStateTree->tree.GetItemData(hCurState) & STATE_TREE_DEFAULT_STATE)
		{			
			int idx = sStateName.Find("  (default)");
			sStateName = sStateName.Left(idx);
		}
		((CStatic*)GetDlgItem(IDC_STATIC_CUR_STATE))->SetWindowText(sStateName);
	}

	// Initialize transition states box
	hApp =  m_pStateTree->tree.GetSelectedApp(hSelector);
	if (hApp)
		m_pStateTree->tree.TraverseStateTree(hApp, NULL, STATE_TREE_STATE_MASK|STATE_TREE_APPLICATION_MASK, &m_stateListBox);
	else
		return FALSE;

	if (m_bIsEditEvent)
	{	
		// Change window caption text
		SetWindowText("Edit Event Handler");

		HTREEITEM hChild;
		CString sEventID;
		CString sTransitStateName;
		CString sHandlerName;
		CString sInnerTransition = STR_INTERNAL_TRAN;

		// Get event id
		sEventID = m_pStateTree->tree.GetItemText(hSelector);
		//		sEventID = sEventID.Mid(13);
		((CComboBox*)GetDlgItem(IDC_EVENT_ID_BOX))->SetWindowText(sEventID);
		m_sOrigEventID = sEventID; // record original event id
		m_sOrigTransStateName = ""; // record original transition state name
		m_sOrigActionName = "";

		// Get event handler name and transaction state name
		hChild = m_pStateTree->tree.GetChildItem(hSelector);
		sTransitStateName = m_pStateTree->tree.GetItemText(hChild);
		if (sTransitStateName.Compare(sInnerTransition))
		{
			m_bIsInternalTransition  = FALSE;
			((CButton*)GetDlgItem(IDC_TRANSITION_RADIO))->SetCheck(1);
			((CButton*)GetDlgItem(IDC_INTERNAL_TRANSITION_RADIO))->SetCheck(0);

			sTransitStateName = sTransitStateName.Mid(13);
			((CComboBox*)GetDlgItem(IDC_TRANSITION_STATE_NAME_BOX))->EnableWindow(TRUE);
			if (((CComboBox*)GetDlgItem(IDC_TRANSITION_STATE_NAME_BOX))->SelectString(-1, sTransitStateName) == CB_ERR)
			{
				AfxMessageBox("The transition state may be deleted already. Choose another state to be transited to!", MB_OK | MB_ICONERROR);
			}
			m_sOrigTransStateName = sTransitStateName;
		}

		hChild = m_pStateTree->tree.GetNextSiblingItem(hChild);
		sHandlerName = m_pStateTree->tree.GetItemText(hChild);
		sHandlerName = sHandlerName.Mid(9);

		int idx = sHandlerName.Find("(struct SME_APP_T *pApp, struct SME_EVENT_T *pEvent)");
		if (idx != -1)
		{
			sHandlerName = sHandlerName.Left(idx);
			m_sOrigActionName = sHandlerName;
		}

		if (sHandlerName.IsEmpty())
		{
			((CButton*)GetDlgItem(IDC_ACTION_CHECK))->SetCheck(0);
			((CEdit*)GetDlgItem(IDC_EVENT_HANDLER_EDIT))->EnableWindow(FALSE);
		}
		((CEdit*)GetDlgItem(IDC_EVENT_HANDLER_EDIT))->SetWindowText(sHandlerName);
		//((CButton*)GetDlgItem(IDOK))->EnableWindow(TRUE);
		UpdateOKBtnStatus();
	}

//.	SME_TRACE("Create add event dialog!\n");

	return TRUE;  // return TRUE unless you set the focus to a control	              
	// EXCEPTION: OCX Property Pages should return FALSE				 
}

void CAddEventDlg::OnDestroy() 
{
	CDialog::OnDestroy();

	// TODO: Add your message handler code here
/*	SME_TRACE("Destroy add event dialog!\n");
	SME_ALLOC_MEM_SIZE();
*/
}

/////////////////////////////////////////////////////////////////////////////
// DESCRIPTION: Response to ok button click
// INPUT: None
// OUTPUT: None
// Note: 
/////////////////////////////////////////////////////////////////////////////
void CAddEventDlg::OnOK() 
{
	// TODO: Add extra validation here

	CString strHdrFullPath;
	CString strSrcFullPath;

	UpdateData(TRUE);

	// Check output validity
	m_eventID.TrimLeft();
	m_eventID.TrimRight();
	m_eventHdlName.TrimLeft();
	m_eventHdlName.TrimRight();

	if (m_eventID.Find(' ') != -1 || m_eventID.Find('\t') != -1 ||
		((((CButton*)GetDlgItem(IDC_ACTION_CHECK))->GetCheck() == 1) &&
		(m_eventHdlName.Find(' ') != -1 || m_eventHdlName.Find('\t') != -1 ||
		m_eventID.IsEmpty() || m_eventHdlName.IsEmpty())) ||
		((m_bIsInternalTransition == FALSE)&& m_transitionStateName == ""))
	{
		AfxMessageBox("Event ID and event handler name can not contain any white space.", MB_ICONERROR|MB_OK);
		return;
	}

	int nCharSeq = 0;
	while (true)
	{
		if (nCharSeq >= m_eventID.GetLength())
			break;

		char ch = m_eventID.GetAt(nCharSeq);
		if (nCharSeq == 0)
		{
			// The first character must be alphabetic or underline
			if (!((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_'))
			{
				AfxMessageBox("First letter in an event name must be '[A-Za-z|_]'.", MB_ICONERROR|MB_OK);
				return;
			}
		}
		else
		{
			if (!((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_' || (ch >= '0' && ch <= '9')))
			{
				AfxMessageBox("Letters in an event name must be '[A-Za-z|0-9|_]'.", MB_ICONERROR|MB_OK);
				return;
			}
		}
		nCharSeq++;
	}

	if (m_bIsEditEvent == FALSE)
	{
		//		CString sEventName = "Event name:  ";
		CString sEventName = "";
		CString sName;
		HTREEITEM hSelector = NULL;
		HTREEITEM hApp = NULL; 
		HTREEITEM hInsert = NULL;
		TV_INSERTSTRUCT Inserter;  /* define insert item structure */

		sEventName += m_eventID;
		hSelector = m_pStateTree->tree.GetSelectedItem();
		if(hSelector)
		{	
			if (IsUniqueEventID(m_eventID, hSelector) != NULL)
			{
				MessageBox("Error!\nA handler for this event already exists. Please choose another event.",0,MB_OK|MB_ICONERROR);
				return;
			}

			hApp = m_pStateTree->tree.GetSelectedApp(hSelector);
			sName = m_pStateTree->tree.GetItemText(hApp);

			CString sSelName;
			DWORD lmark;
			// retrieve current item name
			sSelName = m_pStateTree->tree.GetItemText(hSelector);
			lmark = m_pStateTree->tree.GetItemData(hSelector);

			if (lmark & STATE_TREE_STATE_MASK)
			{
				//				sSelName.Replace("State name:", NULL);
				sSelName.Replace("(default)", NULL);
				sSelName.TrimLeft();
				sSelName.TrimRight();
			}
			CStringArray AppPathList;
			AppPathList.RemoveAll();
			m_pStateTree->GetAppSrcHdrPath(AppPathList, sName, hSelector);
			strHdrFullPath = AppPathList.GetAt(0);
			strSrcFullPath = AppPathList.GetAt(1);

			if (((CButton*)GetDlgItem(IDC_ACTION_CHECK))->GetCheck() == 0)
				m_eventHdlName = "NULL";
			
			BSTR bstrSrcFullPath = _com_util::ConvertStringToBSTR(strSrcFullPath.GetBuffer());
			BSTR bstrHdrFullPath = _com_util::ConvertStringToBSTR(strHdrFullPath.GetBuffer());
			BSTR bstrName = _com_util::ConvertStringToBSTR(sName.GetBuffer());
			BSTR bstrSelName = _com_util::ConvertStringToBSTR(sSelName.GetBuffer());
			BSTR bstrTransitionStateName = _com_util::ConvertStringToBSTR(m_transitionStateName.GetBuffer());
			BSTR bstrEventID = _com_util::ConvertStringToBSTR(m_eventID.GetBuffer());
			BSTR bstrEventHdlName = _com_util::ConvertStringToBSTR(m_eventHdlName.GetBuffer());

			if (m_bIsInternalTransition == TRUE)
			{			
				
				m_pStateTree->Fire_CheckAddEventAtomic(bstrSrcFullPath,bstrHdrFullPath,bstrName,bstrSelName,CComBSTR(""),bstrEventID,bstrEventHdlName);
				if (!m_pStateTree->data.isAddEventAtomic)
				{
					goto final;
					//CDialog::OnOK();
					//return;
				}
			}
			else
			{
				m_pStateTree->Fire_CheckAddEventAtomic(bstrSrcFullPath,bstrHdrFullPath,bstrName,bstrSelName,bstrTransitionStateName,bstrEventID,bstrEventHdlName);
				if (!m_pStateTree->data.isAddEventAtomic)
				{
					goto final;
					//CDialog::OnOK();
					//return;
				}
			}
			strSrcFullPath.ReleaseBuffer();
			strHdrFullPath.ReleaseBuffer();
			sName.ReleaseBuffer();
			sSelName.ReleaseBuffer();
			m_transitionStateName.ReleaseBuffer();
			m_eventID.ReleaseBuffer();
			m_eventHdlName.ReleaseBuffer();

			Inserter.hParent = hSelector; 
			Inserter.hInsertAfter = TVI_LAST;//insert position
			Inserter.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE;//set mask
			Inserter.item.pszText = (LPTSTR)(LPCTSTR)(sEventName);
			Inserter.item.lParam = STATE_TREE_EVENT_ID_MASK;//to be expand to check event id redundancy

			hInsert= m_pStateTree->tree.InsertItem(&Inserter);//do insert

			TV_SORTCB SortCB;
			SortCB.hParent = hSelector;
			SortCB.lpfnCompare = CompareFunc;
			SortCB.lParam = 0;
			m_pStateTree->tree.SortChildrenCB(&SortCB);
			m_pStateTree->tree.SetItemImage(hInsert, 6, 6);
			m_pStateTree->tree.SelectItem(hInsert);
			AddStateEventHdler();
		}
	}
	else
	{
		// Edit an event handler
		if (((((CButton*)GetDlgItem(IDC_ACTION_CHECK))->GetCheck() == 0) && (m_sOrigActionName != "")) ||
			((((CButton*)GetDlgItem(IDC_ACTION_CHECK))->GetCheck() == 1) && (m_sOrigActionName != m_eventHdlName)) ||
			((m_bIsInternalTransition == TRUE) && (m_sOrigTransStateName != "")) ||
			((m_bIsInternalTransition == FALSE) && (m_sOrigTransStateName != m_transitionStateName)) ||
			(m_eventID != m_sOrigEventID))
		{
			//			CString sName = "Event name:  ";
			CString sName = "";
			HTREEITEM hEvent = NULL;
			HTREEITEM hParent = NULL; 
			HTREEITEM hChild = NULL;

			hEvent = m_pStateTree->tree.GetSelectedItem();
			hParent = m_pStateTree->tree.GetParentItem(hEvent);
			hChild = m_pStateTree->tree.GetChildItem(hEvent);

			HTREEITEM hReturn = IsUniqueEventID(m_eventID, hParent);
			if (hReturn != NULL && hReturn != hEvent)
			{
				MessageBox("Error!\nThe name already exists. Please choose another event ID.",0,MB_OK|MB_ICONERROR);
				return;
			}

			HTREEITEM hApp = m_pStateTree->tree.GetSelectedApp(hParent);
			CString sAppName = m_pStateTree->tree.GetItemText(hApp);
			CString sStateName = m_pStateTree->tree.GetItemText(hParent);

			if (m_pStateTree->tree.GetItemData(hParent) & STATE_TREE_STATE_MASK)
			{
				//				sStateName.Replace("State name:  ", NULL);
				sStateName.Replace("(default)", NULL);
				sStateName.TrimLeft();
				sStateName.TrimRight();
			}

			CStringArray AppPathList;
			AppPathList.RemoveAll();
			m_pStateTree->GetAppSrcHdrPath(AppPathList, sAppName, hEvent);
			strHdrFullPath = AppPathList.GetAt(0);
			strSrcFullPath = AppPathList.GetAt(1);

			if (((CButton*)GetDlgItem(IDC_ACTION_CHECK))->GetCheck() == 0)
				m_eventHdlName = "NULL";

			BSTR bstrSrcFullPath = _com_util::ConvertStringToBSTR(strSrcFullPath.GetBuffer());
			BSTR bstrHdrFullPath = _com_util::ConvertStringToBSTR(strHdrFullPath.GetBuffer());
			BSTR bstrAppName = _com_util::ConvertStringToBSTR(sAppName.GetBuffer());
			BSTR bstrStateName = _com_util::ConvertStringToBSTR(sStateName.GetBuffer());
			BSTR bstrOrigEventID = _com_util::ConvertStringToBSTR(m_sOrigEventID.GetBuffer());
			BSTR bstrEventID = _com_util::ConvertStringToBSTR(m_eventID.GetBuffer());
			BSTR bstrTransitionStateName = _com_util::ConvertStringToBSTR(m_transitionStateName.GetBuffer());
			BSTR bstrEventHdlName = _com_util::ConvertStringToBSTR(m_eventHdlName.GetBuffer());
			if (m_bIsInternalTransition == TRUE)
			{
				//!!! Update Interface
				//!!! From CString to BSTR
				
				m_pStateTree->Fire_EditEventHdlDec(bstrSrcFullPath, bstrHdrFullPath, bstrAppName, bstrStateName, bstrOrigEventID, bstrEventID, CComBSTR("") ,bstrEventHdlName);
				if (!m_pStateTree->data.isEditEventHdlDecOk)
				{
					goto final;
					//CDialog::OnOK();
					//return;
				}
			}
			else
			{
				m_pStateTree->Fire_EditEventHdlDec(bstrSrcFullPath, bstrHdrFullPath, bstrAppName, bstrStateName, bstrOrigEventID, bstrEventID, bstrTransitionStateName,bstrEventHdlName);
				if (!m_pStateTree->data.isEditEventHdlDecOk)
				{
					goto final;
					//CDialog::OnOK();
					//return;
				}
			}
			strSrcFullPath.ReleaseBuffer();
			strHdrFullPath.ReleaseBuffer();
			sAppName.ReleaseBuffer();
			sStateName.ReleaseBuffer();
			m_sOrigEventID.ReleaseBuffer();
			m_eventID.ReleaseBuffer();
			m_transitionStateName.ReleaseBuffer();
			m_eventHdlName.ReleaseBuffer();

			sName += m_eventID;
			m_pStateTree->tree.SetItemText(hEvent, sName);
			while (true)
			{
				if (NULL == hChild)
					break;

				if (m_pStateTree->tree.GetItemData(hChild) & STATE_TREE_TRANSITION_MASK)
				{
					if (m_bIsInternalTransition == TRUE)
						m_pStateTree->tree.SetItemText(hChild, STR_INTERNAL_TRAN);
					else
					{
						CString sTransName = "Transit to:  ";

						sTransName += m_transitionStateName;
						m_pStateTree->tree.SetItemText(hChild, sTransName);
					}
				}
				if (m_pStateTree->tree.GetItemData(hChild) & STATE_TREE_EVENT_HANDLER_MASK)
				{
					CString sActionName = "Action:  ";

					if (((CButton*)GetDlgItem(IDC_ACTION_CHECK))->GetCheck() == 1)
					{
						sActionName += m_eventHdlName;
						sActionName += "(struct SME_APP_T *pApp, struct SME_EVENT_T *pEvent)";
					}
					m_pStateTree->tree.SetItemText(hChild, sActionName);
				}
				hChild = m_pStateTree->tree.GetNextSiblingItem(hChild);
			}

		}
		else
		{
			goto final;
			//CDialog::OnOK();
			//return;
		}
	}

final:	CDialog::OnOK();

	// Acivate c file; 
	if (!strSrcFullPath.IsEmpty()) 
		m_pStateTree->Fire_OpenFileAndMoveLineTo(CComBSTR(strSrcFullPath), -1);

}



/////////////////////////////////////////////////////////////////////////////////
// DESCRIPTION: Check "internal transition" radio button
// INPUT: None
// OUTPUT: None
// Note: combo box for choosing states will be text-cleared and also deactivated
//////////////////////////////////////////////////////////////////////////////////
void CAddEventDlg::OnInternalTransationButton() 
{
	// TODO: Add your control notification handler code here
	m_bIsInternalTransition = TRUE;
	((CButton*)GetDlgItem(IDC_TRANSITION_RADIO))->SetCheck(0);
	m_stateListBox.SetWindowText("");
	m_stateListBox.EnableWindow(FALSE);
	UpdateOKBtnStatus();
}

///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION: Check "transit to" Radio button
// INPUT: None
// OUTPUT: None
// Note: combo box for choosing state will be activated.
///////////////////////////////////////////////////////////////////////////////
void CAddEventDlg::OnTransactionStateButton() 
{
	// TODO: Add your control notification handler code here
	m_bIsInternalTransition = FALSE;
	((CButton*)GetDlgItem(IDC_INTERNAL_TRANSITION_RADIO))->SetCheck(0);
	m_stateListBox.EnableWindow(TRUE);
	UpdateOKBtnStatus();
}

///////////////////////////////////////////////////////////////////////////////////
// DESCRIPTION: Automatically create two child nodes(Transit to and Action) 
//              under event node.
// INPUT: None
// OUTPUT: None
// Note: 
/////////////////////////////////////////////////////////////////////////////////////
void CAddEventDlg::AddStateEventHdler()
{
	CString sName = "Transit to:  "; /*record the Transit to Statement */
	HTREEITEM hSelector = NULL;
	HTREEITEM hInsert = NULL;

	TV_INSERTSTRUCT Inserter; /* insert structure */

	hSelector = m_pStateTree->tree.GetSelectedItem();
	Inserter.hParent = hSelector;
	Inserter.hInsertAfter = TVI_LAST;
	Inserter.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE;
	Inserter.item.lParam = STATE_TREE_TRANSITION_MASK;

	if (m_bIsInternalTransition == TRUE) /* controled by radio button */
		Inserter.item.pszText = STR_INTERNAL_TRAN;
	else
	{
		sName += m_transitionStateName;
		Inserter.item.pszText = (LPTSTR)(LPCTSTR)(sName);
	}	
	hInsert = m_pStateTree->tree.InsertItem(&Inserter);
	m_pStateTree->tree.SetItemImage(hInsert, 5, 5);

	sName = "Action:  ";

	if (((CButton*)GetDlgItem(IDC_ACTION_CHECK))->GetCheck() == 1)
	{
		sName += m_eventHdlName;
		sName += "(struct SME_APP_T *pApp, struct SME_EVENT_T *pEvent)";
	}

	Inserter.item.pszText = (LPTSTR)(LPCTSTR)(sName);	
	Inserter.item.lParam = STATE_TREE_EVENT_HANDLER_MASK;
	hInsert = m_pStateTree->tree.InsertItem(&Inserter);
	m_pStateTree->tree.SetItemImage(hInsert, 4, 4);
}

////////////////////////////////////////////////////////////////////////////
// DESCRIPTION: Check whether eventID is existed.
// INPUT: 1) sEventID: the selected the eventID
//        2) hParent: the hParent of the selected eventid 
// OUTPUT: None
// Note: 
////////////////////////////////////////////////////////////////////////////
HTREEITEM CAddEventDlg::IsUniqueEventID(LPCTSTR sEventID, HTREEITEM hParent)
{
	HTREEITEM hChild = NULL;

	hChild = m_pStateTree->tree.GetChildItem(hParent);
	while (true)
	{
		// Seek to the end of current parent tree item
		if (NULL == hChild)
			break; 
		if (m_pStateTree->tree.GetItemData(hChild) & STATE_TREE_EVENT_ID_MASK)
		{
			CString sName = m_pStateTree->tree.GetItemText(hChild);
			// Trim prefix string "Event Name:  "
			//			sName = sName.Mid(13); 
			if (!sName.Compare(sEventID))
				return hChild;
		}
		hChild = m_pStateTree->tree.GetNextSiblingItem(hChild);
	}
	return NULL;
}



void CAddEventDlg::OnActionCheck() 
{
	// TODO: Add your control notification handler code here
	if (((CButton*)GetDlgItem(IDC_ACTION_CHECK))->GetCheck() == 0)
		((CEdit*)GetDlgItem(IDC_EVENT_HANDLER_EDIT))->EnableWindow(FALSE);
	else
		((CEdit*)GetDlgItem(IDC_EVENT_HANDLER_EDIT))->EnableWindow(TRUE);

	UpdateOKBtnStatus();
}


// Update the OK button status (enabled or disabled).
void CAddEventDlg::UpdateOKBtnStatus()
{
	UpdateData(TRUE); //retrieve data 
	if (m_bIsInternalTransition)
	{
		// If it is internal action, should have an handler.
		if (((CButton*)GetDlgItem(IDC_ACTION_CHECK))->GetCheck() == 1 
			/*&& (m_eventHdlName.GetLength() > 0)*/
			&& (m_eventID.GetLength() > 0))
		{
			((CButton*)GetDlgItem(IDOK))->EnableWindow(TRUE);
		} else
			((CButton*)GetDlgItem(IDOK))->EnableWindow(FALSE);
	}
	else 
	{
		//state transition
		if ((m_eventID.GetLength() > 0)
			&& (m_transitionStateName.GetLength() >0))
			((CButton*)GetDlgItem(IDOK))->EnableWindow(TRUE);
		else 
			((CButton*)GetDlgItem(IDOK))->EnableWindow(FALSE);
	}
}

BOOL CAddEventDlg::OnHelpInfo(HELPINFO* pHelpInfo) 
{
	// TODO: Add your message handler code here and/or call default
	//DSUtils(m_pStateTree->m_pApp).GotoWinHelp(0x53);
	CString sCmdName = GetHelpFileName();
	sCmdName+="::/add_event_handler.htm";
	::HtmlHelp(NULL, sCmdName, HH_DISPLAY_TOPIC, 0);
	return TRUE;
	//	return CDialog::OnHelpInfo(pHelpInfo);
}

//////////////////////////////////////////////////////////////////////////////////////
// DESCRIPTION: Check whether eventID is given by users. 
//              Ok button will be allowed to click only when eventID is given.
//		This function is called, when event id box changed.
// INPUT: None
// OUTPUT: None
// Note: 
//////////////////////////////////////////////////////////////////////////////////////
void CAddEventDlg::OnEditchangeEventIdBox() 
{
	// TODO: Add your control notification handler code here
	// TODO: Add your control notification handler code here
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.

	// TODO: Add your control notification handler code here
	UpdateData(TRUE);

	m_eventID.TrimLeft();
	m_eventID.TrimRight();

	UpdateOKBtnStatus();

	if (m_eventID.GetLength() == 0)
	{
		((CEdit*)GetDlgItem(IDC_EVENT_HANDLER_EDIT))->SetWindowText(m_eventID);
	}
	else
	{
		CString sDefltActionName = "On";

		HTREEITEM hSelector = m_pStateTree->tree.GetSelectedItem();
		if (m_bIsEditEvent)
			hSelector = m_pStateTree->tree.GetParentItem(hSelector);
		CString sSelName = m_pStateTree->tree.GetItemText(hSelector);
		DWORD lSelParam = m_pStateTree->tree.GetItemData(hSelector);
		if(lSelParam & STATE_TREE_STATE_MASK)
		{
			//			sSelName = sSelName.Mid(13);
			if (lSelParam & STATE_TREE_DEFAULT_STATE)
			{
				int idx = sSelName.Find("  (default)");
				sSelName = sSelName.Left(idx);
			}
		}
		sDefltActionName += sSelName;
		sDefltActionName += m_eventID;
		((CEdit*)GetDlgItem(IDC_EVENT_HANDLER_EDIT))->SetWindowText(sDefltActionName);
	}	

}

void CAddEventDlg::OnSelchangeEventIdBox() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);

	int nSel = ((CComboBox*)GetDlgItem(IDC_EVENT_ID_BOX))->GetCurSel();	
	((CComboBox*)GetDlgItem(IDC_EVENT_ID_BOX))->GetLBText(nSel, m_eventID);
	((CComboBox*)GetDlgItem(IDC_EVENT_ID_BOX))->SetWindowText(m_eventID);
	OnEditchangeEventIdBox();
}

void CAddEventDlg::OnSelchangeTransitionStateNameBox() 
{
	// TODO: Add your control notification handler code here
	// Selection change.
	UpdateOKBtnStatus();
	
}

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
Software Developer (Senior)
United States United States
Alex "Question is more important than the answer."

Comments and Discussions