




已阅读5页,还剩16页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
MFC编程及应用课程设计报告题目: 简单画图形程序 学号: 姓名: 指导老师: 时间: 评语:程序设计步骤:一、 建立基于对话框的应用程序框架;二、 CMy0910200155Dlg类中关键新增变量的作用:CPtrArray pta; /用于保存已绘图形的相关信息。CMemoryNode *pmN; /指向CMemoryNode类的指针,程序运行过程中动态保存对象信息。CMemoryNode *pmn; /指向CMemoryNode类的指针,从文件中读取信息时动态创建类的对象。 COLORREF m_CurrentBrushColor; /用于存放当前画刷的颜色。COLORREF m_CurrentPenColor; /用于存放当前画笔的颜色。int num; / 用于存放从Index.txt文件中读取的数字。int flag=0; /用于标识:当为1时,表示按下了”画图”按钮;当为2时,表示按下了”撤消”按钮;当为3时,表示按下了”加载历史”按钮,则从文件中读取信息。int mark; /用于标识:当为0时,表示刚画过矩形;当为1时,表示刚画过圆角矩形;当为2时,表示刚画过椭圆。int index; /用于存放pta数组的容量。int flag1=0; /用于标识,和flag搭配,用来处理多种情况下的窗口重绘问题。int ButtonState=0; /用于标识,是类CShow和类CMy0910200155Dlg的一个接口,通过其值在1和0之间转换,来处理弹出式对话框的初次绘制和移动时的重绘问题。三、 CMemoryNode类中变量的作用:COLORREF BrushColor; COLORREF PenColor; int Mark;/以上三者为类CMemoryNode的成员变量,分别用来保存绘图时画刷颜色,画笔颜色和形状。四、 与控件相关联的变量:CComboBox m_BrushColor; /指示画刷颜色组合框。CComboBox m_PenColor; /指示画笔颜色组合框。 CListBox m_Shape; /指示形状列表框。五、 应用程序功能的具体实现:1) 初始化过程:this-m_Shape.AddString(矩形); /给形状列表框添加一个项目。this-m_PenColor.AddString(红色); /给画笔颜色框添加一个项目。this-m_BrushColor.AddString(白色); /给画刷颜色框添加一个项目。(剩余项目的添加方法完全相同,就不再赘述了) m_PenColor.SetCurSel(0); m_BrushColor.SetCurSel(4); m_Shape.SetCurSel(2); /设置光标初始定位。 m_CurrentBrushColor=RGB(0,0,255); /画刷颜色设置默认初值为蓝色。 m_CurrentPenColor=RGB(255,0,0); /画笔颜色设置默认初值为红色。 this-SetWindowText(简单画图形程序); /设置窗口标题。 RECT rect; this-GetWindowRect(&rect); /得到窗体的大小。 CRgn rgn;rgn.CreateRoundRectRgn(rect.left+3,rect.top+5,rect.right-2,rect.bottom-2,40,40); this-SetWindowRgn(HRGN)rgn.GetSafeHandle(),TRUE); /按要求绘制圆角矩形的窗体。ifstream infile1(Index.txt,ios:nocreate);if(!infile1) this-GetDlgItem(IDC_BUTTON_LOAD)-EnableWindow(FALSE); /通过Index.txt文件是否存在来决定”加载历史”按钮的状态,如果存在则可用,否则不可用。2) 窗口绘制过程:此过程调用OnPaint()函数,涉及多种情况下的图形绘制和窗口重绘,是相对比较核心的部分,将在后面具体逐个分析。六、 从某一次程序运行的角度说明各个函数的功能:首先打开应用程序,系统将自动创建窗体,在窗体弹出的一瞬间,你会发现窗体是圆角形的,其次感觉颜色比较柔和。这归功于初始化中的:RECT rect; this-GetWindowRect(&rect); CRgn rgn;rgn.CreateRoundRectRgn(rect.left+3,rect.top+5,rect.right-2,rect.bottom-2,40,40); this-SetWindowRgn(HRGN)rgn.GetSafeHandle(),TRUE); /绘制圆角矩形的窗体。和应用类初始化中添加的:SetDialogBkColor(RGB(80,80,180),RGB(0,0,0); /设置窗体颜色。如果是第一次使用该程序,那么你将看到”加载历史”按钮是灰化的,不能使用,这是因为初始化中使用了该语句,ifstream infile1(Index.txt,ios:nocreate);if(!infile1) this-GetDlgItem(IDC_BUTTON_LOAD)-EnableWindow(FALSE); 没有创建过Index.txt文件,当然无法读取! 将已有的Index.txt文件删除,然后重新启动系统,会有相同的效果。你会看到窗口中”形状”,”画笔颜色”,”填充颜色” 分别默认为”圆角矩形”,”红色”,”蓝色”,这是因为在初始化过程中,已经对相应的变量赋值,而且设置了光标选择:m_PenColor.SetCurSel(0); m_BrushColor.SetCurSel(4); m_Shape.SetCurSel(2); /设置光标初始定位。 m_CurrentBrushColor=RGB(0,0,255); /画刷颜色设置默认初值为蓝色。 m_CurrentPenColor=RGB(255,0,0); /画笔颜色设置默认初值为红色。 如果我们想画一个边框为洋红色,填充色为青色的圆角矩形,那么当鼠标点击”画笔颜色”下的”洋红”时,将触发组合框IDC_COMBO_PEN_COLOR的CBN_SELENDOK消息,将调用,void CMy0910200155Dlg:OnSelendokComboPenColor() int n=m_PenColor.GetCurSel(); switch(n) case 0:m_CurrentPenColor=RGB(255,0,0);break; case 1:m_CurrentPenColor=RGB(0,255,0);break; case 2:m_CurrentPenColor=RGB(0,0,255);break; case 3:m_CurrentPenColor=RGB(255,255,0);break; case 4:m_CurrentPenColor=RGB(255,0,255);break; case 5:m_CurrentPenColor=RGB(0,255,255);break; default:m_CurrentPenColor=RGB(0,0,0);break; 同理可知,当鼠标点击”填充颜色”下的”青色”时,将触发组合框IDC_COMBO_BRUSH_COLOR的CBN_SELENDOK消息,将调用,void CMy0910200155Dlg:OnSelendokComboBrushColor() int n=m_BrushColor.GetCurSel(); switch(n) case 6:m_CurrentBrushColor=RGB(255,0,0);break; case 5:m_CurrentBrushColor=RGB(0,255,0);break; case 4:m_CurrentBrushColor=RGB(0,0,255);break; case 3:m_CurrentBrushColor=RGB(255,255,0);break; case 2:m_CurrentBrushColor=RGB(255,0,255);break; case 1:m_CurrentBrushColor=RGB(0,255,255);break; default:m_CurrentBrushColor=RGB(255,255,255);break; 这两个函数能将光标的选择转换为画笔或画刷的颜色。不过,当然必须先给组合框添加过一个CBN_SELENDOK消息!然后点击”形状”下的”圆角矩形”,这时this-m_Shape.GetSel(1)其值为TRUE,表明”圆角矩形”被选中了,当然,其它两个m_Shape.GetSel(0)和m_Shape.GetSel(2)都为FALSE。在画图前,如果你足够细心,你会注意到刚才在选颜色时,如果颜色还没有选定,它周围就会有一个当前颜色的色圈,而当颜色已选定时,色圈就会变为彩色背景,这是因为之前给类CMy0910200155Dlg添加了WM_CTLCOLOR消息,因此当触发该消息时,会调用,HBRUSH CMy0910200155Dlg:OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) HBRUSH hbr = CDialog:OnCtlColor(pDC, pWnd, nCtlColor);if(pWnd-GetDlgCtrlID()=IDC_COMBO_PEN_COLOR) hbr=:CreateSolidBrush(this-m_CurrentPenColor); pDC-SetBkColor(this-m_CurrentPenColor); if(pWnd-GetDlgCtrlID()=IDC_COMBO_BRUSH_COLOR) hbr=:CreateSolidBrush(this-m_CurrentBrushColor); pDC-SetBkColor(this-m_CurrentBrushColor); return hbr;该方法可以实现控件颜色的改变,考虑到界面的简洁(不是简单)和色彩协调,其它控件的颜色就不必改变了。做好了这些准备工作,现在我们开始绘图,点击”绘图”按钮,就触发了IDC_BUTTON_DRAW的BN_CLICKED消息,会调用,void CMy0910200155Dlg:OnButtonDraw() flag=1;flag1=1;OnPaint();this-GetDlgItem(IDC_BUTTON_LOAD)-EnableWindow(FALSE);在这里,我们只将flag=1和flag1=1条件下的OnPaint()函数展开(系统自己生成的代码我们略去),if(indexGetDlgItem(IDC_BUTTON_CLEAN)-EnableWindow(FALSE); /根据判断确定”撤消”按钮的状态,若绘图区没有图形,则其失效。if(flag=1|flag=2|flag=3) CClientDC dc(this); CPen pNewPen1; pNewPen1.CreatePen(PS_SOLID,2,RGB(80,80,180);CPen *pOldPen1=dc.SelectObject(&pNewPen1);CBrush pNewBrush1; pNewBrush1.CreateSolidBrush(RGB(80,80,180); CBrush *pOldBrush1=dc.SelectObject(&pNewBrush1); CRect rect1;this-GetDlgItem(IDC_DRAW_PLACE)-GetWindowRect(&rect1);this-ScreenToClient(&rect1);CRect draw1(rect1.left+3,rect1.top+9,rect1.right-2,rect1.bottom-2);dc.Rectangle(draw1);dc.SelectObject(pOldPen1);dc.SelectObject(pOldBrush1); /此为所有情况下的公用部分,将绘图区绘为背景色。if(flag=1|flag=3)if(flag=3) this-m_CurrentPenColor=pmn-PenColor; this-m_CurrentBrushColor=pmn-BrushColor; int mark=pmn-Mark;CPen pNewPen; pNewPen.CreatePen(PS_SOLID,2,this-m_CurrentPenColor);CPen *pOldPen=dc.SelectObject(&pNewPen);CBrush pNewBrush; pNewBrush.CreateSolidBrush(this-m_CurrentBrushColor); CBrush *pOldBrush=dc.SelectObject(&pNewBrush);CRect rect; this-GetDlgItem(IDC_DRAW_PLACE)-GetWindowRect(&rect);this-ScreenToClient(&rect);CRect draw(rect.left+3,rect.top+9,rect.right-2,rect.bottom-2); this-GetDlgItem(IDC_DRAW_PLACE)-GetWindowRect(&rect); this-ScreenToClient(&rect);CRect draw(rect.left+3,rect.top+9,rect.right-2,rect.bottom-2);if(flag=1) if(this-m_Shape.GetSel(0) dc.Rectangle(draw);mark=0; else if(this-m_Shape.GetSel(1) dc.RoundRect(draw,CPoint(100,100);mark=1; else dc.Ellipse(draw);mark=2;if(flag=3)switch(mark) case 0:dc.Rectangle(draw);break; case 1:dc.RoundRect(draw,CPoint(100,100);break;default:dc.Ellipse(draw);break;dc.SelectObject(pOldPen);dc.SelectObject(pOldBrush);this-GetDlgItem(IDC_BUTTON_CLEAN)-EnableWindow(TRUE);if(flag=1&flag1=1)pmN=new CMemoryNode(m_CurrentPenColor,m_CurrentBrushColor,mark); pta.Add(pmN); OnFileWrite(); flag1=0; /用当前所选画笔,画刷和图形绘图。 其实,当点击”绘图”按钮时,只是先用背景色的画笔和刷子把绘图区重绘一遍,然后再用当前所选画笔,刷子和图形绘图,同时将当前的绘图信息保存在pta数组中和写入到文件中。 现在,请仔细看一下最后一句flag1=0;,它的作用很大,它解决了当点击绘图按钮,绘出图形后,移动窗口时图形信息的重复保存和文档的重复书写问题。没有它,程序虽然可以正常运行,但当从文件中读取信息后,运行结果和预想很有出入! 点击”绘图按钮”后,”载入历史”按钮将不能使用,这就限定了这个按钮只能在程序的开始使用,而且只能使用一次。 在上面提到了将绘图信息写入到文件中,那么下面看看这个写文件的函数, void CMy0910200155Dlg:OnFileWrite() int sum=pta.GetSize(); /已画图形的个数,即点击”绘图”按钮的次数。 ofstream outfile; ofstream outfile1; outfile.open(Histories.txt,ios:app); /添加式书写。 outfile1.open(Index.txt); /覆盖式书写。 if(!outfile|!outfile1) MessageBox(数据无法保存!); else outfilem_CurrentPenColort; outfilem_CurrentBrushColort; outfilemarkendl; outfile1sumpta.GetUpperBound(); OnPaint(); 仿照前面的方式,为了更好表现出函数的功能,将flag=2和flag1=2条件下的OnPaint()函数完全地展开(和其它情况的公用部分省略),if(flag=2) if(index=0) CPen pNewPen; pNewPen.CreatePen(PS_SOLID,2,RGB(80,80,180); CPen *pOldPen=dc.SelectObject(&pNewPen); CBrush pNewBrush; pNewBrush.CreateSolidBrush(RGB(80,80,180); CBrush *pOldBrush=dc.SelectObject(&pNewBrush);CRect rect; this-GetDlgItem(IDC_DRAW_PLACE)-GetWindowRect(&rect); this-ScreenToClient(&rect); CRect draw(rect.left+3,rect.top+9,rect.right-2,rect.bottom-2); dc.Rectangle(draw); dc.SelectObject(pOldPen); dc.SelectObject(pOldBrush); /当撤消完全时,只需重绘绘图区即可。 if(index0) CMemoryNode *pmN; pmN=(CMemoryNode *)pta.GetAt(index-1); CPen pNewPen1; pNewPen1.CreatePen(PS_SOLID,2,RGB(80,80,180); CPen *pOldPen1=dc.SelectObject(&pNewPen1); CBrush pNewBrush1; pNewBrush1.CreateSolidBrush(RGB(80,80,180); CBrush *pOldBrush1=dc.SelectObject(&pNewBrush1);CRect rect1;this-GetDlgItem(IDC_DRAW_PLACE)-GetWindowRect(&rect1); this-ScreenToClient(&rect1); CRect draw1(rect1.left+3,rect1.top+9,rect1.right-2,rect1.bottom-2); dc.Rectangle(draw1); dc.SelectObject(pOldPen1); dc.SelectObject(pOldBrush1); CPen pNewPen; pNewPen.CreatePen(PS_SOLID,2,pmN-PenColor); CPen *pOldPen=dc.SelectObject(&pNewPen); CBrush pNewBrush; pNewBrush.CreateSolidBrush(pmN-BrushColor); CBrush *pOldBrush=dc.SelectObject(&pNewBrush); CRect rect; this-GetDlgItem(IDC_DRAW_PLACE)-GetWindowRect(&rect); this-ScreenToClient(&rect); CRect draw(rect.left+3,rect.top+9,rect.right-2,rect.bottom-2); if(pmN-Mark=0) dc.Rectangle(draw); else if(pmN-Mark=1) dc.RoundRect(draw,CPoint(100,100); else dc.Ellipse(draw); dc.SelectObject(pOldPen); dc.SelectObject(pOldBrush); if(flag1=2) this-pta.RemoveAt(index-1); flag1=0; 虽然有些冗长,但可以清晰地看出撤消的思路也是先用背景色的画笔和刷子把绘图区重绘一遍,然后调用上一次的绘图信息,重新”复原”图形。 最后的if语句,用flag1=2作为判断条件,并最后置flag1=0;,很好地区分了点击”撤消”按钮与点击后窗口的移动,避免了窗口重绘时的”重复撤消”。 下面点击”版权声明”按钮,这时将会调用, void CMy0910200155Dlg:OnButtonShow() CShow dlg;ButtonState=1; dlg.DoModal();这里面用到了一个标识性变量,int ButtonState,它被声明为类CShow的一个外部变量,我认为在某方面它起到了一个接口的作用。当这个对话框被创建时,自然要调用CShow类的OnPaint()函数,其代码为,void CShow:OnPaint() CPaintDC dc(this); extern ButtonState; if(ButtonState=1) CRect rect; this-GetClientRect(&rect); this-ScreenToClient(&rect); for(int j=3;j=1;j-) for(int i=1;iGetClientRect(&rect); this-ScreenToClient(&rect); for(int j=3;j=1;j-) for(int i=1;inum; index=num; this-GetDlgItem(IDC_BUTTON_CLEAN)-EnableWindow(TRUE); OnFileRead(); this-GetDlgItem(IDC_BUTTON_LOAD)-EnableWindow(FALSE);文件加载后就有东西可操作,所以”撤消”按钮就可用。这里提到了从文件中读取数据,我们就来看看它,void CMy0910200155Dlg:OnFileRead() ifstream infile(Histories.txt,ios:nocreate); if(!infile) MessageBox(文件不存在或不完整,无法读取!); this-GetDlgItem(IDC_BUTTON_CLEAN)-EnableWindow(FALSE); int Mark; COLORREF BrushColor; COLORREF PenColor; for(int i=0;infile;i+) infilePenColor;infileBrushColor;infileMark;m_CurrentPenColor=PenColor; m_CurrentBrushColor=BrushColor; switch(Mark)case 0:m_Shape.GetSel(0);break;case 1:m_Shape.GetSel(1);break;default:m_Shape.GetSel(2);break;pmn=new CMemoryNode(PenColor,BrushColor,Mark);pta.Add(pmn);flag=3; OnPaint(); infile.close();这里是用C+的文件输入流来读取数据的,读取出的数据,以对象的形式保存在数组pta中。其后又调用了OnPaint()函数,同样,我们继续将flag=3时的这一函数展开(共用部分省略),if(flag=1|flag=3)if(flag=3) this-m_CurrentPenColor=pmn-PenColor; this-m_CurrentBrushColor=pmn-BrushColor; int mark=pmn-Mark;CPen pNewPen; pNewPen.CreatePen(PS_SOLID,2,this-m_CurrentPenColor);CPen *pOldPen=dc.SelectObject(&pNewPen);CBrush pNewBrush; pNewBrush.CreateSolidBrush(this-m_CurrentBrushColor); CBrush *pOldBrush=dc.SelectObject(&pNewBrush);CRect rect; this-GetDlgItem(IDC_DRAW_PLACE)-GetWindowRect(&rect);this-ScreenToClient(&rect);CRect draw(rect.left+3,rect.top+9,rect.right-2,rect.bottom-2); this-GetDlgItem(IDC_DRAW_PLACE)-GetWindowRect(&rect); this-ScreenToClient(&rect);CRect draw(rect.left+3,rect.top+9,rect.right-2,rect.bottom-2);if(flag=1) if(this-m_Shape.GetSel(0) dc.Rectangle(draw);mark=0; else if(this-m_Shape.GetSel(1) dc.RoundRect(draw,CPoint(100,100);mark=1; else dc.Ellipse(draw);mark=2;if(flag=3)switch(mark) case 0:dc.Rectangle(draw);break; case 1:dc.RoundRect(draw,CPoint(100,100);break;default:dc.Ellipse(draw);break;dc.SelectObject(pOldPen);dc.SelectObject(pOldBrush);this-GetDlgItem(IDC_BUTTON_CLEAN)-EnableWindow(TRUE);同样也可以看出,载入信息时,也是先用背景色的画笔和画刷将绘图区刷一遍,然后显示最近一次绘制的图形。至此,整个应用程序的功能基本介绍完,其功能的实现思想及源代码也已经能够清晰。其中主要是用了flag和flag1的组合来表示应该执行的程序:flag=1,flag1=1时,绘图按钮被点击,绘图并且写文件;flag=1,flag1=0时,确保绘图按钮被点击过后,窗口重绘时不重写文件;flag=2,flag1=2时,撤消按钮被点击,实现撤消效果;flag=2,flag1=0时,确保撤消按钮被点击过后,窗口重绘时不重复撤消;flag=3时,加载历史按钮被点击,负责加载后图形的绘制与显示。七、 遇到的问题及解决办法:1)在编程过程中,遇到的最多的和最主要的问题就是窗口的重绘问题,往往感觉一切都好了时,一次偶然的机会,才发现只要窗口一移动,窗口中绘出的图像就全都没了,通过很多次的尝试与反复修改,问题解决了。在主对话框中,主要是通过flag和flag1的组合来解决的:在未解决之前,只有flag一个变量标识,当时大致是这样的:flag=1,表明”绘图”按钮被按下,然后执行绘图程序;flag=2,表示”撤消”按钮被按下,然后执行撤消;以上执行完后,都将flag置为初值0,现在看来这是最错的地方,这种做法肯定会使重画时失败!后来增加了一个变量flag1,用两个变量的组合表示会出现的各种情况,基本如下:flag=2,flag1=2时,表明”撤消”按钮被点击,实现撤消效果;flag=2,flag1=0时,确保”撤消”按钮被点击过后,窗口重绘时不重复撤消;flag=3时,表明”加载历史”按钮被点击,负责加载后图形的绘制与显示。在点击”版权声明”按钮后的弹出式的对话框中,是通过ButtonStat的标识来实现的,其值只有在点击”版权声明”按钮时才为1,其余时间均为0。其实问题也最先是在这里发现的,当时的OnPaint()源代码只有前面提到的第一部分,每次移动窗口时都得重画好久,而且位于它下方的主对话框钟会的图形也会被部分地擦掉。2)其次是关于文件的写入和读出问题,尤其是有一段时间,无论怎么,都看不出自己的程序出了什么问题,因为编译完全能通过,而且可以正常运行,但结果与我预想的还是有一定的出入,而且这种出入还似乎是有规律的。经过几天的琢磨,反复尝试与修改,终于在解决窗口重绘问题时一起解决了,原来在移动窗口导致窗口重绘时,都会重复的写入一组相同的数据,即当前的绘图信息。在解决之前,只有一个flag变量标识,当flag=1时,绘图并写文件,而每次重绘时都会使用相同的代码,所以就重复写文件;后来联系窗口的重绘问题,新加了一个变量flag1与flag共同标识,问题就迎刃而解,基本如下:flag=1,flag1=1时,表明”绘图”按钮被点击,绘图并且写文件;flag=1,flag1=0时,确保”绘图”按钮被点击过后,窗口重绘时不重写文件;3)是在编程之初,还不是非常习惯于MFC的这种机制与实现方式,有一些关系没有完全搞清楚,常常不知道通过什么方式实现自己想要实现的功能,什么时候该定义函数,什么时候又该创建新类经常有种无从下手的感觉。通过翻阅大量的书本,上搞清了一些常用的处理方式,而且学到了一些编程技巧,同时通过联系实际现象与问题,感觉自己对MFC编程有了更深层次的认识和体会。4)还有一些其它类型的问题,基本上通过查阅相关书籍都可
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 时间的认识课件
- 秩序岗位服务培训
- 时间和方向课件
- 时间与管理课件讲解
- 2025版电梯维保与应急物资储备服务合同范本
- 二零二五年度市政道路建设项目招投标合同范本
- 二零二五年度矿产资源中介服务合同范例
- 2025版高钙石建筑材料原料购销合作框架协议
- 二零二五年度建筑工程设备租赁及保养合同
- 二零二五年度医疗设备生产与销售及售后服务合同
- 2025年新版《食品安全法》知识竞赛试题(附答案)
- 2025至2030中国保护器行业发展趋势分析与未来投资战略咨询研究报告
- 劳动教育主题活动课说课稿
- 2025年电商行业直播带货研究报告:直播电商产业链分析
- 2025年急诊急救三基考试试题(附参考答案)
- 2024年临汾市纪委监委所属事业单位选调真题
- 企业工程管理办法
- 小学生美术国画课件
- 通信工程安全生产操作规范
- 2025年广东省中考数学试卷真题(含答案详解)
- 氢气安全培训课件
评论
0/150
提交评论