纯C语言用Windows api写画函数图像

!!!如有转载 请注明出处!!!

主要功能介绍:
1、输入函数的解析式,可以在窗口中画出解析式的函数图像。
2、解析式只能以x为自变量。
3、解析式目前只能写数字、括号、加减乘除四则运算(±*/),不能写乘方、开方、各种函数(三角函数、对数等等)。
4、输入解析式时,程序禁用中文输入法,也不能输入中文括号。.
5、输入解析式语法错误时,程序弹出对话框并告知哪里有错误,允许重新输入。
6、输入解析式的窗口在任务栏不显示。
7、输入解析式的窗口一旦打开,主窗口就不响应任何操作,直到输入解析式的窗口关闭。关闭以后,主窗口重画所有函数图像和x、y轴。
8、x、y轴为黑色,图像红色。

环境:
Windows10 64位,MinGW-POSIX-64位。

注:
1、若为32位系统,据说需要将SetWindowLongPtr换为SetWindowLong,里面参数GWLP_WNDPROC需要换为GWL_WNDPROC(我也没试过,所以不能那么肯定。大家可以自己试一试)

2、如果编译不通过,在makefile.bat中编译可执行文件的一行手动链接pthread库。

3、如果报错不支持WinMain函数入口,可以百度下载msys64(大概就是这么一个东西)来支持win32应用程序,至于如何安装百度都有,这里不赘述。

截图:






代码如下:

//libtranslateexpression.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <math.h>

#define SGR_MAX_EXPR 1024

#define CHECKFUNC_NO_ERROR				0x00
#define CHECKFUNC_FOUND_TIMEADDBR		0x01
#define CHECKFUNC_FOUND_TIMESUBBR		0x02
#define CHECKFUNC_FOUND_DIVADDBR		0x03
#define CHECKFUNC_FOUND_DIVSUBBR		0x04
#define CHECKFUNC_BRACKET_ERROR			0x05
#define CHECKFUNC_NONUMBERAFTERSIGN		0x06
#define CHECKFUNC_NONUMBERBEFORESIGN	0x07
#define CHECKFUNC_DECIMALPOINT_ERROR	0x08
#define CHECKFUNC_VARIBLEHASNOSIGN		0x09

BOOL CheckFuncExpr(const char* expr)
{
	if(strstr(expr,"*+(")!=NULL)	return CHECKFUNC_FOUND_TIMEADDBR;
    if(strstr(expr,"*-(")!=NULL)	return CHECKFUNC_FOUND_TIMESUBBR;
    if(strstr(expr,"/+(")!=NULL)	return CHECKFUNC_FOUND_DIVADDBR;
    if(strstr(expr,"/-(")!=NULL)	return CHECKFUNC_FOUND_DIVSUBBR;
    
	int i=0,bracket=0;
    for(;expr[i]!='\0';i++)
    {
		if(expr[i]=='(')	bracket++;
        if(expr[i]==')')	bracket--;
        if(bracket<0)		return CHECKFUNC_BRACKET_ERROR;
        if(expr[i]=='+' || expr[i]=='-')
        {
			if(expr[i+1]!='(' && expr[i+1]>'9' && expr[i+1]<'0' && expr[i+1]!='x')	return CHECKFUNC_NONUMBERAFTERSIGN;
        }
        if(expr[i]=='*' || expr[i]=='/')
        {
			if(i==0)																return CHECKFUNC_NONUMBERBEFORESIGN;
			if(expr[i+1]!='(' && expr[i+1]>'9' && expr[i+1]<'0' && expr[i+1]!='x')	return CHECKFUNC_NONUMBERAFTERSIGN;
            if(expr[i-1]!='(' && expr[i-1]>'9' && expr[i-1]<'0' && expr[i-1]!='x')	return CHECKFUNC_NONUMBERBEFORESIGN;
        }
        if(expr[i]=='.')
        {
			if(expr[i+1]<'0' && expr[i+1]>'9') return CHECKFUNC_DECIMALPOINT_ERROR;
            if(expr[i-1]<'0' && expr[i-1]>'9') return CHECKFUNC_DECIMALPOINT_ERROR;
        }
        if(expr[i]=='x')
        {
			if((expr[i+1]>'0' && expr[i+1]<'9') || expr[i+1]=='.') return CHECKFUNC_VARIBLEHASNOSIGN;
            if(i!=0)
				if((expr[i-1]>'0' && expr[i-1]<'9') || expr[i-1]=='.') return CHECKFUNC_VARIBLEHASNOSIGN;
        }
    }
    if(bracket!=0)
		return CHECKFUNC_BRACKET_ERROR;
    return CHECKFUNC_NO_ERROR;
}

BOOL CheckNum(double x)
{
	switch(fpclassify(x))
    {
	case FP_ZERO:return TRUE;
    case FP_NORMAL:return TRUE;
    default:return FALSE;
    }
}

void ReplaceAddSign(char* expr,char*out)
{
	memset(out,0,sizeof(char)*SGR_MAX_EXPR);
	char *k=expr;
	char *p=out;

	if(*expr!='+' && *expr!='-')
    {
		*p='+';p++;
        *p=*k;
    }

    while(*k!='\0')
    {
		if(*k!='+' && *k!='-')
        {
			*p=*k;p++;k++;
        }
        else
        {
			if(*(k-1)!='+' && *(k-1)!='-')*p=*k;
            if(*k=='-' && (*(k-1)=='+' || *(k-1)=='-'))*p=(*p=='+')?'-':'+';
            if(*(k+1)!='+' && *(k+1)!='-')p++;
            k++;
        }
    }
    p=out;
    while(*p!='\0')
    {
		if(*p>='9' && *p<='0' && *p!='.' && *(p+1)=='+')
			memmove(p+1,p+2,strlen(p+2)+1);
        p++;
    }
}

double GetResult_addsub(char* expr)
{
	double a=0,b=0;
    char* p=expr;
    if(*p=='+' ||*p=='-')p++;
    sscanf(p,"%lf",&a);
    if(*(p-1)=='-')a=-a;
    while(1)
    {
        while(*p!='+' && *p!='-')
        {
			p++;
            if(*p==0)break;
        }
        if(sscanf(++p,"%lf",&b)==0)break;
        switch(*(p-1))
        {
			case '+':a+=b;break;
			case '-':a-=b;break;
        }
    }
    return a;
}

double GetResult_timediv(char* expr)
{
	double a=0,b=0;
    char* p=expr;
    sscanf(p,"%lf",&a);
    while(1)
    {
        while(*p!='/' && *p!='*')
        {
			p++;
            if(*p==0)break;
        }
        if(sscanf(++p,"%lf",&b)<=0)break;
        switch(*(p-1))
        {
			case '*':a*=b;break;
			case '/':a/=b;break;
            case '-':
				switch(*(p-2))
                {
					case '*':a*=-b;break;
                    case '/':a/=-b;break;
                }
                break;
        }
    }
    return a;
}

void gettimedivexpr(const char*expr,char*out)
{
	for(int i=0;expr[i]!='\0';i++)
    {
		if(((expr[i]>='0' && expr[i]<='9') || expr[i]=='.' || expr[i]=='*' || expr[i]=='/') || (expr[i]=='-' && (expr[i-1]=='*' || expr[i-1]=='/')))out[i]=expr[i];
        else	break;
    }
}

double nonebracket_TranslateExpression(char*expr)
{
	char RepAS[SGR_MAX_EXPR]={0};
    ReplaceAddSign(expr,RepAS);

    char*p=RepAS;
	char**p_sep;
    
    double a=0;
    double res[SGR_MAX_EXPR/2]={0.0};
    int n=0,i;
    
    char**sep=(char**)malloc(SGR_MAX_EXPR/2*sizeof(char*));

	for(i=0;i<SGR_MAX_EXPR/2;i++)
    {
		sep[i]=(char*)malloc(SGR_MAX_EXPR*sizeof(char));
        memset(sep[i],0,sizeof(char)*SGR_MAX_EXPR);
    }
    for(p_sep=sep;*p!='\0';n++,p_sep++)
    {
		sscanf(p++,"%c",*p_sep);
        gettimedivexpr(p,(*p_sep)+1);
        p+=strlen((*p_sep)+1);
	}
	for(p_sep=sep;**p_sep!='\0';p_sep++)res[p_sep-sep]=GetResult_timediv(*p_sep+1);
	for(p_sep=sep;**p_sep!='\0';p_sep++)res[p_sep-sep]*=(**p_sep=='+')?(1):(-1);
    for(p_sep=sep;**p_sep!='\0';p_sep++)a+=res[p_sep-sep]; 
	for(i=0;i<SGR_MAX_EXPR/2;i++)
    {
		free(sep[i]);
        sep[i]=NULL;
    }
    free(sep);sep=NULL;
    return a;
}

UINT getbracketstep(char*expr)
{
	UINT bracket=0;
    UINT mostbracket=0;
    UINT i=0;
	for(;expr[i]!='\0';i++)
    {
		switch(expr[i])
        {
        case '(':
			bracket++;
            if(mostbracket<bracket)
				mostbracket=bracket;
            break;
        case ')':
			bracket--;
            break;
        }
    }
	return mostbracket;
}

void exprbracketpos(char*expr,UINT bracketstep,char**out)
{
	UINT i=0;
    UINT bracket=0;
    UINT p=0;
    for(;expr[i]!='\0';i++)
    {
		switch(expr[i])
        {
        case '(':
			bracket++;
            break;
        case ')':
			bracket--;
            if(bracket==bracketstep-1)	p++;
            break;
        }
        if(bracket==bracketstep)
			out[p][strlen(out[p])]=expr[i];
    }
}

double TranslateExpression(char*expr)
{
	UINT mostbracket=getbracketstep(expr);
    if(mostbracket==0)
		return nonebracket_TranslateExpression(expr);
    int bracket=0;
    int i=0;
    char decomp[SGR_MAX_EXPR]={'\0'};
    char laststr[SGR_MAX_EXPR]={'\0'};
    for(;expr[i]!='\0';i++)
    {
		if(expr[i]==')')
        {
			bracket--;
            if(bracket==0)
            {
                sprintf(laststr+strlen(laststr),"%lf",TranslateExpression(decomp));
                memset(decomp,0,strlen(decomp));
                continue;
            }
        }
		if(bracket>=1)decomp[strlen(decomp)]=expr[i];
		if(expr[i]=='(')
        {
			bracket++;
        }
        if(bracket==0)laststr[strlen(laststr)]=expr[i];
    }
    return nonebracket_TranslateExpression(laststr);
}

double GetIndependent(char*func,char indep,double volue)
{
	char expr[SGR_MAX_EXPR]={'\0'};
	for(int i=0;func[i]!='\0';i++)
    {
		if(func[i]==indep)
			sprintf(expr+strlen(expr),"%lf",volue);
        else
			expr[strlen(expr)]=func[i];
    }
    return TranslateExpression(expr);
}


这是一个库的代码,具体就是表达式求值功能。

还有def文件(libtranslateexpression.def):

LIBRARY libtranslateexpression.dll
EXPORTS
	CheckFuncExpr		@1
	CheckNum			@2	
	TranslateExpression	@3
	GetIndependent		@4

接下来是exe文件的代码:

#include <windows.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

#define HMENU_PAINT_FUNC 1

#define HMENU_func_TEXTFX 2
#define HMENU_func_EDITFX 3
#define HMENU_func_BUTTONOKAY 4
#define HMENU_func_BUTTONCANCEL 5

#define SGR_MAX_EXPR 1024

#define CHECKFUNC_NO_ERROR				0x00
#define CHECKFUNC_FOUND_TIMEADDBR		0x01
#define CHECKFUNC_FOUND_TIMESUBBR		0x02
#define CHECKFUNC_FOUND_DIVADDBR		0x03
#define CHECKFUNC_FOUND_DIVSUBBR		0x04
#define CHECKFUNC_BRACKET_ERROR			0x05
#define CHECKFUNC_NONUMBERAFTERSIGN		0x06
#define CHECKFUNC_NONUMBERBEFORESIGN	0x07
#define CHECKFUNC_DECIMALPOINT_ERROR	0x08
#define CHECKFUNC_VARIBLEHASNOSIGN		0x09

BOOL CheckFuncExpr(const char*expr);
BOOL CheckNum(double x);
double GetIndependent(char*func,char indep,double volue);

char functions[64][SGR_MAX_EXPR]={{0}};
int funcnum=0;

void paintfunc(int enlarge,HWND hwnd)
{
	static PAINTSTRUCT ps;
    static HPEN hpen;
    static RECT rect;
	static HDC hdc;
    hdc=BeginPaint(hwnd,&ps);
    hpen=CreatePen(PS_SOLID,1,RGB(255,0,0));
    GetClientRect(hwnd,&rect);
	SelectObject(hdc,hpen);
    
    static int i;
    static int j;
    static BOOL paint;
    static double y;

    for(j=0;j<funcnum;j++)
    {
        for(i=-rect.right/2;i<rect.right/2;i++)
		{
			y=GetIndependent(functions[j],'x',(double)(i)/enlarge);
			if(CheckNum(y))
            {
				MoveToEx(hdc,rect.right/2+i,rect.bottom/2-y*enlarge,NULL);
				break;
            }
        }
        
		for(paint=TRUE;i<(rect.right-rect.left)/2;i++)
		{
			y=GetIndependent(functions[j],'x',(double)(i)/enlarge);
			if(CheckNum(y))
			{
				if(paint==TRUE)
					LineTo(hdc,rect.right/2+i,rect.bottom/2-y*enlarge);
				else
                {
					MoveToEx(hdc,rect.right/2+i,rect.bottom/2-y*enlarge,NULL);
                    paint=TRUE;
				}
            }
            else	paint=FALSE;
        }
	}
    
    for(i=0;i<rect.right;i++)	SetPixel(hdc,i,rect.bottom/2,RGB(0,0,0));
	for(i=0;i<rect.bottom;i++)	SetPixel(hdc,rect.right/2,i,RGB(0,0,0));
    
    DeleteObject(hpen);
    EndPaint(hwnd,&ps);
}

HINSTANCE hInst;

BOOL NEWWINDOWEXISTS=FALSE;
BOOL MAINWINDOW_RESP=TRUE;
RECT MAINWINDOW_RECT;

pthread_t FuncInput_pth;

HWND FuncInput_hwnd;
HWND Main_hwnd;

WNDPROC func_hEDITfx_old_WndProc;

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK func_WndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK func_hEDITfx_WndProc(HWND,UINT,WPARAM,LPARAM);

BOOL CreateFuncInputWindow(HWND hwnd)
{
	static TCHAR szAppName[]=TEXT("MathPaint_FuncInput");
    MSG msg;
	WNDCLASS wndclass;
    
    wndclass.lpfnWndProc=func_WndProc;
    wndclass.cbClsExtra=0;
    wndclass.cbWndExtra=0;
    wndclass.hInstance=hInst;
    wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
    wndclass.hbrBackground=(HBRUSH)CreateSolidBrush(RGB(240,240,240));
    wndclass.lpszMenuName=NULL;
    wndclass.lpszClassName=szAppName;
    
    RegisterClass(&wndclass);
    
    hwnd=CreateWindow(szAppName,TEXT("绘制新函数..."),WS_BORDER|WS_CAPTION|WS_VISIBLE|WS_SYSMENU|WS_POPUP|WS_CHILD,
						(MAINWINDOW_RECT.left+MAINWINDOW_RECT.right)/2-200,(MAINWINDOW_RECT.top+MAINWINDOW_RECT.bottom)/2-100,400,200,Main_hwnd,NULL,hInst,NULL);
    ShowWindow(hwnd,SW_SHOW);
	UpdateWindow(hwnd);
    while(GetMessage(&msg,hwnd,0,0)>0)
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
        Sleep(50);
	}
	return msg.wParam;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) 
{ 
    ShowWindow(GetForegroundWindow(),SW_HIDE);
    DestroyWindow(GetForegroundWindow());
    
	static TCHAR szAppName[]=TEXT("MathPaint");
	HWND hwnd;
	MSG msg;
	WNDCLASS wndclass;
    
    hInst=hInstance;

	wndclass.style=CS_HREDRAW|CS_VREDRAW;
	wndclass.lpfnWndProc=WndProc; 
	wndclass.cbClsExtra=0; 
	wndclass.cbWndExtra=0;
	wndclass.hInstance=hInstance;
	wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); 
	wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); 
	wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); 
	wndclass.lpszMenuName=NULL;
	wndclass.lpszClassName=szAppName; 
	RegisterClass(&wndclass);
    
	Main_hwnd=hwnd=CreateWindow(szAppName,TEXT("MathPaint"),WS_MAXIMIZE|WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
	ShowWindow(hwnd,SW_SHOW);
	UpdateWindow(hwnd);

	while(GetMessage(&msg,hwnd,0,0)>0)
	{
		if(MAINWINDOW_RESP==FALSE && NEWWINDOWEXISTS==FALSE)
        {
			NEWWINDOWEXISTS=TRUE;
			pthread_create(&FuncInput_pth,NULL,(void*)CreateFuncInputWindow,FuncInput_hwnd);
        }
		TranslateMessage(&msg);
		DispatchMessage(&msg);
        Sleep(50);
	}
	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	static HMENU hmenu_paint;
    static HMENU hmenu_paint_func;
    
    if(MAINWINDOW_RESP==TRUE)
	{
		EnableMenuItem(hmenu_paint,0,MF_BYPOSITION|MF_ENABLED);
		switch(message) 
		{ 
		case WM_CREATE: 
			GetWindowRect(hwnd,&MAINWINDOW_RECT);
            hmenu_paint=CreateMenu();
            hmenu_paint_func=CreateMenu();
            AppendMenu(hmenu_paint_func,MF_ENABLED|MF_STRING,HMENU_PAINT_FUNC,TEXT("绘制新函数..."));
            AppendMenu(hmenu_paint,MF_ENABLED|MF_STRING|MF_POPUP,(UINT_PTR)hmenu_paint_func,TEXT("作图(p)"));
            SetMenu(hwnd,hmenu_paint);
            return 0;
        case WM_COMMAND:
			switch(LOWORD(wParam))
            {
			case HMENU_PAINT_FUNC:
				MAINWINDOW_RESP=FALSE;
                EnableMenuItem(hmenu_paint,0,MF_BYPOSITION|MF_GRAYED);
				return 0;
            }
            return 0;
        case WM_PAINT:
			GetWindowRect(hwnd,&MAINWINDOW_RECT);
            break;
		}
    }
    
    else
    {
		switch(message)
        {
        case WM_CLOSE:
			return 0;
        case WM_MOVE:
			MoveWindow(hwnd,MAINWINDOW_RECT.left,MAINWINDOW_RECT.top,MAINWINDOW_RECT.right-MAINWINDOW_RECT.left,MAINWINDOW_RECT.bottom-MAINWINDOW_RECT.top,TRUE);
            return 0;
        }
    }
    switch(message)
    {
	case WM_PAINT:
		paintfunc(50,hwnd);
        break;
    }
    return DefWindowProc(hwnd,message,wParam,lParam);
}

LRESULT CALLBACK func_hEDITfx_WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	ImmAssociateContext(hwnd,NULL);
	switch(message)
    {
    case WM_CHAR:
		switch(wParam)
        {
		case '(':break;
        case ')':break;
        case 'x':break;
        case '+':break;
        case '-':break;
        case '*':break;
        case '/':break;
        case 8:break;
        default:
			if(wParam>='0' && wParam<='9')	break;
            else return 0;
        }
        break;
    case WM_PASTE:
		return 0;
    }
	return func_hEDITfx_old_WndProc(hwnd,message,wParam,lParam);
}

LRESULT CALLBACK func_WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	static RECT rect;
    static HWND hTEXTfx;
    static HWND hEDITfx;
    static HWND hBUTTONokay;
    static HWND hBUTTONcancel;
    
	static HFONT hfont;
    
    static int width;
    static int height;
    
    static char FuncExpr[SGR_MAX_EXPR];
	
	switch(message)
    {
    case WM_CREATE:
		GetClientRect(hwnd,&rect);
        
        width=rect.right-rect.left;
        height=rect.bottom-rect.top;
        
        hfont=CreateFont(-15,-7.5,0,0,400,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,FF_DONTCARE,TEXT("微软雅黑"));
        
		hTEXTfx=CreateWindow(TEXT("static"),TEXT("y="),WS_CHILD|WS_VISIBLE|SS_CENTERIMAGE|SS_LEFT,width/16,height/8,width/4,height/8,hwnd,(HMENU)HMENU_func_TEXTFX,hInst,NULL);
        hEDITfx=CreateWindow(TEXT("edit"),TEXT(""),WS_CHILD|WS_VISIBLE|WS_BORDER|ES_AUTOVSCROLL|ES_MULTILINE,width/16,height/4,width/2,height/2,hwnd,(HMENU)HMENU_func_EDITFX,hInst,NULL);
        
        hBUTTONcancel=CreateWindow(TEXT("button"),TEXT("取消"),WS_CHILD|WS_VISIBLE|WS_BORDER|BS_CENTER,width*11/16,height/8,width/4,height*3/10,hwnd,(HMENU)HMENU_func_BUTTONCANCEL,hInst,NULL);
        hBUTTONokay=CreateWindow(TEXT("button"),TEXT("确定"),WS_CHILD|WS_VISIBLE|WS_BORDER|BS_CENTER,width*11/16,height*23/40,width/4,height*3/10,hwnd,(HMENU)HMENU_func_BUTTONOKAY,hInst,NULL);

		SendMessage(hTEXTfx,WM_SETFONT,(WPARAM)hfont,(LPARAM)NULL);
        SendMessage(hEDITfx,WM_SETFONT,(WPARAM)hfont,(LPARAM)NULL);
		SendMessage(hBUTTONcancel,WM_SETFONT,(WPARAM)hfont,(LPARAM)NULL);
        SendMessage(hBUTTONokay,WM_SETFONT,(WPARAM)hfont,(LPARAM)NULL);
        
        func_hEDITfx_old_WndProc=(WNDPROC)SetWindowLongPtr(hEDITfx,GWLP_WNDPROC,(LONG)func_hEDITfx_WndProc);
        break;
    case WM_COMMAND:
		switch(LOWORD(wParam))
        {
		case HMENU_func_BUTTONCANCEL:
			DestroyWindow(hwnd);
            break;
        case HMENU_func_BUTTONOKAY:
			memset(FuncExpr,0,strlen(FuncExpr));
			GetWindowText(hEDITfx,FuncExpr,sizeof(FuncExpr));
            switch(CheckFuncExpr(FuncExpr))
            {
            case CHECKFUNC_FOUND_TIMEADDBR   :MessageBox(NULL,TEXT("乘号(*)后面不可以跟随加号(+)。"),TEXT("函数语法错误"),MB_OK|MB_ICONERROR);return 0;
            case CHECKFUNC_FOUND_TIMESUBBR   :MessageBox(NULL,TEXT("乘号(*)后面不可以跟随减号(-)。"),TEXT("函数语法错误"),MB_OK|MB_ICONERROR);return 0;
            case CHECKFUNC_FOUND_DIVADDBR    :MessageBox(NULL,TEXT("除号(/)后面不可以跟随加号(+)。"),TEXT("函数语法错误"),MB_OK|MB_ICONERROR);return 0;
			case CHECKFUNC_FOUND_DIVSUBBR    :MessageBox(NULL,TEXT("除号(/)后面不可以跟随减号(-)。"),TEXT("函数语法错误"),MB_OK|MB_ICONERROR);return 0;
            case CHECKFUNC_BRACKET_ERROR     :MessageBox(NULL,TEXT("括号错误")					    ,TEXT("函数语法错误"),MB_OK|MB_ICONERROR);return 0;
            case CHECKFUNC_NONUMBERAFTERSIGN :MessageBox(NULL,TEXT("运算符后无数字")				,TEXT("函数语法错误"),MB_OK|MB_ICONERROR);return 0;
            case CHECKFUNC_NONUMBERBEFORESIGN:MessageBox(NULL,TEXT("运算符前无数字")				,TEXT("函数语法错误"),MB_OK|MB_ICONERROR);return 0;
            case CHECKFUNC_DECIMALPOINT_ERROR:MessageBox(NULL,TEXT("小数点错误")					,TEXT("函数语法错误"),MB_OK|MB_ICONERROR);return 0;
            case CHECKFUNC_VARIBLEHASNOSIGN	 :MessageBox(NULL,TEXT("自变量不能与数字直接连接")	    ,TEXT("函数语法错误"),MB_OK|MB_ICONERROR);return 0;
            }
            if(strlen(FuncExpr)!=0)	sprintf(functions[funcnum++],"%s",FuncExpr);
			DestroyWindow(hwnd);
            break;
        }
        break;
    case WM_DESTROY:
		NEWWINDOWEXISTS=FALSE;
		MAINWINDOW_RESP=TRUE;
        PostQuitMessage(0);
        InvalidateRect(Main_hwnd,NULL,TRUE);
        break;
    }
	return DefWindowProc(hwnd,message,wParam,lParam);
}


makefile.bat:

gcc -c -O3 libtranslateexpression.c
dllwrap --def libtranslateexpression.def -o libtranslateexpression.dll libtranslateexpression.o --output-lib libtranslateexpression.a
gcc mathpaint.c -o mathpaint.exe -lgdi32 -limm32 libtranslateexpression.dll
pause

大约花了一周左右,现在忙于学业还要上网课,也就做到这个程度。
接下来方向是准备实现ln log sin cos tan cot sec csc arcsin arccos arctan arcsec arccsc sqrt abs 根号 乘方。

感谢阅读 希望大家看一看代码而不是仅仅复制。
如有转载 请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值