www.gusucode.com > 一个VC++语法分析模块程序实例源码程序 > 一个VC++语法分析模块程序实例/CompileSys/CompileSys/IDE/IDEView.cpp
// IDEView.cpp : implementation of the CIDEView class // Download: http://www.codesc.net #include "stdafx.h" #include "IDE.h" #include "MainFrm.h" #include "IDEDoc.h" #include "IDEView.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CIDEView IMPLEMENT_DYNCREATE(CIDEView, CEditView) BEGIN_MESSAGE_MAP(CIDEView, CEditView) //{{AFX_MSG_MAP(CIDEView) ON_COMMAND(IDM_START, OnStart) ON_COMMAND(IDM_SET, OnSet) ON_CONTROL_REFLECT(EN_CHANGE, OnChange) ON_WM_PAINT() ON_WM_KEYDOWN() ON_WM_KEYUP() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_LBUTTONDBLCLK() ON_WM_MOUSEMOVE() ON_WM_RBUTTONUP() ON_COMMAND(IDM_SELALL, OnSelall) ON_WM_CAPTURECHANGED() ON_COMMAND(IDM_CLEAN, OnClean) ON_COMMAND(IDM_FONT, OnFont) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CEditView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CEditView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CEditView::OnFilePrintPreview) ON_MESSAGE(MSG_PAINTLEFT,OnPaintLeft) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CIDEView construction/destruction DWORD WINAPI CompileThread(LPVOID pParam) { CIDEView *pView=(CIDEView*)pParam; pView->GetCompileResult(); return 0; } CIDEView::CIDEView() { // TODO: add construction code here m_pMainFrame=0; m_pwndStatusBar=0; m_strCompileProgName="PL.exe"; m_nCurLn=0; m_nCurCol=0; } CIDEView::~CIDEView() { } BOOL CIDEView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs BOOL bPreCreated = CEditView::PreCreateWindow(cs); cs.style &= ~(ES_AUTOHSCROLL|WS_HSCROLL); // Enable word-wrapping return bPreCreated; } ///////////////////////////////////////////////////////////////////////////// // CIDEView drawing void CIDEView::OnDraw(CDC* pDC) { CIDEDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here } ///////////////////////////////////////////////////////////////////////////// // CIDEView printing BOOL CIDEView::OnPreparePrinting(CPrintInfo* pInfo) { // default CEditView preparation return CEditView::OnPreparePrinting(pInfo); } void CIDEView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) { // Default CEditView begin printing. CEditView::OnBeginPrinting(pDC, pInfo); } void CIDEView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo) { // Default CEditView end printing CEditView::OnEndPrinting(pDC, pInfo); } ///////////////////////////////////////////////////////////////////////////// // CIDEView diagnostics #ifdef _DEBUG void CIDEView::AssertValid() const { CEditView::AssertValid(); } void CIDEView::Dump(CDumpContext& dc) const { CEditView::Dump(dc); } CIDEDoc* CIDEView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CIDEDoc))); return (CIDEDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CIDEView message handlers void CIDEView::OnStart() { // TODO: Add your command handler code here DWORD dwThreadID; m_pMainFrame->ShowControlBar(m_pwndOutBar,1,0); ::CreateThread(0,0,CompileThread,this,0,&dwThreadID);//创建进程 } void CIDEView::GetCompileResult() { SECURITY_ATTRIBUTES sa; HANDLE hRead,hWrite; CString strFile; CString str; CString strOut; CIDEDoc *pDoc=GetDocument(); strFile=pDoc->GetPathName(); if(strFile=="")//该文件没有保存过 { CFileDialog fileDlg(0,0,0,0,"PL/0源文件(*.pas)|*.pas|文本文件(*.txt)|*.txt|任何文件(*.*)|*.*|",this); if(fileDlg.DoModal()!=IDOK) return; strFile=fileDlg.GetPathName(); if(strFile.Right(4)!=".pas") strFile+=".pas"; } //下段这段代码在Debug版本下有错误,在Release版本下没问题,不知道为什么 //-------------------------------------------- pDoc->SetPathName(strFile,1); pDoc->SetModifiedFlag(0); pDoc->OnSaveDocument((LPSTR)(LPCSTR)strFile);//先保存该文件 str=pDoc->GetTitle(); pDoc->SetTitle(str); if(str.Right(1)=="*") { str=str.Left(str.GetLength()-1); pDoc->SetTitle(str); } UpdateWindow(); //-------------------------------------------- strFile=m_strCompileProgName+" "+(char)34+strFile+(char)34; m_pwndOutBar->SetFocus(); sa.nLength=sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor=NULL; sa.bInheritHandle=TRUE; if(!CreatePipe(&hRead,&hWrite,&sa,0))//创建管道进行通信 { MessageBox("分析器不存在,请重新输入其路径","错误",MB_ICONWARNING); OnSet(); return; } STARTUPINFO si; PROCESS_INFORMATION pi; si.cb=sizeof(STARTUPINFO); GetStartupInfo(&si); si.hStdError=hWrite; si.hStdOutput=hWrite; si.wShowWindow=SW_HIDE; si.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; //创建进程启动分析核心程序 if(!CreateProcess(NULL,(LPSTR)(LPCTSTR)strFile,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)) { MessageBox("分析器不存在,请重新输入其路径","错误",MB_ICONWARNING); OnSet(); return; } CloseHandle(hWrite); char buffer[4096]={0}; DWORD bytesRead; while(true) { if(!ReadFile(hRead,buffer,4095,&bytesRead,NULL)) break; strOut+=buffer; m_pwndOutBar->SetColorRichEditText(strOut); m_pwndOutBar->GetRichEditCtrl()->PostMessage(WM_VSCROLL,SB_BOTTOM,0); Sleep(500); } //-----------读取分析结果并显示----------- CString strLeft,strRight; int nPos; str=m_pIDEDoc->GetPathName(); nPos=str.ReverseFind('\\'); strLeft=str.Left(nPos+1); strRight=str.Right(str.GetLength()-nPos-1); if(strRight.Right(4)==".pas") str=strLeft+strRight.Left(strRight.GetLength()-4)+"_LexAnanlysisResult.dat"; else str=strLeft+strRight+"_LexAnanlysisResult.dat"; if(GetFileAttributes(str)!=-1) { CFile file(str,CFile::modeRead); LEXPROPERTYVS lpvTemp; int nSize=sizeof(LEXPROPERTYVS)-sizeof(char*); int nCount=file.GetLength()/nSize; m_vectorSymbol.clear(); for(int i=0;i<nCount;i++) { file.Read((char*)&lpvTemp,nSize); m_vectorSymbol.push_back(lpvTemp); } } DisplayCodeInfo();//显示分析结果 //---------------------------------------- } void CIDEView::OnInitialUpdate() { CEditView::OnInitialUpdate(); // TODO: Add your specialized code here and/or call the base class m_pMainFrame=(CMainFrame*)::AfxGetApp()->m_pMainWnd; m_pwndOutBar=m_pMainFrame->GetOutBar(); m_pwndWorkSpaceBar=m_pMainFrame->GetWorkSapceBar(); m_pTreeCtrl=m_pwndWorkSpaceBar->GetTreeCtrl(); m_pwndStatusBar=m_pMainFrame->GetStatusBar(); m_pEdit=&GetEditCtrl(); m_pIDEDoc=GetDocument(); //-----------设置自动换行----------- m_pEdit->ShowScrollBar(SB_BOTH,1); AfxGetApp()->WriteProfileInt(_T("Editor Settings"),_T("Auto Return"),1); //---------------------------------- //-----------设置字体----------- CFont *pFont=CFont::FromHandle((HFONT)::GetStockObject(SYSTEM_FIXED_FONT)); m_pEdit->SetFont(pFont); //------------------------------ //------------设置编辑框的左边界------------ SIZE size; GetTextExtentPoint(GetDC()->GetSafeHdc(),"A",1,&size); m_LineHeight=size.cy;//得到行的高度 m_pEdit->SetMargins(m_LineHeight+6,0); //------------------------------------------ DisplayLnCol();//在状态栏上显示行列信息 } void CIDEView::OnFont() { // TODO: Add your command handler code here CFontDialog fontDlg; LOGFONT lf; CFont font; if(fontDlg.DoModal()==IDOK) { fontDlg.GetCurrentFont(&lf); font.CreateFontIndirect(&lf); m_pEdit->SetFont(&font,1); } } void CIDEView::OnSet() { // TODO: Add your command handler code here if(m_SetDlg.DoModal()!=IDOK) return; m_strCompileProgName=m_SetDlg.GetCompileProgName(); } void CIDEView::OnChange() { // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CEditView::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM_CHANGE flag ORed into the mask. // TODO: Add your control notification handler code here CIDEDoc *pDoc=GetDocument(); CString str; pDoc->SetModifiedFlag(1); str=pDoc->GetTitle(); if(str.Right(1)!="*") { str=str+"*"; pDoc->SetTitle(str); } PaintLeft(); } //画左边的显示条 void CIDEView::PaintLeft() { CBrush brushb(RGB(245,245,230)); CDC* hdc; hdc=GetWindowDC(); CRect rect; GetClientRect(&rect); hdc->FillRect (CRect(rect.left+2,rect.top+2,rect.left+m_LineHeight+7,rect.Height()+2),&brushb);//画底色 brushb.DeleteObject(); int nFirstVisible=m_pEdit->GetFirstVisibleLine();//得到当前显示的最上端的行号 CBrush OrigBrush,brushf(RGB(255,0,0)); CBrush *oldBrush=(CBrush*)hdc->SelectObject(brushf); OrigBrush.FromHandle((HBRUSH)oldBrush); hdc->SelectObject(&OrigBrush); OrigBrush.DeleteObject(); brushf.DeleteObject(); } void CIDEView::OnPaint() { // TODO: Add your message handler code here CEditView::OnPaint(); PaintLeft(); // Do not call CEditView::OnPaint() for painting messages } void CIDEView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default PaintLeft(); switch(nChar) { case VK_UP: m_nCurLn=m_nCurLn>0?m_nCurLn-1:0; break; case VK_DOWN: m_nCurLn=m_nCurLn+1; break; case VK_LEFT: case VK_BACK: m_nCurCol=m_nCurCol>0?m_nCurCol-1:0; break; case VK_SPACE: case VK_RIGHT: m_nCurCol=m_nCurCol+1; break; case VK_RETURN: m_nCurLn+=1; m_nCurCol=0; break; case VK_ESCAPE: m_pMainFrame->ShowControlBar(m_pwndOutBar,0,1); break; case VK_TAB: m_nCurCol+=8; break; } DisplayLnCol(); CEditView::OnKeyDown(nChar, nRepCnt, nFlags); } void CIDEView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default PaintLeft(); CEditView::OnKeyUp(nChar, nRepCnt, nFlags); } void CIDEView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default PaintLeft(); CString str; int nChar=m_pEdit->CharFromPos(point); m_nCurLn=HIWORD(nChar); m_nCurCol=LOWORD(nChar); str.Format("行:%d,列:%d",m_nCurLn,m_nCurCol); m_pwndStatusBar->SetPaneText(1,str,1); CEditView::OnLButtonDown(nFlags, point); } void CIDEView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default PaintLeft(); CEditView::OnLButtonUp(nFlags, point); } void CIDEView::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default PaintLeft(); CEditView::OnLButtonDblClk(nFlags, point); } void CIDEView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default PaintLeft(); CEditView::OnMouseMove(nFlags, point); } void CIDEView::DisplayCodeInfo() { TREENODE_LPV tnlpvTemp; TREE_FILE trfTemp; CString strFile=m_pIDEDoc->GetPathName(); int nLen=m_vectorSymbol.size(); CString strCode; int i; //-----------删掉相同的信息----------- HTREEITEM hFindRoot=m_pTreeCtrl->GetRootItem(); while(hFindRoot) { if(m_pTreeCtrl->GetItemText(hFindRoot)==strFile) m_pTreeCtrl->DeleteItem(hFindRoot); hFindRoot=m_pTreeCtrl->GetNextItem(hFindRoot,TVGN_NEXT); } m_vectorTreeNode_Lpv.clear(); //------------------------------------ GetWindowText(strCode); HTREEITEM hRoot=m_pTreeCtrl->InsertItem(strFile,0,0); HTREEITEM hKeyWordSubRoot=m_pTreeCtrl->InsertItem("关键字",hRoot,0); HTREEITEM hIdSubRoot=m_pTreeCtrl->InsertItem("变量",hRoot,0); HTREEITEM hConstSubRoot=m_pTreeCtrl->InsertItem("常量",hRoot,0); HTREEITEM hOprSymSubRoot=m_pTreeCtrl->InsertItem("运算符",hRoot,0); HTREEITEM hBndSymSubRoot=m_pTreeCtrl->InsertItem("界符",hRoot,0); HTREEITEM hIllegalCharSubRoot=m_pTreeCtrl->InsertItem("非法字符",hRoot,0); bool bKeyWord=0; bool bId=0; bool bConst=0; bool bOprSym=0; bool bBndSym=0; bool bIllegalChar=0; for(i=0;i<nLen;i++) { switch(m_vectorSymbol[i].lpProperty) { case KeyWord: tnlpvTemp.hTreeItem=m_pTreeCtrl->InsertItem(strCode.Mid(m_vectorSymbol[i].nStrPos,m_vectorSymbol[i].nStrLen),hKeyWordSubRoot,0); bKeyWord=1; break; case Id: tnlpvTemp.hTreeItem=m_pTreeCtrl->InsertItem(strCode.Mid(m_vectorSymbol[i].nStrPos,m_vectorSymbol[i].nStrLen),hIdSubRoot,0); bId=1; break; case Const: tnlpvTemp.hTreeItem=m_pTreeCtrl->InsertItem(strCode.Mid(m_vectorSymbol[i].nStrPos,m_vectorSymbol[i].nStrLen),hConstSubRoot,0); bConst=1; break; case OprSym: tnlpvTemp.hTreeItem=m_pTreeCtrl->InsertItem(strCode.Mid(m_vectorSymbol[i].nStrPos,m_vectorSymbol[i].nStrLen),hOprSymSubRoot,0); bOprSym=1; break; case BndSym: tnlpvTemp.hTreeItem=m_pTreeCtrl->InsertItem(strCode.Mid(m_vectorSymbol[i].nStrPos,m_vectorSymbol[i].nStrLen),hBndSymSubRoot,0); bBndSym=1; break; case IllegalChar: tnlpvTemp.hTreeItem=m_pTreeCtrl->InsertItem(strCode.Mid(m_vectorSymbol[i].nStrPos,m_vectorSymbol[i].nStrLen),hIllegalCharSubRoot,0); bIllegalChar=1; break; } tnlpvTemp.lpv=m_vectorSymbol[i]; m_vectorTreeNode_Lpv.push_back(tnlpvTemp); } if(!bKeyWord) m_pTreeCtrl->DeleteItem(hKeyWordSubRoot); if(!bId) m_pTreeCtrl->DeleteItem(hIdSubRoot); if(!bConst) m_pTreeCtrl->DeleteItem(hConstSubRoot); if(!bOprSym) m_pTreeCtrl->DeleteItem(hOprSymSubRoot); if(!bBndSym) m_pTreeCtrl->DeleteItem(hBndSymSubRoot); if(!bIllegalChar) m_pTreeCtrl->DeleteItem(hIllegalCharSubRoot); trfTemp.vectorTnl=m_vectorTreeNode_Lpv; trfTemp.szFile=(LPSTR)(LPCSTR)strFile; m_pwndWorkSpaceBar->AddTRF(trfTemp); m_pTreeCtrl->Expand(hRoot,TVE_EXPAND); } void CIDEView::OnRButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default BCMenu *menuPopup; BCMenu menu; menu.LoadMenu(IDR_IDETYPE); if(m_pMainFrame->GetScreenStatus()) menuPopup=(BCMenu*)menu.GetSubMenu(2); else menuPopup=(BCMenu*)menu.GetSubMenu(1); ClientToScreen(&point); menuPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,point.y,this); menuPopup->DestroyMenu(); } void CIDEView::OnSelall() { // TODO: Add your command handler code here CString str; GetWindowText(str); m_pEdit->SetSel(0,str.GetLength(),1); } void CIDEView::DisplayLnCol() { CString str; str.Format("行:%d,列:%d",m_nCurLn,m_nCurCol); m_pwndStatusBar->SetPaneText(1,str,1); } void CIDEView::OnCaptureChanged(CWnd *pWnd) { // TODO: Add your message handler code here PaintLeft(); CEditView::OnCaptureChanged(pWnd); } void CIDEView::OnPaintLeft(WPARAM wParam,LPARAM lParam) { PaintLeft(); } void CIDEView::OnClean() { // TODO: Add your command handler code here CString str; CString strLeft,strRight; int nPos; str=m_pIDEDoc->GetPathName(); nPos=str.ReverseFind('\\'); strLeft=str.Left(nPos+1); strRight=str.Right(str.GetLength()-nPos-1); if(strRight.Right(4)==".pas") str=strLeft+strRight.Left(strRight.GetLength()-4)+"_LexAnanlysisResult.dat"; else str=strLeft+strRight+"_LexAnanlysisResult.dat"; if(GetFileAttributes(str)==-1) return; CFile file; file.Remove(str); }