Click here to Skip to main content
15,891,253 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.5K   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.

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

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

/* =============================================================================
 * Filename:    StateChartComm.cpp
 * 
 * Copyright  Inc
 * All rights reserved.
 * -----------------------------------------------------------------------------
 * General description of this file:
 *
 * The state chart implementation.
 * -----------------------------------------------------------------------------
 *                               Revision History
 * -----------------------------------------------------------------------------
 * Version   Date      Author          Revision Detail
 * ===========================================================================*/

#include "stdafx.h"
#include "StateChartView.h"
#include "dib.h"
#include "treefile.h"
#include "..\Common\ParamStore.h"

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

/********************************************************************************************
DESCRIPTION: 

INPUT:  
OUTPUT: 
NOTE: 

**********************************************************************************************/
void CStateChartView::OnAddState() 
{
	// TODO: Add your command handler code here

	HWND hWnd = m_pStateTree->m_ctlSysTreeView32.m_hWnd;
	if(hWnd!=NULL)
		::SendMessage(hWnd,WM_GUI_ADD_STATE, m_nSelStateSeqNo, 0);
	// Get current heap memory size
	int nSum = 0;
	HTREEITEM hSel = m_pStateTree->tree.GetSelectedItem();
	m_pStateTree->tree.GetChildSum(hSel, &nSum);

	// If m_StateChartInfoList's memory size is enough, no necessary to allocate new memory
	if (m_StateChartInfoList.GetSize() < nSum)
	{
		STATE_CHART_INFO_T *pNewItem = (STATE_CHART_INFO_T*)new(STATE_CHART_INFO_T);
		m_StateChartInfoList.Add(pNewItem);
	}

	m_EventNameList.RemoveAll();
	m_StateNameList.RemoveAll();

	InitStateNameList(hSel);
	InitEventNameList(hSel, hSel);

	ZeroCharInfoList();
	ZeroEventInfoList();
	
	Invalidate();
	UpdateWindow();
}


/********************************************************************************************
DESCRIPTION: 

INPUT:  
OUTPUT: 
NOTE: 

**********************************************************************************************/
void CStateChartView::OnDelApp() 
{
	// TODO: Add your command handler code here
	HWND hWnd = m_pStateTree->m_ctlSysTreeView32.m_hWnd;
	if(hWnd!=NULL)
		::SendMessage(hWnd,WM_GUI_DEL_APP, 0, 0);
	//m_pStateTree->PostMessage(WM_GUI_DEL_APP, 0, 0);
		
	CWnd *parWnd;
    parWnd = GetParent();
	parWnd->SendMessage(WM_CLOSE_DLG, 0, 0);
}

/********************************************************************************************
DESCRIPTION: 

INPUT:  
OUTPUT: 
NOTE: 

**********************************************************************************************/
void CStateChartView::OnAddHandle() 
{
	// TODO: Add your command handler code here 
	//m_pStateTree->SendMessage(WM_GUI_ADD_EVENT, m_nSelStateSeqNo, 0);
	HWND hWnd = m_pStateTree->m_ctlSysTreeView32.m_hWnd;
	if(hWnd!=NULL)
		::SendMessage(hWnd,WM_GUI_ADD_EVENT, m_nSelStateSeqNo, 0);

	m_EventNameList.RemoveAll();
	m_StateNameList.RemoveAll();

	HTREEITEM hSel = m_pStateTree->tree.GetSelectedItem();
	InitStateNameList(hSel);
	InitEventNameList(hSel, hSel);
	
	int nSum = 0;
	nSum = (int)m_EventNameList.GetSize();
	
	// If m_StateChartInfoList's memory size is enough, no necessary to allocate new memory
	if (m_EventLineInfoList.GetSize() < nSum)
	{
		EVENT_LINE_INFO_T *pNewItem = (EVENT_LINE_INFO_T*)new(EVENT_LINE_INFO_T);
		m_EventLineInfoList.Add(pNewItem);
	}

	ZeroEventInfoList();
	Invalidate();
	UpdateWindow();
}

/********************************************************************************************
DESCRIPTION: On default state change.

INPUT:  
OUTPUT: 
NOTE: 

**********************************************************************************************/
void CStateChartView::OnDefltChange() 
{
	// TODO: Add your command handler code here
//	m_pStateTree->SendMessage(WM_GUI_SET_DEFAULT, m_nSelStateSeqNo, 0);
	::SendMessage(m_pStateTree->m_ctlSysTreeView32.m_hWnd, WM_GUI_SET_DEFAULT, m_nSelStateSeqNo, 0);
	Invalidate();
	UpdateWindow();
}

/********************************************************************************************
DESCRIPTION: 

INPUT:  
OUTPUT: 
NOTE: 

**********************************************************************************************/
void CStateChartView::OnDelState() 
{
	// TODO: Add your command handler code here

	// Delete a state will not cause to minimize the size of allocated m_StateChartInfoList
//	m_pStateTree->SendMessage(WM_GUI_DEL_STATE, m_nSelStateSeqNo, 0);
	::SendMessage(m_pStateTree->m_ctlSysTreeView32.m_hWnd, WM_GUI_DEL_STATE, m_nSelStateSeqNo, 0);
	HTREEITEM hSel = m_pStateTree->tree.GetSelectedItem();
	m_EventNameList.RemoveAll();
	m_StateNameList.RemoveAll();
	
	InitStateNameList(hSel);
	InitEventNameList(hSel, hSel);

	ZeroEventInfoList();
	ZeroCharInfoList();
	
	Invalidate();
	UpdateWindow();
}

/********************************************************************************************
DESCRIPTION: 

INPUT:  
OUTPUT: 
NOTE: 

**********************************************************************************************/
void CStateChartView::OnGotoEntry() 
{
	// TODO: Add your command handler code here
	// Close state chart window firstly, and then jump to the function. Otherwise, VC main window may be in-active.
	CWnd *parWnd;
    parWnd = GetParent();
	parWnd->SendMessage(WM_CLOSE_DLG, 0, 0);

	::PostMessage(m_pStateTree->m_ctlSysTreeView32.m_hWnd, WM_GUI_GOTO_ENTRY_EXIT, m_nSelStateSeqNo, 0);
}

/********************************************************************************************
DESCRIPTION: 

INPUT:  
OUTPUT: 
NOTE: 

**********************************************************************************************/
void CStateChartView::OnGotoExit() 
{
	// TODO: Add your command handler code here
	// Close state chart window firstly, and then jump to the function. Otherwise, VC main window may be in-active.
	CWnd *parWnd;
    parWnd = GetParent();
	parWnd->SendMessage(WM_CLOSE_DLG, 0, 0);

	::PostMessage(m_pStateTree->m_ctlSysTreeView32.m_hWnd, WM_GUI_GOTO_ENTRY_EXIT, m_nSelStateSeqNo, 1);
}

/********************************************************************************************
DESCRIPTION: Jump to the event handler.

INPUT:  
OUTPUT: 
NOTE: 

**********************************************************************************************/
void CStateChartView::OnGotoHdler(UINT nID)
{
	int nSel = nID - WM_STATE_TRAN_ITEM_0;

	if (nID > WM_STATE_TRAN_ITEM_LAST || nID<WM_STATE_TRAN_ITEM_0)
		return;

	// Close state chart window firstly, and then jump to the function. Otherwise, VC main window may be in-active.
	CWnd *parWnd;
    parWnd = GetParent();
	parWnd->SendMessage(WM_CLOSE_DLG, 0, 0);

	::SendMessage(m_pStateTree->m_ctlSysTreeView32.m_hWnd, WM_GUI_GOTO_HANDLER, (WPARAM)(LPCTSTR)(m_ActionNameList[nSel]), 0);

	return;
}

/********************************************************************************************
// DESCRIPTION: Save StateChart as B/W bmp file.
// INPUT:  
// OUTPUT: 
// NOTE: 
Windows B/W Bitmap definition:
	1) Allocate one bit for one pixel.
	2) The data order is from left pixel to right pixel in a line, and then 
	   from bottom line to top line.
	3) One line data size should be 4-byte aligned.
**********************************************************************************************/
void CStateChartView::OnSaveAsBmp()
{
#ifndef PRO_EDITION
	XErrorMsg(STR_UNSUPPORTED_FEATURE);
	return;
#endif


	//load bmp first
	CDC* pDC = GetDC();
	CRect rec;
	GetClientRect(&rec);
	CSize size; //BMP size.
	int nWinWidth = rec.right-rec.left;
	size.cx = ((nWinWidth + 31) >> 5) << 5; // 2^5 =32, 32 bits (4 bytes aligned),  
	size.cy = rec.bottom-rec.top;

	int nBMPByteNumPerLine = size.cx >> 3;
	DWORD dwBufSize =  nBMPByteNumPerLine * size.cy;
	LPBYTE pBMPBuffer = new BYTE[dwBufSize];
	memset(pBMPBuffer, 0xff, dwBufSize); // 0 stands for black. 1 stands for white.

	int x,y;

	int nLineBaseAddr = 0;
	//get each pixel on the DC
	for(y = size.cy-1; y > -1; y-- )//from bottom to top!!!
	{
		for(x = 0; x < nWinWidth; x++ )//from left to right.
		{
			COLORREF Pixel = pDC->GetPixel(x, y);
			int i = x & 7;
			int nBMPByteNo = nLineBaseAddr + (x>>3);

			// RevRGB= blue + (green * 256) + (red * 65536)
			int Col = (Pixel & 0xFF) + ((Pixel & 0xFF00)>>8) + ((Pixel & 0xFF0000)>>16);
			if (Col > 256*3 - 30)
				pBMPBuffer[nBMPByteNo] |= 1 << (7-i); //1 for white.
			else 
				pBMPBuffer[nBMPByteNo] &= ~(1 << (7-i)); //0 for black, red, including line, arrow

			//reverse the pixel data, reverse RGB order in the memory.
		}
		nLineBaseAddr += nBMPByteNumPerLine;
	}
	//finished loading

	HTREEITEM item = m_pStateTree->tree.GetSelectedItem();
	CString text = m_pStateTree->tree.GetItemText(item);
	text += ".bmp";
	CFileDialog filedlg(FALSE,"bmp",text);
	if(filedlg.DoModal()==IDOK)
	{
		text = filedlg.GetFileName();
		WriteToBmpFile(text,pBMPBuffer,size);
	}
	
	delete[] pBMPBuffer;//release the buffer
}

void CStateChartView::OnSaveAsTxt()
{
#ifndef PRO_EDITION
	XErrorMsg(STR_UNSUPPORTED_FEATURE);
	return;
#endif
	//... Shuting down for avoiding error !

	HTREEITEM item = m_pStateTree->tree.GetSelectedItem();
	CString text = m_pStateTree->tree.GetItemText(item);
	text += ".txt";
	CFileDialog filedlg(FALSE,"txt",text);
		if(filedlg.DoModal()==IDOK)
	{
	text = filedlg.GetFileName();
	CFile tartgetfile(text,CFile::modeCreate|CFile::modeWrite);

	TreeFile treefile(item,m_pStateTree);
	treefile.SaveAsTxtFile(tartgetfile);
	tartgetfile.Close();
	}

}

void CStateChartView::WriteToBmpFile(CString filename,LPBYTE pBMPBuffer,CSize& size)
{
	
	CDib bmp(size, 1);//"size" is the size of the bmp, 1 is the bit count of each pixel in the bmp.

	bmp.AttachImageMemory(pBMPBuffer);
	//
	CFile file(filename, CFile::modeCreate|CFile::modeReadWrite|CFile::typeBinary);
	bmp.Write(&file);
	file.Close();
}

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