/**********************************************************************
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();
}