📄 c_minusdlg.cpp
字号:
// C_minusDlg.cpp : implementation file
//
#include "stdafx.h"
#include "C_minus.h"
#include "C_minusDlg.h"
#include <vector>
#include "lex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern int yylex();
extern void ClearTable();
extern FILE *yyin, *yyout;
extern int yylval;
extern std::vector<char *> ctable;
extern std::vector<char *> vtable;
extern char *yytext;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CC_minusDlg dialog
CC_minusDlg::CC_minusDlg(CWnd* pParent /*=NULL*/)
: CDialog(CC_minusDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CC_minusDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CC_minusDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CC_minusDlg)
DDX_Control(pDX, IDC_RICHEDIT2, m_ReportEdit);
DDX_Control(pDX, IDC_RICHEDIT1, m_SrcEdit);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CC_minusDlg, CDialog)
//{{AFX_MSG_MAP(CC_minusDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_OPEN, OnOpen)
ON_BN_CLICKED(IDC_ANALYZE, OnAnalyze)
ON_WM_SIZE()
ON_WM_SIZING()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CC_minusDlg message handlers
BOOL CC_minusDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_DONGAnchor.Init(this);
m_DONGAnchor.Add(IDC_RICHEDIT1, DA_ALL);
m_DONGAnchor.Add(IDC_RICHEDIT2, DA_LEFT | DA_RIGHT | DA_BOTTOM);
m_DONGAnchor.Add(IDC_STATIC1, DA_LEFT | DA_RIGHT | DA_BOTTOM);
return TRUE; // return TRUE unless you set the focus to a control
}
void CC_minusDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CC_minusDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CC_minusDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
static DWORD CALLBACK
MyStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
CFile* pFile = (CFile*) dwCookie;
*pcb = pFile->Read(pbBuff, cb);
return 0;
}
void CC_minusDlg::OnOpen()
{
// 打开C_minus源码文件
// 先清空原有内容
m_SrcEdit.Clear();
// 过滤设置
CString szFileFilter(
"C_minus源码(*.cm)|*.cm|"
"所有文件(*.*)|*.*||");
// 文件打开对话框
CFileDialog filedlg(TRUE, "cm", "", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFileFilter, this );
if ( filedlg.DoModal() != IDOK )
return;
// 读文件内容
m_srcFilePath = filedlg.GetPathName();
CFile srcFile(m_srcFilePath, CFile::modeRead);
// 处理打开文件错误
if ( !srcFile )
{
MessageBox("无法打开目标文件!", "错误", MB_ICONSTOP);
return;
}
// 将内容读到编辑控件内
EDITSTREAM es;
es.dwCookie = (DWORD) &srcFile;
es.pfnCallback = MyStreamInCallback;
m_SrcEdit.StreamIn(SF_TEXT, es);
// 关闭文件
srcFile.Close();
// 修改标题方便识别当前打开的文件
SetWindowText(filedlg.GetFileName() + " - C_minus Lexical Analyzer");
}
static DWORD CALLBACK
MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
CFile* pFile = (CFile*) dwCookie;
pFile->Write(pbBuff, cb);
*pcb = cb;
return 0;
}
void CC_minusDlg::OnSave()
{
CString szFileFilter(
"C_minus源码(*.cm)|*.cm|"
"所有文件(*.*)|*.*||");
// 文件打开对话框
CFileDialog filedlg(FALSE, "cm", "", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFileFilter, this );
if ( filedlg.DoModal() != IDOK )
return;
}
void CC_minusDlg::OnAnalyze()
{
// 分析
// 先保存文件
CFile srcFile("cm.tmp", CFile::modeWrite | CFile::modeCreate);
if ( !srcFile )
{
MessageBox("创建临时文件失败!", "错误", MB_ICONSTOP);
return;
}
EDITSTREAM es;
es.dwCookie = (DWORD) &srcFile;
es.pfnCallback = MyStreamOutCallback;
m_SrcEdit.StreamOut(SF_TEXT, es);
srcFile.Close();
// 重新打开文件
yyin = fopen("cm.tmp", "r");
token aToken;
aToken.code = yylex();
aToken.addr = yylval;
m_ReportEdit.SetReadOnly(FALSE);
m_ReportEdit.SetSel(0, -1);
m_ReportEdit.Clear();
CString str;
m_ReportEdit.ReplaceSel("单词序列:\n\tText\tCode\tAddr\tType\n");
while (aToken.code != $END)
{
if (aToken.code != $ERROR)
{
str.Format("\t%s\t%d\t%d\t", yytext, aToken.code, aToken.addr);
if (aToken.code <= $NULL) str += "关键字\n";
else if(aToken.code <= $ARROWOP) str += "运算符\n";
else if(aToken.code <= $QUES) str += "界符\n";
else
switch(aToken.code)
{
case $ID:
str += "标识符\n";
break;
case $INTNUM:
str += "整型常量\n";
break;
case $FLOATNUM:
str += "浮点常量\n";
break;
case $CHARTYPE:
str += "字符常量\n";
break;
case $STRINGTYPE:
str += "字符串常量\n";
break;
}
}
else
str.Format("\t非法字符:%s\n", yytext);
m_ReportEdit.ReplaceSel(str);
aToken.code = yylex();
aToken.addr = yylval;
}
m_ReportEdit.ReplaceSel("符号表:\n\tID\tSymbol\n");
for (int i = 0; i != vtable.size(); ++i)
{
str.Format("\t%d\t%s\n", i+1, vtable[i]);
m_ReportEdit.ReplaceSel(str);
}
m_ReportEdit.ReplaceSel("常量表:\n\tID\tSymbol");
for (i = 0; i != ctable.size(); ++i)
{
str.Format("\n\t%d\t%s", i+1, ctable[i]);
m_ReportEdit.ReplaceSel(str);
}
m_ReportEdit.SetReadOnly();
ClearTable();
fclose(yyin);
DeleteFile("cm.tmp");
}
void CC_minusDlg::OnSize(UINT nType, int cx, int cy)
{ // 实时调整各控件大小
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
m_DONGAnchor.Run(cx,cy);
}
void CC_minusDlg::OnSizing(UINT nSide, LPRECT lpRect)
{ // 限制对话框的最小尺寸
if (lpRect->right - lpRect->left <= 500)
{
lpRect->right = lpRect->left + 500;
}
if (lpRect->bottom - lpRect->top <= 400)
{
lpRect->bottom = lpRect->top + 400;
}
CDialog::OnSizing(nSide, lpRect);
}
BOOL CC_minusDlg::PreTranslateMessage(MSG* pMsg)
{
// 重载此虚函数以便拦截消息
// 为使翻页编辑框能响应回车键,需要拦截消息,此函数可在GetMessage()函数获得消息
// 而未来得及发送出去之前抢先拦截消息进行处理。拦截位置:
// TranslateMessage(&msg);
// ...........// 在此处拦截
// DispathchMessage(&msg);
// 谨记:勿随便修改此函数!
// 判断是否键盘消息(按下按键)而且是回车键
if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
{
// 获得焦点所在控件
HWND hWnd = ::GetFocus();
// 获得该控件ID
int iID = ::GetDlgCtrlID(hWnd);
// 检查该控件是否C_minus源码编辑框(其ID为IDC_RICHEDIT1)
if( iID == IDC_RICHEDIT1)
{
char strLineBuf[512];
int nChars = m_SrcEdit.GetLine(m_SrcEdit.LineFromChar(-1), strLineBuf);
for (int i = 0; i != nChars; ++i)
{
if (strLineBuf[i] != ' ' && strLineBuf[i] != '\t')
{
strLineBuf[i] = '\0';
break;
}
}
m_SrcEdit.ReplaceSel("\r\n");
m_SrcEdit.ReplaceSel(strLineBuf);
return TRUE;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -