📄 sourcemonitor.cpp
字号:
}
return 0;
}
int CSourceMonitor::Run(char *szInstructionFile, int iChannelNo)
{
if(LoadFile(szInstructionFile, iChannelNo) != 0)
return -1;
CVSInterpreter *pvsInterpreter = (CVSInterpreter *)m_pvsInterpreter;
if(pvsInterpreter->m_pcurrentState != NULL)
{
SelectLine((pvsInterpreter->m_pcurrentState)[m_iChannelNo - 1].vsi.IID, 1);
}
return(0);
}
int CSourceMonitor::SelectLine(char *IID, int iKeyIndex)
{
char aszTemp[100];
char *szTemp, *szTemp2;
m_Edit.SetFocus();
strcpy(aszTemp, "[");
strcat(aszTemp, IID);
strcat(aszTemp, "]");
//在BUFFER中寻找字符串"[IID]"
if((szTemp = strstr(m_szFileBuf, aszTemp)) == NULL)
{
return(-1);
}
if((szTemp2 = strstr(szTemp, "\r\n")) == NULL)
{
return(-1);
}
//寻找指定的KEY
for(int i = 0; i < iKeyIndex; i ++)
{
szTemp = szTemp2 + 2;
szTemp2 = strstr(szTemp, "\r\n");
if(szTemp2 == NULL)
return(-1);
}
//计算所选行的行号
int iLineIndex = 0;
m_iCurSelLineNo = ::SendMessage(m_hwndEdit, EM_LINEFROMCHAR, szTemp - m_szFileBuf, 0);
iLineIndex = m_iCurSelLineNo - 5; //将这一行移到中间
//计算从当前可见的首行的位置所需移动的行数
int iLineIndex2 = ::SendMessage(m_hwndEdit, EM_GETFIRSTVISIBLELINE, 0, 0);
int iScrollCount = iLineIndex - iLineIndex2;
::SendMessage(m_hwndEdit, EM_LINESCROLL, 0, iScrollCount);
::SendMessage(m_hwndEdit, EM_SETSEL, szTemp - m_szFileBuf, szTemp2 - m_szFileBuf);
DWORD dwCoordinates;
dwCoordinates = ::SendMessage(m_hwndEdit, EM_POSFROMCHAR, szTemp - m_szFileBuf, 0);
int x = LOWORD(dwCoordinates);
int y = HIWORD(dwCoordinates);
m_iLineY = y;
//如果所选行是断点,就设置m_bIsBreakPoint标志
int iTemp;
if(IsBreakPointLine(m_iCurSelLineNo, &iTemp))
{
m_bIsBreakPoint = TRUE;
}
else
{
m_bIsBreakPoint = FALSE;
}
UpdateSymbolArea();
return(0);
}
int CSourceMonitor::SelectLine(int iLineNo)
{
//计算指定行的头尾在FILEBUFFER中的位置
int iBufferOffset_LineBegin;
int iBufferOffset_LineEnd;
if((iBufferOffset_LineBegin = ::SendMessage(m_hwndEdit, EM_LINEINDEX, iLineNo, 0)) == -1)
return -1;
if(strstr(m_szFileBuf + iBufferOffset_LineBegin, "\r\n") != NULL)
{
iBufferOffset_LineEnd = strstr(m_szFileBuf + iBufferOffset_LineBegin, "\r\n") - m_szFileBuf;
}
else
{//找不到换行,此行是最后一行
iBufferOffset_LineEnd = m_dwFileBufSize;
}
//计算所选行的行号
m_iCurSelLineNo = iLineNo;
int iLineIndex = iLineNo - 5; //将这一行移到中间
//计算从当前可见的首行的位置所需移动的行数
int iLineIndex2 = ::SendMessage(m_hwndEdit, EM_GETFIRSTVISIBLELINE, 0, 0);
int iScrollCount = iLineIndex - iLineIndex2;
::SendMessage(m_hwndEdit, EM_LINESCROLL, 0, iScrollCount);
::SendMessage(m_hwndEdit, EM_SETSEL, iBufferOffset_LineBegin, iBufferOffset_LineEnd);
DWORD dwCoordinates;
dwCoordinates = ::SendMessage(m_hwndEdit, EM_POSFROMCHAR, iBufferOffset_LineBegin, 0);
int x = LOWORD(dwCoordinates);
int y = HIWORD(dwCoordinates);
m_iLineY = y;
//如果所选行是断点,就设置m_bIsBreakPoint标志
int iTemp;
if(IsBreakPointLine(m_iCurSelLineNo, &iTemp))
{
m_bIsBreakPoint = TRUE;
}
else
{
m_bIsBreakPoint = FALSE;
}
UpdateSymbolArea();
return(0);
}
int CSourceMonitor::Refresh()
{
//刷新INI的CACHE
WritePrivateProfileString(NULL, NULL, NULL, m_aszFileName);
Run(m_aszFileName, m_iChannelNo);
((CVSInterpreter *)m_pvsInterpreter)->SyncVScriptFile(m_iChannelNo);
return 0;
}
BOOL CSourceMonitor::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
// Create a pruple brush.
CBrush brush (RGB (128 , 128 , 128) );
// Select the brush into the device context .
CBrush* pOldBrush = pDC->SelectObject (&brush);
// Get the area that needs to be erased .
CRect rcClip ;
pDC->GetClipBox(&rcClip);
//Paint the area.
pDC-> PatBlt (rcClip.left , rcClip.top ,
rcClip.Width ( ) , rcClip.Height ( ) , PATCOPY );
//Unselect brush out of device context .
pDC->SelectObject (pOldBrush );
// Return nonzero to half fruther processing .
return TRUE;
return CFrameWnd::OnEraseBkgnd(pDC);
}
void CSourceMonitor::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
RECT rectMainWnd;
GetClientRect(&rectMainWnd);
RECT rect;
rect.bottom = rectMainWnd.bottom;
rect.top = rectMainWnd.top;
rect.left = rectMainWnd.left + 20;
rect.right = rectMainWnd.right;
int x = rectMainWnd.left;
int y = rectMainWnd.top;
if(IsWindow(m_Edit.m_hWnd))
{
m_Edit.SetWindowPos(NULL,
x + m_iIndicatorAreaWidth,
y + m_iHeightOfToolBar,
cx - m_iIndicatorAreaWidth,
cy - m_iHeightOfStatusBar - m_iHeightOfToolBar,
SWP_NOZORDER | SWP_SHOWWINDOW);
m_toolBarCtrl.AutoSize();
m_statusBarCtrl.SetWindowPos(NULL,
x,
y + cy - m_iHeightOfStatusBar,
cx - m_iIndicatorAreaWidth,
m_iHeightOfStatusBar,
SWP_NOZORDER | SWP_SHOWWINDOW);
}
}
BOOL CSourceMonitor::OnCommand(WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
//没办法知道是CHECK还是UNCHECK
if(wParam == ID_TOOLBAR_EDIT)
{
Sleep(1);
}
return CFrameWnd::OnCommand(wParam, lParam);
}
BOOL CSourceMonitor::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// TODO: Add your specialized code here and/or call the base class
if(wParam == ID_TOOLBAR_EDIT)
{
Sleep(1);
}
//wParam只能捕捉ID_TOOLBAR的消息, 而不会传入ID_TOOLBAR_STEP
if(wParam == ID_TOOLBAR)
{//这时lParam是指向TBNOTIFY *, 而不是NMHDR *
TBNOTIFY *pnm = (TBNOTIFY *)lParam;
// if(pnm->hdr.code == NM_CLICK)
if(pnm->iItem == ID_TOOLBAR_STEP && pnm->hdr.code == NM_CLICK)
{//切换单步状态
m_bIsStep = !m_bIsStep;
if(!m_bIsStep)
SetEvent(m_hEventStep);
}
if(pnm->iItem == ID_TOOLBAR_STEPOVER && pnm->hdr.code == NM_CLICK)
{//运行下一步
SetEvent(m_hEventStep);
}
if(pnm->iItem == ID_TOOLBAR_BREAKPOINT && pnm->hdr.code == NM_CLICK)
{//切换断点
ToggleBreakPoint();
}
if(pnm->iItem == ID_TOOLBAR_QUERY && pnm->hdr.code == NM_CLICK)
{//查询EDITBOX中输入的变量值
::SendMessage(m_toolBarCtrl.m_Edit.m_hWnd, WM_GETTEXT, sizeof(m_szQueryVariableName), (LPARAM)m_szQueryVariableName);
SetEvent(m_hEventQuery);
//在这里顺便增加"刷新脚本文件BUFFER"的功能
Refresh();
}
if(pnm->iItem == ID_TOOLBAR_FIND && pnm->hdr.code == NM_CLICK)
{//查找在EDIT_FIND中指定的字符串
char aszTemp[100];
::SendMessage(m_toolBarCtrl.m_Edit_Find.m_hWnd, WM_GETTEXT, sizeof(aszTemp), (LPARAM)aszTemp);
FindString(aszTemp);
}
if(pnm->iItem == ID_TOOLBAR_NEXTCHANNEL && pnm->hdr.code == NM_CLICK)
{//切换到下一个通道
int iNextChannelNo;
if(m_iChannelNo + 1 > ((CVSInterpreter *)m_pvsInterpreter)->m_iChannelCount)
{
iNextChannelNo = (m_iChannelNo + 1)%((CVSInterpreter *)m_pvsInterpreter)->m_iChannelCount;
}
else
{
iNextChannelNo = m_iChannelNo + 1;
}
Run((((CVSInterpreter *)m_pvsInterpreter)->m_pcurrentState)[iNextChannelNo - 1].aszInstructionFile, iNextChannelNo);
SetMonitorData(iNextChannelNo, &((((CVSInterpreter *)m_pvsInterpreter)->m_pcurrentState)[iNextChannelNo - 1]));
}
if(pnm->iItem == ID_TOOLBAR_PREVIOUSCHANNEL && pnm->hdr.code == NM_CLICK)
{//切换到上一个通道
int iNextChannelNo;
if(m_iChannelNo - 1 == 0)
{
iNextChannelNo = ((CVSInterpreter *)m_pvsInterpreter)->m_iChannelCount;
}
else
{
iNextChannelNo = m_iChannelNo - 1;
}
Run((((CVSInterpreter *)m_pvsInterpreter)->m_pcurrentState)[iNextChannelNo - 1].aszInstructionFile, iNextChannelNo);
SetMonitorData(iNextChannelNo, &((((CVSInterpreter *)m_pvsInterpreter)->m_pcurrentState)[iNextChannelNo - 1]));
}
}
if(wParam == ID_EDIT_SOURCEWINDOW)
{
Sleep(1);
}
return CFrameWnd::OnNotify(wParam, lParam, pResult);
}
void CSourceMonitor::OnToolBarNotify( NMHDR * pNotifyStruct, LRESULT * result )
{//捕捉ID_TOOLBAR_STEP的消息,失败
Sleep(1);
}
BOOL CSourceMonitor::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult)
{
// TODO: Add your specialized code here and/or call the base class
//捕捉EDITBOX按键的消息,失败
return CFrameWnd::OnChildNotify(message, wParam, lParam, pLResult);
}
void CSourceMonitor::OnEditScroll()
{
UpdateSymbolArea();
}
int CSourceMonitor::ToggleBreakPoint()
{
//光标当前的行号
int iCaretLineNo = ::SendMessage(m_Edit.m_hWnd, EM_LINEFROMCHAR, -1, 0);
int j;
if(!IsBreakPointLine(iCaretLineNo, &j))
{//加入新断点
int *piLineNo = (int *)malloc(sizeof(int));
*piLineNo = iCaretLineNo;
m_ptrListBreakPointLineNo.AddTail(piLineNo);
}
else
{//删除断点
void *p2 = m_ptrListBreakPointLineNo.GetAt(m_ptrListBreakPointLineNo.FindIndex(j));
free(p2);
m_ptrListBreakPointLineNo.RemoveAt(m_ptrListBreakPointLineNo.FindIndex(j));
}
UpdateSymbolArea();
return(0);
}
int CSourceMonitor::UpdateSymbolArea()
{//更新窗口的标志区
RECT rect, rect2;
GetClientRect(&rect2);
rect.bottom = rect2.bottom;
rect.left = 15 - 5;
rect.top = rect2.top + m_iHeightOfToolBar;
rect.right = 15 + 5;
InvalidateRect(&rect2, TRUE);
UpdateWindow();
ValidateRect(&rect2);
return(0);
}
BOOL CSourceMonitor::IsBreakPointLine(int iLineNo, int *piIndex)
{//判断指定行是否有断点
for(int j = 0; j < m_ptrListBreakPointLineNo.GetCount(); j ++)
{
POSITION position = m_ptrListBreakPointLineNo.FindIndex(j);
int iTemp = *(int *)m_ptrListBreakPointLineNo.GetAt(position);
if(iLineNo == iTemp)
break;
}
if(j == m_ptrListBreakPointLineNo.GetCount())
{//否
return(FALSE);
}
else
{//是, 并自动设置为单步状态
*piIndex = j;
m_bIsStep = TRUE;
m_toolBarCtrl.CheckButton(ID_TOOLBAR_STEP, TRUE);
return(TRUE);
}
}
int CSourceMonitor::DisplyQueryValue()
{
char aszTemp[10000];
switch(m_iQueryVariableType)
{
case STRINGTYPE_VAR_INT:
itoa(m_iQueryVariableValue, aszTemp, 10);
break;
case STRINGTYPE_UNKNOWN:
case STRINGTYPE_VAR_STRING:
strcpy(aszTemp, m_szQueryVariableValue);
break;
case STRINGTYPE_VAR_FLOAT:
sprintf(aszTemp, "%g", m_fQueryVariableValue);
break;
default:
break;
}
MessageBox(aszTemp);
return(0);
}
int CSourceMonitor::FindString(char *szString)
{
char aszTemp[100];
char *szTemp;
m_Edit.SetFocus();
strcpy(aszTemp, szString);
//光标当前的字符偏移
int iIndexOfCaret = ::SendMessage(m_Edit.m_hWnd, EM_GETSEL, 0, 0);
iIndexOfCaret = LOWORD(iIndexOfCaret);
//如果继续上次查找,返回的是上次选中的部分的首个字符,故需后移一个
iIndexOfCaret ++;
//从BUFFER的当前位置以后中寻找字符串
if((szTemp = strstr(m_szFileBuf + iIndexOfCaret, aszTemp)) == NULL)
{
return(-1);
}
//计算所选行的行号
int iLineIndex = 0;
m_iCurSelLineNo = ::SendMessage(m_hwndEdit, EM_LINEFROMCHAR, szTemp - m_szFileBuf, 0);
iLineIndex = m_iCurSelLineNo - 5; //将这一行移到中间
//计算从当前可见的首行的位置所需移动的行数
int iLineIndex2 = ::SendMessage(m_hwndEdit, EM_GETFIRSTVISIBLELINE, 0, 0);
int iScrollCount = iLineIndex - iLineIndex2;
//滚动到找到的字符串,并选中
::SendMessage(m_hwndEdit, EM_LINESCROLL, 0, iScrollCount);
::SendMessage(m_hwndEdit, EM_SETSEL, szTemp - m_szFileBuf, szTemp + strlen(szString) - m_szFileBuf);
UpdateSymbolArea();
return(0);
}
int CSourceMonitor::SetMonitorData(int iChannelNo, struct CurrentState *pcurrentState)
{
/************************************************************************
iChannelNo 从1开始
//这些功能可以考虑用vsinterpreter向sourcemonitor postmessage实现,比较安全些
************************************************************************/
char aszTemp[100];
if(m_iChannelNo == iChannelNo)
{
sprintf(aszTemp, "本通道话务量: %d", pcurrentState->iCountOfTurnOn);
m_statusBarCtrl.SetText(aszTemp, 1, 0);
}
sprintf(aszTemp, "总呼入话务量: %d", ((CVSInterpreter *)m_pvsInterpreter)->m_iCountOfTurnOnOfTotal_In);
m_statusBarCtrl.SetText(aszTemp, 2, 0);
sprintf(aszTemp, "总呼出话务量: %d", ((CVSInterpreter *)m_pvsInterpreter)->m_iCountOfTurnOnOfTotal_Out);
m_statusBarCtrl.SetText(aszTemp, 3, 0);
return 0;
}
void CSourceMonitor::OnClose()
{
// TODO: Add your message handler code here and/or call default
//CFrameWnd::OnClose();
}
/////////////////////////////////////////////////////////////////////////////
// CMyEdit
CMyEdit::CMyEdit()
{
}
CMyEdit::~CMyEdit()
{
}
BEGIN_MESSAGE_MAP(CMyEdit, CEdit)
//{{AFX_MSG_MAP(CMyEdit)
ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyEdit message handlers
void CMyEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
char aszTemp[100];
// TODO: Add your message handler code here and/or call default
if(nChar == VK_RETURN && m_iType == EDITTYPE_QUERY)
{
CSourceMonitor *pMainWnd = (CSourceMonitor *)GetTopLevelParent();
GetLine(0, pMainWnd->m_szQueryVariableName, sizeof(pMainWnd->m_szQueryVariableName));
SetEvent(pMainWnd->m_hEventQuery);
}
if(nChar == VK_RETURN && m_iType == EDITTYPE_FIND)
{
if(SendMessage(WM_GETTEXT, sizeof(aszTemp), (LPARAM)aszTemp) != 0)
{
CSourceMonitor *pMainWnd = (CSourceMonitor *)GetTopLevelParent();
pMainWnd->FindString(aszTemp);
}
}
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -