📄 公式编辑dlg.cpp
字号:
// 公式编辑Dlg.cpp : implementation file
//
#include "stdafx.h"
#include "公式编辑.h"
#include "公式编辑Dlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
/////////////////////////////////////////////////////////////////////////////
//链表
struct ListNode
{
int cx;
int step;
ListNode * next;
ListNode * before;
};
struct Node
{
int ud;
Node * next;
Node * before;
};
class udList
{
private:
Node * first;
Node * Cur;
public:
udList()
{first=Cur=new Node;
first->next=NULL;
first->before=NULL;
first->ud=3;
}
void putin(int num)
{
Node * temp=new Node;
temp->ud=num;
temp->before=Cur;
temp->next=NULL;
Cur->next=temp;
Cur=temp;
}
void back(int &num)
{Node * temp=Cur;
Cur=Cur->before;
num=temp->ud;
Cur->next=NULL;
delete temp;
}
};
class List
{
private:
ListNode * first;
ListNode * Cur;
public:
List(int x)
{first=Cur=new ListNode;
Cur->cx=x;
Cur->step=0;
Cur->next=NULL;
Cur->before=NULL;
}
~List()
{
while(first!=NULL)
{
Cur=first;
first=first->next;
delete Cur;
}
}
int biggsetStep()
{
ListNode * temp=first;
while(temp->next!=NULL)
{
temp=temp->next;
}
return temp->step;
}
void AddToList(int num,int step)
{
if(biggsetStep()<step){
ListNode *temp=new ListNode;
temp->cx=num;
temp->step=Cur->step++;
temp->next=NULL;
temp->before=Cur;
Cur=temp;
}
if(Cur->step==step){
if(Cur->cx<num)
{Cur->cx=num;
if(Cur->next!=NULL)
Cur=Cur->next;
}
}
}
void BackToList(long & x)
{
x=Cur->cx;
if(Cur->before!=first)
Cur=Cur->before;
}
};
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()
/////////////////////////////////////////////////////////////////////////////
// CMyDlg dialog
CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMyDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMyDlg)
m_input = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMyDlg)
DDX_Text(pDX, IDC_ED_INPUT, m_input);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
//{{AFX_MSG_MAP(CMyDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BT_TRANSEFER, OnBtTransefer)
ON_BN_CLICKED(IDC_BT_CLEAR, OnBtClear)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyDlg message handlers
BOOL CMyDlg::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
return TRUE; // return TRUE unless you set the focus to a control
}
void CMyDlg::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 CMyDlg::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 CMyDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CMyDlg::OnBtTransefer()
{
// TODO: Add your control notification handler code here
GetDlgItem(IDC_ED_INPUT)->GetWindowText(m_input);
CWnd * pWnd=GetDlgItem(IDC_ED_OUTPUT);
CDC * pDC=pWnd->GetDC();
CFont *pfont=pWnd->GetFont();
LOGFONT lf;
pfont->GetLogFont(&lf);
lf.lfHeight*=3;
lf.lfWidth*=3;
pDC->SelectObject(pfont);
int a=2;//表示字体显示大小级别
CSize current(100,70);
List list(current.cx);
int step=0;
int newlast=0;//表示最后一级的横位置
int yulei=current.cy ;//表示开始的 纵位置
udList ud;
for(int i=0;i<m_input.GetLength();i++)
{
switch(m_input[i])
{
//上标符号全局变量置1
case '^':{
m_ud=1;
break;
}
//下标符号 全局变量置0
case '_':{
m_ud=0;
break;
}
//{,A^{B_{5}}_{4}
case '{':{
//current的纵坐标在全局变量的指导下提1/3或者降2/3
ud.putin(m_ud);
if(m_ud==1){
current.cy-=abs(lf.lfHeight/3);
}
if(m_ud==0){
current.cy+=abs(2*lf.lfHeight/3);
}
//字体变小为当前字体小一级
lf.lfHeight/=a;
lf.lfWidth/=a;
step++;
break;
}
//如果是},
case'}':{
//字体变大为当前字体大一级
ud.back(m_ud);
lf.lfHeight*=a;
lf.lfWidth*=a;
//current的纵坐标在全局变量的指导下恢复原来的地方
if(m_ud==1){
current.cy+=abs(lf.lfHeight/3);
}
if(m_ud==0){
current.cy-=abs(2*lf.lfHeight/3);
}
step--; //
//恢复current的cx
list.BackToList(current.cx);
break;
}
//如果是字母
default:
{//按照当前位置+字体输出
CFont * pfont=new CFont;
pfont->CreateFontIndirect(&lf);
pDC->SelectObject(pfont);
//////////////////////////
// A^{3_{a}^{b}}_{4}B_{5}
if(i!=0&&m_input[i-1]=='}')
{
current.cx=newlast;
current.cy=yulei;
}//重新开始的东西
pDC->TextOut(current.cx,current.cy,m_input[i]);
delete pfont;//删除旧字体
if(i!=0&&m_input[i-1]=='{')
list.AddToList(current.cx,step);
//修改current的位置,其中横坐标等于当前坐标+字体宽度。
char c=m_input[i];
current.cx+=pDC->GetTextExtent(&c,1).cx;
if(newlast<current.cx)
newlast=current.cx;
}//case的结尾
}//switch结尾
}//for结尾
}
void CMyDlg::OnBtClear()
{
// TODO: Add your control notification handler code here
m_input.Empty();
GetDlgItem(IDC_ED_INPUT)->SetWindowText(m_input);
Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -